/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Coin = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; self.startY = self.y; // Store initial Y position for floating reference self.floatingUp = true; // Track floating direction self.update = function () { // Floating animation is handled by tween, no manual updates needed }; // Start floating animation self.startFloating = function () { var floatDistance = 20; // How far up and down to float var floatDuration = 2000; // 2 seconds per direction function floatUp() { tween(self, { y: self.startY - floatDistance }, { duration: floatDuration, easing: tween.easeInOut, onFinish: floatDown }); } function floatDown() { tween(self, { y: self.startY + floatDistance }, { duration: floatDuration, easing: tween.easeInOut, onFinish: floatUp }); } floatUp(); // Start the floating animation }; return self; }); var MovingPlatform = Container.expand(function () { var self = Container.call(this); var platformGraphics = self.attachAsset('movingPlatform', { anchorX: 0.5, anchorY: 0.5 }); self.platformType = 'moving'; self.velocityX = 0; self.velocityY = 0; self.startX = 0; self.startY = 0; self.endX = 0; self.endY = 0; self.moveSpeed = 2; self.direction = 1; self.setMovement = function (startX, startY, endX, endY, speed) { self.startX = startX; self.startY = startY; self.endX = endX; self.endY = endY; self.moveSpeed = speed || 2; self.x = startX; self.y = startY; }; self.update = function () { var targetX = self.direction > 0 ? self.endX : self.startX; var targetY = self.direction > 0 ? self.endY : self.startY; var deltaX = targetX - self.x; var deltaY = targetY - self.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); // Change direction when close to target if (distance < 5) { self.direction *= -1; } // Always move unless exactly at target if (distance > 1) { // Normalize direction vector and apply speed var normalizedX = deltaX / distance; var normalizedY = deltaY / distance; self.velocityX = normalizedX * self.moveSpeed; self.velocityY = normalizedY * self.moveSpeed; self.x += self.velocityX; self.y += self.velocityY; } else { self.velocityX = 0; self.velocityY = 0; } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 1.0 }); self.velocityY = 0; self.velocityX = 0; self.onGround = false; self.onMovingPlatform = null; self.jumpPower = -25; self.gravity = 0.8; self.speed = 8; self.maxFallSpeed = 15; self.jumpCount = 0; self.maxJumps = 2; self.jump = function () { if (self.jumpCount < self.maxJumps) { self.velocityY = self.jumpPower; self.jumpCount++; if (self.jumpCount === 1) { self.onGround = false; self.onMovingPlatform = null; } LK.getSound('jump').play(); } }; self.moveLeft = function () { // Allow movement in air for turning while jumping self.velocityX = Math.max(-self.speed, self.velocityX - 2); // Set player to face left playerGraphics.scaleX = -Math.abs(playerGraphics.scaleX || 1); }; self.moveRight = function () { // Allow movement in air for turning while jumping self.velocityX = Math.min(self.speed, self.velocityX + 2); // Set player to face right playerGraphics.scaleX = Math.abs(playerGraphics.scaleX || 1); }; self.update = function () { // Apply gravity if (!self.onGround) { self.velocityY += self.gravity; if (self.velocityY > self.maxFallSpeed) { self.velocityY = self.maxFallSpeed; } } // Move with platform if on one if (self.onMovingPlatform) { self.x += self.onMovingPlatform.velocityX; self.y += self.onMovingPlatform.velocityY; } // Apply movement self.x += self.velocityX; self.y += self.velocityY; // Reduce horizontal velocity (friction) - less friction when in air if (self.onGround) { self.velocityX *= 0.8; } else { self.velocityX *= 0.95; // Less friction in air for better control } // Keep player in bounds horizontally if (self.x < 30) self.x = 30; if (self.x > 2018) self.x = 2018; // Check if fallen below screen if (self.y > 2800) { resetLevel(); } }; return self; }); var StaticPlatform = Container.expand(function () { var self = Container.call(this); var platformGraphics = self.attachAsset('staticPlatform', { anchorX: 0.5, anchorY: 0.5 }); self.platformType = 'static'; return self; }); /**** * Initialize Game ****/ var game = new LK.Game(); /**** * Game Code ****/ var player; var platforms = []; var coins = []; var currentLevel = 1; var cameraY = 0; var backgroundElements = []; var levelBackgrounds = [0x228B22, // Forest - Green 0x8B4513, // Cave - Brown 0x87CEEB, // Sky - Light Blue 0x696969, // Industrial - Gray 0x191970, // Space - Midnight Blue 0x008B8B, // Underwater - Dark Cyan 0xF4A460, // Desert - Sandy Brown 0xB0E0E6, // Ice - Powder Blue 0xFF4500, // Volcano - Orange Red 0x4B0082 // Futuristic - Indigo ]; var levelBackgroundImages = ['forestBg', 'caveBg', 'skyBg', 'industrialBg', 'spaceBg', 'underwaterBg', 'desertBg', 'iceBg', 'volcanoBg', 'futuristicBg']; var currentBackground = null; // UI Elements var scoreText = new Text2('Coins: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); scoreText.x = 120; // Position away from platform menu icon LK.gui.topLeft.addChild(scoreText); var levelText = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); levelText.x = 120; // Position away from platform menu icon levelText.y = 70; // Position below score text LK.gui.topLeft.addChild(levelText); // Level data for each level var levelData = [ // Level 1 - Forest (Easy) { platforms: [{ type: 'static', x: 1024, y: 2600, width: 600 }, { type: 'static', x: 400, y: 2100, width: 400 }, { type: 'static', x: 1600, y: 1600, width: 400 }, { type: 'moving', x1: 600, y1: 1100, x2: 1200, y2: 1100, speed: 1 }, { type: 'static', x: 1024, y: 600, width: 400 }, { type: 'static', x: 300, y: 100, width: 400 }, { type: 'static', x: 1700, y: 2000, width: 350 }, { type: 'static', x: 800, y: 1500, width: 350 }, { type: 'moving', x1: 1300, y1: 1000, x2: 1700, y2: 1000, speed: 1.5 }, { type: 'static', x: 500, y: 500, width: 350 }, { type: 'moving', x1: 1200, y1: 300, x2: 1600, y2: 300, speed: 1.2 }, { type: 'static', x: 1500, y: 1400, width: 400 }, { type: 'static', x: 600, y: 900, width: 350 }, { type: 'static', x: 1400, y: 400, width: 350 }, { type: 'moving', x1: 300, y1: 800, x2: 700, y2: 800, speed: 1.3 }, { type: 'static', x: 1700, y: 200, width: 350 }], coins: [{ x: 1024, y: 2500 }, { x: 400, y: 2000 }, { x: 1600, y: 1500 }, { x: 900, y: 1000 }, { x: 1024, y: 500 }, { x: 300, y: 0 }] }, // Level 2 - Cave (Easy-Medium) { platforms: [{ type: 'static', x: 1024, y: 2600, width: 600 }, { type: 'moving', x1: 300, y1: 2100, x2: 700, y2: 2100, speed: 1.5 }, { type: 'static', x: 1700, y: 1600, width: 400 }, { type: 'moving', x1: 1200, y1: 1100, x2: 1200, y2: 900, speed: 1 }, { type: 'static', x: 400, y: 600, width: 400 }, { type: 'moving', x1: 800, y1: 100, x2: 1400, y2: 100, speed: 2 }, { type: 'static', x: 1600, y: 2000, width: 350 }, { type: 'static', x: 800, y: 1500, width: 350 }, { type: 'moving', x1: 1400, y1: 1000, x2: 1700, y2: 1000, speed: 1.8 }, { type: 'static', x: 600, y: 500, width: 400 }, { type: 'static', x: 1500, y: 200, width: 350 }, { type: 'static', x: 250, y: 2200, width: 350 }, { type: 'moving', x1: 1300, y1: 1400, x2: 1600, y2: 1400, speed: 1.3 }, { type: 'static', x: 300, y: 800, width: 350 }, { type: 'moving', x1: 1000, y1: 300, x2: 1300, y2: 300, speed: 1.7 }], coins: [{ x: 1024, y: 2500 }, { x: 500, y: 2000 }, { x: 1700, y: 1500 }, { x: 1200, y: 1000 }, { x: 400, y: 500 }, { x: 1100, y: 0 }] }, // Level 3 - Sky (Medium) { platforms: [{ type: 'static', x: 1024, y: 2600, width: 600 }, { type: 'moving', x1: 200, y1: 2100, x2: 600, y2: 2100, speed: 2 }, { type: 'moving', x1: 1400, y1: 1600, x2: 1800, y2: 1600, speed: 2 }, { type: 'static', x: 800, y: 1100, width: 350 }, { type: 'moving', x1: 400, y1: 600, x2: 1200, y2: 600, speed: 2.5 }, { type: 'static', x: 1600, y: 100, width: 400 }, { type: 'static', x: 1700, y: 2000, width: 350 }, { type: 'moving', x1: 300, y1: 1500, x2: 700, y2: 1500, speed: 2.2 }, { type: 'static', x: 1500, y: 1000, width: 350 }, { type: 'moving', x1: 900, y1: 500, x2: 1300, y2: 500, speed: 2.8 }, { type: 'static', x: 400, y: 200, width: 400 }, { type: 'static', x: 600, y: 2200, width: 350 }, { type: 'moving', x1: 1200, y1: 1400, x2: 1600, y2: 1400, speed: 2.3 }, { type: 'static', x: 250, y: 800, width: 350 }, { type: 'moving', x1: 1100, y1: 300, x2: 1500, y2: 300, speed: 2.6 }], coins: [{ x: 1024, y: 2500 }, { x: 400, y: 2000 }, { x: 1600, y: 1500 }, { x: 800, y: 1000 }, { x: 800, y: 500 }, { x: 400, y: 100 }] }]; // Add more levels (4-10) with increasing difficulty for (var i = 3; i < 10; i++) { var level = { platforms: [{ type: 'static', x: 1024, y: 2600, width: 600 }], coins: [] }; var difficulty = Math.floor(i / 3); // 0, 1, 2, 3 for different difficulty tiers var platformCount = 14 + difficulty * 3; var speed = 1.5 + difficulty * 0.5; for (var j = 1; j < platformCount; j++) { var yPos = 2600 - j * 500; var isMoving = Math.random() < 0.4 + difficulty * 0.1; if (isMoving) { var x1 = 300 + Math.random() * 800; var x2 = 300 + Math.random() * 800; level.platforms.push({ type: 'moving', x1: x1, y1: yPos, x2: x2, y2: yPos, speed: speed }); } else { level.platforms.push({ type: 'static', x: 400 + Math.random() * 1200, y: yPos, width: 300 + Math.random() * 200 }); } // Add coin level.coins.push({ x: 400 + Math.random() * 1200, y: yPos - 100 }); } levelData.push(level); } function createAnimatedBackground() { // Clear existing background elements for (var i = backgroundElements.length - 1; i >= 0; i--) { backgroundElements[i].destroy(); } backgroundElements = []; // Create floating background elements var _loop = function _loop() { elementType = 'bgElement' + (Math.floor(Math.random() * 3) + 1); element = game.addChild(LK.getAsset(elementType, { anchorX: 0.5, anchorY: 0.5 })); element.x = Math.random() * 2048; element.y = Math.random() * 2732; element.alpha = 0.3 + Math.random() * 0.4; backgroundElements.push(element); // Animate floating movement moveX = (Math.random() - 0.5) * 400; moveY = (Math.random() - 0.5) * 400; duration = 3000 + Math.random() * 4000; function animateElement() { tween(element, { x: element.x + moveX, y: element.y + moveY, rotation: element.rotation + Math.PI * 2 }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { // Reset position if out of bounds if (element.x < -100 || element.x > 2148 || element.y < -100 || element.y > 2832) { element.x = Math.random() * 2048; element.y = Math.random() * 2732; } animateElement(); } }); } animateElement(); }, elementType, element, moveX, moveY, duration; for (var i = 0; i < 15; i++) { _loop(); } } function initializeLevel(levelNum) { // Clear existing objects for (var i = platforms.length - 1; i >= 0; i--) { platforms[i].destroy(); } platforms = []; for (var i = coins.length - 1; i >= 0; i--) { coins[i].destroy(); } coins = []; if (player) { player.destroy(); } // Remove previous background image if (currentBackground) { currentBackground.destroy(); currentBackground = null; } // Create photographic background with duplicates above and below var bgImageId = levelBackgroundImages[(levelNum - 1) % levelBackgroundImages.length]; // Create main background currentBackground = game.addChild(LK.getAsset(bgImageId, { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 })); // Create background above using the same level-specific background var backgroundAbove = game.addChild(LK.getAsset(bgImageId, { anchorX: 0, anchorY: 0, x: 0, y: -2732, width: 2048, height: 2732 })); // Create background below using the same level-specific background var backgroundBelow = game.addChild(LK.getAsset(bgImageId, { anchorX: 0, anchorY: 0, x: 0, y: 2732, width: 2048, height: 2732 })); // For level 2 (caveBg), create additional background duplicates higher up using level-specific background if (levelNum === 2) { var backgroundAbove2 = game.addChild(LK.getAsset('caveBg', { anchorX: 0, anchorY: 0, x: 0, y: -5464, width: 2048, height: 2732 })); var backgroundAbove3 = game.addChild(LK.getAsset('caveBg', { anchorX: 0, anchorY: 0, x: 0, y: -8196, width: 2048, height: 2732 })); game.setChildIndex(backgroundAbove2, 3); game.setChildIndex(backgroundAbove3, 4); } // For level 3 (skyBg), create additional background duplicates higher up using level-specific background if (levelNum === 3) { var backgroundAbove2 = game.addChild(LK.getAsset('skyBg', { anchorX: 0, anchorY: 0, x: 0, y: -5464, width: 2048, height: 2732 })); var backgroundAbove3 = game.addChild(LK.getAsset('skyBg', { anchorX: 0, anchorY: 0, x: 0, y: -8196, width: 2048, height: 2732 })); game.setChildIndex(backgroundAbove2, 3); game.setChildIndex(backgroundAbove3, 4); } // For level 4 (volcanoBg), create additional background duplicates higher up using level-specific background if (levelNum === 4) { var backgroundAbove2 = game.addChild(LK.getAsset('volcanoBg', { anchorX: 0, anchorY: 0, x: 0, y: -5464, width: 2048, height: 2732 })); var backgroundAbove3 = game.addChild(LK.getAsset('volcanoBg', { anchorX: 0, anchorY: 0, x: 0, y: -8196, width: 2048, height: 2732 })); game.setChildIndex(backgroundAbove2, 3); game.setChildIndex(backgroundAbove3, 4); } // For levels 5-10, create additional background duplicates higher up using level-specific background if (levelNum >= 5 && levelNum <= 10) { var backgroundAbove2 = game.addChild(LK.getAsset(bgImageId, { anchorX: 0, anchorY: 0, x: 0, y: -5464, width: 2048, height: 2732 })); var backgroundAbove3 = game.addChild(LK.getAsset(bgImageId, { anchorX: 0, anchorY: 0, x: 0, y: -8196, width: 2048, height: 2732 })); game.setChildIndex(backgroundAbove2, 3); game.setChildIndex(backgroundAbove3, 4); } // Send all backgrounds to back game.setChildIndex(currentBackground, 0); game.setChildIndex(backgroundAbove, 1); game.setChildIndex(backgroundBelow, 2); // Create animated background createAnimatedBackground(); // Background color removed - only using background images // Create player player = game.addChild(new Player()); player.x = 1024; player.y = 2550; // Create platforms var levelConfig = levelData[levelNum - 1]; if (levelConfig) { for (var i = 0; i < levelConfig.platforms.length; i++) { var platformConfig = levelConfig.platforms[i]; var platform; if (platformConfig.type === 'moving') { platform = game.addChild(new MovingPlatform()); platform.setMovement(platformConfig.x1, platformConfig.y1, platformConfig.x2, platformConfig.y2, platformConfig.speed); } else { platform = game.addChild(new StaticPlatform()); platform.x = platformConfig.x; platform.y = platformConfig.y; if (platformConfig.width) { platform.scaleX = platformConfig.width / 200; } } platforms.push(platform); } // Create coins for (var i = 0; i < levelConfig.coins.length; i++) { var coinConfig = levelConfig.coins[i]; var coin = game.addChild(new Coin()); coin.x = coinConfig.x; coin.y = coinConfig.y; coin.startY = coinConfig.y; // Set the reference Y position for floating coin.startFloating(); // Start the floating animation coins.push(coin); } } levelText.setText('Level: ' + levelNum); cameraY = 0; } function resetLevel() { initializeLevel(currentLevel); } function nextLevel() { currentLevel++; if (currentLevel > 10) { LK.showYouWin(); return; } initializeLevel(currentLevel); } function checkPlatformCollisions() { player.onGround = false; var wasOnMovingPlatform = player.onMovingPlatform; player.onMovingPlatform = null; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; if (player.intersects(platform)) { // Check if player is falling onto platform if (player.velocityY > 0) { var playerBottom = player.y; var platformTop = platform.y - 15; if (playerBottom > platformTop - 20 && playerBottom < platformTop + 20) { player.y = platformTop; player.velocityY = 0; player.onGround = true; player.jumpCount = 0; if (platform.platformType === 'moving') { player.onMovingPlatform = platform; } break; } } } } } function checkCoinCollisions() { for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; if (!coin.collected && player.intersects(coin)) { coin.collected = true; coin.destroy(); coins.splice(i, 1); LK.setScore(LK.getScore() + 1); scoreText.setText('Coins: ' + LK.getScore()); LK.getSound('coin').play(); } } } function updateCamera() { var targetY = -player.y + 1800; cameraY += (targetY - cameraY) * 0.1; game.y = cameraY; } function checkLevelComplete() { // Find the topmost platform in the current level var topmostY = 2600; // Start with the bottom platform y position var levelConfig = levelData[currentLevel - 1]; if (levelConfig) { for (var i = 0; i < levelConfig.platforms.length; i++) { var platformConfig = levelConfig.platforms[i]; var platformY = platformConfig.y || platformConfig.y1; // Use y1 for moving platforms if (platformY < topmostY) { topmostY = platformY; } } } // Check if player has reached the topmost platform (with some tolerance) if (player.y <= topmostY + 50 && player.onGround) { nextLevel(); } } // Touch controls restored // Touch controls game.down = function (x, y, obj) { // Jump on any touch player.jump(); // Movement based on left/right side of screen if (x < 1024) { player.moveLeft(); } else { player.moveRight(); } }; game.move = function (x, y, obj) { // Continue movement while dragging if (x < 1024) { player.moveLeft(); } else { player.moveRight(); } }; // Initialize first level initializeLevel(1); // Main game loop game.update = function () { // Touch controls are handled by touch events below checkPlatformCollisions(); checkCoinCollisions(); updateCamera(); checkLevelComplete(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.startY = self.y; // Store initial Y position for floating reference
self.floatingUp = true; // Track floating direction
self.update = function () {
// Floating animation is handled by tween, no manual updates needed
};
// Start floating animation
self.startFloating = function () {
var floatDistance = 20; // How far up and down to float
var floatDuration = 2000; // 2 seconds per direction
function floatUp() {
tween(self, {
y: self.startY - floatDistance
}, {
duration: floatDuration,
easing: tween.easeInOut,
onFinish: floatDown
});
}
function floatDown() {
tween(self, {
y: self.startY + floatDistance
}, {
duration: floatDuration,
easing: tween.easeInOut,
onFinish: floatUp
});
}
floatUp(); // Start the floating animation
};
return self;
});
var MovingPlatform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('movingPlatform', {
anchorX: 0.5,
anchorY: 0.5
});
self.platformType = 'moving';
self.velocityX = 0;
self.velocityY = 0;
self.startX = 0;
self.startY = 0;
self.endX = 0;
self.endY = 0;
self.moveSpeed = 2;
self.direction = 1;
self.setMovement = function (startX, startY, endX, endY, speed) {
self.startX = startX;
self.startY = startY;
self.endX = endX;
self.endY = endY;
self.moveSpeed = speed || 2;
self.x = startX;
self.y = startY;
};
self.update = function () {
var targetX = self.direction > 0 ? self.endX : self.startX;
var targetY = self.direction > 0 ? self.endY : self.startY;
var deltaX = targetX - self.x;
var deltaY = targetY - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Change direction when close to target
if (distance < 5) {
self.direction *= -1;
}
// Always move unless exactly at target
if (distance > 1) {
// Normalize direction vector and apply speed
var normalizedX = deltaX / distance;
var normalizedY = deltaY / distance;
self.velocityX = normalizedX * self.moveSpeed;
self.velocityY = normalizedY * self.moveSpeed;
self.x += self.velocityX;
self.y += self.velocityY;
} else {
self.velocityX = 0;
self.velocityY = 0;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1.0
});
self.velocityY = 0;
self.velocityX = 0;
self.onGround = false;
self.onMovingPlatform = null;
self.jumpPower = -25;
self.gravity = 0.8;
self.speed = 8;
self.maxFallSpeed = 15;
self.jumpCount = 0;
self.maxJumps = 2;
self.jump = function () {
if (self.jumpCount < self.maxJumps) {
self.velocityY = self.jumpPower;
self.jumpCount++;
if (self.jumpCount === 1) {
self.onGround = false;
self.onMovingPlatform = null;
}
LK.getSound('jump').play();
}
};
self.moveLeft = function () {
// Allow movement in air for turning while jumping
self.velocityX = Math.max(-self.speed, self.velocityX - 2);
// Set player to face left
playerGraphics.scaleX = -Math.abs(playerGraphics.scaleX || 1);
};
self.moveRight = function () {
// Allow movement in air for turning while jumping
self.velocityX = Math.min(self.speed, self.velocityX + 2);
// Set player to face right
playerGraphics.scaleX = Math.abs(playerGraphics.scaleX || 1);
};
self.update = function () {
// Apply gravity
if (!self.onGround) {
self.velocityY += self.gravity;
if (self.velocityY > self.maxFallSpeed) {
self.velocityY = self.maxFallSpeed;
}
}
// Move with platform if on one
if (self.onMovingPlatform) {
self.x += self.onMovingPlatform.velocityX;
self.y += self.onMovingPlatform.velocityY;
}
// Apply movement
self.x += self.velocityX;
self.y += self.velocityY;
// Reduce horizontal velocity (friction) - less friction when in air
if (self.onGround) {
self.velocityX *= 0.8;
} else {
self.velocityX *= 0.95; // Less friction in air for better control
}
// Keep player in bounds horizontally
if (self.x < 30) self.x = 30;
if (self.x > 2018) self.x = 2018;
// Check if fallen below screen
if (self.y > 2800) {
resetLevel();
}
};
return self;
});
var StaticPlatform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('staticPlatform', {
anchorX: 0.5,
anchorY: 0.5
});
self.platformType = 'static';
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game();
/****
* Game Code
****/
var player;
var platforms = [];
var coins = [];
var currentLevel = 1;
var cameraY = 0;
var backgroundElements = [];
var levelBackgrounds = [0x228B22,
// Forest - Green
0x8B4513,
// Cave - Brown
0x87CEEB,
// Sky - Light Blue
0x696969,
// Industrial - Gray
0x191970,
// Space - Midnight Blue
0x008B8B,
// Underwater - Dark Cyan
0xF4A460,
// Desert - Sandy Brown
0xB0E0E6,
// Ice - Powder Blue
0xFF4500,
// Volcano - Orange Red
0x4B0082 // Futuristic - Indigo
];
var levelBackgroundImages = ['forestBg', 'caveBg', 'skyBg', 'industrialBg', 'spaceBg', 'underwaterBg', 'desertBg', 'iceBg', 'volcanoBg', 'futuristicBg'];
var currentBackground = null;
// UI Elements
var scoreText = new Text2('Coins: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 120; // Position away from platform menu icon
LK.gui.topLeft.addChild(scoreText);
var levelText = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
levelText.x = 120; // Position away from platform menu icon
levelText.y = 70; // Position below score text
LK.gui.topLeft.addChild(levelText);
// Level data for each level
var levelData = [
// Level 1 - Forest (Easy)
{
platforms: [{
type: 'static',
x: 1024,
y: 2600,
width: 600
}, {
type: 'static',
x: 400,
y: 2100,
width: 400
}, {
type: 'static',
x: 1600,
y: 1600,
width: 400
}, {
type: 'moving',
x1: 600,
y1: 1100,
x2: 1200,
y2: 1100,
speed: 1
}, {
type: 'static',
x: 1024,
y: 600,
width: 400
}, {
type: 'static',
x: 300,
y: 100,
width: 400
}, {
type: 'static',
x: 1700,
y: 2000,
width: 350
}, {
type: 'static',
x: 800,
y: 1500,
width: 350
}, {
type: 'moving',
x1: 1300,
y1: 1000,
x2: 1700,
y2: 1000,
speed: 1.5
}, {
type: 'static',
x: 500,
y: 500,
width: 350
}, {
type: 'moving',
x1: 1200,
y1: 300,
x2: 1600,
y2: 300,
speed: 1.2
}, {
type: 'static',
x: 1500,
y: 1400,
width: 400
}, {
type: 'static',
x: 600,
y: 900,
width: 350
}, {
type: 'static',
x: 1400,
y: 400,
width: 350
}, {
type: 'moving',
x1: 300,
y1: 800,
x2: 700,
y2: 800,
speed: 1.3
}, {
type: 'static',
x: 1700,
y: 200,
width: 350
}],
coins: [{
x: 1024,
y: 2500
}, {
x: 400,
y: 2000
}, {
x: 1600,
y: 1500
}, {
x: 900,
y: 1000
}, {
x: 1024,
y: 500
}, {
x: 300,
y: 0
}]
},
// Level 2 - Cave (Easy-Medium)
{
platforms: [{
type: 'static',
x: 1024,
y: 2600,
width: 600
}, {
type: 'moving',
x1: 300,
y1: 2100,
x2: 700,
y2: 2100,
speed: 1.5
}, {
type: 'static',
x: 1700,
y: 1600,
width: 400
}, {
type: 'moving',
x1: 1200,
y1: 1100,
x2: 1200,
y2: 900,
speed: 1
}, {
type: 'static',
x: 400,
y: 600,
width: 400
}, {
type: 'moving',
x1: 800,
y1: 100,
x2: 1400,
y2: 100,
speed: 2
}, {
type: 'static',
x: 1600,
y: 2000,
width: 350
}, {
type: 'static',
x: 800,
y: 1500,
width: 350
}, {
type: 'moving',
x1: 1400,
y1: 1000,
x2: 1700,
y2: 1000,
speed: 1.8
}, {
type: 'static',
x: 600,
y: 500,
width: 400
}, {
type: 'static',
x: 1500,
y: 200,
width: 350
}, {
type: 'static',
x: 250,
y: 2200,
width: 350
}, {
type: 'moving',
x1: 1300,
y1: 1400,
x2: 1600,
y2: 1400,
speed: 1.3
}, {
type: 'static',
x: 300,
y: 800,
width: 350
}, {
type: 'moving',
x1: 1000,
y1: 300,
x2: 1300,
y2: 300,
speed: 1.7
}],
coins: [{
x: 1024,
y: 2500
}, {
x: 500,
y: 2000
}, {
x: 1700,
y: 1500
}, {
x: 1200,
y: 1000
}, {
x: 400,
y: 500
}, {
x: 1100,
y: 0
}]
},
// Level 3 - Sky (Medium)
{
platforms: [{
type: 'static',
x: 1024,
y: 2600,
width: 600
}, {
type: 'moving',
x1: 200,
y1: 2100,
x2: 600,
y2: 2100,
speed: 2
}, {
type: 'moving',
x1: 1400,
y1: 1600,
x2: 1800,
y2: 1600,
speed: 2
}, {
type: 'static',
x: 800,
y: 1100,
width: 350
}, {
type: 'moving',
x1: 400,
y1: 600,
x2: 1200,
y2: 600,
speed: 2.5
}, {
type: 'static',
x: 1600,
y: 100,
width: 400
}, {
type: 'static',
x: 1700,
y: 2000,
width: 350
}, {
type: 'moving',
x1: 300,
y1: 1500,
x2: 700,
y2: 1500,
speed: 2.2
}, {
type: 'static',
x: 1500,
y: 1000,
width: 350
}, {
type: 'moving',
x1: 900,
y1: 500,
x2: 1300,
y2: 500,
speed: 2.8
}, {
type: 'static',
x: 400,
y: 200,
width: 400
}, {
type: 'static',
x: 600,
y: 2200,
width: 350
}, {
type: 'moving',
x1: 1200,
y1: 1400,
x2: 1600,
y2: 1400,
speed: 2.3
}, {
type: 'static',
x: 250,
y: 800,
width: 350
}, {
type: 'moving',
x1: 1100,
y1: 300,
x2: 1500,
y2: 300,
speed: 2.6
}],
coins: [{
x: 1024,
y: 2500
}, {
x: 400,
y: 2000
}, {
x: 1600,
y: 1500
}, {
x: 800,
y: 1000
}, {
x: 800,
y: 500
}, {
x: 400,
y: 100
}]
}];
// Add more levels (4-10) with increasing difficulty
for (var i = 3; i < 10; i++) {
var level = {
platforms: [{
type: 'static',
x: 1024,
y: 2600,
width: 600
}],
coins: []
};
var difficulty = Math.floor(i / 3); // 0, 1, 2, 3 for different difficulty tiers
var platformCount = 14 + difficulty * 3;
var speed = 1.5 + difficulty * 0.5;
for (var j = 1; j < platformCount; j++) {
var yPos = 2600 - j * 500;
var isMoving = Math.random() < 0.4 + difficulty * 0.1;
if (isMoving) {
var x1 = 300 + Math.random() * 800;
var x2 = 300 + Math.random() * 800;
level.platforms.push({
type: 'moving',
x1: x1,
y1: yPos,
x2: x2,
y2: yPos,
speed: speed
});
} else {
level.platforms.push({
type: 'static',
x: 400 + Math.random() * 1200,
y: yPos,
width: 300 + Math.random() * 200
});
}
// Add coin
level.coins.push({
x: 400 + Math.random() * 1200,
y: yPos - 100
});
}
levelData.push(level);
}
function createAnimatedBackground() {
// Clear existing background elements
for (var i = backgroundElements.length - 1; i >= 0; i--) {
backgroundElements[i].destroy();
}
backgroundElements = [];
// Create floating background elements
var _loop = function _loop() {
elementType = 'bgElement' + (Math.floor(Math.random() * 3) + 1);
element = game.addChild(LK.getAsset(elementType, {
anchorX: 0.5,
anchorY: 0.5
}));
element.x = Math.random() * 2048;
element.y = Math.random() * 2732;
element.alpha = 0.3 + Math.random() * 0.4;
backgroundElements.push(element);
// Animate floating movement
moveX = (Math.random() - 0.5) * 400;
moveY = (Math.random() - 0.5) * 400;
duration = 3000 + Math.random() * 4000;
function animateElement() {
tween(element, {
x: element.x + moveX,
y: element.y + moveY,
rotation: element.rotation + Math.PI * 2
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Reset position if out of bounds
if (element.x < -100 || element.x > 2148 || element.y < -100 || element.y > 2832) {
element.x = Math.random() * 2048;
element.y = Math.random() * 2732;
}
animateElement();
}
});
}
animateElement();
},
elementType,
element,
moveX,
moveY,
duration;
for (var i = 0; i < 15; i++) {
_loop();
}
}
function initializeLevel(levelNum) {
// Clear existing objects
for (var i = platforms.length - 1; i >= 0; i--) {
platforms[i].destroy();
}
platforms = [];
for (var i = coins.length - 1; i >= 0; i--) {
coins[i].destroy();
}
coins = [];
if (player) {
player.destroy();
}
// Remove previous background image
if (currentBackground) {
currentBackground.destroy();
currentBackground = null;
}
// Create photographic background with duplicates above and below
var bgImageId = levelBackgroundImages[(levelNum - 1) % levelBackgroundImages.length];
// Create main background
currentBackground = game.addChild(LK.getAsset(bgImageId, {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
}));
// Create background above using the same level-specific background
var backgroundAbove = game.addChild(LK.getAsset(bgImageId, {
anchorX: 0,
anchorY: 0,
x: 0,
y: -2732,
width: 2048,
height: 2732
}));
// Create background below using the same level-specific background
var backgroundBelow = game.addChild(LK.getAsset(bgImageId, {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2732,
width: 2048,
height: 2732
}));
// For level 2 (caveBg), create additional background duplicates higher up using level-specific background
if (levelNum === 2) {
var backgroundAbove2 = game.addChild(LK.getAsset('caveBg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: -5464,
width: 2048,
height: 2732
}));
var backgroundAbove3 = game.addChild(LK.getAsset('caveBg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: -8196,
width: 2048,
height: 2732
}));
game.setChildIndex(backgroundAbove2, 3);
game.setChildIndex(backgroundAbove3, 4);
}
// For level 3 (skyBg), create additional background duplicates higher up using level-specific background
if (levelNum === 3) {
var backgroundAbove2 = game.addChild(LK.getAsset('skyBg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: -5464,
width: 2048,
height: 2732
}));
var backgroundAbove3 = game.addChild(LK.getAsset('skyBg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: -8196,
width: 2048,
height: 2732
}));
game.setChildIndex(backgroundAbove2, 3);
game.setChildIndex(backgroundAbove3, 4);
}
// For level 4 (volcanoBg), create additional background duplicates higher up using level-specific background
if (levelNum === 4) {
var backgroundAbove2 = game.addChild(LK.getAsset('volcanoBg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: -5464,
width: 2048,
height: 2732
}));
var backgroundAbove3 = game.addChild(LK.getAsset('volcanoBg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: -8196,
width: 2048,
height: 2732
}));
game.setChildIndex(backgroundAbove2, 3);
game.setChildIndex(backgroundAbove3, 4);
}
// For levels 5-10, create additional background duplicates higher up using level-specific background
if (levelNum >= 5 && levelNum <= 10) {
var backgroundAbove2 = game.addChild(LK.getAsset(bgImageId, {
anchorX: 0,
anchorY: 0,
x: 0,
y: -5464,
width: 2048,
height: 2732
}));
var backgroundAbove3 = game.addChild(LK.getAsset(bgImageId, {
anchorX: 0,
anchorY: 0,
x: 0,
y: -8196,
width: 2048,
height: 2732
}));
game.setChildIndex(backgroundAbove2, 3);
game.setChildIndex(backgroundAbove3, 4);
}
// Send all backgrounds to back
game.setChildIndex(currentBackground, 0);
game.setChildIndex(backgroundAbove, 1);
game.setChildIndex(backgroundBelow, 2);
// Create animated background
createAnimatedBackground();
// Background color removed - only using background images
// Create player
player = game.addChild(new Player());
player.x = 1024;
player.y = 2550;
// Create platforms
var levelConfig = levelData[levelNum - 1];
if (levelConfig) {
for (var i = 0; i < levelConfig.platforms.length; i++) {
var platformConfig = levelConfig.platforms[i];
var platform;
if (platformConfig.type === 'moving') {
platform = game.addChild(new MovingPlatform());
platform.setMovement(platformConfig.x1, platformConfig.y1, platformConfig.x2, platformConfig.y2, platformConfig.speed);
} else {
platform = game.addChild(new StaticPlatform());
platform.x = platformConfig.x;
platform.y = platformConfig.y;
if (platformConfig.width) {
platform.scaleX = platformConfig.width / 200;
}
}
platforms.push(platform);
}
// Create coins
for (var i = 0; i < levelConfig.coins.length; i++) {
var coinConfig = levelConfig.coins[i];
var coin = game.addChild(new Coin());
coin.x = coinConfig.x;
coin.y = coinConfig.y;
coin.startY = coinConfig.y; // Set the reference Y position for floating
coin.startFloating(); // Start the floating animation
coins.push(coin);
}
}
levelText.setText('Level: ' + levelNum);
cameraY = 0;
}
function resetLevel() {
initializeLevel(currentLevel);
}
function nextLevel() {
currentLevel++;
if (currentLevel > 10) {
LK.showYouWin();
return;
}
initializeLevel(currentLevel);
}
function checkPlatformCollisions() {
player.onGround = false;
var wasOnMovingPlatform = player.onMovingPlatform;
player.onMovingPlatform = null;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
if (player.intersects(platform)) {
// Check if player is falling onto platform
if (player.velocityY > 0) {
var playerBottom = player.y;
var platformTop = platform.y - 15;
if (playerBottom > platformTop - 20 && playerBottom < platformTop + 20) {
player.y = platformTop;
player.velocityY = 0;
player.onGround = true;
player.jumpCount = 0;
if (platform.platformType === 'moving') {
player.onMovingPlatform = platform;
}
break;
}
}
}
}
}
function checkCoinCollisions() {
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (!coin.collected && player.intersects(coin)) {
coin.collected = true;
coin.destroy();
coins.splice(i, 1);
LK.setScore(LK.getScore() + 1);
scoreText.setText('Coins: ' + LK.getScore());
LK.getSound('coin').play();
}
}
}
function updateCamera() {
var targetY = -player.y + 1800;
cameraY += (targetY - cameraY) * 0.1;
game.y = cameraY;
}
function checkLevelComplete() {
// Find the topmost platform in the current level
var topmostY = 2600; // Start with the bottom platform y position
var levelConfig = levelData[currentLevel - 1];
if (levelConfig) {
for (var i = 0; i < levelConfig.platforms.length; i++) {
var platformConfig = levelConfig.platforms[i];
var platformY = platformConfig.y || platformConfig.y1; // Use y1 for moving platforms
if (platformY < topmostY) {
topmostY = platformY;
}
}
}
// Check if player has reached the topmost platform (with some tolerance)
if (player.y <= topmostY + 50 && player.onGround) {
nextLevel();
}
}
// Touch controls restored
// Touch controls
game.down = function (x, y, obj) {
// Jump on any touch
player.jump();
// Movement based on left/right side of screen
if (x < 1024) {
player.moveLeft();
} else {
player.moveRight();
}
};
game.move = function (x, y, obj) {
// Continue movement while dragging
if (x < 1024) {
player.moveLeft();
} else {
player.moveRight();
}
};
// Initialize first level
initializeLevel(1);
// Main game loop
game.update = function () {
// Touch controls are handled by touch events below
checkPlatformCollisions();
checkCoinCollisions();
updateCamera();
checkLevelComplete();
};
Stone platform sprite, solid gray granite texture with green moss covering, ancient ruins style, rectangular shape, weathered stone surface, small cracks and details, stable and heavy appearance, 2D pixel art, side view, transparent background. In-Game asset. 2d. High contrast. No shadows
Mechanical floating platform, red metal surface with glowing energy core, sci-fi futuristic design, sleek metallic texture, blue energy particles or trails around edges, hovering effect, technological appearance with small lights or circuits, 2D pixel art style, side view, transparent background. In-Game asset. 2d. High contrast. No shadows
Golden coin sprite, shiny yellow gold surface, circular shape with star or gem symbol in center, pixel art style, slight shine effect or sparkle, collectible item appearance, rotating animation-ready, bright and eye-catching, classic video game coin design, 16-bit aesthetic, transparent background. In-Game asset. 2d. High contrast. No shadows
Morning sky background, fluffy white clouds, soft blue gradient, sunrise colors, peaceful atmosphere, 2D pixel art. In-Game asset. 2d. High contrast. No shadows
Bright day sky, cotton candy clouds, clear blue background, sun rays, cheerful mood, 2D pixel art. In-Game asset. 2d. High contrast. No shadows
Storm clouds background, dark gray clouds, lightning bolts, dramatic sky, purple-gray gradient, 2D pixel art. In-Game asset. 2d. High contrast. No shadows
Night sky background, dark blue clouds, stars and moon, peaceful nighttime atmosphere, 2D pixel art. In-Game asset. 2d. High contrast. No shadows
Space nebula background, cosmic clouds, purple and blue colors, stars and galaxies, sci-fi atmosphere, 2D pixel art. In-Game asset. 2d. High contrast. No shadows
Winter sky, ice-crystal clouds, cold blue-white gradient, snowy atmosphere, frosty background, 2D pixel art. In-Game asset. 2d. High contrast. No shadows
Volcanic sky, red-orange fiery clouds, lava glow effect, hot atmosphere, dramatic red gradient, 2D pixel art. In-Game asset. 2d. High contrast. No shadows
Golden heaven sky, shimmering gold clouds, divine atmosphere, bright yellow-gold gradient, epic finale background, 2D pixel art. In-Game asset. 2d. High contrast. No shadows
Rainbow sky background, colorful clouds with rainbow stripes, magical atmosphere, vibrant colors, 2D pixel art. In-Game asset. 2d. High contrast. No shadows
Sunset sky, orange and pink clouds, golden hour atmosphere, warm gradient background, 2D pixel art. In-Game asset. 2d. High contrast. No shadows