/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { worlds: {}, currentWorld: "default", avatarColor: 3447003 }); /**** * Classes ****/ var Avatar = Container.expand(function () { var self = Container.call(this); var avatarGraphics = self.attachAsset('avatar', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.onGround = false; self.jumpPower = -15; self.moveSpeed = 5; self.gravity = 0.6; self.updateColor = function (color) { avatarGraphics.tint = color; }; self.jump = function () { if (self.onGround) { self.vy = self.jumpPower; self.onGround = false; LK.getSound('jump').play(); } }; self.update = function () { // Apply gravity self.vy += self.gravity; // Apply movement self.x += self.vx; self.y += self.vy; // Detect collisions with blocks self.onGround = false; for (var i = 0; i < blocks.length; i++) { if (self.intersects(blocks[i])) { // Calculate collision sides var dx = self.x - blocks[i].x; var dy = self.y - blocks[i].y; var combinedHalfWidths = (avatarGraphics.width + blocks[i].width) / 2; var combinedHalfHeights = (avatarGraphics.height + blocks[i].height) / 2; var overlapX = combinedHalfWidths - Math.abs(dx); var overlapY = combinedHalfHeights - Math.abs(dy); // Resolve collision (simple AABB resolution) if (overlapX < overlapY) { if (dx > 0) { self.x += overlapX; self.vx = 0; } else { self.x -= overlapX; self.vx = 0; } } else { if (dy > 0) { self.y += overlapY; self.vy = 0; } else { self.y -= overlapY; self.vy = 0; self.onGround = true; } } } } // Keep avatar within bounds if (self.x < 0) { self.x = 0; } if (self.x > 2048) { self.x = 2048; } if (self.y < 0) { self.y = 0; } if (self.y > 2732) { self.y = 2732; } }; return self; }); var Block = Container.expand(function () { var self = Container.call(this); self.blockType = 'normal'; self.blockColor = 0x888888; var blockGraphics = self.attachAsset('block', { anchorX: 0.5, anchorY: 0.5 }); self.setType = function (type, color) { self.blockType = type || 'normal'; self.blockColor = color || 0x888888; blockGraphics.tint = self.blockColor; }; self.down = function (x, y, obj) { if (currentTool === 'delete') { self.shouldDelete = true; } }; return self; }); var Button = Container.expand(function (label, callback) { var self = Container.call(this); var buttonGraphics = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); var labelText = new Text2(label, { size: 32, fill: 0xFFFFFF }); labelText.anchor.set(0.5, 0.5); self.addChild(labelText); self.callback = callback; self.down = function (x, y, obj) { buttonGraphics.tint = 0x2980b9; }; self.up = function (x, y, obj) { buttonGraphics.tint = 0x3498db; if (self.callback) { self.callback(); } LK.getSound('select').play(); }; return self; }); var ColorSwatch = Container.expand(function (color) { var self = Container.call(this); self.color = color; var swatchGraphics = self.attachAsset('colorSwatch', { anchorX: 0.5, anchorY: 0.5 }); swatchGraphics.tint = color; self.down = function (x, y, obj) { currentColor = self.color; colorPalette.visible = false; LK.getSound('select').play(); }; return self; }); var Tool = Container.expand(function (type, iconColor) { var self = Container.call(this); self.toolType = type; var toolGraphics = self.attachAsset('toolSelector', { anchorX: 0.5, anchorY: 0.5 }); var iconGraphics = self.attachAsset('block', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); iconGraphics.tint = iconColor || 0xffffff; self.setSelected = function (selected) { if (selected) { toolGraphics.tint = 0xffcc00; } else { toolGraphics.tint = 0xffffff; } }; self.down = function (x, y, obj) { currentTool = self.toolType; updateToolSelection(); LK.getSound('select').play(); }; return self; }); var WorldThumbnail = Container.expand(function (worldName, worldData) { var self = Container.call(this); self.worldName = worldName; var thumbnailGraphics = self.attachAsset('worldThumbnail', { anchorX: 0.5, anchorY: 0.5 }); var nameText = new Text2(worldName, { size: 24, fill: 0x333333 }); nameText.anchor.set(0.5, 0.5); nameText.y = thumbnailGraphics.height / 2 + 20; self.addChild(nameText); self.down = function (x, y, obj) { thumbnailGraphics.tint = 0xbbbbbb; }; self.up = function (x, y, obj) { thumbnailGraphics.tint = 0xffffff; loadWorld(self.worldName); worldsMenu.visible = false; LK.getSound('select').play(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game state variables var isBuilderMode = true; var currentTool = 'block'; var currentColor = 0x888888; var blocks = []; var avatar; var colorPalette; var toolsContainer; var worldsMenu; var menuButton; var colorPickerButton; var dragStartX, dragStartY; var isAvatarDragging = false; var isJumping = false; var isMovingLeft = false; var isMovingRight = false; // Colors for the palette var paletteColors = [0xff0000, 0xff9900, 0xffff00, 0x00ff00, 0x00ffff, 0x0000ff, 0x9900ff, 0xff00ff, 0xffffff, 0xcccccc, 0x888888, 0x444444, 0x000000, 0x996633, 0x663300, 0x336600]; // Initialize UI function initUI() { // Tools container toolsContainer = new Container(); toolsContainer.x = 120; toolsContainer.y = 80; game.addChild(toolsContainer); // Add tools var blockTool = new Tool('block', 0x888888); blockTool.x = 0; blockTool.y = 0; toolsContainer.addChild(blockTool); var deleteTool = new Tool('delete', 0xff0000); deleteTool.x = 0; deleteTool.y = 80; toolsContainer.addChild(deleteTool); var avatarTool = new Tool('avatar', 0x3498db); avatarTool.x = 0; avatarTool.y = 160; toolsContainer.addChild(avatarTool); var playTool = new Tool('play', 0x2ecc71); playTool.x = 0; playTool.y = 240; toolsContainer.addChild(playTool); // Color palette colorPalette = new Container(); var paletteBackground = LK.getAsset('palette', { anchorX: 0.5, anchorY: 0.5 }); colorPalette.addChild(paletteBackground); var paletteTitle = new Text2("Select Color", { size: 30, fill: 0x333333 }); paletteTitle.anchor.set(0.5, 0); paletteTitle.x = 0; paletteTitle.y = -120; colorPalette.addChild(paletteTitle); // Add color swatches for (var i = 0; i < paletteColors.length; i++) { var swatch = new ColorSwatch(paletteColors[i]); swatch.x = i % 4 * 60 - 90; swatch.y = Math.floor(i / 4) * 60 - 60; colorPalette.addChild(swatch); } colorPalette.x = 2048 / 2; colorPalette.y = 2732 / 2; colorPalette.visible = false; game.addChild(colorPalette); // Color picker button colorPickerButton = new Button("Colors", function () { colorPalette.visible = true; }); colorPickerButton.x = 120; colorPickerButton.y = 400; game.addChild(colorPickerButton); // Menu button menuButton = new Button("Menu", function () { showWorldsMenu(); }); menuButton.x = 120; menuButton.y = 500; game.addChild(menuButton); // Worlds menu worldsMenu = new Container(); var menuBackground = LK.getAsset('menuBackground', { anchorX: 0.5, anchorY: 0.5 }); worldsMenu.addChild(menuBackground); var menuTitle = new Text2("Worlds", { size: 40, fill: 0x333333 }); menuTitle.anchor.set(0.5, 0); menuTitle.x = 0; menuTitle.y = -250; worldsMenu.addChild(menuTitle); var newWorldButton = new Button("New World", function () { createNewWorld(); }); newWorldButton.x = 0; newWorldButton.y = 200; worldsMenu.addChild(newWorldButton); var closeButton = new Button("Close", function () { worldsMenu.visible = false; }); closeButton.x = 0; closeButton.y = 250; worldsMenu.addChild(closeButton); worldsMenu.x = 2048 / 2; worldsMenu.y = 2732 / 2; worldsMenu.visible = false; game.addChild(worldsMenu); // Instructions text var instructionsText = new Text2("Tap to place blocks\nDrag avatar to move\nUse tools on the left", { size: 30, fill: 0x333333 }); instructionsText.anchor.set(0.5, 0); instructionsText.x = 2048 / 2; instructionsText.y = 40; game.addChild(instructionsText); } function updateToolSelection() { for (var i = 0; i < toolsContainer.children.length; i++) { var tool = toolsContainer.children[i]; if (tool.toolType === currentTool) { tool.setSelected(true); } else { tool.setSelected(false); } } // Toggle builder/play mode if (currentTool === 'play') { isBuilderMode = false; startPlayMode(); } else { isBuilderMode = true; endPlayMode(); } } function startPlayMode() { if (!avatar) { // Create default avatar if none exists avatar = new Avatar(); avatar.x = 2048 / 2; avatar.y = 2732 / 2; avatar.updateColor(storage.avatarColor); game.addChild(avatar); } toolsContainer.visible = false; colorPickerButton.visible = false; menuButton.visible = false; // Alert player var playingText = new Text2("PLAYING MODE", { size: 60, fill: 0xFF0000 }); playingText.anchor.set(0.5, 0.5); playingText.x = 2048 / 2; playingText.y = 2732 / 2; game.addChild(playingText); LK.setTimeout(function () { game.removeChild(playingText); }, 1500); } function endPlayMode() { toolsContainer.visible = true; colorPickerButton.visible = true; menuButton.visible = true; } function placeBlock(x, y) { var block = new Block(); block.x = Math.floor(x / 64) * 64 + 32; block.y = Math.floor(y / 64) * 64 + 32; block.setType('normal', currentColor); // Check if block already exists at this position for (var i = 0; i < blocks.length; i++) { if (Math.abs(blocks[i].x - block.x) < 5 && Math.abs(blocks[i].y - block.y) < 5) { return; // Block already exists here } } game.addChild(block); blocks.push(block); LK.getSound('place').play(); } function createAvatar(x, y) { // Remove existing avatar if present if (avatar) { game.removeChild(avatar); } avatar = new Avatar(); avatar.x = x; avatar.y = y; avatar.updateColor(currentColor); storage.avatarColor = currentColor; game.addChild(avatar); } function showWorldsMenu() { // Clear previous world thumbnails for (var i = worldsMenu.children.length - 1; i >= 0; i--) { if (worldsMenu.children[i] instanceof WorldThumbnail) { worldsMenu.removeChild(worldsMenu.children[i]); } } // Add world thumbnails var worldNames = Object.keys(storage.worlds); var yPos = -150; for (var i = 0; i < worldNames.length; i++) { var thumbnail = new WorldThumbnail(worldNames[i], storage.worlds[worldNames[i]]); thumbnail.x = 0; thumbnail.y = yPos; worldsMenu.addChild(thumbnail); yPos += 150; } worldsMenu.visible = true; } function saveCurrentWorld() { var worldData = { blocks: [], avatarPosition: avatar ? { x: avatar.x, y: avatar.y } : null, avatarColor: storage.avatarColor }; // Save block data for (var i = 0; i < blocks.length; i++) { worldData.blocks.push({ x: blocks[i].x, y: blocks[i].y, color: blocks[i].blockColor, type: blocks[i].blockType }); } storage.worlds[storage.currentWorld] = worldData; } function loadWorld(worldName) { saveCurrentWorld(); // Save current world first // Clear existing blocks for (var i = blocks.length - 1; i >= 0; i--) { game.removeChild(blocks[i]); } blocks = []; // Remove existing avatar if (avatar) { game.removeChild(avatar); avatar = null; } // Set current world storage.currentWorld = worldName; // Load world data var worldData = storage.worlds[worldName]; if (!worldData) { // Create empty world if it doesn't exist return; } // Load blocks for (var i = 0; i < worldData.blocks.length; i++) { var blockData = worldData.blocks[i]; var block = new Block(); block.x = blockData.x; block.y = blockData.y; block.setType(blockData.type, blockData.color); game.addChild(block); blocks.push(block); } // Load avatar if (worldData.avatarPosition) { avatar = new Avatar(); avatar.x = worldData.avatarPosition.x; avatar.y = worldData.avatarPosition.y; avatar.updateColor(worldData.avatarColor || 0x3498db); storage.avatarColor = worldData.avatarColor || 0x3498db; game.addChild(avatar); } } function createNewWorld() { var worldName = "World" + Math.floor(Math.random() * 1000); // Save current world saveCurrentWorld(); // Initialize new world storage.worlds[worldName] = { blocks: [], avatarPosition: null, avatarColor: 0x3498db }; // Load the new empty world loadWorld(worldName); worldsMenu.visible = false; } // Initialize game initUI(); // Check if we have any worlds, if not create a default one if (Object.keys(storage.worlds).length === 0) { // Create default world with platform storage.worlds['default'] = { blocks: [], avatarPosition: null, avatarColor: 0x3498db }; // Add some blocks to the default world for (var i = 0; i < 20; i++) { storage.worlds['default'].blocks.push({ x: 400 + i * 64, y: 1500, color: 0x888888, type: 'normal' }); } } // Load the current world loadWorld(storage.currentWorld); // Start background music LK.playMusic('bgmusic'); // Game update logic game.update = function () { // Handle block deletion for (var i = blocks.length - 1; i >= 0; i--) { if (blocks[i].shouldDelete) { game.removeChild(blocks[i]); blocks.splice(i, 1); } } // Update avatar in play mode if (!isBuilderMode && avatar) { // Handle input for avatar movement if (isMovingLeft) { avatar.vx = -avatar.moveSpeed; } else if (isMovingRight) { avatar.vx = avatar.moveSpeed; } else { avatar.vx = 0; } if (isJumping) { avatar.jump(); isJumping = false; } // Update avatar physics avatar.update(); } }; // Game input handlers game.down = function (x, y, obj) { // Store drag start position dragStartX = x; dragStartY = y; // Skip if color palette or worlds menu is open if (colorPalette.visible || worldsMenu.visible) { return; } // Handle building/deleting in builder mode if (isBuilderMode) { if (currentTool === 'block') { placeBlock(x, y); } else if (currentTool === 'avatar') { createAvatar(x, y); } } else { // Play mode controls if (avatar) { // Check if clicking on avatar (for dragging) var localPoint = avatar.toLocal({ x: x, y: y }); if (Math.abs(localPoint.x) < avatar.width / 2 && Math.abs(localPoint.y) < avatar.height / 2) { isAvatarDragging = true; } else { // Check for movement controls (left side = left, right side = right, top = jump) if (y < 2732 / 3) { isJumping = true; } else if (x < 2048 / 2) { isMovingLeft = true; } else { isMovingRight = true; } } } } }; game.move = function (x, y, obj) { // Skip if color palette or worlds menu is open if (colorPalette.visible || worldsMenu.visible) { return; } // Handle avatar dragging in play mode if (!isBuilderMode && isAvatarDragging && avatar) { avatar.x = x; avatar.y = y; avatar.vx = 0; avatar.vy = 0; } }; game.up = function (x, y, obj) { // Reset movement flags isAvatarDragging = false; isMovingLeft = false; isMovingRight = false; // Save world when interaction ends saveCurrentWorld(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
worlds: {},
currentWorld: "default",
avatarColor: 3447003
});
/****
* Classes
****/
var Avatar = Container.expand(function () {
var self = Container.call(this);
var avatarGraphics = self.attachAsset('avatar', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = 0;
self.vy = 0;
self.onGround = false;
self.jumpPower = -15;
self.moveSpeed = 5;
self.gravity = 0.6;
self.updateColor = function (color) {
avatarGraphics.tint = color;
};
self.jump = function () {
if (self.onGround) {
self.vy = self.jumpPower;
self.onGround = false;
LK.getSound('jump').play();
}
};
self.update = function () {
// Apply gravity
self.vy += self.gravity;
// Apply movement
self.x += self.vx;
self.y += self.vy;
// Detect collisions with blocks
self.onGround = false;
for (var i = 0; i < blocks.length; i++) {
if (self.intersects(blocks[i])) {
// Calculate collision sides
var dx = self.x - blocks[i].x;
var dy = self.y - blocks[i].y;
var combinedHalfWidths = (avatarGraphics.width + blocks[i].width) / 2;
var combinedHalfHeights = (avatarGraphics.height + blocks[i].height) / 2;
var overlapX = combinedHalfWidths - Math.abs(dx);
var overlapY = combinedHalfHeights - Math.abs(dy);
// Resolve collision (simple AABB resolution)
if (overlapX < overlapY) {
if (dx > 0) {
self.x += overlapX;
self.vx = 0;
} else {
self.x -= overlapX;
self.vx = 0;
}
} else {
if (dy > 0) {
self.y += overlapY;
self.vy = 0;
} else {
self.y -= overlapY;
self.vy = 0;
self.onGround = true;
}
}
}
}
// Keep avatar within bounds
if (self.x < 0) {
self.x = 0;
}
if (self.x > 2048) {
self.x = 2048;
}
if (self.y < 0) {
self.y = 0;
}
if (self.y > 2732) {
self.y = 2732;
}
};
return self;
});
var Block = Container.expand(function () {
var self = Container.call(this);
self.blockType = 'normal';
self.blockColor = 0x888888;
var blockGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
self.setType = function (type, color) {
self.blockType = type || 'normal';
self.blockColor = color || 0x888888;
blockGraphics.tint = self.blockColor;
};
self.down = function (x, y, obj) {
if (currentTool === 'delete') {
self.shouldDelete = true;
}
};
return self;
});
var Button = Container.expand(function (label, callback) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5
});
var labelText = new Text2(label, {
size: 32,
fill: 0xFFFFFF
});
labelText.anchor.set(0.5, 0.5);
self.addChild(labelText);
self.callback = callback;
self.down = function (x, y, obj) {
buttonGraphics.tint = 0x2980b9;
};
self.up = function (x, y, obj) {
buttonGraphics.tint = 0x3498db;
if (self.callback) {
self.callback();
}
LK.getSound('select').play();
};
return self;
});
var ColorSwatch = Container.expand(function (color) {
var self = Container.call(this);
self.color = color;
var swatchGraphics = self.attachAsset('colorSwatch', {
anchorX: 0.5,
anchorY: 0.5
});
swatchGraphics.tint = color;
self.down = function (x, y, obj) {
currentColor = self.color;
colorPalette.visible = false;
LK.getSound('select').play();
};
return self;
});
var Tool = Container.expand(function (type, iconColor) {
var self = Container.call(this);
self.toolType = type;
var toolGraphics = self.attachAsset('toolSelector', {
anchorX: 0.5,
anchorY: 0.5
});
var iconGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
iconGraphics.tint = iconColor || 0xffffff;
self.setSelected = function (selected) {
if (selected) {
toolGraphics.tint = 0xffcc00;
} else {
toolGraphics.tint = 0xffffff;
}
};
self.down = function (x, y, obj) {
currentTool = self.toolType;
updateToolSelection();
LK.getSound('select').play();
};
return self;
});
var WorldThumbnail = Container.expand(function (worldName, worldData) {
var self = Container.call(this);
self.worldName = worldName;
var thumbnailGraphics = self.attachAsset('worldThumbnail', {
anchorX: 0.5,
anchorY: 0.5
});
var nameText = new Text2(worldName, {
size: 24,
fill: 0x333333
});
nameText.anchor.set(0.5, 0.5);
nameText.y = thumbnailGraphics.height / 2 + 20;
self.addChild(nameText);
self.down = function (x, y, obj) {
thumbnailGraphics.tint = 0xbbbbbb;
};
self.up = function (x, y, obj) {
thumbnailGraphics.tint = 0xffffff;
loadWorld(self.worldName);
worldsMenu.visible = false;
LK.getSound('select').play();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state variables
var isBuilderMode = true;
var currentTool = 'block';
var currentColor = 0x888888;
var blocks = [];
var avatar;
var colorPalette;
var toolsContainer;
var worldsMenu;
var menuButton;
var colorPickerButton;
var dragStartX, dragStartY;
var isAvatarDragging = false;
var isJumping = false;
var isMovingLeft = false;
var isMovingRight = false;
// Colors for the palette
var paletteColors = [0xff0000, 0xff9900, 0xffff00, 0x00ff00, 0x00ffff, 0x0000ff, 0x9900ff, 0xff00ff, 0xffffff, 0xcccccc, 0x888888, 0x444444, 0x000000, 0x996633, 0x663300, 0x336600];
// Initialize UI
function initUI() {
// Tools container
toolsContainer = new Container();
toolsContainer.x = 120;
toolsContainer.y = 80;
game.addChild(toolsContainer);
// Add tools
var blockTool = new Tool('block', 0x888888);
blockTool.x = 0;
blockTool.y = 0;
toolsContainer.addChild(blockTool);
var deleteTool = new Tool('delete', 0xff0000);
deleteTool.x = 0;
deleteTool.y = 80;
toolsContainer.addChild(deleteTool);
var avatarTool = new Tool('avatar', 0x3498db);
avatarTool.x = 0;
avatarTool.y = 160;
toolsContainer.addChild(avatarTool);
var playTool = new Tool('play', 0x2ecc71);
playTool.x = 0;
playTool.y = 240;
toolsContainer.addChild(playTool);
// Color palette
colorPalette = new Container();
var paletteBackground = LK.getAsset('palette', {
anchorX: 0.5,
anchorY: 0.5
});
colorPalette.addChild(paletteBackground);
var paletteTitle = new Text2("Select Color", {
size: 30,
fill: 0x333333
});
paletteTitle.anchor.set(0.5, 0);
paletteTitle.x = 0;
paletteTitle.y = -120;
colorPalette.addChild(paletteTitle);
// Add color swatches
for (var i = 0; i < paletteColors.length; i++) {
var swatch = new ColorSwatch(paletteColors[i]);
swatch.x = i % 4 * 60 - 90;
swatch.y = Math.floor(i / 4) * 60 - 60;
colorPalette.addChild(swatch);
}
colorPalette.x = 2048 / 2;
colorPalette.y = 2732 / 2;
colorPalette.visible = false;
game.addChild(colorPalette);
// Color picker button
colorPickerButton = new Button("Colors", function () {
colorPalette.visible = true;
});
colorPickerButton.x = 120;
colorPickerButton.y = 400;
game.addChild(colorPickerButton);
// Menu button
menuButton = new Button("Menu", function () {
showWorldsMenu();
});
menuButton.x = 120;
menuButton.y = 500;
game.addChild(menuButton);
// Worlds menu
worldsMenu = new Container();
var menuBackground = LK.getAsset('menuBackground', {
anchorX: 0.5,
anchorY: 0.5
});
worldsMenu.addChild(menuBackground);
var menuTitle = new Text2("Worlds", {
size: 40,
fill: 0x333333
});
menuTitle.anchor.set(0.5, 0);
menuTitle.x = 0;
menuTitle.y = -250;
worldsMenu.addChild(menuTitle);
var newWorldButton = new Button("New World", function () {
createNewWorld();
});
newWorldButton.x = 0;
newWorldButton.y = 200;
worldsMenu.addChild(newWorldButton);
var closeButton = new Button("Close", function () {
worldsMenu.visible = false;
});
closeButton.x = 0;
closeButton.y = 250;
worldsMenu.addChild(closeButton);
worldsMenu.x = 2048 / 2;
worldsMenu.y = 2732 / 2;
worldsMenu.visible = false;
game.addChild(worldsMenu);
// Instructions text
var instructionsText = new Text2("Tap to place blocks\nDrag avatar to move\nUse tools on the left", {
size: 30,
fill: 0x333333
});
instructionsText.anchor.set(0.5, 0);
instructionsText.x = 2048 / 2;
instructionsText.y = 40;
game.addChild(instructionsText);
}
function updateToolSelection() {
for (var i = 0; i < toolsContainer.children.length; i++) {
var tool = toolsContainer.children[i];
if (tool.toolType === currentTool) {
tool.setSelected(true);
} else {
tool.setSelected(false);
}
}
// Toggle builder/play mode
if (currentTool === 'play') {
isBuilderMode = false;
startPlayMode();
} else {
isBuilderMode = true;
endPlayMode();
}
}
function startPlayMode() {
if (!avatar) {
// Create default avatar if none exists
avatar = new Avatar();
avatar.x = 2048 / 2;
avatar.y = 2732 / 2;
avatar.updateColor(storage.avatarColor);
game.addChild(avatar);
}
toolsContainer.visible = false;
colorPickerButton.visible = false;
menuButton.visible = false;
// Alert player
var playingText = new Text2("PLAYING MODE", {
size: 60,
fill: 0xFF0000
});
playingText.anchor.set(0.5, 0.5);
playingText.x = 2048 / 2;
playingText.y = 2732 / 2;
game.addChild(playingText);
LK.setTimeout(function () {
game.removeChild(playingText);
}, 1500);
}
function endPlayMode() {
toolsContainer.visible = true;
colorPickerButton.visible = true;
menuButton.visible = true;
}
function placeBlock(x, y) {
var block = new Block();
block.x = Math.floor(x / 64) * 64 + 32;
block.y = Math.floor(y / 64) * 64 + 32;
block.setType('normal', currentColor);
// Check if block already exists at this position
for (var i = 0; i < blocks.length; i++) {
if (Math.abs(blocks[i].x - block.x) < 5 && Math.abs(blocks[i].y - block.y) < 5) {
return; // Block already exists here
}
}
game.addChild(block);
blocks.push(block);
LK.getSound('place').play();
}
function createAvatar(x, y) {
// Remove existing avatar if present
if (avatar) {
game.removeChild(avatar);
}
avatar = new Avatar();
avatar.x = x;
avatar.y = y;
avatar.updateColor(currentColor);
storage.avatarColor = currentColor;
game.addChild(avatar);
}
function showWorldsMenu() {
// Clear previous world thumbnails
for (var i = worldsMenu.children.length - 1; i >= 0; i--) {
if (worldsMenu.children[i] instanceof WorldThumbnail) {
worldsMenu.removeChild(worldsMenu.children[i]);
}
}
// Add world thumbnails
var worldNames = Object.keys(storage.worlds);
var yPos = -150;
for (var i = 0; i < worldNames.length; i++) {
var thumbnail = new WorldThumbnail(worldNames[i], storage.worlds[worldNames[i]]);
thumbnail.x = 0;
thumbnail.y = yPos;
worldsMenu.addChild(thumbnail);
yPos += 150;
}
worldsMenu.visible = true;
}
function saveCurrentWorld() {
var worldData = {
blocks: [],
avatarPosition: avatar ? {
x: avatar.x,
y: avatar.y
} : null,
avatarColor: storage.avatarColor
};
// Save block data
for (var i = 0; i < blocks.length; i++) {
worldData.blocks.push({
x: blocks[i].x,
y: blocks[i].y,
color: blocks[i].blockColor,
type: blocks[i].blockType
});
}
storage.worlds[storage.currentWorld] = worldData;
}
function loadWorld(worldName) {
saveCurrentWorld(); // Save current world first
// Clear existing blocks
for (var i = blocks.length - 1; i >= 0; i--) {
game.removeChild(blocks[i]);
}
blocks = [];
// Remove existing avatar
if (avatar) {
game.removeChild(avatar);
avatar = null;
}
// Set current world
storage.currentWorld = worldName;
// Load world data
var worldData = storage.worlds[worldName];
if (!worldData) {
// Create empty world if it doesn't exist
return;
}
// Load blocks
for (var i = 0; i < worldData.blocks.length; i++) {
var blockData = worldData.blocks[i];
var block = new Block();
block.x = blockData.x;
block.y = blockData.y;
block.setType(blockData.type, blockData.color);
game.addChild(block);
blocks.push(block);
}
// Load avatar
if (worldData.avatarPosition) {
avatar = new Avatar();
avatar.x = worldData.avatarPosition.x;
avatar.y = worldData.avatarPosition.y;
avatar.updateColor(worldData.avatarColor || 0x3498db);
storage.avatarColor = worldData.avatarColor || 0x3498db;
game.addChild(avatar);
}
}
function createNewWorld() {
var worldName = "World" + Math.floor(Math.random() * 1000);
// Save current world
saveCurrentWorld();
// Initialize new world
storage.worlds[worldName] = {
blocks: [],
avatarPosition: null,
avatarColor: 0x3498db
};
// Load the new empty world
loadWorld(worldName);
worldsMenu.visible = false;
}
// Initialize game
initUI();
// Check if we have any worlds, if not create a default one
if (Object.keys(storage.worlds).length === 0) {
// Create default world with platform
storage.worlds['default'] = {
blocks: [],
avatarPosition: null,
avatarColor: 0x3498db
};
// Add some blocks to the default world
for (var i = 0; i < 20; i++) {
storage.worlds['default'].blocks.push({
x: 400 + i * 64,
y: 1500,
color: 0x888888,
type: 'normal'
});
}
}
// Load the current world
loadWorld(storage.currentWorld);
// Start background music
LK.playMusic('bgmusic');
// Game update logic
game.update = function () {
// Handle block deletion
for (var i = blocks.length - 1; i >= 0; i--) {
if (blocks[i].shouldDelete) {
game.removeChild(blocks[i]);
blocks.splice(i, 1);
}
}
// Update avatar in play mode
if (!isBuilderMode && avatar) {
// Handle input for avatar movement
if (isMovingLeft) {
avatar.vx = -avatar.moveSpeed;
} else if (isMovingRight) {
avatar.vx = avatar.moveSpeed;
} else {
avatar.vx = 0;
}
if (isJumping) {
avatar.jump();
isJumping = false;
}
// Update avatar physics
avatar.update();
}
};
// Game input handlers
game.down = function (x, y, obj) {
// Store drag start position
dragStartX = x;
dragStartY = y;
// Skip if color palette or worlds menu is open
if (colorPalette.visible || worldsMenu.visible) {
return;
}
// Handle building/deleting in builder mode
if (isBuilderMode) {
if (currentTool === 'block') {
placeBlock(x, y);
} else if (currentTool === 'avatar') {
createAvatar(x, y);
}
} else {
// Play mode controls
if (avatar) {
// Check if clicking on avatar (for dragging)
var localPoint = avatar.toLocal({
x: x,
y: y
});
if (Math.abs(localPoint.x) < avatar.width / 2 && Math.abs(localPoint.y) < avatar.height / 2) {
isAvatarDragging = true;
} else {
// Check for movement controls (left side = left, right side = right, top = jump)
if (y < 2732 / 3) {
isJumping = true;
} else if (x < 2048 / 2) {
isMovingLeft = true;
} else {
isMovingRight = true;
}
}
}
}
};
game.move = function (x, y, obj) {
// Skip if color palette or worlds menu is open
if (colorPalette.visible || worldsMenu.visible) {
return;
}
// Handle avatar dragging in play mode
if (!isBuilderMode && isAvatarDragging && avatar) {
avatar.x = x;
avatar.y = y;
avatar.vx = 0;
avatar.vy = 0;
}
};
game.up = function (x, y, obj) {
// Reset movement flags
isAvatarDragging = false;
isMovingLeft = false;
isMovingRight = false;
// Save world when interaction ends
saveCurrentWorld();
};