use threejs module js, remove unused libraries, increase world generation seed to 64 bit, implement random world spawn, improve start script
This commit is contained in:
@@ -34,9 +34,11 @@ Click [here](https://labystudio.github.io/js-minecraft/) for a demo!
|
||||
- World
|
||||
- 16x16x16 Chunks
|
||||
- Block type, data, sky & block lightning
|
||||
- Perlin world generation
|
||||
- Cave generation
|
||||
- Tree and big tree generation
|
||||
- Minecraft Alpha Generator
|
||||
- 64 bits seed
|
||||
- Perlin terrain generation
|
||||
- Perlin cave generation
|
||||
- Perlin tree and big tree generation
|
||||
- Camera
|
||||
- Frustum Culling
|
||||
- Fog
|
||||
@@ -47,18 +49,18 @@ Click [here](https://labystudio.github.io/js-minecraft/) for a demo!
|
||||
- First person item in hand
|
||||
- GUI
|
||||
- Screens
|
||||
- Loading Screen
|
||||
- InGame Menu
|
||||
- Controls Screen
|
||||
- Loading Screen
|
||||
- InGame Menu
|
||||
- Controls Screen
|
||||
- Widgets
|
||||
- Button
|
||||
- KeyBinding
|
||||
- Slider
|
||||
- Switches
|
||||
- Button
|
||||
- KeyBinding
|
||||
- Slider
|
||||
- Switches
|
||||
- Overlay
|
||||
- Cross-hair
|
||||
- Font rendering
|
||||
- Hot-Bar
|
||||
- Cross-hair
|
||||
- Font rendering
|
||||
- Hot-Bar
|
||||
</details>
|
||||
<hr>
|
||||
|
||||
@@ -72,8 +74,6 @@ _Note: All textures from the original game were used for the screenshots only!_
|
||||
|
||||
### Licensing
|
||||
- The main rendering library is [three.js](https://github.com/mrdoob/three.js/)
|
||||
- The [stats.js](https://github.com/mrdoob/stats.js/) library is used for performance tracking
|
||||
- Safari render issues fixed by [context-filter-polyfill](https://github.com/davidenke/context-filter-polyfill)
|
||||
- All used sound resources are taken from [freesounds.org](https://freesound.org/people/C418/downloaded_sounds/?page=8#sound)
|
||||
|
||||
<hr>
|
||||
|
||||
+2
-2
@@ -11,12 +11,12 @@
|
||||
|
||||
<div id="content">
|
||||
<div id="canvas-container" class="fullscreen"></div>
|
||||
<span id="pre-status">Loading page...</span>
|
||||
<span id="pre-status">Loading scripts...</span>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
<script type="module" src="src/start.js"></script>
|
||||
<script type="module" src="src/js/Start.js"></script>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
-363
@@ -1,363 +0,0 @@
|
||||
!function() {
|
||||
"use strict";
|
||||
var t;
|
||||
!function(t) {
|
||||
t.None = "none",
|
||||
t.Url = "url",
|
||||
t.Blur = "blur",
|
||||
t.Brightness = "brightness",
|
||||
t.Contrast = "contrast",
|
||||
t.DropShadow = "drop-shadow",
|
||||
t.Grayscale = "grayscale",
|
||||
t.HueRotate = "hue-rotate",
|
||||
t.Invert = "invert",
|
||||
t.Opacity = "opacity",
|
||||
t.Saturate = "saturate",
|
||||
t.Sepia = "sepia"
|
||||
}(t || (t = {}));
|
||||
var r = new Map
|
||||
, a = function(t) {
|
||||
var r = document.createElement("canvas");
|
||||
return r.height = t.canvas.height,
|
||||
r.width = t.canvas.width,
|
||||
Object.defineProperty(r, "__skipFilterPatch", {
|
||||
value: !0
|
||||
}),
|
||||
r.getContext("2d")
|
||||
};
|
||||
var e = ["__skipFilterPatch", "__currentPathMirror", "canvas", "filter", "getImageData"];
|
||||
var n = ["clearRect", "drawImage", "fill", "fillRect", "fillText", "stroke", "strokeRect", "strokeText"]
|
||||
, i = function(t, a) {
|
||||
a.match(/([-a-z]+)(?:\(([\w\d\s\.%-]*)\))?/gim).map(function(t) {
|
||||
return t.match(/([-a-z]+)(?:\((.*)\))?/i).slice(1, 3)
|
||||
}).reduce(function(t, a) {
|
||||
var e = a[0]
|
||||
, n = a[1];
|
||||
return r.has(e) ? r.get(e).apply(void 0, [t].concat((n || "").split(" "))) : t
|
||||
}, t)
|
||||
}
|
||||
, o = function(t) {
|
||||
var r = parseFloat(t);
|
||||
return /%\s*?$/i.test(t) && (r /= 100),
|
||||
r
|
||||
}
|
||||
, s = function(t) {
|
||||
return parseFloat(t)
|
||||
};
|
||||
var c, h;
|
||||
r.set(t.None, function(t) {
|
||||
return t
|
||||
}),
|
||||
r.set(t.Blur, function(t, r) {
|
||||
void 0 === r && (r = "0");
|
||||
var a = s(r);
|
||||
if (a <= 0)
|
||||
return t;
|
||||
for (var e, n, i, o, c = t.canvas, h = c.height, u = c.width, v = t.getImageData(0, 0, u, h), f = v.data, p = u - 1, g = h - 1, l = a + 1, d = [1, 57, 41, 21, 203, 34, 97, 73, 227, 91, 149, 62, 105, 45, 39, 137, 241, 107, 3, 173, 39, 71, 65, 238, 219, 101, 187, 87, 81, 151, 141, 133, 249, 117, 221, 209, 197, 187, 177, 169, 5, 153, 73, 139, 133, 127, 243, 233, 223, 107, 103, 99, 191, 23, 177, 171, 165, 159, 77, 149, 9, 139, 135, 131, 253, 245, 119, 231, 224, 109, 211, 103, 25, 195, 189, 23, 45, 175, 171, 83, 81, 79, 155, 151, 147, 9, 141, 137, 67, 131, 129, 251, 123, 30, 235, 115, 113, 221, 217, 53, 13, 51, 50, 49, 193, 189, 185, 91, 179, 175, 43, 169, 83, 163, 5, 79, 155, 19, 75, 147, 145, 143, 35, 69, 17, 67, 33, 65, 255, 251, 247, 243, 239, 59, 29, 229, 113, 111, 219, 27, 213, 105, 207, 51, 201, 199, 49, 193, 191, 47, 93, 183, 181, 179, 11, 87, 43, 85, 167, 165, 163, 161, 159, 157, 155, 77, 19, 75, 37, 73, 145, 143, 141, 35, 138, 137, 135, 67, 33, 131, 129, 255, 63, 250, 247, 61, 121, 239, 237, 117, 29, 229, 227, 225, 111, 55, 109, 216, 213, 211, 209, 207, 205, 203, 201, 199, 197, 195, 193, 48, 190, 47, 93, 185, 183, 181, 179, 178, 176, 175, 173, 171, 85, 21, 167, 165, 41, 163, 161, 5, 79, 157, 78, 154, 153, 19, 75, 149, 74, 147, 73, 144, 143, 71, 141, 140, 139, 137, 17, 135, 134, 133, 66, 131, 65, 129, 1][a], m = [0, 9, 10, 10, 14, 12, 14, 14, 16, 15, 16, 15, 16, 15, 15, 17, 18, 17, 12, 18, 16, 17, 17, 19, 19, 18, 19, 18, 18, 19, 19, 19, 20, 19, 20, 20, 20, 20, 20, 20, 15, 20, 19, 20, 20, 20, 21, 21, 21, 20, 20, 20, 21, 18, 21, 21, 21, 21, 20, 21, 17, 21, 21, 21, 22, 22, 21, 22, 22, 21, 22, 21, 19, 22, 22, 19, 20, 22, 22, 21, 21, 21, 22, 22, 22, 18, 22, 22, 21, 22, 22, 23, 22, 20, 23, 22, 22, 23, 23, 21, 19, 21, 21, 21, 23, 23, 23, 22, 23, 23, 21, 23, 22, 23, 18, 22, 23, 20, 22, 23, 23, 23, 21, 22, 20, 22, 21, 22, 24, 24, 24, 24, 24, 22, 21, 24, 23, 23, 24, 21, 24, 23, 24, 22, 24, 24, 22, 24, 24, 22, 23, 24, 24, 24, 20, 23, 22, 23, 24, 24, 24, 24, 24, 24, 24, 23, 21, 23, 22, 23, 24, 24, 24, 22, 24, 24, 24, 23, 22, 24, 24, 25, 23, 25, 25, 23, 24, 25, 25, 24, 22, 25, 25, 25, 24, 23, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 23, 25, 23, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 24, 22, 25, 25, 23, 25, 25, 20, 24, 25, 24, 25, 25, 22, 24, 25, 24, 25, 24, 25, 25, 24, 25, 25, 25, 25, 22, 25, 25, 25, 24, 25, 24, 25, 18][a], _ = [], w = [], y = [], D = [], P = [], I = [], b = 3; b-- > 0; ) {
|
||||
for (var M = 0, O = 0, k = 0; k < h; k++) {
|
||||
for (var C = f[M] * l, x = f[M + 1] * l, F = f[M + 2] * l, j = f[M + 3] * l, R = 1; R <= a; R++)
|
||||
e = M + ((R > p ? p : R) << 2),
|
||||
C += f[e++],
|
||||
x += f[e++],
|
||||
F += f[e++],
|
||||
j += f[e];
|
||||
for (var S = 0; S < u; S++)
|
||||
_[O] = C,
|
||||
w[O] = x,
|
||||
y[O] = F,
|
||||
D[O] = j,
|
||||
0 === k && (P[S] = ((e = S + l) < p ? e : p) << 2,
|
||||
I[S] = (e = S - a) > 0 ? e << 2 : 0),
|
||||
n = M + P[S],
|
||||
i = M + I[S],
|
||||
C += f[n++] - f[i++],
|
||||
x += f[n++] - f[i++],
|
||||
F += f[n++] - f[i++],
|
||||
j += f[n] - f[i],
|
||||
O++;
|
||||
M += u << 2
|
||||
}
|
||||
for (S = 0; S < u; S++) {
|
||||
var T = S;
|
||||
for (C = _[T] * l,
|
||||
x = w[T] * l,
|
||||
F = y[T] * l,
|
||||
j = D[T] * l,
|
||||
R = 1; R <= a; R++)
|
||||
C += _[T += R > g ? 0 : u],
|
||||
x += w[T],
|
||||
F += y[T],
|
||||
j += D[T];
|
||||
for (O = S << 2,
|
||||
k = 0; k < h; k++)
|
||||
f[O + 3] = o = j * d >>> m,
|
||||
o > 0 ? (o = 255 / o,
|
||||
f[O] = (C * d >>> m) * o,
|
||||
f[O + 1] = (x * d >>> m) * o,
|
||||
f[O + 2] = (F * d >>> m) * o) : f[O] = f[O + 1] = f[O + 2] = 0,
|
||||
0 === S && (P[k] = ((e = k + l) < g ? e : g) * u,
|
||||
I[k] = (e = k - a) > 0 ? e * u : 0),
|
||||
n = S + P[k],
|
||||
i = S + I[k],
|
||||
C += _[n] - _[i],
|
||||
x += w[n] - w[i],
|
||||
F += y[n] - y[i],
|
||||
j += D[n] - D[i],
|
||||
O += u << 2
|
||||
}
|
||||
}
|
||||
return t.putImageData(v, 0, 0),
|
||||
t
|
||||
}),
|
||||
r.set(t.Brightness, function(t, r) {
|
||||
if (void 0 === r && (r = "1"),
|
||||
1 === (r = o(r)))
|
||||
return t;
|
||||
r < 0 && (r = 0);
|
||||
for (var a = t.canvas, e = a.height, n = a.width, i = t.getImageData(0, 0, n, e), s = i.data, c = s.length, h = 0; h < c; h += 4)
|
||||
s[h + 0] *= r,
|
||||
s[h + 1] *= r,
|
||||
s[h + 2] *= r;
|
||||
return t.putImageData(i, 0, 0),
|
||||
t
|
||||
}),
|
||||
r.set(t.Contrast, function(t, r) {
|
||||
if (void 0 === r && (r = "1"),
|
||||
1 === (r = o(r)))
|
||||
return t;
|
||||
r < 0 && (r = 0);
|
||||
for (var a = t.canvas, e = a.height, n = a.width, i = t.getImageData(0, 0, n, e), s = i.data, c = s.length, h = 0; h < c; h += 4)
|
||||
s[h + 0] = 255 * ((s[h + 0] / 255 - .5) * r + .5),
|
||||
s[h + 1] = 255 * ((s[h + 1] / 255 - .5) * r + .5),
|
||||
s[h + 2] = 255 * ((s[h + 2] / 255 - .5) * r + .5);
|
||||
return t.putImageData(i, 0, 0),
|
||||
t
|
||||
}),
|
||||
r.set(t.DropShadow, function(t, r, a, e, n) {
|
||||
var i = document.createElement("canvas").getContext("2d");
|
||||
i.shadowOffsetX = s(r),
|
||||
i.shadowOffsetY = s(a),
|
||||
i.shadowBlur = n ? s(e || "0") : 0,
|
||||
i.shadowColor = n || e || "transparent",
|
||||
i.drawImage(t.canvas, 0, 0);
|
||||
var o = t.canvas
|
||||
, c = o.width
|
||||
, h = o.height;
|
||||
return t.putImageData(i.getImageData(0, 0, c, h), 0, 0),
|
||||
t
|
||||
}),
|
||||
r.set(t.Grayscale, function(t, r) {
|
||||
if (void 0 === r && (r = "0"),
|
||||
(r = o(r)) <= 0)
|
||||
return t;
|
||||
r > 1 && (r = 1);
|
||||
for (var a = t.canvas, e = a.height, n = a.width, i = t.getImageData(0, 0, n, e), s = i.data, c = s.length, h = 0; h < c; h += 4) {
|
||||
var u = .2126 * s[h] + .7152 * s[h + 1] + .0722 * s[h + 2];
|
||||
s[h + 0] += (u - s[h + 0]) * r,
|
||||
s[h + 1] += (u - s[h + 1]) * r,
|
||||
s[h + 2] += (u - s[h + 2]) * r
|
||||
}
|
||||
return t.putImageData(i, 0, 0),
|
||||
t
|
||||
}),
|
||||
r.set(t.HueRotate, function(t, r) {
|
||||
void 0 === r && (r = "0deg");
|
||||
var a = function(t) {
|
||||
var r = parseFloat(t);
|
||||
switch (t.slice(r.toString().length)) {
|
||||
case "deg":
|
||||
r /= 360;
|
||||
break;
|
||||
case "grad":
|
||||
r /= 400;
|
||||
break;
|
||||
case "rad":
|
||||
r /= 2 * Math.PI
|
||||
}
|
||||
return r
|
||||
}(r);
|
||||
if (a <= 0)
|
||||
return t;
|
||||
var e, n, i, o, s, c, h, u, v, f = t.canvas, p = f.height, g = f.width, l = t.getImageData(0, 0, g, p), d = l.data, m = (a % 1 + 1) % 1 * 3, _ = Math.floor(m), w = m - _, y = 1 - w;
|
||||
switch (_) {
|
||||
case 0:
|
||||
e = y,
|
||||
n = 0,
|
||||
i = w,
|
||||
o = w,
|
||||
s = y,
|
||||
c = 0,
|
||||
h = 0,
|
||||
u = w,
|
||||
v = y;
|
||||
break;
|
||||
case 1:
|
||||
e = 0,
|
||||
n = w,
|
||||
i = y,
|
||||
o = y,
|
||||
s = 0,
|
||||
c = w,
|
||||
h = w,
|
||||
u = y,
|
||||
v = 0;
|
||||
break;
|
||||
case 2:
|
||||
e = w,
|
||||
n = y,
|
||||
i = 0,
|
||||
o = 0,
|
||||
s = w,
|
||||
c = y,
|
||||
h = y,
|
||||
u = 0,
|
||||
v = w
|
||||
}
|
||||
for (var D = 0, P = 0; P < p; ++P)
|
||||
for (var I = 0; I < g; ++I) {
|
||||
var b = d[0 + (D = 4 * (P * g + I))]
|
||||
, M = d[D + 1]
|
||||
, O = d[D + 2];
|
||||
d[D + 0] = Math.floor(e * b + n * M + i * O),
|
||||
d[D + 1] = Math.floor(o * b + s * M + c * O),
|
||||
d[D + 2] = Math.floor(h * b + u * M + v * O)
|
||||
}
|
||||
return t.putImageData(l, 0, 0),
|
||||
t
|
||||
}),
|
||||
r.set(t.Invert, function(t, r) {
|
||||
if (void 0 === r && (r = "0"),
|
||||
(r = o(r)) <= 0)
|
||||
return t;
|
||||
r > 1 && (r = 1);
|
||||
for (var a = t.canvas, e = a.height, n = a.width, i = t.getImageData(0, 0, n, e), s = i.data, c = s.length, h = 0; h < c; h += 4)
|
||||
s[h + 0] = Math.abs(s[h + 0] - 255 * r),
|
||||
s[h + 1] = Math.abs(s[h + 1] - 255 * r),
|
||||
s[h + 2] = Math.abs(s[h + 2] - 255 * r);
|
||||
return t.putImageData(i, 0, 0),
|
||||
t
|
||||
}),
|
||||
r.set(t.Opacity, function(t, r) {
|
||||
if (void 0 === r && (r = "1"),
|
||||
(r = o(r)) < 0)
|
||||
return t;
|
||||
r > 1 && (r = 1);
|
||||
for (var a = t.canvas, e = a.height, n = a.width, i = t.getImageData(0, 0, n, e), s = i.data, c = s.length, h = 3; h < c; h += 4)
|
||||
s[h] *= r;
|
||||
return t.putImageData(i, 0, 0),
|
||||
t
|
||||
}),
|
||||
r.set(t.Saturate, function(t, r) {
|
||||
void 0 === r && (r = "1");
|
||||
var a = o(r);
|
||||
if (1 === a)
|
||||
return t;
|
||||
a < 0 && (a = 0);
|
||||
for (var e = t.canvas, n = e.height, i = e.width, s = t.getImageData(0, 0, i, n), c = s.data, h = .3086 * (1 - a), u = .6094 * (1 - a), v = .082 * (1 - a), f = i << 2, p = 0; p < n; p++)
|
||||
for (var g = p * f, l = 0; l < i; l++) {
|
||||
var d = g + (l << 2)
|
||||
, m = c[d + 0]
|
||||
, _ = c[d + 1]
|
||||
, w = c[d + 2];
|
||||
c[d + 0] = (h + a) * m + u * _ + v * w,
|
||||
c[d + 1] = h * m + (u + a) * _ + v * w,
|
||||
c[d + 2] = h * m + u * _ + (v + a) * w
|
||||
}
|
||||
return t.putImageData(s, 0, 0),
|
||||
t
|
||||
}),
|
||||
r.set(t.Sepia, function(t, r) {
|
||||
if (void 0 === r && (r = "0"),
|
||||
(r = o(r)) <= 0)
|
||||
return t;
|
||||
r > 1 && (r = 1);
|
||||
for (var a = t.canvas, e = a.height, n = a.width, i = t.getImageData(0, 0, n, e), s = i.data, c = s.length, h = 0; h < c; h += 4) {
|
||||
var u = s[h + 0]
|
||||
, v = s[h + 1]
|
||||
, f = s[h + 2];
|
||||
s[h + 0] = (.393 * u + .769 * v + .189 * f) * r + u * (1 - r),
|
||||
s[h + 1] = (.349 * u + .686 * v + .168 * f) * r + v * (1 - r),
|
||||
s[h + 2] = (.272 * u + .534 * v + .131 * f) * r + f * (1 - r)
|
||||
}
|
||||
return t.putImageData(i, 0, 0),
|
||||
t
|
||||
}),
|
||||
"filter"in CanvasRenderingContext2D.prototype || (c = HTMLCanvasElement,
|
||||
h = CanvasRenderingContext2D,
|
||||
Object.defineProperty(c.prototype, "__skipFilterPatch", {
|
||||
writable: !0,
|
||||
value: !1
|
||||
}),
|
||||
Object.defineProperty(c.prototype, "__currentPathMirror", {
|
||||
writable: !0,
|
||||
value: void 0
|
||||
}),
|
||||
Object.defineProperty(h.prototype, "filter", {
|
||||
writable: !0,
|
||||
value: t.None
|
||||
}),
|
||||
function(t) {
|
||||
Object.keys(t.prototype).filter(function(t) {
|
||||
return e.indexOf(t) < 0
|
||||
}).map(function(r) {
|
||||
return {
|
||||
member: r,
|
||||
descriptor: Object.getOwnPropertyDescriptor(t.prototype, r)
|
||||
}
|
||||
}).filter(function(t) {
|
||||
return t.descriptor.set
|
||||
}).forEach(function(r) {
|
||||
var e = r.member
|
||||
, n = r.descriptor;
|
||||
Object.defineProperty(t.prototype, e, {
|
||||
get: function() {
|
||||
return this.canvas.__skipFilterPatch ? n.get.call(this) : this.canvas.__currentPathMirror[e]
|
||||
},
|
||||
set: function(t) {
|
||||
if (this.canvas.__skipFilterPatch)
|
||||
return n.set.call(this, t);
|
||||
this.canvas.__currentPathMirror || (this.canvas.__currentPathMirror = a(this)),
|
||||
this.canvas.__currentPathMirror[e] = t
|
||||
}
|
||||
})
|
||||
})
|
||||
}(CanvasRenderingContext2D),
|
||||
function(t) {
|
||||
Object.keys(t.prototype).filter(function(t) {
|
||||
return e.indexOf(t) < 0
|
||||
}).map(function(r) {
|
||||
return {
|
||||
member: r,
|
||||
descriptor: Object.getOwnPropertyDescriptor(t.prototype, r)
|
||||
}
|
||||
}).filter(function(t) {
|
||||
var r = t.descriptor;
|
||||
return r.value && "function" == typeof r.value
|
||||
}).forEach(function(r) {
|
||||
var e = r.member
|
||||
, o = r.descriptor.value;
|
||||
Object.defineProperty(t.prototype, e, {
|
||||
value: function() {
|
||||
for (var t, r = [], s = 0; s < arguments.length; s++)
|
||||
r[s] = arguments[s];
|
||||
if (this.canvas.__skipFilterPatch)
|
||||
return o.call.apply(o, [this].concat(r));
|
||||
this.canvas.__currentPathMirror || (this.canvas.__currentPathMirror = a(this));
|
||||
var c = (t = this.canvas.__currentPathMirror)[e].apply(t, r);
|
||||
if (n.indexOf(e) > -1) {
|
||||
i(this.canvas.__currentPathMirror, this.filter),
|
||||
this.canvas.__skipFilterPatch = !0;
|
||||
var h = void 0;
|
||||
"getTransform"in this && (h = this.getTransform(),
|
||||
this.setTransform(1, 0, 0, 1, 0, 0)),
|
||||
this.drawImage(this.canvas.__currentPathMirror.canvas, 0, 0),
|
||||
h && this.setTransform(h),
|
||||
this.canvas.__skipFilterPatch = !1,
|
||||
this.canvas.__currentPathMirror = a(this)
|
||||
}
|
||||
return c
|
||||
}
|
||||
})
|
||||
})
|
||||
}(CanvasRenderingContext2D))
|
||||
}();
|
||||
+1467
File diff suppressed because it is too large
Load Diff
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
// stats.js - http://github.com/mrdoob/stats.js
|
||||
(function(f,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"===typeof define&&define.amd?define(e):f.Stats=e()})(this,function(){var f=function(){function e(a){c.appendChild(a.dom);return a}function u(a){for(var d=0;d<c.children.length;d++)c.children[d].style.display=d===a?"block":"none";l=a}var l=0,c=document.createElement("div");c.style.cssText="position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000";c.addEventListener("click",function(a){a.preventDefault();
|
||||
u(++l%c.children.length)},!1);var k=(performance||Date).now(),g=k,a=0,r=e(new f.Panel("FPS","#0ff","#002")),h=e(new f.Panel("MS","#0f0","#020"));if(self.performance&&self.performance.memory)var t=e(new f.Panel("MB","#f08","#201"));u(0);return{REVISION:16,dom:c,addPanel:e,showPanel:u,begin:function(){k=(performance||Date).now()},end:function(){a++;var c=(performance||Date).now();h.update(c-k,200);if(c>=g+1E3&&(r.update(1E3*a/(c-g),100),g=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/
|
||||
1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){k=this.end()},domElement:c,setMode:u}};f.Panel=function(e,f,l){var c=Infinity,k=0,g=Math.round,a=g(window.devicePixelRatio||1),r=80*a,h=48*a,t=3*a,v=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=h;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,h);b.fillStyle=f;b.fillText(e,t,v);
|
||||
b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(h,w){c=Math.min(c,h);k=Math.max(k,h);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=f;b.fillText(g(h)+" "+e+" ("+g(c)+"-"+g(k)+")",t,v);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,g((1-h/w)*p))}}};return f});
|
||||
Vendored
-6
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,51 @@
|
||||
import Minecraft from './net/minecraft/client/Minecraft.js';
|
||||
|
||||
class Start {
|
||||
|
||||
constructor(preStatusElementId) {
|
||||
this.preStatusElement = document.getElementById(preStatusElementId);
|
||||
}
|
||||
|
||||
loadTextures(textures) {
|
||||
let resources = [];
|
||||
let index = 0;
|
||||
|
||||
return textures.reduce((currentPromise, texturePath) => {
|
||||
return currentPromise.then(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Load texture
|
||||
let image = new Image();
|
||||
image.src = "src/resources/" + texturePath;
|
||||
image.onload = () => resolve();
|
||||
resources[texturePath] = image;
|
||||
|
||||
index++;
|
||||
});
|
||||
});
|
||||
}, Promise.resolve()).then(() => {
|
||||
return resources;
|
||||
});
|
||||
}
|
||||
|
||||
launch(canvasWrapperId) {
|
||||
this.loadTextures([
|
||||
"misc/grasscolor.png",
|
||||
"gui/font.png",
|
||||
"gui/gui.png",
|
||||
"gui/background.png",
|
||||
"gui/icons.png",
|
||||
"terrain/terrain.png",
|
||||
"terrain/sun.png",
|
||||
"terrain/moon.png",
|
||||
"char.png"
|
||||
]).then((resources) => {
|
||||
this.preStatusElement.remove();
|
||||
|
||||
// Launch actual game on canvas
|
||||
window.app = new Minecraft(canvasWrapperId, resources);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Launch game
|
||||
new Start("pre-status").launch("canvas-container");
|
||||
@@ -29,17 +29,6 @@ export default class GameWindow {
|
||||
this.canvasItems = document.createElement('canvas');
|
||||
this.wrapper.appendChild(this.canvasItems);
|
||||
|
||||
// Stats
|
||||
this.statsFps = new Stats()
|
||||
this.statsFps.showPanel(0);
|
||||
this.statsFps.domElement.style.cssText = 'position:absolute;top:0px;right:80px;float:right';
|
||||
//this.wrapper.appendChild(this.statsFps.dom);
|
||||
|
||||
this.statsMs = new Stats()
|
||||
this.statsMs.showPanel(1);
|
||||
this.statsMs.domElement.style.cssText = 'position:absolute;top:0px;right:160px;float:right';
|
||||
//this.wrapper.appendChild(this.statsMs.dom);
|
||||
|
||||
// On resize
|
||||
let scope = this;
|
||||
|
||||
|
||||
@@ -84,17 +84,14 @@ export default class Minecraft {
|
||||
}
|
||||
|
||||
init() {
|
||||
// Load spawn chunk
|
||||
for (let x = -WorldRenderer.RENDER_DISTANCE; x <= WorldRenderer.RENDER_DISTANCE; x++) {
|
||||
for (let z = -WorldRenderer.RENDER_DISTANCE; z <= WorldRenderer.RENDER_DISTANCE; z++) {
|
||||
this.world.getChunkAt(x, z);
|
||||
}
|
||||
}
|
||||
this.player.respawn();
|
||||
|
||||
// Start render loop
|
||||
this.running = true;
|
||||
this.requestNextFrame();
|
||||
|
||||
// Load spawn chunks and respawn player
|
||||
this.world.findSpawn();
|
||||
this.world.loadSpawnChunks();
|
||||
this.player.respawn();
|
||||
}
|
||||
|
||||
hasInGameFocus() {
|
||||
@@ -112,9 +109,6 @@ export default class Minecraft {
|
||||
}
|
||||
|
||||
onLoop() {
|
||||
this.window.statsFps.begin();
|
||||
this.window.statsMs.begin();
|
||||
|
||||
// Update the timer
|
||||
this.timer.advanceTime();
|
||||
|
||||
@@ -135,9 +129,6 @@ export default class Minecraft {
|
||||
this.lastTime += 1000;
|
||||
this.frames = 0;
|
||||
}
|
||||
|
||||
this.window.statsFps.end();
|
||||
this.window.statsMs.end();
|
||||
}
|
||||
|
||||
onRender(partialTicks) {
|
||||
|
||||
@@ -47,8 +47,8 @@ export default class PlayerEntity extends EntityLiving {
|
||||
}
|
||||
|
||||
respawn() {
|
||||
let spawnY = this.world.getHeightAt(0, 0);
|
||||
this.setPosition(0, spawnY + 8, 0);
|
||||
let spawn = this.world.getSpawn();
|
||||
this.setPosition(spawn.x, spawn.y, spawn.z);
|
||||
}
|
||||
|
||||
setPosition(x, y, z) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import * as THREE from "../../../../../../libraries/three.module.js";
|
||||
|
||||
export default class Tessellator {
|
||||
|
||||
constructor() {
|
||||
|
||||
@@ -6,6 +6,7 @@ import Tessellator from "./Tessellator.js";
|
||||
import ChunkSection from "../world/ChunkSection.js";
|
||||
import Random from "../../util/Random.js";
|
||||
import Vector3 from "../../util/Vector3.js";
|
||||
import * as THREE from "../../../../../../libraries/three.module.js";
|
||||
|
||||
export default class WorldRenderer {
|
||||
|
||||
@@ -105,8 +106,8 @@ export default class WorldRenderer {
|
||||
|
||||
// Render chunks
|
||||
let player = this.minecraft.player;
|
||||
let cameraChunkX = Math.floor(player.x >> 4);
|
||||
let cameraChunkZ = Math.floor(player.z >> 4);
|
||||
let cameraChunkX = Math.floor(player.x) >> 4;
|
||||
let cameraChunkZ = Math.floor(player.z) >> 4;
|
||||
this.renderChunks(cameraChunkX, cameraChunkZ);
|
||||
|
||||
// Render sky
|
||||
@@ -611,6 +612,13 @@ export default class WorldRenderer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update render order of chunks
|
||||
world.group.children.sort((a, b) => {
|
||||
let distance1 = Math.floor(Math.pow(a.chunkX - cameraChunkX, 2) + Math.pow(a.chunkZ - cameraChunkZ, 2));
|
||||
let distance2 = Math.floor(Math.pow(b.chunkX - cameraChunkX, 2) + Math.pow(b.chunkZ - cameraChunkZ, 2));
|
||||
return distance2 - distance1;
|
||||
});
|
||||
}
|
||||
|
||||
rebuildAll() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Tessellator from "../Tessellator.js";
|
||||
import MathHelper from "../../../util/MathHelper.js";
|
||||
import * as THREE from "../../../../../../../libraries/three.module.js";
|
||||
|
||||
export default class EntityRenderer {
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import ModelPlayer from "../../model/model/ModelPlayer.js";
|
||||
import EntityRenderer from "../EntityRenderer.js";
|
||||
import Block from "../../../world/block/Block.js";
|
||||
import * as THREE from "../../../../../../../../libraries/three.module.js";
|
||||
|
||||
export default class PlayerRenderer extends EntityRenderer {
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import * as THREE from "../../../../../../../libraries/three.module.js";
|
||||
|
||||
export default class ItemRenderer {
|
||||
|
||||
constructor(minecraft, window) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Polygon from "./Polygon.js";
|
||||
import Vertex from "./Vertex.js";
|
||||
import * as THREE from "../../../../../../../../libraries/three.module.js";
|
||||
|
||||
export default class ModelRenderer {
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Block from "../world/block/Block.js";
|
||||
import * as THREE from "../../../../../../libraries/three.module.js";
|
||||
|
||||
export default class SoundManager {
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import EnumSkyBlock from "../../util/EnumSkyBlock.js";
|
||||
import Block from "./block/Block.js";
|
||||
import World from "./World.js";
|
||||
import ChunkSection from "./ChunkSection.js";
|
||||
import * as THREE from "../../../../../../libraries/three.module.js";
|
||||
|
||||
export default class Chunk {
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import EnumSkyBlock from "../../util/EnumSkyBlock.js";
|
||||
import Block from "./block/Block.js";
|
||||
import * as THREE from "../../../../../../libraries/three.module.js";
|
||||
|
||||
export default class ChunkSection {
|
||||
|
||||
|
||||
@@ -8,12 +8,16 @@ import EnumBlockFace from "../../util/EnumBlockFace.js";
|
||||
import Vector3 from "../../util/Vector3.js";
|
||||
import Vector4 from "../../util/Vector4.js";
|
||||
import MetadataChunkBlock from "../../util/MetadataChunkBlock.js";
|
||||
import Long from "../../../../../../libraries/long.js";
|
||||
import * as THREE from "../../../../../../libraries/three.module.js";
|
||||
import WorldRenderer from "../render/WorldRenderer.js";
|
||||
import Random from "../../util/Random.js";
|
||||
|
||||
export default class World {
|
||||
|
||||
static TOTAL_HEIGHT = ChunkSection.SIZE * 8 - 1; // ChunkSection.SIZE * 16 - 1;
|
||||
|
||||
constructor(minecraft) {
|
||||
constructor(minecraft, seed = Long.fromInt(Date.now() % 100000)) {
|
||||
this.minecraft = minecraft;
|
||||
|
||||
this.entities = [];
|
||||
@@ -25,10 +29,9 @@ export default class World {
|
||||
this.lightUpdateQueue = [];
|
||||
|
||||
this.time = 0;
|
||||
this.spawn = new Vector3(0, 0, 0);
|
||||
|
||||
// Load world
|
||||
this.seed = Date.now() % 100000;
|
||||
this.generator = new WorldGenerator(this, this.seed);
|
||||
this.setSeed(seed);
|
||||
|
||||
// Update lights async
|
||||
let scope = this;
|
||||
@@ -41,18 +44,17 @@ export default class World {
|
||||
}, 0);
|
||||
}
|
||||
|
||||
setSeed(seed) {
|
||||
this.seed = seed;
|
||||
this.generator = new WorldGenerator(this, seed);
|
||||
this.random = new Random(seed);
|
||||
}
|
||||
|
||||
getSeed() {
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
onTick() {
|
||||
let player = this.minecraft.player;
|
||||
let cameraChunkX = Math.floor(player.x >> 4);
|
||||
let cameraChunkZ = Math.floor(player.z >> 4);
|
||||
|
||||
// Update render order of chunks
|
||||
this.group.children.sort((a, b) => {
|
||||
let distance1 = Math.floor(Math.pow(a.chunkX - cameraChunkX, 2) + Math.pow(a.chunkZ - cameraChunkZ, 2));
|
||||
let distance2 = Math.floor(Math.pow(b.chunkX - cameraChunkX, 2) + Math.pow(b.chunkZ - cameraChunkZ, 2));
|
||||
return distance2 - distance1;
|
||||
});
|
||||
|
||||
// Update skylight subtracted (To make the night dark)
|
||||
let lightLevel = this.calculateSkylightSubtracted(1.0);
|
||||
if (lightLevel !== this.skylightSubtracted) {
|
||||
@@ -108,9 +110,6 @@ export default class World {
|
||||
}
|
||||
|
||||
getChunkAtBlock(x, y, z) {
|
||||
if (!this.blockExists(x, y, z)) {
|
||||
return null;
|
||||
}
|
||||
return this.getChunkAt(x >> 4, z >> 4).getSection(y >> 4);
|
||||
}
|
||||
|
||||
@@ -617,4 +616,42 @@ export default class World {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getSpawn() {
|
||||
return this.spawn;
|
||||
}
|
||||
|
||||
setSpawn(x, z) {
|
||||
let y = this.getHeightAt(x, z);
|
||||
this.spawn = new Vector3(x, y + 8, z);
|
||||
}
|
||||
|
||||
findSpawn() {
|
||||
if (this.spawn.y <= 0) {
|
||||
this.spawn.y = 64;
|
||||
}
|
||||
|
||||
while (this.getBlockAboveSeaLevel(this.spawn.x, this.spawn.z) === 0) {
|
||||
this.spawn.x += this.random.nextInt(8) - this.random.nextInt(8);
|
||||
this.spawn.z += this.random.nextInt(8) - this.random.nextInt(8);
|
||||
}
|
||||
}
|
||||
|
||||
getBlockAboveSeaLevel(x, z) {
|
||||
let y = this.generator.seaLevel;
|
||||
while (this.getBlockAt(x, y + 1, z) !== 0) {
|
||||
y++;
|
||||
}
|
||||
return this.getBlockAt(x, y, z);
|
||||
}
|
||||
|
||||
loadSpawnChunks() {
|
||||
for (let x = -WorldRenderer.RENDER_DISTANCE; x <= WorldRenderer.RENDER_DISTANCE; x++) {
|
||||
for (let z = -WorldRenderer.RENDER_DISTANCE; z <= WorldRenderer.RENDER_DISTANCE; z++) {
|
||||
this.getChunkAt(x + this.spawn.x >> 4, z + this.spawn.z >> 4);
|
||||
}
|
||||
}
|
||||
this.spawn.y = this.getHeightAt(this.spawn.x, this.spawn.z) + 8;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import Random from "../../../util/Random.js";
|
||||
import Long from "../../../../../../../libraries/long.js";
|
||||
|
||||
export default class Generator {
|
||||
|
||||
@@ -15,4 +16,23 @@ export default class Generator {
|
||||
generateAtBlock(x, y, z, primer) {
|
||||
|
||||
}
|
||||
|
||||
generateSeedOffset() {
|
||||
this.random.setSeed(this.seed);
|
||||
|
||||
let seedX = this.random.nextLong().divide(2).multiply(2).add(1);
|
||||
let seedZ = this.random.nextLong().divide(2).multiply(2).add(1);
|
||||
|
||||
return {seedX, seedZ};
|
||||
}
|
||||
|
||||
setSeedOffset(chunkX, chunkZ, seedX, seedZ) {
|
||||
let seed = Long.fromInt(chunkX).multiply(seedX).add(Long.fromInt(chunkZ).multiply(seedZ)).xor(this.seed);
|
||||
this.random.setSeed(seed);
|
||||
}
|
||||
|
||||
setChunkSeed(chunkX, chunkZ) {
|
||||
let {seedX, seedZ} = this.generateSeedOffset();
|
||||
this.setSeedOffset(chunkX, chunkZ, seedX, seedZ);
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,13 @@ export default class WorldGenerator extends Generator {
|
||||
this.terrainGenerator4 = new NoiseGeneratorOctaves(this.random, 16);
|
||||
this.terrainGenerator5 = new NoiseGeneratorOctaves(this.random, 16);
|
||||
this.terrainGenerator3 = new NoiseGeneratorOctaves(this.random, 8);
|
||||
this.terrainGenerator1 = new NoiseGeneratorOctaves(this.random, 10);
|
||||
this.terrainGenerator2 = new NoiseGeneratorOctaves(this.random, 16);
|
||||
|
||||
this.natureGenerator1 = new NoiseGeneratorOctaves(this.random, 4);
|
||||
this.natureGenerator2 = new NoiseGeneratorOctaves(this.random, 4);
|
||||
|
||||
this.terrainGenerator1 = new NoiseGeneratorOctaves(this.random, 10);
|
||||
this.terrainGenerator2 = new NoiseGeneratorOctaves(this.random, 16);
|
||||
|
||||
this.populationNoiseGenerator = new NoiseGeneratorOctaves(this.random, 8);
|
||||
}
|
||||
|
||||
@@ -52,18 +53,13 @@ export default class WorldGenerator extends Generator {
|
||||
}
|
||||
|
||||
populateChunk(chunkX, chunkZ) {
|
||||
// Reset seed
|
||||
this.random.setSeed(this.seed);
|
||||
|
||||
// Set seed for chunk
|
||||
let seedX = (this.random.nextInt() / 2) * 2 + 1;
|
||||
let seedZ = (this.random.nextInt() / 2) * 2 + 1;
|
||||
this.random.setSeed(chunkX * seedX + chunkZ * seedZ ^ this.seed);
|
||||
this.setChunkSeed(chunkX, chunkZ);
|
||||
|
||||
// Access noise data for population
|
||||
let absoluteX = chunkX * 16;
|
||||
let absoluteY = chunkZ * 16;
|
||||
let amount = Math.floor((this.populationNoiseGenerator.perlin(absoluteX * 0.5, absoluteY * 0.5) / 8 + this.random.nextFloat() * 4 + 4) / 3);
|
||||
let amount = Math.floor((this.populationNoiseGenerator.perlin(absoluteX * 0.5, absoluteY * 0.5) / 8 + this.random.nextDouble() * 4 + 4) / 3);
|
||||
if (amount < 0) {
|
||||
amount = 0;
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ export default class NoiseGeneratorPerlin extends NoiseGenerator {
|
||||
constructor(random) {
|
||||
super();
|
||||
|
||||
this.offsetX = random.nextFloat() * 256;
|
||||
this.offsetY = random.nextFloat() * 256;
|
||||
this.offsetZ = random.nextFloat() * 256;
|
||||
this.offsetX = random.nextDouble() * 256;
|
||||
this.offsetY = random.nextDouble() * 256;
|
||||
this.offsetZ = random.nextDouble() * 256;
|
||||
|
||||
this.permutations = [];
|
||||
for (let i = 0; i < 256; i++) {
|
||||
|
||||
@@ -21,7 +21,7 @@ export default class BigTreeGenerator extends Generator {
|
||||
}
|
||||
|
||||
generateAtBlock(x, y, z) {
|
||||
let seed = this.random.nextInt();
|
||||
let seed = this.random.nextLong();
|
||||
this.random.setSeed(seed);
|
||||
|
||||
this.coords[0] = x;
|
||||
|
||||
@@ -11,18 +11,14 @@ export default class CaveGenerator extends Generator {
|
||||
}
|
||||
|
||||
generateInChunk(originChunkX, originChunkZ, primer) {
|
||||
// Reset seed
|
||||
this.random.setSeed(this.seed);
|
||||
|
||||
let offset = this.chunkRange;
|
||||
let seedX = (this.random.nextInt() / 2) * 2 + 1;
|
||||
let seedZ = (this.random.nextInt() / 2) * 2 + 1;
|
||||
let {seedX, seedZ} = this.generateSeedOffset();
|
||||
|
||||
// Generate entire cave over 16x16 chunk area
|
||||
for (let chunkX = originChunkX - offset; chunkX <= originChunkX + offset; chunkX++) {
|
||||
for (let chunkZ = originChunkZ - offset; chunkZ <= originChunkZ + offset; chunkZ++) {
|
||||
// Set seed for position
|
||||
this.random.setSeed(chunkX * seedX + chunkZ * seedZ ^ this.seed);
|
||||
this.setSeedOffset(chunkX, chunkZ, seedX, seedZ);
|
||||
|
||||
// Generate entire cave
|
||||
this.generateCave(chunkX, chunkZ, originChunkX, originChunkZ, primer);
|
||||
@@ -50,10 +46,10 @@ export default class CaveGenerator extends Generator {
|
||||
}
|
||||
|
||||
for (let j = 0; j < amount; j++) {
|
||||
let num1 = this.random.nextFloat() * Math.PI * 2.0;
|
||||
let num2 = ((this.random.nextFloat() - 0.5) * 2.0) / 8;
|
||||
let num3 = this.random.nextFloat() * 2.0 + this.random.nextFloat();
|
||||
this.generateCaveAtBlock(originChunkX, originChunkZ, primer, x, y, z, num3, num1, num2, 0, 0, 1.0);
|
||||
let rotation1 = this.random.nextFloat() * Math.PI * 2.0;
|
||||
let rotation2 = ((this.random.nextFloat() - 0.5) * 2.0) / 8;
|
||||
let amplitude = this.random.nextFloat() * 2.0 + this.random.nextFloat();
|
||||
this.generateCaveAtBlock(originChunkX, originChunkZ, primer, x, y, z, amplitude, rotation1, rotation2, 0, 0, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,47 +63,47 @@ export default class CaveGenerator extends Generator {
|
||||
);
|
||||
}
|
||||
|
||||
generateCaveAtBlock(originChunkX, originChunkZ, primer, absoluteX, absoluteY, absoluteZ, amplitude, rotation2, rotation1, progress, distance, strength) {
|
||||
generateCaveAtBlock(originChunkX, originChunkZ, primer, absoluteX, absoluteY, absoluteZ, amplitude, rotation1, rotation2, progress, distance, strength) {
|
||||
let centerX = originChunkX * 16 + 8;
|
||||
let centerZ = originChunkZ * 16 + 8;
|
||||
|
||||
let motion2 = 0;
|
||||
let motion1 = 0;
|
||||
|
||||
let random = new Random(this.random.nextInt());
|
||||
let random = new Random(this.random.nextLong());
|
||||
if (distance <= 0) {
|
||||
let i1 = this.chunkRange * 16 - 16;
|
||||
distance = i1 - random.nextInt(i1 / 4);
|
||||
let range = this.chunkRange * 16 - 16;
|
||||
distance = range - random.nextInt(Math.floor(range / 4));
|
||||
}
|
||||
|
||||
let isBeginning = false;
|
||||
if (progress === -1) {
|
||||
progress = distance / 2;
|
||||
progress = Math.floor(distance / 2);
|
||||
isBeginning = true;
|
||||
}
|
||||
|
||||
let maxProgress = random.nextInt(distance / 2) + distance / 4;
|
||||
let maxProgress = random.nextInt(Math.floor(distance / 2)) + Math.floor(distance / 4);
|
||||
let isStrong = random.nextInt(6) === 0;
|
||||
|
||||
for (; progress < distance; progress++) {
|
||||
let value = 1.5 + (Math.sin((progress * Math.PI) / distance) * amplitude);
|
||||
let valueWithStrength = value * strength;
|
||||
|
||||
let cos = Math.cos(rotation1);
|
||||
let sin = Math.sin(rotation1);
|
||||
let cos = Math.cos(rotation2);
|
||||
let sin = Math.sin(rotation2);
|
||||
|
||||
absoluteX += Math.cos(rotation2) * cos;
|
||||
absoluteX += Math.cos(rotation1) * cos;
|
||||
absoluteY += sin;
|
||||
absoluteZ += Math.sin(rotation2) * cos;
|
||||
absoluteZ += Math.sin(rotation1) * cos;
|
||||
|
||||
if (isStrong) {
|
||||
rotation1 *= 0.92;
|
||||
rotation2 *= 0.92;
|
||||
} else {
|
||||
rotation1 *= 0.7;
|
||||
rotation2 *= 0.7;
|
||||
}
|
||||
|
||||
rotation1 += motion1 * 0.1;
|
||||
rotation2 += motion2 * 0.1;
|
||||
rotation2 += motion1 * 0.1;
|
||||
rotation1 += motion2 * 0.1;
|
||||
|
||||
motion1 *= 0.9;
|
||||
motion2 *= 0.75;
|
||||
@@ -119,12 +115,12 @@ export default class CaveGenerator extends Generator {
|
||||
this.generateCaveAtBlock(
|
||||
originChunkX, originChunkZ, primer,
|
||||
absoluteX, absoluteY, absoluteZ,
|
||||
random.nextFloat() * 0.5 + 0.5, rotation2 - 1.570796, rotation1 / 3, progress, distance, 1.0
|
||||
random.nextFloat() * 0.5 + 0.5, rotation1 - 1.570796, rotation2 / 3, progress, distance, 1.0
|
||||
);
|
||||
this.generateCaveAtBlock(
|
||||
originChunkX, originChunkZ, primer,
|
||||
absoluteX, absoluteY, absoluteZ,
|
||||
random.nextFloat() * 0.5 + 0.5, rotation2 + 1.570796, rotation1 / 3, progress, distance, 1.0
|
||||
random.nextFloat() * 0.5 + 0.5, rotation1 + 1.570796, rotation2 / 3, progress, distance, 1.0
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,32 +1,78 @@
|
||||
import Long from "../../../../../libraries/long.js";
|
||||
|
||||
export default class Random {
|
||||
|
||||
static instances = 0;
|
||||
|
||||
constructor(seed = Date.now() % 1000000000 ^ Random.instances++ * 1000) {
|
||||
this.mask = 0xffffffff;
|
||||
this.multiplier = Long.fromString("25214903917");
|
||||
this.mask = Long.fromInt(1).shiftLeft(48).subtract(1);
|
||||
this.addend = Long.fromInt(0xB);
|
||||
this.doubleUnit = 1.1102230246251565E-16;
|
||||
|
||||
this.setSeed(seed);
|
||||
}
|
||||
|
||||
nextBoolean() {
|
||||
return this.nextFloat() > 0.5;
|
||||
}
|
||||
|
||||
nextInt(max = 0x7fffffff) {
|
||||
return Math.floor(this.nextFloat() * (max + 1));
|
||||
}
|
||||
|
||||
nextFloat() {
|
||||
this.m_z = (36969 * (this.m_z & 65535) + (this.m_z >>> 16)) & this.mask;
|
||||
this.m_w = (18000 * (this.m_w & 65535) + (this.m_w >>> 16)) & this.mask;
|
||||
|
||||
let result = ((this.m_z << 16) + (this.m_w & 65535)) >>> 0;
|
||||
result /= 4294967296;
|
||||
return result;
|
||||
return this.next(24) / (1 << 24);
|
||||
}
|
||||
|
||||
setSeed(seed) {
|
||||
this.seed = seed;
|
||||
this.m_w = (123456789 + seed) & this.mask;
|
||||
this.m_z = (987654321 - seed) & this.mask;
|
||||
nextDouble() {
|
||||
return Long.fromInt(this.next(26)).shiftLeft(27).add(Long.fromInt(this.next(27))).toNumber() * this.doubleUnit;
|
||||
}
|
||||
|
||||
nextInt(max = -1) {
|
||||
if (max === -1) {
|
||||
return this.next(32);
|
||||
}
|
||||
|
||||
let r = this.next(31);
|
||||
let m = max - 1;
|
||||
if ((max & m) === 0) // i.e., bound is a power of 2
|
||||
r = Long.fromInt(max).multiply(Long.fromInt(r)).shiftRightUnsigned(31).toNumber();
|
||||
else {
|
||||
for (let u = r;
|
||||
u - (r = u % max) + m < 0;
|
||||
u = this.next(31))
|
||||
;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
nextLong() {
|
||||
return Long.fromInt(this.next(32)).shiftLeft(32).add(Long.fromInt(this.next(32)));
|
||||
}
|
||||
|
||||
next(bits) {
|
||||
let oldSeed;
|
||||
let nextSeed;
|
||||
do {
|
||||
oldSeed = this.seed;
|
||||
nextSeed = oldSeed.multiply(this.multiplier).add(this.addend).and(this.mask);
|
||||
} while (!this._compareAndSet(oldSeed, nextSeed));
|
||||
return nextSeed.shiftRight(48 - bits).toNumber();
|
||||
}
|
||||
|
||||
_compareAndSet(expect, update) {
|
||||
if (!this.seed.equals(expect)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.seed = update;
|
||||
return true;
|
||||
}
|
||||
|
||||
setSeed(n) {
|
||||
let long;
|
||||
|
||||
if (typeof n === "number") {
|
||||
long = Long.fromInt(n);
|
||||
} else if (n instanceof Long) {
|
||||
long = n;
|
||||
} else {
|
||||
long = Long.fromString(n);
|
||||
}
|
||||
|
||||
this.seed = long.xor(this.multiplier).and(this.mask);
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
import Minecraft from './js/net/minecraft/client/Minecraft.js';
|
||||
|
||||
let resources = [];
|
||||
|
||||
// Script loader
|
||||
function loadScripts(scripts) {
|
||||
let total = scripts.length;
|
||||
let index = 0;
|
||||
|
||||
return scripts.reduce((currentPromise, scriptUrl) => {
|
||||
return currentPromise.then(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Update status message
|
||||
updatePreStatus("Loading scripts... " + index + "/" + total);
|
||||
|
||||
// Load script
|
||||
let script = document.createElement('script');
|
||||
script.async = true;
|
||||
script.src = scriptUrl;
|
||||
script.onload = () => resolve();
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
|
||||
index++;
|
||||
});
|
||||
});
|
||||
}, Promise.resolve());
|
||||
}
|
||||
|
||||
// Texture loader
|
||||
function loadTexture(textures) {
|
||||
let total = textures.length;
|
||||
let index = 0;
|
||||
|
||||
return textures.reduce((currentPromise, texturePath) => {
|
||||
return currentPromise.then(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Update status message
|
||||
updatePreStatus("Loading texture... " + index + "/" + total);
|
||||
|
||||
// Load texture
|
||||
let image = new Image();
|
||||
image.src = "src/resources/" + texturePath;
|
||||
image.onload = () => resolve();
|
||||
resources[texturePath] = image;
|
||||
|
||||
index++;
|
||||
});
|
||||
});
|
||||
}, Promise.resolve());
|
||||
}
|
||||
|
||||
|
||||
function updatePreStatus(message) {
|
||||
document.getElementById("pre-status").innerText = message;
|
||||
}
|
||||
|
||||
// Load textures
|
||||
loadTexture([
|
||||
"misc/grasscolor.png",
|
||||
"gui/font.png",
|
||||
"gui/gui.png",
|
||||
"gui/background.png",
|
||||
"gui/icons.png",
|
||||
"terrain/terrain.png",
|
||||
"terrain/sun.png",
|
||||
"terrain/moon.png",
|
||||
"char.png"
|
||||
]).then(() => {
|
||||
// Load scripts
|
||||
loadScripts([
|
||||
// Dependencies
|
||||
"libraries/three.min.js",
|
||||
"libraries/stats.min.js",
|
||||
"libraries/context-filter-polyfill.min.js"
|
||||
]).then(() => {
|
||||
// Remove pre status
|
||||
document.getElementById("pre-status").remove();
|
||||
|
||||
// Start Minecraft
|
||||
window.app = new Minecraft("canvas-container", resources);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user