/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Block = Container.expand(function (blockType) { var self = Container.call(this); this.blockType = blockType; this.gridX = 0; this.gridY = 0; var blockGraphics = self.attachAsset(blockType, { anchorX: 0.5, anchorY: 0.5 }); // Add slight border effect blockGraphics.alpha = 0.9; self.setGridPosition = function (gridX, gridY) { self.gridX = gridX; self.gridY = gridY; self.x = gridX * 80 + 40; self.y = gridY * 80 + 40; }; return self; }); var DeleteAllButton = Container.expand(function () { var self = Container.call(this); var buttonBackground = self.attachAsset('uiButton', { anchorX: 0.5, anchorY: 0.5 }); buttonBackground.tint = 0xFF0000; var buttonText = new Text2('DELETE ALL!', { size: 32, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.x = 1024; self.y = 2400; self.visible = false; self.show = function () { self.visible = true; // Animate in self.alpha = 0; tween(self, { alpha: 1 }, { duration: 300 }); }; self.hide = function () { self.visible = false; }; self.down = function (x, y, obj) { // Delete all blocks for (var gridKey in gameGrid) { var block = gameGrid[gridKey]; if (block) { block.destroy(); } } gameGrid = {}; self.hide(); LK.getSound('break').play(); }; return self; }); var GridHighlight = Container.expand(function () { var self = Container.call(this); var highlightGraphics = self.attachAsset('highlight', { anchorX: 0.5, anchorY: 0.5 }); highlightGraphics.alpha = 0.3; self.visible = false; self.showAt = function (gridX, gridY) { self.x = gridX * 80 + 40; self.y = gridY * 80 + 40; self.visible = true; }; self.hide = function () { self.visible = false; }; return self; }); var InventorySlot = Container.expand(function (blockType, index) { var self = Container.call(this); this.blockType = blockType; this.count = -1; // Unlimited blocks var slotBackground = self.attachAsset('inventorySlot', { anchorX: 0.5, anchorY: 0.5 }); var blockPreview = self.attachAsset(blockType, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); // No count display for unlimited blocks self.x = 150 + index * 120; self.y = 2600; self.updateCount = function (newCount) { // Unlimited blocks - no count updates needed }; self.down = function (x, y, obj) { selectedBlockType = self.blockType; updateSelectedIndicator(); }; return self; }); var ModeButton = Container.expand(function () { var self = Container.call(this); var buttonBackground = self.attachAsset('uiButton', { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2('BUILD', { size: 36, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.x = 1024; self.y = 2500; self.updateMode = function (isBuildMode) { if (isBuildMode) { buttonText.setText('BUILD'); buttonBackground.tint = 0x00AA00; } else { buttonText.setText('BREAK'); buttonBackground.tint = 0xAA0000; } }; self.down = function (x, y, obj) { isBuildMode = !isBuildMode; self.updateMode(isBuildMode); // Hide DELETE ALL! button when switching to build mode if (isBuildMode && deleteAllButton) { deleteAllButton.hide(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Sound effects // UI elements // Grid-based building blocks // Game state variables var gameGrid = {}; var gridWidth = 25; var gridHeight = 30; var isBuildMode = true; var selectedBlockType = 'stone'; // UI elements var gridHighlight; var inventorySlots = []; var modeButton; var selectedIndicator; var deleteAllButton; // Add UI area background first (behind other elements) var uiBackground = LK.getAsset('inventorySlot', { anchorX: 0.5, anchorY: 0, scaleX: 20.48, scaleY: 3.32 }); uiBackground.x = 1024; uiBackground.y = 2400; uiBackground.tint = 0xffffff; uiBackground.alpha = 0.95; game.addChild(uiBackground); // Initialize grid highlight gridHighlight = game.addChild(new GridHighlight()); // Initialize inventory var blockTypes = ['stone', 'wood', 'dirt', 'grass', 'cobblestone', 'iron_ore', 'gold_ore', 'diamond_ore', 'iron_block', 'gold_block', 'diamond_block', 'wood_block', 'tree_leaf', 'water', 'ice', 'lava']; for (var i = 0; i < blockTypes.length; i++) { var slot = new InventorySlot(blockTypes[i], i); inventorySlots.push(slot); game.addChild(slot); } // Initialize mode button modeButton = game.addChild(new ModeButton()); modeButton.updateMode(isBuildMode); // DELETE ALL! button will be created when needed deleteAllButton = null; // Remove any existing stone blocks behind and below UI area (y >= 2400) for (var gridKey in gameGrid) { var block = gameGrid[gridKey]; if (block && block.blockType === 'stone' && block.y >= 2400) { block.destroy(); delete gameGrid[gridKey]; } } // Also remove stone blocks below the UI area for (var gridY = 30; gridY <= 40; gridY++) { for (var gridX = 0; gridX < gridWidth; gridX++) { var gridKey = getGridKey(gridX, gridY); var block = gameGrid[gridKey]; if (block && block.blockType === 'stone') { block.destroy(); delete gameGrid[gridKey]; } } } // Add bottom border for (var j = 0; j < 26; j++) { var bottomBorderBlock = LK.getAsset('dirt', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); bottomBorderBlock.x = j * 80 + 40; bottomBorderBlock.y = 2700; bottomBorderBlock.alpha = 0.3; bottomBorderBlock.tint = 0x444444; game.addChild(bottomBorderBlock); } // Selected block indicator selectedIndicator = LK.getAsset('highlight', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); selectedIndicator.alpha = 0.5; game.addChild(selectedIndicator); function updateSelectedIndicator() { for (var i = 0; i < inventorySlots.length; i++) { if (inventorySlots[i].blockType === selectedBlockType) { selectedIndicator.x = inventorySlots[i].x; selectedIndicator.y = inventorySlots[i].y; break; } } } updateSelectedIndicator(); function worldToGrid(worldX, worldY) { return { x: Math.floor(worldX / 80), y: Math.floor(worldY / 80) }; } function isValidGridPosition(gridX, gridY) { return true; // Allow placing blocks anywhere } function getGridKey(gridX, gridY) { return gridX + ',' + gridY; } function hasBlockAt(gridX, gridY) { return gameGrid[getGridKey(gridX, gridY)] !== undefined; } function getInventorySlot(blockType) { for (var i = 0; i < inventorySlots.length; i++) { if (inventorySlots[i].blockType === blockType) { return inventorySlots[i]; } } return null; } function placeBlock(gridX, gridY, blockType) { if (!isValidGridPosition(gridX, gridY) || hasBlockAt(gridX, gridY)) { return false; } var slot = getInventorySlot(blockType); if (!slot) { return false; } var block = new Block(blockType); block.setGridPosition(gridX, gridY); game.addChild(block); gameGrid[getGridKey(gridX, gridY)] = block; // Keep unlimited blocks - no count decrement LK.getSound('place').play(); // Place animation block.alpha = 0; tween(block, { alpha: 1 }, { duration: 200 }); return true; } function breakBlock(gridX, gridY) { var gridKey = getGridKey(gridX, gridY); var block = gameGrid[gridKey]; if (!block) { return false; } var slot = getInventorySlot(block.blockType); if (slot) { slot.updateCount(slot.count + 1); } LK.getSound('break').play(); // Break animation tween(block, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 200, onFinish: function onFinish() { block.destroy(); } }); delete gameGrid[gridKey]; // Create DELETE ALL! button if it doesn't exist if (!deleteAllButton) { deleteAllButton = game.addChild(new DeleteAllButton()); deleteAllButton.y = 2580; // Position below BUILD button } // Show delete all button after breaking deleteAllButton.show(); return true; } var lastHoverGridX = -1; var lastHoverGridY = -1; game.move = function (x, y, obj) { // Only show highlight in build area if (y < 2400) { var gridPos = worldToGrid(x, y); if (gridPos.x !== lastHoverGridX || gridPos.y !== lastHoverGridY) { if (isBuildMode && !hasBlockAt(gridPos.x, gridPos.y)) { gridHighlight.showAt(gridPos.x, gridPos.y); } else if (!isBuildMode && hasBlockAt(gridPos.x, gridPos.y)) { gridHighlight.showAt(gridPos.x, gridPos.y); } else { gridHighlight.hide(); } lastHoverGridX = gridPos.x; lastHoverGridY = gridPos.y; } } else { gridHighlight.hide(); lastHoverGridX = -1; lastHoverGridY = -1; } }; game.down = function (x, y, obj) { // Only allow building/breaking in the main game area if (y < 2400) { var gridPos = worldToGrid(x, y); if (isBuildMode) { placeBlock(gridPos.x, gridPos.y, selectedBlockType); } else { breakBlock(gridPos.x, gridPos.y); } } }; game.update = function () { // Update game state if needed };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Block = Container.expand(function (blockType) {
var self = Container.call(this);
this.blockType = blockType;
this.gridX = 0;
this.gridY = 0;
var blockGraphics = self.attachAsset(blockType, {
anchorX: 0.5,
anchorY: 0.5
});
// Add slight border effect
blockGraphics.alpha = 0.9;
self.setGridPosition = function (gridX, gridY) {
self.gridX = gridX;
self.gridY = gridY;
self.x = gridX * 80 + 40;
self.y = gridY * 80 + 40;
};
return self;
});
var DeleteAllButton = Container.expand(function () {
var self = Container.call(this);
var buttonBackground = self.attachAsset('uiButton', {
anchorX: 0.5,
anchorY: 0.5
});
buttonBackground.tint = 0xFF0000;
var buttonText = new Text2('DELETE ALL!', {
size: 32,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.x = 1024;
self.y = 2400;
self.visible = false;
self.show = function () {
self.visible = true;
// Animate in
self.alpha = 0;
tween(self, {
alpha: 1
}, {
duration: 300
});
};
self.hide = function () {
self.visible = false;
};
self.down = function (x, y, obj) {
// Delete all blocks
for (var gridKey in gameGrid) {
var block = gameGrid[gridKey];
if (block) {
block.destroy();
}
}
gameGrid = {};
self.hide();
LK.getSound('break').play();
};
return self;
});
var GridHighlight = Container.expand(function () {
var self = Container.call(this);
var highlightGraphics = self.attachAsset('highlight', {
anchorX: 0.5,
anchorY: 0.5
});
highlightGraphics.alpha = 0.3;
self.visible = false;
self.showAt = function (gridX, gridY) {
self.x = gridX * 80 + 40;
self.y = gridY * 80 + 40;
self.visible = true;
};
self.hide = function () {
self.visible = false;
};
return self;
});
var InventorySlot = Container.expand(function (blockType, index) {
var self = Container.call(this);
this.blockType = blockType;
this.count = -1; // Unlimited blocks
var slotBackground = self.attachAsset('inventorySlot', {
anchorX: 0.5,
anchorY: 0.5
});
var blockPreview = self.attachAsset(blockType, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
// No count display for unlimited blocks
self.x = 150 + index * 120;
self.y = 2600;
self.updateCount = function (newCount) {
// Unlimited blocks - no count updates needed
};
self.down = function (x, y, obj) {
selectedBlockType = self.blockType;
updateSelectedIndicator();
};
return self;
});
var ModeButton = Container.expand(function () {
var self = Container.call(this);
var buttonBackground = self.attachAsset('uiButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2('BUILD', {
size: 36,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.x = 1024;
self.y = 2500;
self.updateMode = function (isBuildMode) {
if (isBuildMode) {
buttonText.setText('BUILD');
buttonBackground.tint = 0x00AA00;
} else {
buttonText.setText('BREAK');
buttonBackground.tint = 0xAA0000;
}
};
self.down = function (x, y, obj) {
isBuildMode = !isBuildMode;
self.updateMode(isBuildMode);
// Hide DELETE ALL! button when switching to build mode
if (isBuildMode && deleteAllButton) {
deleteAllButton.hide();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Sound effects
// UI elements
// Grid-based building blocks
// Game state variables
var gameGrid = {};
var gridWidth = 25;
var gridHeight = 30;
var isBuildMode = true;
var selectedBlockType = 'stone';
// UI elements
var gridHighlight;
var inventorySlots = [];
var modeButton;
var selectedIndicator;
var deleteAllButton;
// Add UI area background first (behind other elements)
var uiBackground = LK.getAsset('inventorySlot', {
anchorX: 0.5,
anchorY: 0,
scaleX: 20.48,
scaleY: 3.32
});
uiBackground.x = 1024;
uiBackground.y = 2400;
uiBackground.tint = 0xffffff;
uiBackground.alpha = 0.95;
game.addChild(uiBackground);
// Initialize grid highlight
gridHighlight = game.addChild(new GridHighlight());
// Initialize inventory
var blockTypes = ['stone', 'wood', 'dirt', 'grass', 'cobblestone', 'iron_ore', 'gold_ore', 'diamond_ore', 'iron_block', 'gold_block', 'diamond_block', 'wood_block', 'tree_leaf', 'water', 'ice', 'lava'];
for (var i = 0; i < blockTypes.length; i++) {
var slot = new InventorySlot(blockTypes[i], i);
inventorySlots.push(slot);
game.addChild(slot);
}
// Initialize mode button
modeButton = game.addChild(new ModeButton());
modeButton.updateMode(isBuildMode);
// DELETE ALL! button will be created when needed
deleteAllButton = null;
// Remove any existing stone blocks behind and below UI area (y >= 2400)
for (var gridKey in gameGrid) {
var block = gameGrid[gridKey];
if (block && block.blockType === 'stone' && block.y >= 2400) {
block.destroy();
delete gameGrid[gridKey];
}
}
// Also remove stone blocks below the UI area
for (var gridY = 30; gridY <= 40; gridY++) {
for (var gridX = 0; gridX < gridWidth; gridX++) {
var gridKey = getGridKey(gridX, gridY);
var block = gameGrid[gridKey];
if (block && block.blockType === 'stone') {
block.destroy();
delete gameGrid[gridKey];
}
}
}
// Add bottom border
for (var j = 0; j < 26; j++) {
var bottomBorderBlock = LK.getAsset('dirt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
bottomBorderBlock.x = j * 80 + 40;
bottomBorderBlock.y = 2700;
bottomBorderBlock.alpha = 0.3;
bottomBorderBlock.tint = 0x444444;
game.addChild(bottomBorderBlock);
}
// Selected block indicator
selectedIndicator = LK.getAsset('highlight', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
selectedIndicator.alpha = 0.5;
game.addChild(selectedIndicator);
function updateSelectedIndicator() {
for (var i = 0; i < inventorySlots.length; i++) {
if (inventorySlots[i].blockType === selectedBlockType) {
selectedIndicator.x = inventorySlots[i].x;
selectedIndicator.y = inventorySlots[i].y;
break;
}
}
}
updateSelectedIndicator();
function worldToGrid(worldX, worldY) {
return {
x: Math.floor(worldX / 80),
y: Math.floor(worldY / 80)
};
}
function isValidGridPosition(gridX, gridY) {
return true; // Allow placing blocks anywhere
}
function getGridKey(gridX, gridY) {
return gridX + ',' + gridY;
}
function hasBlockAt(gridX, gridY) {
return gameGrid[getGridKey(gridX, gridY)] !== undefined;
}
function getInventorySlot(blockType) {
for (var i = 0; i < inventorySlots.length; i++) {
if (inventorySlots[i].blockType === blockType) {
return inventorySlots[i];
}
}
return null;
}
function placeBlock(gridX, gridY, blockType) {
if (!isValidGridPosition(gridX, gridY) || hasBlockAt(gridX, gridY)) {
return false;
}
var slot = getInventorySlot(blockType);
if (!slot) {
return false;
}
var block = new Block(blockType);
block.setGridPosition(gridX, gridY);
game.addChild(block);
gameGrid[getGridKey(gridX, gridY)] = block;
// Keep unlimited blocks - no count decrement
LK.getSound('place').play();
// Place animation
block.alpha = 0;
tween(block, {
alpha: 1
}, {
duration: 200
});
return true;
}
function breakBlock(gridX, gridY) {
var gridKey = getGridKey(gridX, gridY);
var block = gameGrid[gridKey];
if (!block) {
return false;
}
var slot = getInventorySlot(block.blockType);
if (slot) {
slot.updateCount(slot.count + 1);
}
LK.getSound('break').play();
// Break animation
tween(block, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
block.destroy();
}
});
delete gameGrid[gridKey];
// Create DELETE ALL! button if it doesn't exist
if (!deleteAllButton) {
deleteAllButton = game.addChild(new DeleteAllButton());
deleteAllButton.y = 2580; // Position below BUILD button
}
// Show delete all button after breaking
deleteAllButton.show();
return true;
}
var lastHoverGridX = -1;
var lastHoverGridY = -1;
game.move = function (x, y, obj) {
// Only show highlight in build area
if (y < 2400) {
var gridPos = worldToGrid(x, y);
if (gridPos.x !== lastHoverGridX || gridPos.y !== lastHoverGridY) {
if (isBuildMode && !hasBlockAt(gridPos.x, gridPos.y)) {
gridHighlight.showAt(gridPos.x, gridPos.y);
} else if (!isBuildMode && hasBlockAt(gridPos.x, gridPos.y)) {
gridHighlight.showAt(gridPos.x, gridPos.y);
} else {
gridHighlight.hide();
}
lastHoverGridX = gridPos.x;
lastHoverGridY = gridPos.y;
}
} else {
gridHighlight.hide();
lastHoverGridX = -1;
lastHoverGridY = -1;
}
};
game.down = function (x, y, obj) {
// Only allow building/breaking in the main game area
if (y < 2400) {
var gridPos = worldToGrid(x, y);
if (isBuildMode) {
placeBlock(gridPos.x, gridPos.y, selectedBlockType);
} else {
breakBlock(gridPos.x, gridPos.y);
}
}
};
game.update = function () {
// Update game state if needed
};