/****
* 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
};