/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, currentLevel: 1 }); /**** * 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.update = function () { // Make the coin bounce slightly self.y += Math.sin(LK.ticks / 10) * 0.5; }; self.collect = function () { if (!self.collected) { self.collected = true; // Animation for collection tween(self, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); LK.getSound('collect').play(); return true; } return false; }; return self; }); var Platform = Container.expand(function () { var self = Container.call(this); var platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); self.width = platformGraphics.width; self.height = platformGraphics.height; self.moving = false; self.movingLeft = false; self.moveSpeed = 0; self.leftBound = 0; self.rightBound = 0; self.setMoving = function (isMoving, speed, leftBound, rightBound) { self.moving = isMoving; self.moveSpeed = speed || 2; self.leftBound = leftBound || 0; self.rightBound = rightBound || 2048; self.movingLeft = false; }; self.update = function () { if (self.moving) { if (self.movingLeft) { self.x -= self.moveSpeed; if (self.x <= self.leftBound) { self.x = self.leftBound; self.movingLeft = false; } } else { self.x += self.moveSpeed; if (self.x >= self.rightBound) { self.x = self.rightBound; self.movingLeft = true; } } } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.velocity = { x: 0, y: 0 }; self.isJumping = false; self.isOnGround = false; self.moveDirection = 0; // -1 for left, 0 for none, 1 for right self.speed = 8; self.jumpForce = -20; self.gravity = 1; self.jump = function () { if (self.isOnGround) { self.velocity.y = self.jumpForce; self.isJumping = true; self.isOnGround = false; LK.getSound('jump').play(); } }; self.update = function () { // Apply horizontal movement self.velocity.x = self.moveDirection * self.speed; // Apply gravity self.velocity.y += self.gravity; // Update position self.x += self.velocity.x; self.y += self.velocity.y; // Boundary checks if (self.x < 50) { self.x = 50; } else if (self.x > 2048 - 50) { self.x = 2048 - 50; } }; return self; }); var Spike = Container.expand(function () { var self = Container.call(this); var spikeGraphics = self.attachAsset('spike', { anchorX: 0.5, anchorY: 0.5 }); // Make it look more like a spike spikeGraphics.rotation = Math.PI / 4; // 45 degrees return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game state variables var player; var platforms = []; var coins = []; var spikes = []; var ground; var isGameActive = false; var score = 0; var level = storage.currentLevel || 1; var leftTouchActive = false; var rightTouchActive = false; // UI Elements var scoreTxt; var levelTxt; var instructionsTxt; // Initialize game elements function initGame() { // Reset game state platforms = []; coins = []; spikes = []; score = 0; isGameActive = true; // Play background music with fade in LK.playMusic('gameMusic', { fade: { start: 0, end: 0.8, duration: 1000 } }); // Create player player = new Player(); player.x = 150; player.y = 2732 - 200; game.addChild(player); // Create ground ground = LK.getAsset('ground', { anchorX: 0.5, anchorY: 0.5 }); ground.x = 2048 / 2; ground.y = 2732 - 20; game.addChild(ground); // Create UI elements scoreTxt = new Text2('Score: 0', { size: 70, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -300; // Offset from right edge levelTxt = new Text2('Level: ' + level, { size: 70, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); LK.gui.top.addChild(levelTxt); // Add instructions at first if (level === 1) { instructionsTxt = new Text2('Tap left/right sides to move\nTap middle to jump', { size: 70, fill: 0xFFFFFF }); instructionsTxt.anchor.set(0.5, 0); instructionsTxt.y = 200; LK.gui.center.addChild(instructionsTxt); // Hide instructions after 5 seconds LK.setTimeout(function () { if (instructionsTxt) { tween(instructionsTxt, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { if (instructionsTxt && instructionsTxt.parent) { instructionsTxt.parent.removeChild(instructionsTxt); } } }); } }, 5000); } // Create level elements createLevel(level); } // Level creation function createLevel(levelNum) { // Clear level text levelTxt.setText('Level: ' + levelNum); var platformCount = 5 + levelNum * 2; // More platforms in higher levels var coinCount = 3 + levelNum; // More coins in higher levels var spikeCount = levelNum; // Spikes start appearing from level 1 // Create platforms with increasing complexity based on level for (var i = 0; i < platformCount; i++) { var platform = new Platform(); // Calculate platform position var xPos = 100 + Math.random() * (2048 - 200); var yPos = 2732 - 200 - i * 300 - Math.random() * 100; platform.x = xPos; platform.y = yPos; // Make some platforms moving in higher levels if (levelNum > 1 && Math.random() < 0.3) { platform.setMoving(true, 2 + Math.random() * levelNum, Math.max(50, xPos - 300), Math.min(2048 - 50, xPos + 300)); } platforms.push(platform); game.addChild(platform); } // Create coins for (var j = 0; j < coinCount; j++) { var coin = new Coin(); // Place coins above platforms var platformIndex = Math.floor(Math.random() * platforms.length); coin.x = platforms[platformIndex].x + (-100 + Math.random() * 200); coin.y = platforms[platformIndex].y - 70 - Math.random() * 50; coins.push(coin); game.addChild(coin); } // Create spikes (hazards) for (var k = 0; k < spikeCount; k++) { var spike = new Spike(); // Place spikes on some platforms var platformIndex = Math.floor(Math.random() * (platforms.length - 1)) + 1; // Avoid first platform spike.x = platforms[platformIndex].x + (-50 + Math.random() * 100); spike.y = platforms[platformIndex].y - 30; spikes.push(spike); game.addChild(spike); } } // Handle input events game.down = function (x, y, obj) { if (!isGameActive) { return; } // Determine touch position for controls if (x < 2048 / 3) { // Left third of screen leftTouchActive = true; player.moveDirection = -1; } else if (x > 2048 / 3 * 2) { // Right third of screen rightTouchActive = true; player.moveDirection = 1; } else { // Middle third - jump player.jump(); } }; game.up = function (x, y, obj) { // Reset movement when touch ends if (x < 2048 / 3) { leftTouchActive = false; } else if (x > 2048 / 3 * 2) { rightTouchActive = false; } // If both left and right are released, stop moving if (!leftTouchActive && !rightTouchActive) { player.moveDirection = 0; } else if (leftTouchActive) { player.moveDirection = -1; } else if (rightTouchActive) { player.moveDirection = 1; } }; game.move = function (x, y, obj) { // Handle dragging (not critical for this game) }; // Main game loop game.update = function () { if (!isGameActive) { return; } // Update player player.update(); // Check if player fell off the bottom if (player.y > 2732 + 100) { gameOver(); return; } // Check for collisions with ground if (player.y + 50 >= ground.y - 20 && player.velocity.y > 0) { player.y = ground.y - 20 - 50; player.velocity.y = 0; player.isOnGround = true; player.isJumping = false; } // Check for platform collisions var wasOnGround = player.isOnGround; player.isOnGround = false; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; platform.update(); // Only check for landing on top of platforms if (player.y + 50 <= platform.y - platform.height / 2 && player.y + 50 + player.velocity.y >= platform.y - platform.height / 2 && player.x + 40 > platform.x - platform.width / 2 && player.x - 40 < platform.x + platform.width / 2) { player.y = platform.y - platform.height / 2 - 50; player.velocity.y = 0; player.isOnGround = true; player.isJumping = false; // If platform is moving, move the player with it if (platform.moving) { if (platform.movingLeft) { player.x -= platform.moveSpeed; } else { player.x += platform.moveSpeed; } } } } // Check for coin collisions for (var j = 0; j < coins.length; j++) { var coin = coins[j]; coin.update(); if (player.intersects(coin) && !coin.collected) { if (coin.collect()) { // Increase score score += 10; scoreTxt.setText('Score: ' + score); // Remove from array coins.splice(j, 1); j--; } } } // Check for spike collisions for (var k = 0; k < spikes.length; k++) { var spike = spikes[k]; if (player.intersects(spike)) { LK.getSound('hit').play(); gameOver(); return; } } // Check if player reached the top of the screen to complete level if (player.y < 100) { completeLevel(); } }; // Level completion function completeLevel() { isGameActive = false; // Briefly fade music for level transition effect LK.playMusic('gameMusic', { fade: { start: 0.8, end: 0.3, duration: 400 } }); LK.setTimeout(function () { LK.playMusic('gameMusic', { fade: { start: 0.3, end: 0.8, duration: 600 } }); }, 400); // Save progress level++; storage.currentLevel = level; // Add level completion bonus var levelBonus = level * 50; score += levelBonus; // Check for high score if (score > storage.highScore) { storage.highScore = score; } // Show level complete message var completeTxt = new Text2('Level Complete!\nScore: ' + score + '\nBonus: ' + levelBonus, { size: 90, fill: 0xFFFFFF }); completeTxt.anchor.set(0.5, 0.5); LK.gui.center.addChild(completeTxt); // Flash screen with success color LK.effects.flashScreen(0x27ae60, 1000); // Create next level after delay LK.setTimeout(function () { // Clear all game objects for (var i = 0; i < platforms.length; i++) { platforms[i].destroy(); } for (var j = 0; j < coins.length; j++) { coins[j].destroy(); } for (var k = 0; k < spikes.length; k++) { spikes[k].destroy(); } player.destroy(); ground.destroy(); if (completeTxt && completeTxt.parent) { completeTxt.parent.removeChild(completeTxt); } // Start next level initGame(); }, 3000); } // Game over handling function gameOver() { isGameActive = false; LK.getSound('hit').play(); // Fade out music LK.playMusic('gameMusic', { fade: { start: 0.8, end: 0, duration: 800 } }); // Check for high score if (score > storage.highScore) { storage.highScore = score; } // Flash screen red LK.effects.flashScreen(0xe74c3c, 1000); // Show game over LK.showGameOver(); } // Initialize the game when it loads initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
currentLevel: 1
});
/****
* 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.update = function () {
// Make the coin bounce slightly
self.y += Math.sin(LK.ticks / 10) * 0.5;
};
self.collect = function () {
if (!self.collected) {
self.collected = true;
// Animation for collection
tween(self, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
LK.getSound('collect').play();
return true;
}
return false;
};
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = platformGraphics.width;
self.height = platformGraphics.height;
self.moving = false;
self.movingLeft = false;
self.moveSpeed = 0;
self.leftBound = 0;
self.rightBound = 0;
self.setMoving = function (isMoving, speed, leftBound, rightBound) {
self.moving = isMoving;
self.moveSpeed = speed || 2;
self.leftBound = leftBound || 0;
self.rightBound = rightBound || 2048;
self.movingLeft = false;
};
self.update = function () {
if (self.moving) {
if (self.movingLeft) {
self.x -= self.moveSpeed;
if (self.x <= self.leftBound) {
self.x = self.leftBound;
self.movingLeft = false;
}
} else {
self.x += self.moveSpeed;
if (self.x >= self.rightBound) {
self.x = self.rightBound;
self.movingLeft = true;
}
}
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = {
x: 0,
y: 0
};
self.isJumping = false;
self.isOnGround = false;
self.moveDirection = 0; // -1 for left, 0 for none, 1 for right
self.speed = 8;
self.jumpForce = -20;
self.gravity = 1;
self.jump = function () {
if (self.isOnGround) {
self.velocity.y = self.jumpForce;
self.isJumping = true;
self.isOnGround = false;
LK.getSound('jump').play();
}
};
self.update = function () {
// Apply horizontal movement
self.velocity.x = self.moveDirection * self.speed;
// Apply gravity
self.velocity.y += self.gravity;
// Update position
self.x += self.velocity.x;
self.y += self.velocity.y;
// Boundary checks
if (self.x < 50) {
self.x = 50;
} else if (self.x > 2048 - 50) {
self.x = 2048 - 50;
}
};
return self;
});
var Spike = Container.expand(function () {
var self = Container.call(this);
var spikeGraphics = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 0.5
});
// Make it look more like a spike
spikeGraphics.rotation = Math.PI / 4; // 45 degrees
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state variables
var player;
var platforms = [];
var coins = [];
var spikes = [];
var ground;
var isGameActive = false;
var score = 0;
var level = storage.currentLevel || 1;
var leftTouchActive = false;
var rightTouchActive = false;
// UI Elements
var scoreTxt;
var levelTxt;
var instructionsTxt;
// Initialize game elements
function initGame() {
// Reset game state
platforms = [];
coins = [];
spikes = [];
score = 0;
isGameActive = true;
// Play background music with fade in
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.8,
duration: 1000
}
});
// Create player
player = new Player();
player.x = 150;
player.y = 2732 - 200;
game.addChild(player);
// Create ground
ground = LK.getAsset('ground', {
anchorX: 0.5,
anchorY: 0.5
});
ground.x = 2048 / 2;
ground.y = 2732 - 20;
game.addChild(ground);
// Create UI elements
scoreTxt = new Text2('Score: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -300; // Offset from right edge
levelTxt = new Text2('Level: ' + level, {
size: 70,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
LK.gui.top.addChild(levelTxt);
// Add instructions at first
if (level === 1) {
instructionsTxt = new Text2('Tap left/right sides to move\nTap middle to jump', {
size: 70,
fill: 0xFFFFFF
});
instructionsTxt.anchor.set(0.5, 0);
instructionsTxt.y = 200;
LK.gui.center.addChild(instructionsTxt);
// Hide instructions after 5 seconds
LK.setTimeout(function () {
if (instructionsTxt) {
tween(instructionsTxt, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
if (instructionsTxt && instructionsTxt.parent) {
instructionsTxt.parent.removeChild(instructionsTxt);
}
}
});
}
}, 5000);
}
// Create level elements
createLevel(level);
}
// Level creation
function createLevel(levelNum) {
// Clear level text
levelTxt.setText('Level: ' + levelNum);
var platformCount = 5 + levelNum * 2; // More platforms in higher levels
var coinCount = 3 + levelNum; // More coins in higher levels
var spikeCount = levelNum; // Spikes start appearing from level 1
// Create platforms with increasing complexity based on level
for (var i = 0; i < platformCount; i++) {
var platform = new Platform();
// Calculate platform position
var xPos = 100 + Math.random() * (2048 - 200);
var yPos = 2732 - 200 - i * 300 - Math.random() * 100;
platform.x = xPos;
platform.y = yPos;
// Make some platforms moving in higher levels
if (levelNum > 1 && Math.random() < 0.3) {
platform.setMoving(true, 2 + Math.random() * levelNum, Math.max(50, xPos - 300), Math.min(2048 - 50, xPos + 300));
}
platforms.push(platform);
game.addChild(platform);
}
// Create coins
for (var j = 0; j < coinCount; j++) {
var coin = new Coin();
// Place coins above platforms
var platformIndex = Math.floor(Math.random() * platforms.length);
coin.x = platforms[platformIndex].x + (-100 + Math.random() * 200);
coin.y = platforms[platformIndex].y - 70 - Math.random() * 50;
coins.push(coin);
game.addChild(coin);
}
// Create spikes (hazards)
for (var k = 0; k < spikeCount; k++) {
var spike = new Spike();
// Place spikes on some platforms
var platformIndex = Math.floor(Math.random() * (platforms.length - 1)) + 1; // Avoid first platform
spike.x = platforms[platformIndex].x + (-50 + Math.random() * 100);
spike.y = platforms[platformIndex].y - 30;
spikes.push(spike);
game.addChild(spike);
}
}
// Handle input events
game.down = function (x, y, obj) {
if (!isGameActive) {
return;
}
// Determine touch position for controls
if (x < 2048 / 3) {
// Left third of screen
leftTouchActive = true;
player.moveDirection = -1;
} else if (x > 2048 / 3 * 2) {
// Right third of screen
rightTouchActive = true;
player.moveDirection = 1;
} else {
// Middle third - jump
player.jump();
}
};
game.up = function (x, y, obj) {
// Reset movement when touch ends
if (x < 2048 / 3) {
leftTouchActive = false;
} else if (x > 2048 / 3 * 2) {
rightTouchActive = false;
}
// If both left and right are released, stop moving
if (!leftTouchActive && !rightTouchActive) {
player.moveDirection = 0;
} else if (leftTouchActive) {
player.moveDirection = -1;
} else if (rightTouchActive) {
player.moveDirection = 1;
}
};
game.move = function (x, y, obj) {
// Handle dragging (not critical for this game)
};
// Main game loop
game.update = function () {
if (!isGameActive) {
return;
}
// Update player
player.update();
// Check if player fell off the bottom
if (player.y > 2732 + 100) {
gameOver();
return;
}
// Check for collisions with ground
if (player.y + 50 >= ground.y - 20 && player.velocity.y > 0) {
player.y = ground.y - 20 - 50;
player.velocity.y = 0;
player.isOnGround = true;
player.isJumping = false;
}
// Check for platform collisions
var wasOnGround = player.isOnGround;
player.isOnGround = false;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
platform.update();
// Only check for landing on top of platforms
if (player.y + 50 <= platform.y - platform.height / 2 && player.y + 50 + player.velocity.y >= platform.y - platform.height / 2 && player.x + 40 > platform.x - platform.width / 2 && player.x - 40 < platform.x + platform.width / 2) {
player.y = platform.y - platform.height / 2 - 50;
player.velocity.y = 0;
player.isOnGround = true;
player.isJumping = false;
// If platform is moving, move the player with it
if (platform.moving) {
if (platform.movingLeft) {
player.x -= platform.moveSpeed;
} else {
player.x += platform.moveSpeed;
}
}
}
}
// Check for coin collisions
for (var j = 0; j < coins.length; j++) {
var coin = coins[j];
coin.update();
if (player.intersects(coin) && !coin.collected) {
if (coin.collect()) {
// Increase score
score += 10;
scoreTxt.setText('Score: ' + score);
// Remove from array
coins.splice(j, 1);
j--;
}
}
}
// Check for spike collisions
for (var k = 0; k < spikes.length; k++) {
var spike = spikes[k];
if (player.intersects(spike)) {
LK.getSound('hit').play();
gameOver();
return;
}
}
// Check if player reached the top of the screen to complete level
if (player.y < 100) {
completeLevel();
}
};
// Level completion
function completeLevel() {
isGameActive = false;
// Briefly fade music for level transition effect
LK.playMusic('gameMusic', {
fade: {
start: 0.8,
end: 0.3,
duration: 400
}
});
LK.setTimeout(function () {
LK.playMusic('gameMusic', {
fade: {
start: 0.3,
end: 0.8,
duration: 600
}
});
}, 400);
// Save progress
level++;
storage.currentLevel = level;
// Add level completion bonus
var levelBonus = level * 50;
score += levelBonus;
// Check for high score
if (score > storage.highScore) {
storage.highScore = score;
}
// Show level complete message
var completeTxt = new Text2('Level Complete!\nScore: ' + score + '\nBonus: ' + levelBonus, {
size: 90,
fill: 0xFFFFFF
});
completeTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(completeTxt);
// Flash screen with success color
LK.effects.flashScreen(0x27ae60, 1000);
// Create next level after delay
LK.setTimeout(function () {
// Clear all game objects
for (var i = 0; i < platforms.length; i++) {
platforms[i].destroy();
}
for (var j = 0; j < coins.length; j++) {
coins[j].destroy();
}
for (var k = 0; k < spikes.length; k++) {
spikes[k].destroy();
}
player.destroy();
ground.destroy();
if (completeTxt && completeTxt.parent) {
completeTxt.parent.removeChild(completeTxt);
}
// Start next level
initGame();
}, 3000);
}
// Game over handling
function gameOver() {
isGameActive = false;
LK.getSound('hit').play();
// Fade out music
LK.playMusic('gameMusic', {
fade: {
start: 0.8,
end: 0,
duration: 800
}
});
// Check for high score
if (score > storage.highScore) {
storage.highScore = score;
}
// Flash screen red
LK.effects.flashScreen(0xe74c3c, 1000);
// Show game over
LK.showGameOver();
}
// Initialize the game when it loads
initGame();