From c2262a43ffa9db7f5500fa189fb25445a1496c99 Mon Sep 17 00:00:00 2001 From: LabyStudio Date: Fri, 4 Feb 2022 12:26:02 +0100 Subject: [PATCH] implement hotbar --- src/js/net/minecraft/client/GameWindow.js | 13 +++++++++ src/js/net/minecraft/client/Minecraft.js | 26 +++++++++++++---- src/js/net/minecraft/client/gui/Gui.js | 18 ++++++++++++ .../net/minecraft/client/gui/IngameOverlay.js | 29 +++++++++++++++++++ .../client/gui/screens/GuiIngameMenu.js | 2 +- .../minecraft/client/gui/widgets/GuiButton.js | 2 +- .../minecraft/client/inventory/Inventory.js | 27 +++++++++++++++++ .../minecraft/client/render/BlockRenderer.js | 1 - src/start.js | 1 + 9 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 src/js/net/minecraft/client/inventory/Inventory.js diff --git a/src/js/net/minecraft/client/GameWindow.js b/src/js/net/minecraft/client/GameWindow.js index 6b441b2..11399ed 100644 --- a/src/js/net/minecraft/client/GameWindow.js +++ b/src/js/net/minecraft/client/GameWindow.js @@ -3,6 +3,7 @@ window.GameWindow = class { constructor(minecraft, canvasWrapperId) { this.minecraft = minecraft; this.canvasWrapperId = canvasWrapperId; + this.renderer = null; this.mouseMotionX = 0; this.mouseMotionY = 0; @@ -46,6 +47,12 @@ window.GameWindow = class { } }, false); + // Mouse scroll + document.addEventListener('wheel', function (event) { + let delta = Math.sign(event.deltaY); + minecraft.onMouseScroll(delta); + }, false); + // Keyboard interaction with screen window.addEventListener('keydown', function (event) { if (!(minecraft.currentScreen === null)) { @@ -59,6 +66,8 @@ window.GameWindow = class { } else if (event.code === 'Escape') { event.preventDefault(); minecraft.displayScreen(new GuiIngameMenu()); + } else { + minecraft.onKeyPressed(event.code); } }); @@ -105,6 +114,10 @@ window.GameWindow = class { this.width = this.width / this.scaleFactor; this.height = this.height / this.scaleFactor; + + if (!(this.renderer === null)) { + this.renderer.webRenderer.setPixelRatio(/*this.minecraft.currentScreen === null ? 1 :*/ 1 / this.scaleFactor); + } } onResize() { diff --git a/src/js/net/minecraft/client/Minecraft.js b/src/js/net/minecraft/client/Minecraft.js index acb051e..d49dd0e 100644 --- a/src/js/net/minecraft/client/Minecraft.js +++ b/src/js/net/minecraft/client/Minecraft.js @@ -32,7 +32,7 @@ window.Minecraft = class { // Create player this.player = new Player(this, this.world); - this.pickedBlock = 1; + this.inventory = new Inventory(); // Initialize this.init(); @@ -112,12 +112,13 @@ window.Minecraft = class { // Switch screen this.currentScreen = screen; + // Update window size + this.window.updateWindowSize(); + // Initialize new screen if (screen === null) { - this.worldRenderer.webRenderer.setPixelRatio(1); this.window.requestFocus(); } else { - this.worldRenderer.webRenderer.setPixelRatio(1 / this.window.scaleFactor); screen.setup(this, this.window.width, this.window.height); } } @@ -142,6 +143,14 @@ window.Minecraft = class { } } + onKeyPressed(button) { + for (let i = 1; i <= 9; i++) { + if (button === 'Digit' + i) { + this.inventory.selectedSlotIndex = i - 1; + } + } + } + onMouseClicked(button) { if (this.window.mouseLocked) { let hitResult = this.player.rayTrace(5, this.timer.partialTicks); @@ -158,7 +167,7 @@ window.Minecraft = class { if (hitResult != null) { let typeId = this.world.getBlockAt(hitResult.x, hitResult.y, hitResult.z); if (typeId !== 0) { - this.pickedBlock = typeId; + this.inventory.setItemInSelectedSlot(typeId); } } } @@ -174,11 +183,18 @@ window.Minecraft = class { // Don't place blocks if the player is standing there if (!placedBoundingBox.intersects(this.player.boundingBox)) { - this.world.setBlockAt(x, y, z, this.pickedBlock); + let typeId = this.inventory.getItemInSelectedSlot(); + if (typeId !== 0) { + this.world.setBlockAt(x, y, z, typeId); + } } } } } } + onMouseScroll(delta) { + this.inventory.shiftSelectedSlot(delta); + } + } \ No newline at end of file diff --git a/src/js/net/minecraft/client/gui/Gui.js b/src/js/net/minecraft/client/gui/Gui.js index 3cc82b9..aa800c7 100644 --- a/src/js/net/minecraft/client/gui/Gui.js +++ b/src/js/net/minecraft/client/gui/Gui.js @@ -39,6 +39,24 @@ window.Gui = class { stack.restore(); } + renderBlock(stack, texture, block, x, y) { + stack.save(); + stack.translate(x + 3, y + 3); + this.renderBlockFace(stack, texture, block, EnumBlockFace.NORTH); + stack.restore(); + } + + renderBlockFace(stack, texture, block, face) { + // UV Mapping + let textureIndex = block.getTextureForFace(face); + let minU = (textureIndex % 16) / 16.0; + let minV = Math.floor(textureIndex / 16) / 16.0; + + stack.save(); + this.drawSprite(stack, texture, minU * 256, minV, 16, 16, 0, 0, 16, 16) + stack.restore(); + } + static drawSprite(stack, texture, spriteX, spriteY, spriteWidth, spriteHeight, x, y, width, height, alpha = 1.0) { stack.save(); stack.globalAlpha = alpha; diff --git a/src/js/net/minecraft/client/gui/IngameOverlay.js b/src/js/net/minecraft/client/gui/IngameOverlay.js index f5271c9..b4104f0 100644 --- a/src/js/net/minecraft/client/gui/IngameOverlay.js +++ b/src/js/net/minecraft/client/gui/IngameOverlay.js @@ -6,12 +6,16 @@ window.IngameOverlay = class extends Gui { this.window = window; this.textureCrosshair = Gui.loadTexture("icons.png"); + this.textureHotbar = Gui.loadTexture("gui.png"); + this.textureTerrain = Gui.loadTexture("terrain.png"); } render(stack, mouseX, mouseY, partialTicks) { if (this.minecraft.hasInGameFocus()) { this.renderCrosshair(stack, this.window.width / 2, this.window.height / 2) } + + this.renderHotbar(stack, this.window.width / 2 - 100, this.window.height - 22); } renderCrosshair(stack, x, y) { @@ -19,4 +23,29 @@ window.IngameOverlay = class extends Gui { this.drawSprite(stack, this.textureCrosshair, 0, 0, 15, 15, x - size / 2, y - size / 2, size, size, 0.6); } + renderHotbar(stack, x, y) { + this.drawSprite(stack, this.textureHotbar, 0, 0, 200, 22, x, y, 200, 22) + this.drawSprite( + stack, + this.textureHotbar, + 0, 22, + 24, 24, + x + this.minecraft.inventory.selectedSlotIndex * 20, y - 1, + 24, 24 + ) + + for (let i = 0; i < 9; i++) { + let typeId = this.minecraft.inventory.getItemInSlot(i); + + if (typeId !== 0) { + this.renderBlock( + stack, + this.textureTerrain, Block.getById(typeId), + x + i * 20, + y + ); + } + } + } + } \ No newline at end of file diff --git a/src/js/net/minecraft/client/gui/screens/GuiIngameMenu.js b/src/js/net/minecraft/client/gui/screens/GuiIngameMenu.js index 6a70e34..e34f646 100644 --- a/src/js/net/minecraft/client/gui/screens/GuiIngameMenu.js +++ b/src/js/net/minecraft/client/gui/screens/GuiIngameMenu.js @@ -18,7 +18,7 @@ window.GuiIngameMenu = class extends GuiScreen { this.drawRect(stack, 0, 0, this.width, this.height, 'black', 0.6); // Title - this.drawCenteredString(stack, "Game paused", this.width / 2, 50); + this.drawCenteredString(stack, "Game menu", this.width / 2, 50); super.drawScreen(stack, mouseX, mouseY, partialTicks); } diff --git a/src/js/net/minecraft/client/gui/widgets/GuiButton.js b/src/js/net/minecraft/client/gui/widgets/GuiButton.js index de84cb7..6f89c12 100644 --- a/src/js/net/minecraft/client/gui/widgets/GuiButton.js +++ b/src/js/net/minecraft/client/gui/widgets/GuiButton.js @@ -15,7 +15,7 @@ window.GuiButton = class extends Gui { render(stack, mouseX, mouseY, partialTicks) { let mouseOver = this.isMouseOver(mouseX, mouseY); - this.drawSprite(stack, GuiButton.textureGui, 0, mouseOver ? 40 : 20, 200, 20, this.x, this.y, this.width, this.height); + this.drawSprite(stack, GuiButton.textureGui, 0, 66 + (mouseOver ? 20 : 0), 200, 20, this.x, this.y, this.width, this.height); this.drawCenteredString(stack, this.string, this.x + this.width / 2, this.y + this.height / 2 - 5); } diff --git a/src/js/net/minecraft/client/inventory/Inventory.js b/src/js/net/minecraft/client/inventory/Inventory.js new file mode 100644 index 0000000..55c5309 --- /dev/null +++ b/src/js/net/minecraft/client/inventory/Inventory.js @@ -0,0 +1,27 @@ +window.Inventory = class { + + constructor() { + this.selectedSlotIndex = 0; + this.items = []; + } + + setItemInSelectedSlot(typeId) { + this.items[this.selectedSlotIndex] = typeId; + } + + getItemInSelectedSlot() { + return this.getItemInSlot(this.selectedSlotIndex); + } + + shiftSelectedSlot(offset) { + if (this.selectedSlotIndex + offset < 0) { + this.selectedSlotIndex = 9 + (this.selectedSlotIndex + offset); + } else { + this.selectedSlotIndex = (this.selectedSlotIndex + offset) % 9; + } + } + + getItemInSlot(slot) { + return this.items.hasOwnProperty(slot) ? this.items[slot] : 0; + } +} \ No newline at end of file diff --git a/src/js/net/minecraft/client/render/BlockRenderer.js b/src/js/net/minecraft/client/render/BlockRenderer.js index 0e53824..fcb7380 100644 --- a/src/js/net/minecraft/client/render/BlockRenderer.js +++ b/src/js/net/minecraft/client/render/BlockRenderer.js @@ -135,5 +135,4 @@ window.BlockRenderer = class { // Calculate the average light level of all surrounding blocks return totalBlocks === 0 ? 0 : totalLightLevel / totalBlocks; } - } \ No newline at end of file diff --git a/src/start.js b/src/start.js index 35b90c1..b1f83b1 100644 --- a/src/start.js +++ b/src/start.js @@ -83,6 +83,7 @@ loadScripts([ "src/js/net/minecraft/client/world/generator/noise/NoiseGeneratorCombined.js", "src/js/net/minecraft/client/world/generator/WorldGenerator.js", "src/js/net/minecraft/client/entity/Player.js", + "src/js/net/minecraft/client/inventory/Inventory.js", "src/js/net/minecraft/client/Minecraft.js", "src/js/net/minecraft/client/render/FontRenderer.js", "src/js/net/minecraft/client/render/Tessellator.js",