User prompt
Oyuna mobil tuşlar ekle
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.world = world;' Line Number: 283
User prompt
Please fix the bug: 'Uncaught TypeError: storage.setItem is not a function' in or related to this line: 'storage.setItem('world', world);' Line Number: 283
User prompt
Blokların doğma noktası ortada olsun
User prompt
Please fix the bug: 'Uncaught TypeError: storage.save is not a function' in or related to this line: 'storage.save('world', world);' Line Number: 280
User prompt
Please fix the bug: 'Uncaught TypeError: storage.set is not a function' in or related to this line: 'storage.set('world', world);' Line Number: 280
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.world = world;' Line Number: 280
Code edit (1 edits merged)
Please save this source code
User prompt
MiniCraft: Block Builder
Initial prompt
Minecraft
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Block class: represents a single block in the world grid var Block = Container.expand(function () { var self = Container.call(this); self.blockType = 'grass'; // default, will be set on init self.gridX = 0; self.gridY = 0; // The block asset self.blockAsset = null; self.setType = function (type) { self.blockType = type; if (self.blockAsset) { self.removeChild(self.blockAsset); } self.blockAsset = self.attachAsset('block_' + type, { anchorX: 0.5, anchorY: 0.5 }); }; self.setGrid = function (x, y) { self.gridX = x; self.gridY = y; }; return self; }); // InventorySlot class: represents a selectable block type in the inventory var InventorySlot = Container.expand(function () { var self = Container.call(this); self.blockType = 'grass'; self.selected = false; // Slot background self.bg = self.attachAsset('inv_slot', { anchorX: 0.5, anchorY: 0.5 }); // Block icon self.icon = self.attachAsset('block_grass', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); // Selection highlight self.selectHighlight = self.attachAsset('block_select', { anchorX: 0.5, anchorY: 0.5 }); self.selectHighlight.alpha = 0; self.setType = function (type) { self.blockType = type; self.removeChild(self.icon); self.icon = self.attachAsset('block_' + type, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); self.addChild(self.icon); }; self.setSelected = function (sel) { self.selected = sel; self.selectHighlight.alpha = sel ? 0.7 : 0; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // light blue sky }); /**** * Game Code ****/ // Inventory slot background // Selection highlight // Each block is a colored box shape, 120x120px // Block types: grass, dirt, stone, water, wood, sand // --- World/grid setup --- var BLOCK_SIZE = 120; var GRID_COLS = 16; // 16x16 visible grid (1920x1920), fits on iPad Pro with some margin var GRID_ROWS = 16; var WORLD_COLS = 32; // world is 32x32 blocks var WORLD_ROWS = 32; // The world data: 2D array of block types var world = []; // Try to load from storage, else generate new if (storage.world && storage.world.length === WORLD_ROWS) { for (var y = 0; y < WORLD_ROWS; y++) { world[y] = []; for (var x = 0; x < WORLD_COLS; x++) { world[y][x] = storage.world[y][x]; } } } else { // Generate a simple world: grass on top, dirt below, stone at bottom, some water and sand for (var y = 0; y < WORLD_ROWS; y++) { world[y] = []; for (var x = 0; x < WORLD_COLS; x++) { if (y === WORLD_ROWS - 1) { world[y][x] = 'stone'; } else if (y > WORLD_ROWS - 4) { world[y][x] = 'dirt'; } else if (y === WORLD_ROWS - 4) { world[y][x] = 'grass'; } else if (y > WORLD_ROWS - 8 && x > 5 && x < 10) { world[y][x] = 'water'; } else if (y > WORLD_ROWS - 8 && x > 20 && x < 25) { world[y][x] = 'sand'; } else { world[y][x] = 'air'; } } } } // The block types available to the player var blockTypes = ['grass', 'dirt', 'stone', 'water', 'wood', 'sand']; var blockTypeNames = { grass: 'Grass', dirt: 'Dirt', stone: 'Stone', water: 'Water', wood: 'Wood', sand: 'Sand' }; // The currently selected block type for placement var selectedBlockType = storage.selectedBlockType || 'grass'; // Camera offset (in grid units) // Center the camera on the world spawn (center of the world) var defaultCameraX = Math.floor((WORLD_COLS - GRID_COLS) / 2); var defaultCameraY = Math.floor((WORLD_ROWS - GRID_ROWS) / 2); var cameraX = typeof storage.cameraX === "number" ? storage.cameraX : defaultCameraX; var cameraY = typeof storage.cameraY === "number" ? storage.cameraY : defaultCameraY; // Clamp camera to world bounds function clampCamera() { if (cameraX < 0) cameraX = 0; if (cameraY < 0) cameraY = 0; if (cameraX > WORLD_COLS - GRID_COLS) cameraX = WORLD_COLS - GRID_COLS; if (cameraY > WORLD_ROWS - GRID_ROWS) cameraY = WORLD_ROWS - GRID_ROWS; } // --- Block rendering --- var blockLayer = new Container(); game.addChild(blockLayer); // 2D array of Block objects for visible grid var blockObjs = []; for (var y = 0; y < GRID_ROWS; y++) { blockObjs[y] = []; for (var x = 0; x < GRID_COLS; x++) { var block = new Block(); block.x = x * BLOCK_SIZE + BLOCK_SIZE / 2; block.y = y * BLOCK_SIZE + BLOCK_SIZE / 2 + 100; // leave space for inventory block.setGrid(x, y); blockLayer.addChild(block); blockObjs[y][x] = block; } } // Center the grid horizontally blockLayer.x = (2048 - GRID_COLS * BLOCK_SIZE) / 2; blockLayer.y = 0; // --- Inventory UI --- var inventoryBar = new Container(); LK.gui.bottom.addChild(inventoryBar); var invSlots = []; var invSlotMargin = 20; var invBarWidth = blockTypes.length * (130 + invSlotMargin) - invSlotMargin; for (var i = 0; i < blockTypes.length; i++) { var slot = new InventorySlot(); slot.setType(blockTypes[i]); slot.x = i * (130 + invSlotMargin) - invBarWidth / 2 + 2048 / 2; slot.y = -80; // above bottom edge inventoryBar.addChild(slot); invSlots.push(slot); // Touch/click to select block type (function (slot, i) { slot.down = function (x, y, obj) { selectedBlockType = slot.blockType; for (var j = 0; j < invSlots.length; j++) { invSlots[j].setSelected(j === i); } storage.selectedBlockType = selectedBlockType; }; })(slot, i); // Set initial selection if (blockTypes[i] === selectedBlockType) { slot.setSelected(true); } } // --- Instructions UI --- var instructions = new Text2("Tap/drag to place blocks\nDouble tap to remove\nDrag background to scroll", { size: 60, fill: 0xFFFFFF }); instructions.anchor.set(0.5, 0); LK.gui.top.addChild(instructions); instructions.x = 2048 / 2; instructions.y = 120; // --- World update/render --- function updateBlockObjs() { for (var y = 0; y < GRID_ROWS; y++) { for (var x = 0; x < GRID_COLS; x++) { var wx = x + cameraX; var wy = y + cameraY; var blockType = world[wy] && world[wy][wx] ? world[wy][wx] : 'air'; var block = blockObjs[y][x]; block.setGrid(wx, wy); block.visible = blockType !== 'air'; if (block.visible) { block.setType(blockType); } } } } updateBlockObjs(); // --- Touch/drag controls --- var dragMode = null; // 'place', 'remove', 'scroll' var lastTouchGrid = { x: -1, y: -1 }; var lastTouchTime = 0; var lastTouchPos = { x: 0, y: 0 }; var scrollStart = { x: 0, y: 0 }; var cameraStart = { x: 0, y: 0 }; // Convert game coordinates to grid coordinates function gameToGrid(x, y) { var gx = Math.floor((x - blockLayer.x) / BLOCK_SIZE); var gy = Math.floor((y - blockLayer.y - 100) / BLOCK_SIZE); return { x: gx, y: gy }; } // Place a block at grid (gx, gy) function placeBlock(gx, gy) { var wx = gx + cameraX; var wy = gy + cameraY; if (wx < 0 || wx >= WORLD_COLS || wy < 0 || wy >= WORLD_ROWS) return; if (world[wy][wx] === selectedBlockType) return; world[wy][wx] = selectedBlockType; updateBlockObjs(); } // Remove a block at grid (gx, gy) function removeBlock(gx, gy) { var wx = gx + cameraX; var wy = gy + cameraY; if (wx < 0 || wx >= WORLD_COLS || wy < 0 || wy >= WORLD_ROWS) return; if (world[wy][wx] === 'air') return; world[wy][wx] = 'air'; updateBlockObjs(); } // --- Main touch handlers --- game.down = function (x, y, obj) { // Check if touch is on inventory bar var guiY = y / 2732 * LK.gui.height; if (guiY > LK.gui.height - 200) { // Let inventory slots handle their own down return; } var grid = gameToGrid(x, y); lastTouchGrid.x = grid.x; lastTouchGrid.y = grid.y; lastTouchPos.x = x; lastTouchPos.y = y; scrollStart.x = x; scrollStart.y = y; cameraStart.x = cameraX; cameraStart.y = cameraY; // Double tap to remove var now = Date.now(); if (now - lastTouchTime < 350) { removeBlock(grid.x, grid.y); dragMode = 'remove'; } else { placeBlock(grid.x, grid.y); dragMode = 'place'; } lastTouchTime = now; }; game.move = function (x, y, obj) { if (dragMode === 'scroll') { // Drag to scroll var dx = x - scrollStart.x; var dy = y - scrollStart.y; cameraX = cameraStart.x - Math.round(dx / BLOCK_SIZE); cameraY = cameraStart.y - Math.round(dy / BLOCK_SIZE); clampCamera(); updateBlockObjs(); return; } var grid = gameToGrid(x, y); if (grid.x === lastTouchGrid.x && grid.y === lastTouchGrid.y) return; lastTouchGrid.x = grid.x; lastTouchGrid.y = grid.y; if (dragMode === 'place') { placeBlock(grid.x, grid.y); } else if (dragMode === 'remove') { removeBlock(grid.x, grid.y); } else { // If moved far, start scrolling var dist = Math.abs(x - scrollStart.x) + Math.abs(y - scrollStart.y); if (dist > 40) { dragMode = 'scroll'; } } }; game.up = function (x, y, obj) { dragMode = null; storage.cameraX = cameraX; storage.cameraY = cameraY; }; // --- Save selected block type and camera on exit --- LK.on('destroy', function () { storage.selectedBlockType = selectedBlockType; storage.cameraX = cameraX; storage.cameraY = cameraY; }); // --- Game update loop (not much needed) --- game.update = function () { // No per-frame logic needed for MVP };
===================================================================
--- original.js
+++ change.js
@@ -255,9 +255,8 @@
var wy = gy + cameraY;
if (wx < 0 || wx >= WORLD_COLS || wy < 0 || wy >= WORLD_ROWS) return;
if (world[wy][wx] === selectedBlockType) return;
world[wy][wx] = selectedBlockType;
- storage.world = world;
updateBlockObjs();
}
// Remove a block at grid (gx, gy)
function removeBlock(gx, gy) {
@@ -265,9 +264,8 @@
var wy = gy + cameraY;
if (wx < 0 || wx >= WORLD_COLS || wy < 0 || wy >= WORLD_ROWS) return;
if (world[wy][wx] === 'air') return;
world[wy][wx] = 'air';
- storage.world = world;
updateBlockObjs();
}
// --- Main touch handlers ---
game.down = function (x, y, obj) {
@@ -333,9 +331,8 @@
LK.on('destroy', function () {
storage.selectedBlockType = selectedBlockType;
storage.cameraX = cameraX;
storage.cameraY = cameraY;
- storage.world = world;
});
// --- Game update loop (not much needed) ---
game.update = function () {
// No per-frame logic needed for MVP