/****
* 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();