implement render distance setting, flush chunk rebuilds on block place, version 1.0.1
This commit is contained in:
@@ -9,6 +9,7 @@ export default class GameSettings {
|
|||||||
this.viewBobbing = true;
|
this.viewBobbing = true;
|
||||||
this.ambientOcclusion = true;
|
this.ambientOcclusion = true;
|
||||||
this.sensitivity = 100;
|
this.sensitivity = 100;
|
||||||
|
this.viewDistance = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
load() {
|
load() {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import * as THREE from "../../../../../libraries/three.module.js";
|
|||||||
|
|
||||||
export default class Minecraft {
|
export default class Minecraft {
|
||||||
|
|
||||||
static VERSION = "1.0.0"
|
static VERSION = "1.0.1"
|
||||||
static URL_GITHUB = "https://github.com/labystudio/js-minecraft";
|
static URL_GITHUB = "https://github.com/labystudio/js-minecraft";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,6 +88,7 @@ export default class Minecraft {
|
|||||||
this.worldRenderer.reset();
|
this.worldRenderer.reset();
|
||||||
this.itemRenderer.reset();
|
this.itemRenderer.reset();
|
||||||
|
|
||||||
|
this.world.chunks.clear();
|
||||||
this.world = null;
|
this.world = null;
|
||||||
this.player = null;
|
this.player = null;
|
||||||
this.loadingScreen = null;
|
this.loadingScreen = null;
|
||||||
@@ -232,7 +233,7 @@ export default class Minecraft {
|
|||||||
let cameraChunkX = Math.floor(this.player.x) >> 4;
|
let cameraChunkX = Math.floor(this.player.x) >> 4;
|
||||||
let cameraChunkZ = Math.floor(this.player.z) >> 4;
|
let cameraChunkZ = Math.floor(this.player.z) >> 4;
|
||||||
|
|
||||||
let renderDistance = WorldRenderer.RENDER_DISTANCE;
|
let renderDistance = this.settings.viewDistance;
|
||||||
let requiredChunks = Math.pow(renderDistance * 2 - 1, 2);
|
let requiredChunks = Math.pow(renderDistance * 2 - 1, 2);
|
||||||
let loadedChunks = this.world.chunks.size;
|
let loadedChunks = this.world.chunks.size;
|
||||||
|
|
||||||
@@ -354,6 +355,9 @@ export default class Minecraft {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rebuild multiple chunk sections
|
||||||
|
this.worldRenderer.flushRebuild = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export default class GuiScreen extends Gui {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.buttonList = [];
|
this.buttonList = [];
|
||||||
|
this.previousScreen = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
setup(minecraft, width, height) {
|
setup(minecraft, width, height) {
|
||||||
@@ -43,7 +44,7 @@ export default class GuiScreen extends Gui {
|
|||||||
|
|
||||||
keyTyped(key, character) {
|
keyTyped(key, character) {
|
||||||
if (key === "Escape") {
|
if (key === "Escape") {
|
||||||
this.minecraft.displayScreen(null);
|
this.minecraft.displayScreen(this.previousScreen);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export default class GuiControls extends GuiScreen {
|
|||||||
settings.togglePerspective = key;
|
settings.togglePerspective = key;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.buttonList.push(new GuiButton("Done", this.width / 2 - 100, y + 110, 200, 20, () => {
|
this.buttonList.push(new GuiButton("Done", this.width / 2 - 100, y + 130, 200, 20, () => {
|
||||||
this.minecraft.displayScreen(this.previousScreen);
|
this.minecraft.displayScreen(this.previousScreen);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import GuiButton from "../widgets/GuiButton.js";
|
|||||||
import World from "../../world/World.js";
|
import World from "../../world/World.js";
|
||||||
import GuiTextField from "../widgets/GuiTextField.js";
|
import GuiTextField from "../widgets/GuiTextField.js";
|
||||||
import Random from "../../../util/Random.js";
|
import Random from "../../../util/Random.js";
|
||||||
|
import Long from "../../../../../../../libraries/long.js";
|
||||||
|
|
||||||
export default class GuiCreateWorld extends GuiScreen {
|
export default class GuiCreateWorld extends GuiScreen {
|
||||||
|
|
||||||
@@ -25,6 +26,12 @@ export default class GuiCreateWorld extends GuiScreen {
|
|||||||
let seed = this.fieldSeed.getText();
|
let seed = this.fieldSeed.getText();
|
||||||
if (seed.length === 0) {
|
if (seed.length === 0) {
|
||||||
seed = new Random().nextLong();
|
seed = new Random().nextLong();
|
||||||
|
} else if (typeof seed === "string") {
|
||||||
|
let h = 0;
|
||||||
|
for (let i = 0; i < seed.length; i++) {
|
||||||
|
h = 31 * h + seed.charCodeAt(i);
|
||||||
|
}
|
||||||
|
seed = Long.fromNumber(h);
|
||||||
}
|
}
|
||||||
this.minecraft.loadWorld(new World(this.minecraft, seed));
|
this.minecraft.loadWorld(new World(this.minecraft, seed));
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export default class GuiMainMenu extends GuiScreen {
|
|||||||
this.drawLogo(stack, x, y);
|
this.drawLogo(stack, x, y);
|
||||||
|
|
||||||
// Draw version
|
// Draw version
|
||||||
this.drawString(stack, "minecraft-js " + Minecraft.VERSION, 2, this.height - 10, 0xFFFFFF);
|
this.drawString(stack, "js-minecraft " + Minecraft.VERSION, 2, this.height - 10, 0xFFFFFF);
|
||||||
|
|
||||||
// Draw copyright
|
// Draw copyright
|
||||||
let mouseOver = mouseX > this.width / 2 + 70 && mouseY > this.height - 20;
|
let mouseOver = mouseX > this.width / 2 + 70 && mouseY > this.height - 20;
|
||||||
|
|||||||
@@ -28,11 +28,14 @@ export default class GuiOptions extends GuiScreen {
|
|||||||
this.buttonList.push(new GuiSliderButton("FOV", settings.fov, 50, 100, this.width / 2 - 100, y + 24 * 2, 200, 20, value => {
|
this.buttonList.push(new GuiSliderButton("FOV", settings.fov, 50, 100, this.width / 2 - 100, y + 24 * 2, 200, 20, value => {
|
||||||
settings.fov = value;
|
settings.fov = value;
|
||||||
}));
|
}));
|
||||||
this.buttonList.push(new GuiButton("Controls...", this.width / 2 - 100, y + 24 * 3, 200, 20, () => {
|
this.buttonList.push(new GuiSliderButton("Render Distance", settings.viewDistance, 2, 16, this.width / 2 - 100, y + 24 * 3, 200, 20, value => {
|
||||||
|
settings.viewDistance = value;
|
||||||
|
}));
|
||||||
|
this.buttonList.push(new GuiButton("Controls...", this.width / 2 - 100, y + 24 * 4, 200, 20, () => {
|
||||||
this.minecraft.displayScreen(new GuiControls(this));
|
this.minecraft.displayScreen(new GuiControls(this));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.buttonList.push(new GuiButton("Done", this.width / 2 - 100, y + 110, 200, 20, () => {
|
this.buttonList.push(new GuiButton("Done", this.width / 2 - 100, y + 130, 200, 20, () => {
|
||||||
this.minecraft.displayScreen(this.previousScreen);
|
this.minecraft.displayScreen(this.previousScreen);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import * as THREE from "../../../../../../libraries/three.module.js";
|
|||||||
|
|
||||||
export default class WorldRenderer {
|
export default class WorldRenderer {
|
||||||
|
|
||||||
static RENDER_DISTANCE = 4;
|
|
||||||
static THIRD_PERSON_DISTANCE = 4;
|
static THIRD_PERSON_DISTANCE = 4;
|
||||||
|
|
||||||
constructor(minecraft, window) {
|
constructor(minecraft, window) {
|
||||||
@@ -48,6 +47,8 @@ export default class WorldRenderer {
|
|||||||
this.prevFogBrightness = 0;
|
this.prevFogBrightness = 0;
|
||||||
this.fogBrightness = 0;
|
this.fogBrightness = 0;
|
||||||
|
|
||||||
|
this.flushRebuild = false;
|
||||||
|
|
||||||
this.initialize();
|
this.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +149,17 @@ export default class WorldRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onTick() {
|
onTick() {
|
||||||
|
// Rebuild 2 chunk sections each tick
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
if (this.chunkSectionUpdateQueue.length !== 0) {
|
||||||
|
let chunkSection = this.chunkSectionUpdateQueue.shift();
|
||||||
|
if (chunkSection != null) {
|
||||||
|
// Rebuild chunk
|
||||||
|
chunkSection.rebuild(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.prevFogBrightness = this.fogBrightness;
|
this.prevFogBrightness = this.fogBrightness;
|
||||||
this.prevEquippedProgress = this.equippedProgress;
|
this.prevEquippedProgress = this.equippedProgress;
|
||||||
|
|
||||||
@@ -174,7 +186,7 @@ export default class WorldRenderer {
|
|||||||
|
|
||||||
// Update fog brightness
|
// Update fog brightness
|
||||||
let brightnessAtPosition = this.minecraft.world.getLightBrightnessForEntity(player);
|
let brightnessAtPosition = this.minecraft.world.getLightBrightnessForEntity(player);
|
||||||
let renderDistance = WorldRenderer.RENDER_DISTANCE / 32.0;
|
let renderDistance = this.minecraft.settings.viewDistance / 32.0;
|
||||||
let fogBrightness = brightnessAtPosition * (1.0 - renderDistance) + renderDistance;
|
let fogBrightness = brightnessAtPosition * (1.0 - renderDistance) + renderDistance;
|
||||||
this.fogBrightness += (fogBrightness - this.fogBrightness) * 0.1;
|
this.fogBrightness += (fogBrightness - this.fogBrightness) * 0.1;
|
||||||
}
|
}
|
||||||
@@ -482,8 +494,8 @@ export default class WorldRenderer {
|
|||||||
} else {
|
} else {
|
||||||
let world = this.minecraft.world;
|
let world = this.minecraft.world;
|
||||||
|
|
||||||
let viewDistance = WorldRenderer.RENDER_DISTANCE * ChunkSection.SIZE;
|
let viewDistance = this.minecraft.settings.viewDistance * ChunkSection.SIZE;
|
||||||
let viewFactor = 1.0 - Math.pow(0.25 + 0.75 * WorldRenderer.RENDER_DISTANCE / 32.0, 0.25);
|
let viewFactor = 1.0 - Math.pow(0.25 + 0.75 * this.minecraft.settings.viewDistance / 32.0, 0.25);
|
||||||
|
|
||||||
let angle = world.getCelestialAngle(partialTicks);
|
let angle = world.getCelestialAngle(partialTicks);
|
||||||
|
|
||||||
@@ -538,7 +550,7 @@ export default class WorldRenderer {
|
|||||||
|
|
||||||
renderChunks(cameraChunkX, cameraChunkZ) {
|
renderChunks(cameraChunkX, cameraChunkZ) {
|
||||||
let world = this.minecraft.world;
|
let world = this.minecraft.world;
|
||||||
let renderDistance = WorldRenderer.RENDER_DISTANCE;
|
let renderDistance = this.minecraft.settings.viewDistance;
|
||||||
|
|
||||||
// Update chunks
|
// Update chunks
|
||||||
for (let [index, chunk] of world.chunks) {
|
for (let [index, chunk] of world.chunks) {
|
||||||
@@ -602,13 +614,17 @@ export default class WorldRenderer {
|
|||||||
return distance2 - distance1;
|
return distance2 - distance1;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Rebuild 8 chunk sections each frame
|
// Flush by rebuilding 8 chunk sections
|
||||||
for (let i = 0; i < 8; i++) {
|
if(this.flushRebuild) {
|
||||||
if (this.chunkSectionUpdateQueue.length !== 0) {
|
this.flushRebuild = false;
|
||||||
let chunkSection = this.chunkSectionUpdateQueue.shift();
|
|
||||||
if (chunkSection != null) {
|
for (let i = 0; i < 8; i++) {
|
||||||
// Rebuild chunk
|
if (this.chunkSectionUpdateQueue.length !== 0) {
|
||||||
chunkSection.rebuild(this);
|
let chunkSection = this.chunkSectionUpdateQueue.shift();
|
||||||
|
if (chunkSection != null) {
|
||||||
|
// Rebuild chunk
|
||||||
|
chunkSection.rebuild(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import Vector3 from "../../util/Vector3.js";
|
|||||||
import Vector4 from "../../util/Vector4.js";
|
import Vector4 from "../../util/Vector4.js";
|
||||||
import MetadataChunkBlock from "../../util/MetadataChunkBlock.js";
|
import MetadataChunkBlock from "../../util/MetadataChunkBlock.js";
|
||||||
import * as THREE from "../../../../../../libraries/three.module.js";
|
import * as THREE from "../../../../../../libraries/three.module.js";
|
||||||
import WorldRenderer from "../render/WorldRenderer.js";
|
|
||||||
import Random from "../../util/Random.js";
|
import Random from "../../util/Random.js";
|
||||||
|
|
||||||
export default class World {
|
export default class World {
|
||||||
@@ -652,8 +651,9 @@ export default class World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadSpawnChunks() {
|
loadSpawnChunks() {
|
||||||
for (let x = -WorldRenderer.RENDER_DISTANCE; x <= WorldRenderer.RENDER_DISTANCE; x++) {
|
let viewDistance = this.minecraft.settings.viewDistance;
|
||||||
for (let z = -WorldRenderer.RENDER_DISTANCE; z <= WorldRenderer.RENDER_DISTANCE; z++) {
|
for (let x = -viewDistance; x <= viewDistance; x++) {
|
||||||
|
for (let z = -viewDistance; z <= viewDistance; z++) {
|
||||||
this.getChunkAt(x + this.spawn.x >> 4, z + this.spawn.z >> 4);
|
this.getChunkAt(x + this.spawn.x >> 4, z + this.spawn.z >> 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user