User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'NaN')' in or related to this line: 'var type = world[x][y];' Line Number: 408
User prompt
i canet see player
User prompt
make player otto attak
User prompt
fix game pls
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'NaN')' in or related to this line: 'var type = world[x][y];' Line Number: 392
User prompt
Please fix the bug: 'ReferenceError: zombies is not defined' in or related to this line: 'for (var i = 0; i < zombies.length; i++) {' Line Number: 772
User prompt
Please fix the bug: 'Player is not defined' in or related to this line: 'var player = new Player();' Line Number: 218
User prompt
add enemys zombes
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '22.65000000000009')' in or related to this line: 'if (world[nx][ny] === BLOCK_AIR) {' Line Number: 83
User prompt
make mous controles
User prompt
Please fix the bug: 'updatePlayerPos is not defined' in or related to this line: 'updatePlayerPos();' Line Number: 795
User prompt
make proper player
Code edit (1 edits merged)
Please save this source code
User prompt
BlockCraft 2D
Initial prompt
make 2d minecraft
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // BlockSprite class var BlockSprite = Container.expand(function () { var self = Container.call(this); self.blockType = BLOCK_AIR; self.xIndex = 0; self.yIndex = 0; self.asset = null; self.setBlock = function (type) { self.blockType = type; if (self.asset) { self.removeChild(self.asset); self.asset = null; } if (type !== BLOCK_AIR) { self.asset = self.attachAsset('block_' + type, { width: BLOCK_SIZE, height: BLOCK_SIZE, color: BLOCK_COLORS[type], shape: 'box', anchorX: 0, anchorY: 0 }); } }; return self; }); // Minimal Player class definition to fix 'Player is not defined' var Player = Container.expand(function () { var self = Container.call(this); self.xIndex = playerX; self.yIndex = playerY; // Attach player asset self.asset = self.attachAsset('player', { width: BLOCK_SIZE, height: BLOCK_SIZE, anchorX: 0, anchorY: 0 }); // Dummy update method for compatibility self.update = function () { self.x = self.xIndex * BLOCK_SIZE - cameraX; self.y = self.yIndex * BLOCK_SIZE - cameraY; }; // Dummy move method for compatibility self.move = function (dx, dy) { self.xIndex += dx; self.yIndex += dy; }; // Dummy jump method for compatibility self.jump = function () {}; // Dummy applyGravity method for compatibility self.applyGravity = function () {}; // Attack method: damages any zombie adjacent to player self.attack = function () { // Player attacks all zombies in adjacent blocks (including diagonals) for (var i = zombies.length - 1; i >= 0; i--) { var z = zombies[i]; var dx = Math.abs(z.xIndex - self.xIndex); var dy = Math.abs(z.yIndex - self.yIndex); if (dx <= 1 && dy <= 1) { // Remove zombie from game and array if (z.destroy) z.destroy(); zombies.splice(i, 1); } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // sky blue }); /**** * Game Code ****/ // Block types // Generate world var BLOCK_AIR = 0; var BLOCK_DIRT = 1; var BLOCK_GRASS = 2; var BLOCK_STONE = 3; var BLOCK_WOOD = 4; var BLOCK_LEAF = 5; var BLOCK_CRAFTING = 6; var BLOCK_CHEST = 7; var BLOCK_SAND = 8; // Block colors var BLOCK_COLORS = {}; BLOCK_COLORS[BLOCK_AIR] = 0x000000; // invisible BLOCK_COLORS[BLOCK_DIRT] = 0x8B5A2B; BLOCK_COLORS[BLOCK_GRASS] = 0x4CAF50; BLOCK_COLORS[BLOCK_STONE] = 0x888888; BLOCK_COLORS[BLOCK_WOOD] = 0xA0522D; BLOCK_COLORS[BLOCK_LEAF] = 0x228B22; BLOCK_COLORS[BLOCK_CRAFTING] = 0xFFD700; BLOCK_COLORS[BLOCK_CHEST] = 0xC2B280; BLOCK_COLORS[BLOCK_SAND] = 0xF4E2B2; // Block size var BLOCK_SIZE = 100; // World size (in blocks) var WORLD_WIDTH = 20; var WORLD_HEIGHT = 24; // Inventory size var INVENTORY_SIZE = 6; // Simple recipes: [ [inputBlock, count], ... ] => [outputBlock, count] var RECIPES = [{ inputs: [[BLOCK_WOOD, 2]], output: [BLOCK_CRAFTING, 1] }, { inputs: [[BLOCK_STONE, 3]], output: [BLOCK_CHEST, 1] }, { inputs: [[BLOCK_SAND, 2]], output: [BLOCK_GLASS = 9, 1] } // glass is not in world, but can be crafted ]; // Add glass to block colors BLOCK_COLORS[BLOCK_GLASS] = 0xE0FFFF; // Block names var BLOCK_NAMES = {}; BLOCK_NAMES[BLOCK_AIR] = "Air"; BLOCK_NAMES[BLOCK_DIRT] = "Dirt"; BLOCK_NAMES[BLOCK_GRASS] = "Grass"; BLOCK_NAMES[BLOCK_STONE] = "Stone"; BLOCK_NAMES[BLOCK_WOOD] = "Wood"; BLOCK_NAMES[BLOCK_LEAF] = "Leaf"; BLOCK_NAMES[BLOCK_CRAFTING] = "Crafting Table"; BLOCK_NAMES[BLOCK_CHEST] = "Chest"; BLOCK_NAMES[BLOCK_SAND] = "Sand"; BLOCK_NAMES[BLOCK_GLASS] = "Glass"; // Block can be placed var BLOCK_PLACEABLE = {}; BLOCK_PLACEABLE[BLOCK_DIRT] = true; BLOCK_PLACEABLE[BLOCK_GRASS] = true; BLOCK_PLACEABLE[BLOCK_STONE] = true; BLOCK_PLACEABLE[BLOCK_WOOD] = true; BLOCK_PLACEABLE[BLOCK_LEAF] = true; BLOCK_PLACEABLE[BLOCK_CRAFTING] = true; BLOCK_PLACEABLE[BLOCK_CHEST] = true; BLOCK_PLACEABLE[BLOCK_SAND] = true; BLOCK_PLACEABLE[BLOCK_GLASS] = true; // Block can be mined var BLOCK_MINEABLE = {}; BLOCK_MINEABLE[BLOCK_DIRT] = true; BLOCK_MINEABLE[BLOCK_GRASS] = true; BLOCK_MINEABLE[BLOCK_STONE] = true; BLOCK_MINEABLE[BLOCK_WOOD] = true; BLOCK_MINEABLE[BLOCK_LEAF] = true; BLOCK_MINEABLE[BLOCK_CRAFTING] = true; BLOCK_MINEABLE[BLOCK_CHEST] = true; BLOCK_MINEABLE[BLOCK_SAND] = true; BLOCK_MINEABLE[BLOCK_GLASS] = true; // Block drops (what you get when you mine it) var BLOCK_DROPS = {}; BLOCK_DROPS[BLOCK_GRASS] = BLOCK_DIRT; BLOCK_DROPS[BLOCK_DIRT] = BLOCK_DIRT; BLOCK_DROPS[BLOCK_STONE] = BLOCK_STONE; BLOCK_DROPS[BLOCK_WOOD] = BLOCK_WOOD; BLOCK_DROPS[BLOCK_LEAF] = BLOCK_LEAF; BLOCK_DROPS[BLOCK_CRAFTING] = BLOCK_CRAFTING; BLOCK_DROPS[BLOCK_CHEST] = BLOCK_CHEST; BLOCK_DROPS[BLOCK_SAND] = BLOCK_SAND; BLOCK_DROPS[BLOCK_GLASS] = BLOCK_GLASS; // World data: 2D array [x][y] = block type var world = []; // Block sprites: 2D array [x][y] = BlockSprite var blockSprites = []; // Zombies array var zombies = []; // Inventory: array of {type, count} var inventory = []; for (var i = 0; i < INVENTORY_SIZE; i++) inventory.push({ type: BLOCK_AIR, count: 0 }); // Selected inventory slot var selectedSlot = 0; // Player position (in block coordinates) var playerX = Math.floor(WORLD_WIDTH / 2); var playerY = 6; // Player direction (1=right, -1=left) var playerDir = 1; // Is mining/placing var isMining = false; var isPlacing = false; // Drag state var dragStartX = null; var dragStartY = null; // Camera offset (in px) var cameraX = 0; var cameraY = 0; // Day-night cycle var dayTicks = 0; var DAY_LENGTH = 1800; // 30 seconds // UI elements var inventoryNodes = []; var selectedRect = null; var blockNameText = null; var craftingPanel = null; var craftingButtons = []; var showCrafting = false; function generateWorld() { for (var x = 0; x < WORLD_WIDTH; x++) { world[x] = []; blockSprites[x] = []; for (var y = 0; y < WORLD_HEIGHT; y++) { var type = BLOCK_AIR; if (y > 18) { type = BLOCK_STONE; } else if (y > 14) { type = BLOCK_DIRT; } else if (y == 14) { type = BLOCK_GRASS; } else if (y == 13 && Math.random() < 0.2) { type = BLOCK_WOOD; } else if (y == 12 && world[x] && // check world[x] is defined world[x][13] === BLOCK_WOOD && Math.random() < 0.7) { type = BLOCK_LEAF; } else if (y == 14 && Math.random() < 0.1) { type = BLOCK_SAND; } world[x][y] = type; var block = new BlockSprite(); block.xIndex = x; block.yIndex = y; block.x = x * BLOCK_SIZE; block.y = y * BLOCK_SIZE; block.setBlock(type); blockSprites[x][y] = block; game.addChild(block); } } } // Place player var player = new Player(); game.addChild(player); // Camera function updateCamera() { // Center on player, clamp to world cameraX = player.xIndex * BLOCK_SIZE + BLOCK_SIZE / 2 - 2048 / 2; cameraY = player.yIndex * BLOCK_SIZE + BLOCK_SIZE - 1200; if (cameraX < 0) cameraX = 0; if (cameraY < 0) cameraY = 0; var maxX = WORLD_WIDTH * BLOCK_SIZE - 2048; var maxY = WORLD_HEIGHT * BLOCK_SIZE - 2732; if (cameraX > maxX) cameraX = maxX; if (cameraY > maxY) cameraY = maxY; // Move all blocks for (var x = 0; x < WORLD_WIDTH; x++) { for (var y = 0; y < WORLD_HEIGHT; y++) { blockSprites[x][y].x = x * BLOCK_SIZE - cameraX; blockSprites[x][y].y = y * BLOCK_SIZE - cameraY; } } // Player's update will set its own position if (player && player.update) player.update(); } // Inventory UI function updateInventoryUI() { for (var i = 0; i < INVENTORY_SIZE; i++) { var node = inventoryNodes[i]; var inv = inventory[i]; if (inv.type !== BLOCK_AIR) { node.visible = true; node.asset.width = 90; node.asset.height = 90; node.asset.color = BLOCK_COLORS[inv.type]; node.countText.setText(inv.count > 1 ? inv.count : ""); } else { node.visible = false; } if (i === selectedSlot) { selectedRect.x = node.x - 5; selectedRect.y = node.y - 5; selectedRect.visible = true; } } } // Show block name function showBlockName(type) { if (!blockNameText) return; blockNameText.setText(BLOCK_NAMES[type] || ""); blockNameText.visible = true; LK.setTimeout(function () { blockNameText.visible = false; }, 1000); } // Crafting UI function showCraftingPanel() { if (craftingPanel) craftingPanel.visible = true; showCrafting = true; // Update buttons for (var i = 0; i < RECIPES.length; i++) { var btn = craftingButtons[i]; var canCraft = true; for (var j = 0; j < RECIPES[i].inputs.length; j++) { var input = RECIPES[i].inputs[j]; var have = 0; for (var k = 0; k < INVENTORY_SIZE; k++) { if (inventory[k].type === input[0]) have += inventory[k].count; } if (have < input[1]) canCraft = false; } btn.alpha = canCraft ? 1 : 0.5; btn.interactive = canCraft; } } function hideCraftingPanel() { if (craftingPanel) craftingPanel.visible = false; showCrafting = false; } // Add to inventory function addToInventory(type, count) { // Try to stack for (var i = 0; i < INVENTORY_SIZE; i++) { if (inventory[i].type === type && inventory[i].count < 99) { var add = Math.min(count, 99 - inventory[i].count); inventory[i].count += add; count -= add; if (count <= 0) return true; } } // Try to add to empty slot for (var i = 0; i < INVENTORY_SIZE; i++) { if (inventory[i].type === BLOCK_AIR) { inventory[i].type = type; inventory[i].count = count; return true; } } return false; } // Remove from inventory function removeFromInventory(type, count) { for (var i = 0; i < INVENTORY_SIZE; i++) { if (inventory[i].type === type && inventory[i].count > 0) { var take = Math.min(count, inventory[i].count); inventory[i].count -= take; count -= take; if (inventory[i].count === 0) inventory[i].type = BLOCK_AIR; if (count <= 0) return true; } } return false; } // Mining/placing logic function mineBlock(x, y) { if (x < 0 || x >= WORLD_WIDTH || y < 0 || y >= WORLD_HEIGHT) return; if (!world[x]) return; var type = world[x][y]; if (type === BLOCK_AIR) return; if (!BLOCK_MINEABLE[type]) return; // Remove block world[x][y] = BLOCK_AIR; blockSprites[x][y].setBlock(BLOCK_AIR); // Drop item var drop = BLOCK_DROPS[type]; if (drop) addToInventory(drop, 1); updateInventoryUI(); showBlockName(type); } function placeBlock(x, y) { if (x < 0 || x >= WORLD_WIDTH || y < 0 || y >= WORLD_HEIGHT) return; if (world[x][y] !== BLOCK_AIR) return; var inv = inventory[selectedSlot]; if (inv.type === BLOCK_AIR) return; if (!BLOCK_PLACEABLE[inv.type]) return; // Place block world[x][y] = inv.type; blockSprites[x][y].setBlock(inv.type); removeFromInventory(inv.type, 1); updateInventoryUI(); showBlockName(inv.type); } // Touch/mouse events game.down = function (x, y, obj) { if (showCrafting) return; dragStartX = x; dragStartY = y; // Convert to world block var wx = Math.floor((x + cameraX) / BLOCK_SIZE); var wy = Math.floor((y + cameraY) / BLOCK_SIZE); // If tap on player, open crafting if standing on crafting table if (wx === playerX && wy === playerY - 1 && world[playerX][playerY - 1] === BLOCK_CRAFTING) { showCraftingPanel(); return; } // Mouse/touch controls for moving player: tap left/right block to move if (wx === player.xIndex - 1 && wy === player.yIndex) { movePlayer(-1, 0); return; } if (wx === player.xIndex + 1 && wy === player.yIndex) { movePlayer(1, 0); return; } if (wx === player.xIndex && wy === player.yIndex - 1) { movePlayer(0, -1); return; } // If tap on zombie: attack! var attackedZombie = false; for (var i = zombies.length - 1; i >= 0; i--) { var z = zombies[i]; if (z.xIndex === wx && z.yIndex === wy) { if (player && player.attack) player.attack(); attackedZombie = true; break; } } // If not attacking a zombie, mine/place as usual if (!attackedZombie && world[wx] && world[wx][wy] !== undefined) { if (world[wx][wy] !== BLOCK_AIR) { mineBlock(wx, wy); isMining = true; } else { placeBlock(wx, wy); isPlacing = true; } } }; game.up = function (x, y, obj) { isMining = false; isPlacing = false; dragStartX = null; dragStartY = null; }; game.move = function (x, y, obj) { if (showCrafting) return; if (dragStartX === null) return; var wx = Math.floor((x + cameraX) / BLOCK_SIZE); var wy = Math.floor((y + cameraY) / BLOCK_SIZE); if (isMining) { mineBlock(wx, wy); } else if (isPlacing) { placeBlock(wx, wy); } }; // Inventory tap function onInventoryTap(i) { selectedSlot = i; updateInventoryUI(); } // Crafting tap function onCraftingTap(i) { var recipe = RECIPES[i]; // Remove inputs for (var j = 0; j < recipe.inputs.length; j++) { removeFromInventory(recipe.inputs[j][0], recipe.inputs[j][1]); } // Add output addToInventory(recipe.output[0], recipe.output[1]); updateInventoryUI(); showCraftingPanel(); } // Close crafting function onCloseCrafting() { hideCraftingPanel(); } // Move player left/right/jump function movePlayer(dx, dy) { if (!player) return; if (dx !== 0) { player.move(dx, 0); } if (dy !== 0) { // Only allow jump if moving up if (dy < 0) player.jump(); } updateCamera(); } // Gravity function applyGravity() { if (!player) return; player.applyGravity(); updateCamera(); } // Day-night cycle function updateDayNight() { dayTicks++; if (dayTicks >= DAY_LENGTH) dayTicks = 0; // Fade to dark at night var t = dayTicks / DAY_LENGTH * 2 * Math.PI; var night = (Math.cos(t) + 1) / 2; var overlay = 0x000000; var alpha = 0.2 + 0.5 * night; if (!game.nightOverlay) { game.nightOverlay = LK.getAsset('nightOverlay', { width: 2048, height: 2732, color: overlay, shape: 'box', anchorX: 0, anchorY: 0 }); game.nightOverlay.alpha = alpha; game.addChild(game.nightOverlay); } game.nightOverlay.alpha = alpha; game.nightOverlay.zIndex = 9999; } // GUI function setupGUI() { // Inventory bar for (var i = 0; i < INVENTORY_SIZE; i++) { var node = new Container(); node.x = 300 + i * 130; node.y = 2632; node.asset = node.attachAsset('inv_' + i, { width: 90, height: 90, color: 0x222222, shape: 'box', anchorX: 0, anchorY: 0 }); node.countText = new Text2("", { size: 40, fill: "#fff" }); node.countText.x = 60; node.countText.y = 50; node.addChild(node.countText); node.interactive = true; (function (idx) { node.down = function (x, y, obj) { onInventoryTap(idx); }; })(i); LK.gui.bottom.addChild(node); inventoryNodes.push(node); } // Selected rect selectedRect = LK.getAsset('selectedRect', { width: 100, height: 100, color: 0xffff00, shape: 'box', anchorX: 0, anchorY: 0 }); selectedRect.alpha = 0.3; LK.gui.bottom.addChild(selectedRect); // Block name text blockNameText = new Text2("", { size: 60, fill: "#fff" }); blockNameText.x = 1024; blockNameText.y = 100; blockNameText.anchor.set(0.5, 0); LK.gui.top.addChild(blockNameText); // Crafting panel craftingPanel = new Container(); craftingPanel.x = 400; craftingPanel.y = 800; var panelBg = craftingPanel.attachAsset('craftingBg', { width: 1200, height: 900, color: 0x333333, shape: 'box', anchorX: 0, anchorY: 0 }); var title = new Text2("Crafting", { size: 80, fill: "#fff" }); title.x = 600; title.y = 60; title.anchor.set(0.5, 0); craftingPanel.addChild(title); // Recipe buttons for (var i = 0; i < RECIPES.length; i++) { var btn = new Container(); btn.x = 100; btn.y = 180 + i * 200; btn.bg = btn.attachAsset('craftBtn' + i, { width: 1000, height: 160, color: 0x555555, shape: 'box', anchorX: 0, anchorY: 0 }); var txt = new Text2("Craft " + BLOCK_NAMES[RECIPES[i].output[0]], { size: 50, fill: "#fff" }); txt.x = 500; txt.y = 40; txt.anchor.set(0.5, 0); btn.addChild(txt); btn.interactive = true; (function (idx) { btn.down = function (x, y, obj) { onCraftingTap(idx); }; })(i); craftingPanel.addChild(btn); craftingButtons.push(btn); } // Close button var closeBtn = new Container(); closeBtn.x = 1050; closeBtn.y = 60; closeBtn.bg = closeBtn.attachAsset('closeBtn', { width: 100, height: 100, color: 0xaa2222, shape: 'box', anchorX: 0, anchorY: 0 }); var closeTxt = new Text2("X", { size: 70, fill: "#fff" }); closeTxt.x = 50; closeTxt.y = 15; closeTxt.anchor.set(0.5, 0); closeBtn.addChild(closeTxt); closeBtn.interactive = true; closeBtn.down = function (x, y, obj) { onCloseCrafting(); }; craftingPanel.addChild(closeBtn); craftingPanel.visible = false; LK.gui.center.addChild(craftingPanel); } // Controls function setupControls() { // Left button var leftBtn = new Container(); leftBtn.x = 100; leftBtn.y = 2500; leftBtn.bg = leftBtn.attachAsset('leftBtn', { width: 120, height: 120, color: 0x444444, shape: 'box', anchorX: 0, anchorY: 0 }); var ltxt = new Text2("<", { size: 80, fill: "#fff" }); ltxt.x = 60; ltxt.y = 20; ltxt.anchor.set(0.5, 0); leftBtn.addChild(ltxt); leftBtn.interactive = true; leftBtn.down = function (x, y, obj) { movePlayer(-1, 0); }; LK.gui.bottomLeft.addChild(leftBtn); // Right button var rightBtn = new Container(); rightBtn.x = 350; rightBtn.y = 2500; rightBtn.bg = rightBtn.attachAsset('rightBtn', { width: 120, height: 120, color: 0x444444, shape: 'box', anchorX: 0, anchorY: 0 }); var rtxt = new Text2(">", { size: 80, fill: "#fff" }); rtxt.x = 60; rtxt.y = 20; rtxt.anchor.set(0.5, 0); rightBtn.addChild(rtxt); rightBtn.interactive = true; rightBtn.down = function (x, y, obj) { movePlayer(1, 0); }; LK.gui.bottomLeft.addChild(rightBtn); // Jump button var jumpBtn = new Container(); jumpBtn.x = 1800; jumpBtn.y = 2500; jumpBtn.bg = jumpBtn.attachAsset('jumpBtn', { width: 120, height: 120, color: 0x444444, shape: 'box', anchorX: 0, anchorY: 0 }); var jtxt = new Text2("^", { size: 80, fill: "#fff" }); jtxt.x = 60; jtxt.y = 20; jtxt.anchor.set(0.5, 0); jumpBtn.addChild(jtxt); jumpBtn.interactive = true; jumpBtn.down = function (x, y, obj) { movePlayer(0, -1); }; LK.gui.bottomRight.addChild(jumpBtn); } // Main update game.update = function () { // Gravity applyGravity(); // Zombies update for (var i = 0; i < zombies.length; i++) { var z = zombies[i]; // Save last position for event logic z.lastXIndex = z.xIndex; z.lastYIndex = z.yIndex; var wasTouching = z.lastWasTouchingPlayer; // AI and gravity z.ai(); z.applyGravity(); if (z.update) z.update(); // Check collision with player (only trigger on first frame of contact) var touching = z.isTouchingPlayer(); if (!wasTouching && touching) { // Flash screen red and show game over LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } z.lastWasTouchingPlayer = touching; } // Camera updateCamera(); // Day-night updateDayNight(); }; // Init generateWorld(); if (player && player.update) player.update(); updateCamera(); setupGUI(); setupControls(); updateInventoryUI();
===================================================================
--- original.js
+++ change.js
@@ -359,8 +359,9 @@
}
// Mining/placing logic
function mineBlock(x, y) {
if (x < 0 || x >= WORLD_WIDTH || y < 0 || y >= WORLD_HEIGHT) return;
+ if (!world[x]) return;
var type = world[x][y];
if (type === BLOCK_AIR) return;
if (!BLOCK_MINEABLE[type]) return;
// Remove block