From 02c36a79ba6b12f2233aeeb672c125c01170230e Mon Sep 17 00:00:00 2001 From: LabyStudio Date: Mon, 31 Jan 2022 22:30:00 +0100 Subject: [PATCH] implement block types --- src/js/net/minecraft/client/Minecraft.js | 4 ++ src/js/net/minecraft/client/entity/Player.js | 2 +- .../minecraft/client/render/BlockRenderer.js | 20 +++---- .../minecraft/client/world/ChunkSection.js | 3 +- src/js/net/minecraft/client/world/World.js | 16 ++--- .../net/minecraft/client/world/block/Block.js | 58 +++++++++++++++++++ .../minecraft/client/world/block/BlockDirt.js | 7 +++ .../client/world/block/BlockGrass.js | 18 ++++++ .../client/world/block/BlockLeave.js | 10 ++++ .../minecraft/client/world/block/BlockLog.js | 10 ++++ .../minecraft/client/world/block/BlockSand.js | 7 +++ .../client/world/block/BlockStone.js | 7 +++ .../client/world/block/BlockWater.js | 29 ++++++++++ src/start.js | 8 +++ 14 files changed, 178 insertions(+), 21 deletions(-) create mode 100644 src/js/net/minecraft/client/world/block/Block.js create mode 100644 src/js/net/minecraft/client/world/block/BlockDirt.js create mode 100644 src/js/net/minecraft/client/world/block/BlockGrass.js create mode 100644 src/js/net/minecraft/client/world/block/BlockLeave.js create mode 100644 src/js/net/minecraft/client/world/block/BlockLog.js create mode 100644 src/js/net/minecraft/client/world/block/BlockSand.js create mode 100644 src/js/net/minecraft/client/world/block/BlockStone.js create mode 100644 src/js/net/minecraft/client/world/block/BlockWater.js diff --git a/src/js/net/minecraft/client/Minecraft.js b/src/js/net/minecraft/client/Minecraft.js index 1e48b0d..0f12569 100644 --- a/src/js/net/minecraft/client/Minecraft.js +++ b/src/js/net/minecraft/client/Minecraft.js @@ -23,6 +23,10 @@ window.Minecraft = class { } init() { + // Create all blocks + Block.create(); + + // Start render loop this.running = true; this.requestNextFrame(); } diff --git a/src/js/net/minecraft/client/entity/Player.js b/src/js/net/minecraft/client/entity/Player.js index cc16281..2d200b1 100644 --- a/src/js/net/minecraft/client/entity/Player.js +++ b/src/js/net/minecraft/client/entity/Player.js @@ -47,7 +47,7 @@ window.Player = class { } resetPos() { - this.setPos(0, 2, 0); + this.setPos(0, 25, 0); } setPos(x, y, z) { diff --git a/src/js/net/minecraft/client/render/BlockRenderer.js b/src/js/net/minecraft/client/render/BlockRenderer.js index 030e1fc..cc91005 100644 --- a/src/js/net/minecraft/client/render/BlockRenderer.js +++ b/src/js/net/minecraft/client/render/BlockRenderer.js @@ -6,18 +6,21 @@ window.BlockRenderer = class { this.tessellator.bindTexture(worldRenderer.terrainTexture); } - renderBlock(world, group, typeId, x, y, z) { - let boundingBox = new BoundingBox(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); + renderBlock(world, group, block, x, y, z) { + let boundingBox = block.getBoundingBox(world, x, y, z); + // Render all faces let values = EnumBlockFace.values(); for (let i = 0; i < values.length; i++) { let face = values[i]; - if (this.shouldRenderFace(world, x, y, z, face)) { + + // Check if face is hidden by other block + if (block.shouldRenderFace(world, x, y, z, face)) { // Start drawing this.tessellator.startDrawing(); // Render face - this.renderFace(world, typeId, boundingBox, face, x, y, z); + this.renderFace(world, block, boundingBox, face, x, y, z); // Draw this.tessellator.draw(group); @@ -25,12 +28,7 @@ window.BlockRenderer = class { } } - shouldRenderFace(world, x, y, z, face) { - let typeId = world.getBlockAt(x + face.x, y + face.y, z + face.z); - return typeId === 0; /*|| Block.getById(typeId).isTransparent();*/ - } - - renderFace(world, typeId, boundingBox, face, x, y, z) { + renderFace(world, block, boundingBox, face, x, y, z) { // Vertex mappings let minX = x + boundingBox.minX; let minY = y + boundingBox.minY; @@ -40,7 +38,7 @@ window.BlockRenderer = class { let maxZ = z + boundingBox.maxZ; // UV Mapping - let textureIndex = typeId; + let textureIndex = block.getTextureForFace(face); let minU = (textureIndex % 16) / 16.0; let maxU = minU + (16 / 256); let minV = Math.round(textureIndex / 16); diff --git a/src/js/net/minecraft/client/world/ChunkSection.js b/src/js/net/minecraft/client/world/ChunkSection.js index f4c58eb..2abb6af 100644 --- a/src/js/net/minecraft/client/world/ChunkSection.js +++ b/src/js/net/minecraft/client/world/ChunkSection.js @@ -37,7 +37,8 @@ window.ChunkSection = class { let absoluteY = this.y * ChunkSection.SIZE + y; let absoluteZ = this.z * ChunkSection.SIZE + z; - renderer.blockRenderer.renderBlock(this.world, this.group, typeId, absoluteX, absoluteY, absoluteZ); + let block = Block.getById(typeId); + renderer.blockRenderer.renderBlock(this.world, this.group, block, absoluteX, absoluteY, absoluteZ); } } } diff --git a/src/js/net/minecraft/client/world/World.js b/src/js/net/minecraft/client/world/World.js index 3d54acf..7df66a9 100644 --- a/src/js/net/minecraft/client/world/World.js +++ b/src/js/net/minecraft/client/world/World.js @@ -1,20 +1,20 @@ window.World = class { - static get TOTAL_HEIGHT() { - return ChunkSection.SIZE * 16 - 1; - } + static TOTAL_HEIGHT = ChunkSection.SIZE * 16 - 1; constructor() { this.group = new THREE.Object3D(); this.chunks = []; + // Debug world for (let x = -16; x < 16; x++) { - for (let z = -16; z < 16; z++) { - this.setBlockAt(x, 0, z, 1); + for (let y = 0; y < 16; y++) { + for (let z = -16; z < 16; z++) { + this.setBlockAt(x, y, z, y === 15 ? 2 : 3); + } } } - - this.setBlockAt(0, 1, -2, 2); + this.setBlockAt(0, 16, -2, 17); } getChunkAtBlock(x, y, z) { @@ -46,7 +46,7 @@ window.World = class { isSolidBlockAt(x, y, z) { let typeId = this.getBlockAt(x, y, z); - return typeId !== 0; /* && Block.getById(typeId).isSolid();*/ + return typeId !== 0 && Block.getById(typeId).isSolid(); } setBlockAt(x, y, z, type) { diff --git a/src/js/net/minecraft/client/world/block/Block.js b/src/js/net/minecraft/client/world/block/Block.js new file mode 100644 index 0000000..1fa9b0c --- /dev/null +++ b/src/js/net/minecraft/client/world/block/Block.js @@ -0,0 +1,58 @@ +window.Block = class { + + static blocks = []; + + static create() { + Block.STONE = new BlockStone(1, 0); + Block.GRASS = new BlockGrass(2, 1); + Block.DIRT = new BlockDirt(3, 2); + Block.LOG = new BlockLog(17, 4); + Block.LEAVE = new BlockLeave(18, 6); + Block.WATER = new BlockWater(9, 7); + Block.SAND = new BlockSand(12, 8) + } + + constructor(id, textureSlotId = id) { + this.id = id; + this.textureSlotId = textureSlotId; + + this.boundingBox = new BoundingBox(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); + + // Register block + Block.blocks[id] = this; + } + + getId() { + return this.id; + } + + getTextureForFace(face) { + return this.textureSlotId; + } + + isTransparent() { + return this.getOpacity() < 1.0; + } + + shouldRenderFace(world, x, y, z, face) { + let typeId = world.getBlockAt(x + face.x, y + face.y, z + face.z); + return typeId === 0 || Block.getById(typeId).isTransparent(); + } + + isSolid() { + return true; + } + + getOpacity() { + return 1.0; + } + + getBoundingBox(world, x, y, z) { + return this.boundingBox; + } + + static getById(typeId) { + return Block.blocks[typeId]; + } + +} \ No newline at end of file diff --git a/src/js/net/minecraft/client/world/block/BlockDirt.js b/src/js/net/minecraft/client/world/block/BlockDirt.js new file mode 100644 index 0000000..3bbdf34 --- /dev/null +++ b/src/js/net/minecraft/client/world/block/BlockDirt.js @@ -0,0 +1,7 @@ +window.BlockDirt = class extends Block { + + constructor(id, textureSlotId) { + super(id, textureSlotId); + } + +} \ No newline at end of file diff --git a/src/js/net/minecraft/client/world/block/BlockGrass.js b/src/js/net/minecraft/client/world/block/BlockGrass.js new file mode 100644 index 0000000..79ce0ce --- /dev/null +++ b/src/js/net/minecraft/client/world/block/BlockGrass.js @@ -0,0 +1,18 @@ +window.BlockGrass = class extends Block { + + constructor(id, textureSlotId) { + super(id, textureSlotId); + } + + getTextureForFace(face) { + switch (face) { + case EnumBlockFace.TOP: + return this.textureSlotId; + case EnumBlockFace.BOTTOM: + return this.textureSlotId + 1; + default: + return this.textureSlotId + 2; + } + } + +} \ No newline at end of file diff --git a/src/js/net/minecraft/client/world/block/BlockLeave.js b/src/js/net/minecraft/client/world/block/BlockLeave.js new file mode 100644 index 0000000..614b82d --- /dev/null +++ b/src/js/net/minecraft/client/world/block/BlockLeave.js @@ -0,0 +1,10 @@ +window.BlockLeave = class extends Block { + + constructor(id, textureSlotId) { + super(id, textureSlotId); + } + + getOpacity() { + return 0.3; + } +} \ No newline at end of file diff --git a/src/js/net/minecraft/client/world/block/BlockLog.js b/src/js/net/minecraft/client/world/block/BlockLog.js new file mode 100644 index 0000000..5cd05b5 --- /dev/null +++ b/src/js/net/minecraft/client/world/block/BlockLog.js @@ -0,0 +1,10 @@ +window.BlockLog = class extends Block { + + constructor(id, textureSlotId) { + super(id, textureSlotId); + } + + getTextureForFace(face) { + return this.textureSlotId + (face.isYAxis() ? 1 : 0); + } +} \ No newline at end of file diff --git a/src/js/net/minecraft/client/world/block/BlockSand.js b/src/js/net/minecraft/client/world/block/BlockSand.js new file mode 100644 index 0000000..32f895a --- /dev/null +++ b/src/js/net/minecraft/client/world/block/BlockSand.js @@ -0,0 +1,7 @@ +window.BlockSand = class extends Block { + + constructor(id, textureSlotId) { + super(id, textureSlotId); + } + +} \ No newline at end of file diff --git a/src/js/net/minecraft/client/world/block/BlockStone.js b/src/js/net/minecraft/client/world/block/BlockStone.js new file mode 100644 index 0000000..f7be028 --- /dev/null +++ b/src/js/net/minecraft/client/world/block/BlockStone.js @@ -0,0 +1,7 @@ +window.BlockStone = class extends Block { + + constructor(id, textureSlotId) { + super(id, textureSlotId); + } + +} \ No newline at end of file diff --git a/src/js/net/minecraft/client/world/block/BlockWater.js b/src/js/net/minecraft/client/world/block/BlockWater.js new file mode 100644 index 0000000..f14259c --- /dev/null +++ b/src/js/net/minecraft/client/world/block/BlockWater.js @@ -0,0 +1,29 @@ +window.BlockWater = class extends Block { + + constructor(id, textureSlotId) { + super(id, textureSlotId); + } + + + getOpacity() { + return 0.3; + } + + isSolid() { + return false; + } + + shouldRenderFace(world, x, y, z, face) { + let typeId = world.getBlockAt(x + face.x, y + face.y, z + face.z); + return typeId === 0 || typeId !== this.id && Block.getById(typeId).isTransparent(); + } + + getBoundingBox(world, x, y, z) { + let box = this.boundingBox.clone(); + if (world.getBlockAt(x, y + 1, z) !== this.id) { + box.maxY = 1.0 - 0.12; + } + return box; + } + +} \ No newline at end of file diff --git a/src/start.js b/src/start.js index 53603fe..ffc56bb 100644 --- a/src/start.js +++ b/src/start.js @@ -53,6 +53,14 @@ loadScripts([ "src/js/net/minecraft/util/BoundingBox.js", "src/js/net/minecraft/util/Keyboard.js", "src/js/net/minecraft/client/GameWindow.js", + "src/js/net/minecraft/client/world/block/Block.js", + "src/js/net/minecraft/client/world/block/BlockStone.js", + "src/js/net/minecraft/client/world/block/BlockGrass.js", + "src/js/net/minecraft/client/world/block/BlockDirt.js", + "src/js/net/minecraft/client/world/block/BlockLog.js", + "src/js/net/minecraft/client/world/block/BlockLeave.js", + "src/js/net/minecraft/client/world/block/BlockWater.js", + "src/js/net/minecraft/client/world/block/BlockSand.js", "src/js/net/minecraft/client/world/ChunkSection.js", "src/js/net/minecraft/client/world/Chunk.js", "src/js/net/minecraft/client/world/World.js",