implement render distance setting, flush chunk rebuilds on block place, version 1.0.1

This commit is contained in:
LabyStudio
2022-05-13 18:50:57 +02:00
parent ea4d058dab
commit 5e50a6b634
9 changed files with 54 additions and 22 deletions
@@ -9,6 +9,7 @@ export default class GameSettings {
this.viewBobbing = true;
this.ambientOcclusion = true;
this.sensitivity = 100;
this.viewDistance = 4;
}
load() {
+6 -2
View File
@@ -18,7 +18,7 @@ import * as THREE from "../../../../../libraries/three.module.js";
export default class Minecraft {
static VERSION = "1.0.0"
static VERSION = "1.0.1"
static URL_GITHUB = "https://github.com/labystudio/js-minecraft";
/**
@@ -88,6 +88,7 @@ export default class Minecraft {
this.worldRenderer.reset();
this.itemRenderer.reset();
this.world.chunks.clear();
this.world = null;
this.player = null;
this.loadingScreen = null;
@@ -232,7 +233,7 @@ export default class Minecraft {
let cameraChunkX = Math.floor(this.player.x) >> 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 loadedChunks = this.world.chunks.size;
@@ -354,6 +355,9 @@ export default class Minecraft {
}
}
}
// Rebuild multiple chunk sections
this.worldRenderer.flushRebuild = true;
}
}
+2 -1
View File
@@ -6,6 +6,7 @@ export default class GuiScreen extends Gui {
super();
this.buttonList = [];
this.previousScreen = null;
}
setup(minecraft, width, height) {
@@ -43,7 +44,7 @@ export default class GuiScreen extends Gui {
keyTyped(key, character) {
if (key === "Escape") {
this.minecraft.displayScreen(null);
this.minecraft.displayScreen(this.previousScreen);
return true;
}
@@ -35,7 +35,7 @@ export default class GuiControls extends GuiScreen {
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);
}));
}
@@ -3,6 +3,7 @@ import GuiButton from "../widgets/GuiButton.js";
import World from "../../world/World.js";
import GuiTextField from "../widgets/GuiTextField.js";
import Random from "../../../util/Random.js";
import Long from "../../../../../../../libraries/long.js";
export default class GuiCreateWorld extends GuiScreen {
@@ -25,6 +26,12 @@ export default class GuiCreateWorld extends GuiScreen {
let seed = this.fieldSeed.getText();
if (seed.length === 0) {
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));
}));
@@ -64,7 +64,7 @@ export default class GuiMainMenu extends GuiScreen {
this.drawLogo(stack, x, y);
// 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
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 => {
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.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);
}));
}
@@ -10,7 +10,6 @@ import * as THREE from "../../../../../../libraries/three.module.js";
export default class WorldRenderer {
static RENDER_DISTANCE = 4;
static THIRD_PERSON_DISTANCE = 4;
constructor(minecraft, window) {
@@ -48,6 +47,8 @@ export default class WorldRenderer {
this.prevFogBrightness = 0;
this.fogBrightness = 0;
this.flushRebuild = false;
this.initialize();
}
@@ -148,6 +149,17 @@ export default class WorldRenderer {
}
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.prevEquippedProgress = this.equippedProgress;
@@ -174,7 +186,7 @@ export default class WorldRenderer {
// Update fog brightness
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;
this.fogBrightness += (fogBrightness - this.fogBrightness) * 0.1;
}
@@ -482,8 +494,8 @@ export default class WorldRenderer {
} else {
let world = this.minecraft.world;
let viewDistance = WorldRenderer.RENDER_DISTANCE * ChunkSection.SIZE;
let viewFactor = 1.0 - Math.pow(0.25 + 0.75 * WorldRenderer.RENDER_DISTANCE / 32.0, 0.25);
let viewDistance = this.minecraft.settings.viewDistance * ChunkSection.SIZE;
let viewFactor = 1.0 - Math.pow(0.25 + 0.75 * this.minecraft.settings.viewDistance / 32.0, 0.25);
let angle = world.getCelestialAngle(partialTicks);
@@ -538,7 +550,7 @@ export default class WorldRenderer {
renderChunks(cameraChunkX, cameraChunkZ) {
let world = this.minecraft.world;
let renderDistance = WorldRenderer.RENDER_DISTANCE;
let renderDistance = this.minecraft.settings.viewDistance;
// Update chunks
for (let [index, chunk] of world.chunks) {
@@ -602,13 +614,17 @@ export default class WorldRenderer {
return distance2 - distance1;
});
// Rebuild 8 chunk sections each frame
for (let i = 0; i < 8; i++) {
if (this.chunkSectionUpdateQueue.length !== 0) {
let chunkSection = this.chunkSectionUpdateQueue.shift();
if (chunkSection != null) {
// Rebuild chunk
chunkSection.rebuild(this);
// Flush by rebuilding 8 chunk sections
if(this.flushRebuild) {
this.flushRebuild = false;
for (let i = 0; i < 8; i++) {
if (this.chunkSectionUpdateQueue.length !== 0) {
let chunkSection = this.chunkSectionUpdateQueue.shift();
if (chunkSection != null) {
// Rebuild chunk
chunkSection.rebuild(this);
}
}
}
}
+3 -3
View File
@@ -9,7 +9,6 @@ import Vector3 from "../../util/Vector3.js";
import Vector4 from "../../util/Vector4.js";
import MetadataChunkBlock from "../../util/MetadataChunkBlock.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 {
@@ -652,8 +651,9 @@ export default class World {
}
loadSpawnChunks() {
for (let x = -WorldRenderer.RENDER_DISTANCE; x <= WorldRenderer.RENDER_DISTANCE; x++) {
for (let z = -WorldRenderer.RENDER_DISTANCE; z <= WorldRenderer.RENDER_DISTANCE; z++) {
let viewDistance = this.minecraft.settings.viewDistance;
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);
}
}