/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, coins: 0 }); /**** * Classes ****/ var Coin = Container.expand(function () { var self = Container.call(this); self.lane = Math.floor(Math.random() * 3); self.speed = 0; self.collected = false; var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.y += self.speed; // Spinning animation coinGraphics.scaleX = Math.abs(Math.sin(LK.ticks * 0.05)) * 0.5 + 0.5; }; self.collect = function () { if (self.collected) { return; } self.collected = true; LK.getSound('collect').play(); // Animate collection tween(self, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeOut }); }; self.getCollisionBox = function () { var box = { x: self.x - coinGraphics.width * 0.5 * 0.8, y: self.y - coinGraphics.height * 0.5 * 0.8, width: coinGraphics.width * 0.8, height: coinGraphics.height * 0.8 }; return box; }; return self; }); var Obstacle = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'regular'; // regular, low, high self.lane = Math.floor(Math.random() * 3); self.speed = 0; var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); // Adjust obstacle appearance based on type if (self.type === 'low') { obstacleGraphics.scaleY = 0.5; obstacleGraphics.y = obstacleGraphics.height * 0.25; } else if (self.type === 'high') { obstacleGraphics.scaleY = 0.5; obstacleGraphics.y = -obstacleGraphics.height * 0.25; } self.update = function () { self.y += self.speed; }; self.getCollisionBox = function () { var box = { x: self.x - obstacleGraphics.width * 0.5 * 0.9, y: self.y - obstacleGraphics.height * 0.5 * 0.9 + (self.type === 'low' ? obstacleGraphics.height * 0.25 : self.type === 'high' ? -obstacleGraphics.height * 0.25 : 0), width: obstacleGraphics.width * 0.9, height: obstacleGraphics.height * 0.9 * (self.type === 'low' || self.type === 'high' ? 0.5 : 1) }; return box; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); // Player states self.isJumping = false; self.isSliding = false; self.lane = 1; // 0: left, 1: center, 2: right self.speed = 10; self.jumpHeight = 200; self.jumpDuration = 500; self.slideDuration = 600; self.powerupActive = false; self.powerupType = null; self.powerupDuration = 0; // Player graphics var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // Methods for player actions self.switchLane = function (targetLane) { if (targetLane < 0 || targetLane > 2 || self.lane === targetLane) { return; } var targetX = LANE_POSITIONS[targetLane]; tween.stop(self, { x: true }); tween(self, { x: targetX }, { duration: 200, easing: tween.easeOut }); self.lane = targetLane; }; self.jump = function () { if (self.isJumping || self.isSliding) { return; } self.isJumping = true; LK.getSound('jump').play(); var initialY = self.y; // Jump up tween(self, { y: initialY - self.jumpHeight }, { duration: self.jumpDuration / 2, easing: tween.easeOut, onFinish: function onFinish() { // Fall down tween(self, { y: initialY }, { duration: self.jumpDuration / 2, easing: tween.easeIn, onFinish: function onFinish() { self.isJumping = false; } }); } }); }; self.slide = function () { if (self.isJumping || self.isSliding) { return; } self.isSliding = true; LK.getSound('slide').play(); // Shrink player height for sliding tween(playerGraphics, { scaleY: 0.5 }, { duration: 200, easing: tween.linear }); // Return to normal after slide duration LK.setTimeout(function () { tween(playerGraphics, { scaleY: 1 }, { duration: 200, easing: tween.linear, onFinish: function onFinish() { self.isSliding = false; } }); }, self.slideDuration); }; self.activatePowerup = function (type) { self.powerupActive = true; self.powerupType = type; switch (type) { case 'magnet': self.powerupDuration = 5000; break; case 'multiplier': self.powerupDuration = 8000; break; case 'invincibility': self.powerupDuration = 4000; playerGraphics.alpha = 0.7; break; } LK.getSound('powerup').play(); }; self.updatePowerup = function () { if (!self.powerupActive) { return; } self.powerupDuration -= 16.67; // Approximate ms per frame at 60fps if (self.powerupDuration <= 0) { self.powerupActive = false; self.powerupType = null; playerGraphics.alpha = 1; } }; // Collision detection utility self.getCollisionBox = function () { var box = { x: self.x - playerGraphics.width * 0.5 * 0.8, y: self.y - playerGraphics.height * 0.5 * (self.isSliding ? 0.5 : 0.9), width: playerGraphics.width * 0.8, height: playerGraphics.height * (self.isSliding ? 0.5 : 0.9) }; return box; }; return self; }); var Powerup = Container.expand(function () { var self = Container.call(this); self.lane = Math.floor(Math.random() * 3); self.speed = 0; self.collected = false; // Random powerup type var types = ['magnet', 'multiplier', 'invincibility']; self.type = types[Math.floor(Math.random() * types.length)]; var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); // Different colors for different powerups if (self.type === 'magnet') { powerupGraphics.tint = 0x0088ff; } else if (self.type === 'multiplier') { powerupGraphics.tint = 0xff8800; } else if (self.type === 'invincibility') { powerupGraphics.tint = 0xff00ff; } self.update = function () { self.y += self.speed; // Pulsing animation var pulse = Math.sin(LK.ticks * 0.1) * 0.1 + 1; powerupGraphics.scale.set(pulse, pulse); }; self.collect = function () { if (self.collected) { return; } self.collected = true; LK.getSound('powerup').play(); // Animate collection tween(self, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 300, easing: tween.easeOut }); }; self.getCollisionBox = function () { var box = { x: self.x - powerupGraphics.width * 0.5 * 0.8, y: self.y - powerupGraphics.height * 0.5 * 0.8, width: powerupGraphics.width * 0.8, height: powerupGraphics.height * 0.8 }; return box; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x202020 }); /**** * Game Code ****/ // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var PLAYER_START_Y = GAME_HEIGHT - 400; var LANE_WIDTH = 200; var LANE_POSITIONS = [GAME_WIDTH / 2 - LANE_WIDTH, GAME_WIDTH / 2, GAME_WIDTH / 2 + LANE_WIDTH]; var SPAWN_Y = -200; var DESPAWN_Y = GAME_HEIGHT + 200; // Game variables var gameStarted = false; var gameSpeed = 10; var score = 0; var distance = 0; var coins = 0; var multiplier = 1; var lastObstacleSpawn = 0; var lastCoinSpawn = 0; var lastPowerupSpawn = 0; var obstacleSpawnRate = 1500; // ms var coinSpawnRate = 1000; // ms var powerupSpawnRate = 10000; // ms var playerSwipeStartY = 0; var playerSwipeStartX = 0; var MIN_SWIPE_DISTANCE = 50; // Game elements var player; var obstacles = []; var coinsArray = []; var powerups = []; var swipeDirection = null; // Create lanes and background var background = LK.getAsset('ground', { anchorX: 0, anchorY: 0 }); game.addChild(background); for (var i = 0; i < 3; i++) { var lane = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0, alpha: 0.3 }); lane.x = LANE_POSITIONS[i]; lane.y = 0; game.addChild(lane); } // Create UI elements var scoreText = new Text2('SCORE: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); scoreText.x = GAME_WIDTH / 2; scoreText.y = 50; LK.gui.top.addChild(scoreText); var coinText = new Text2('COINS: 0', { size: 80, fill: 0xFFD700 }); coinText.anchor.set(0, 0); coinText.x = 150; coinText.y = 50; LK.gui.top.addChild(coinText); var highScoreText = new Text2('HIGH SCORE: ' + storage.highScore, { size: 60, fill: 0xFFAA00 }); highScoreText.anchor.set(1, 0); highScoreText.x = GAME_WIDTH - 150; highScoreText.y = 50; LK.gui.top.addChild(highScoreText); var powerupText = new Text2('', { size: 70, fill: 0x83DE44 }); powerupText.anchor.set(0.5, 0); powerupText.x = GAME_WIDTH / 2; powerupText.y = 150; powerupText.alpha = 0; LK.gui.top.addChild(powerupText); var tapToStartText = new Text2('TAP TO START', { size: 120, fill: 0xFFFFFF }); tapToStartText.anchor.set(0.5, 0.5); tapToStartText.x = GAME_WIDTH / 2; tapToStartText.y = GAME_HEIGHT / 2; LK.gui.center.addChild(tapToStartText); // Initialize player function initPlayer() { player = new Player(); player.x = LANE_POSITIONS[1]; // Start in center lane player.y = PLAYER_START_Y; game.addChild(player); } // Spawn obstacle function spawnObstacle() { var now = Date.now(); if (now - lastObstacleSpawn < obstacleSpawnRate) { return; } lastObstacleSpawn = now; // Determine obstacle type var types = ['regular', 'low', 'high']; var type = types[Math.floor(Math.random() * types.length)]; var obstacle = new Obstacle(type); obstacle.x = LANE_POSITIONS[obstacle.lane]; obstacle.y = SPAWN_Y; obstacle.speed = gameSpeed; obstacles.push(obstacle); game.addChild(obstacle); // Gradually increase spawn rate obstacleSpawnRate = Math.max(800, obstacleSpawnRate - 5); } // Spawn coin function spawnCoin() { var now = Date.now(); if (now - lastCoinSpawn < coinSpawnRate) { return; } lastCoinSpawn = now; // Spawn 1-3 coins in a row or pattern var coinCount = Math.floor(Math.random() * 3) + 1; var lane = Math.floor(Math.random() * 3); for (var i = 0; i < coinCount; i++) { var coin = new Coin(); // Determine pattern type var patternType = Math.floor(Math.random() * 3); if (patternType === 0) { // Straight line in same lane coin.lane = lane; } else if (patternType === 1) { // Diagonal pattern coin.lane = (lane + i) % 3; } else { // Random lanes coin.lane = Math.floor(Math.random() * 3); } coin.x = LANE_POSITIONS[coin.lane]; coin.y = SPAWN_Y - i * 120; // Spaced out vertically coin.speed = gameSpeed; coinsArray.push(coin); game.addChild(coin); } } // Spawn powerup function spawnPowerup() { var now = Date.now(); if (now - lastPowerupSpawn < powerupSpawnRate) { return; } lastPowerupSpawn = now; var powerup = new Powerup(); powerup.x = LANE_POSITIONS[powerup.lane]; powerup.y = SPAWN_Y; powerup.speed = gameSpeed; powerups.push(powerup); game.addChild(powerup); } // Check collision between two objects using their collision boxes function checkCollision(obj1, obj2) { var box1 = obj1.getCollisionBox(); var box2 = obj2.getCollisionBox(); return box1.x < box2.x + box2.width && box1.x + box1.width > box2.x && box1.y < box2.y + box2.height && box1.y + box1.height > box2.y; } // Handle collisions function handleCollisions() { if (!player) { return; } // Check obstacle collisions for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; if (checkCollision(player, obstacle)) { if (player.powerupActive && player.powerupType === 'invincibility') { // Destroy obstacle if player is invincible obstacle.destroy(); obstacles.splice(i, 1); // Add points for destroying obstacle addScore(50); } else { // Game over on collision LK.getSound('crash').play(); LK.effects.flashScreen(0xff0000, 500); // Update high score if (score > storage.highScore) { storage.highScore = score; highScoreText.setText('HIGH SCORE: ' + storage.highScore); } // Update total coins storage.coins += coins; LK.showGameOver(); return; } } } // Check coin collisions for (var j = coinsArray.length - 1; j >= 0; j--) { var coin = coinsArray[j]; // For magnet powerup, attract nearby coins if (player.powerupActive && player.powerupType === 'magnet') { var dx = player.x - coin.x; var dy = player.y - coin.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 400) { // Move coin towards player var speed = 0.1; coin.x += dx * speed; coin.y += dy * speed; } } if (checkCollision(player, coin)) { coin.collect(); coinsArray.splice(j, 1); // Add coin and points coins++; coinText.setText('COINS: ' + coins); addScore(10); } } // Check powerup collisions for (var k = powerups.length - 1; k >= 0; k--) { var powerup = powerups[k]; if (checkCollision(player, powerup)) { powerup.collect(); player.activatePowerup(powerup.type); powerups.splice(k, 1); // Show powerup text var powerupName = powerup.type.charAt(0).toUpperCase() + powerup.type.slice(1); powerupText.setText(powerupName + ' ACTIVATED!'); powerupText.alpha = 1; // Fade out powerup text tween(powerupText, { alpha: 0 }, { duration: 2000, easing: tween.linear }); // Set multiplier if applicable if (powerup.type === 'multiplier') { multiplier = 2; } } } } // Add to score function addScore(points) { score += points * multiplier; scoreText.setText('SCORE: ' + score); } // Handle touch/mouse events game.down = function (x, y, obj) { if (!gameStarted) { startGame(); return; } playerSwipeStartX = x; playerSwipeStartY = y; swipeDirection = null; }; game.move = function (x, y, obj) { if (!gameStarted || !player) { return; } // Make player follow mouse/touch position horizontally // Find the closest lane based on x position var closestLane = 0; var closestDist = Math.abs(x - LANE_POSITIONS[0]); for (var i = 1; i < LANE_POSITIONS.length; i++) { var dist = Math.abs(x - LANE_POSITIONS[i]); if (dist < closestDist) { closestDist = dist; closestLane = i; } } // Only change lane if needed if (player.lane !== closestLane) { player.switchLane(closestLane); } }; game.up = function (x, y, obj) { // Reset swipe state swipeDirection = null; }; // Start the game function startGame() { if (gameStarted) { return; } gameStarted = true; // Hide start text tween(tapToStartText, { alpha: 0 }, { duration: 500, easing: tween.easeOut }); // Initialize game variables score = 0; distance = 0; coins = 0; multiplier = 1; gameSpeed = 10; // Update UI scoreText.setText('SCORE: 0'); coinText.setText('COINS: 0'); highScoreText.setText('HIGH SCORE: ' + storage.highScore); // Initialize player initPlayer(); // Play music LK.playMusic('gameMusic'); } // Game update function game.update = function () { if (!gameStarted) { return; } // Increase distance and score distance += gameSpeed; if (LK.ticks % 10 === 0) { addScore(1); } // Gradually increase game speed if (LK.ticks % 300 === 0) { gameSpeed += 0.2; } // Spawn game elements spawnObstacle(); spawnCoin(); spawnPowerup(); // Update powerup status if (player) { player.updatePowerup(); // Reset multiplier when powerup ends if (!player.powerupActive && player.powerupType === 'multiplier') { multiplier = 1; } } // Update and clean up obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; if (obstacle.y > DESPAWN_Y) { obstacle.destroy(); obstacles.splice(i, 1); } } // Update and clean up coins for (var j = coinsArray.length - 1; j >= 0; j--) { var coin = coinsArray[j]; if (coin.y > DESPAWN_Y || coin.collected) { coin.destroy(); coinsArray.splice(j, 1); } } // Update and clean up powerups for (var k = powerups.length - 1; k >= 0; k--) { var powerup = powerups[k]; if (powerup.y > DESPAWN_Y || powerup.collected) { powerup.destroy(); powerups.splice(k, 1); } } // Check for collisions handleCollisions(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
coins: 0
});
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
self.lane = Math.floor(Math.random() * 3);
self.speed = 0;
self.collected = false;
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += self.speed;
// Spinning animation
coinGraphics.scaleX = Math.abs(Math.sin(LK.ticks * 0.05)) * 0.5 + 0.5;
};
self.collect = function () {
if (self.collected) {
return;
}
self.collected = true;
LK.getSound('collect').play();
// Animate collection
tween(self, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
easing: tween.easeOut
});
};
self.getCollisionBox = function () {
var box = {
x: self.x - coinGraphics.width * 0.5 * 0.8,
y: self.y - coinGraphics.height * 0.5 * 0.8,
width: coinGraphics.width * 0.8,
height: coinGraphics.height * 0.8
};
return box;
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'regular'; // regular, low, high
self.lane = Math.floor(Math.random() * 3);
self.speed = 0;
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
// Adjust obstacle appearance based on type
if (self.type === 'low') {
obstacleGraphics.scaleY = 0.5;
obstacleGraphics.y = obstacleGraphics.height * 0.25;
} else if (self.type === 'high') {
obstacleGraphics.scaleY = 0.5;
obstacleGraphics.y = -obstacleGraphics.height * 0.25;
}
self.update = function () {
self.y += self.speed;
};
self.getCollisionBox = function () {
var box = {
x: self.x - obstacleGraphics.width * 0.5 * 0.9,
y: self.y - obstacleGraphics.height * 0.5 * 0.9 + (self.type === 'low' ? obstacleGraphics.height * 0.25 : self.type === 'high' ? -obstacleGraphics.height * 0.25 : 0),
width: obstacleGraphics.width * 0.9,
height: obstacleGraphics.height * 0.9 * (self.type === 'low' || self.type === 'high' ? 0.5 : 1)
};
return box;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
// Player states
self.isJumping = false;
self.isSliding = false;
self.lane = 1; // 0: left, 1: center, 2: right
self.speed = 10;
self.jumpHeight = 200;
self.jumpDuration = 500;
self.slideDuration = 600;
self.powerupActive = false;
self.powerupType = null;
self.powerupDuration = 0;
// Player graphics
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Methods for player actions
self.switchLane = function (targetLane) {
if (targetLane < 0 || targetLane > 2 || self.lane === targetLane) {
return;
}
var targetX = LANE_POSITIONS[targetLane];
tween.stop(self, {
x: true
});
tween(self, {
x: targetX
}, {
duration: 200,
easing: tween.easeOut
});
self.lane = targetLane;
};
self.jump = function () {
if (self.isJumping || self.isSliding) {
return;
}
self.isJumping = true;
LK.getSound('jump').play();
var initialY = self.y;
// Jump up
tween(self, {
y: initialY - self.jumpHeight
}, {
duration: self.jumpDuration / 2,
easing: tween.easeOut,
onFinish: function onFinish() {
// Fall down
tween(self, {
y: initialY
}, {
duration: self.jumpDuration / 2,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isJumping = false;
}
});
}
});
};
self.slide = function () {
if (self.isJumping || self.isSliding) {
return;
}
self.isSliding = true;
LK.getSound('slide').play();
// Shrink player height for sliding
tween(playerGraphics, {
scaleY: 0.5
}, {
duration: 200,
easing: tween.linear
});
// Return to normal after slide duration
LK.setTimeout(function () {
tween(playerGraphics, {
scaleY: 1
}, {
duration: 200,
easing: tween.linear,
onFinish: function onFinish() {
self.isSliding = false;
}
});
}, self.slideDuration);
};
self.activatePowerup = function (type) {
self.powerupActive = true;
self.powerupType = type;
switch (type) {
case 'magnet':
self.powerupDuration = 5000;
break;
case 'multiplier':
self.powerupDuration = 8000;
break;
case 'invincibility':
self.powerupDuration = 4000;
playerGraphics.alpha = 0.7;
break;
}
LK.getSound('powerup').play();
};
self.updatePowerup = function () {
if (!self.powerupActive) {
return;
}
self.powerupDuration -= 16.67; // Approximate ms per frame at 60fps
if (self.powerupDuration <= 0) {
self.powerupActive = false;
self.powerupType = null;
playerGraphics.alpha = 1;
}
};
// Collision detection utility
self.getCollisionBox = function () {
var box = {
x: self.x - playerGraphics.width * 0.5 * 0.8,
y: self.y - playerGraphics.height * 0.5 * (self.isSliding ? 0.5 : 0.9),
width: playerGraphics.width * 0.8,
height: playerGraphics.height * (self.isSliding ? 0.5 : 0.9)
};
return box;
};
return self;
});
var Powerup = Container.expand(function () {
var self = Container.call(this);
self.lane = Math.floor(Math.random() * 3);
self.speed = 0;
self.collected = false;
// Random powerup type
var types = ['magnet', 'multiplier', 'invincibility'];
self.type = types[Math.floor(Math.random() * types.length)];
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
// Different colors for different powerups
if (self.type === 'magnet') {
powerupGraphics.tint = 0x0088ff;
} else if (self.type === 'multiplier') {
powerupGraphics.tint = 0xff8800;
} else if (self.type === 'invincibility') {
powerupGraphics.tint = 0xff00ff;
}
self.update = function () {
self.y += self.speed;
// Pulsing animation
var pulse = Math.sin(LK.ticks * 0.1) * 0.1 + 1;
powerupGraphics.scale.set(pulse, pulse);
};
self.collect = function () {
if (self.collected) {
return;
}
self.collected = true;
LK.getSound('powerup').play();
// Animate collection
tween(self, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
easing: tween.easeOut
});
};
self.getCollisionBox = function () {
var box = {
x: self.x - powerupGraphics.width * 0.5 * 0.8,
y: self.y - powerupGraphics.height * 0.5 * 0.8,
width: powerupGraphics.width * 0.8,
height: powerupGraphics.height * 0.8
};
return box;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x202020
});
/****
* Game Code
****/
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var PLAYER_START_Y = GAME_HEIGHT - 400;
var LANE_WIDTH = 200;
var LANE_POSITIONS = [GAME_WIDTH / 2 - LANE_WIDTH, GAME_WIDTH / 2, GAME_WIDTH / 2 + LANE_WIDTH];
var SPAWN_Y = -200;
var DESPAWN_Y = GAME_HEIGHT + 200;
// Game variables
var gameStarted = false;
var gameSpeed = 10;
var score = 0;
var distance = 0;
var coins = 0;
var multiplier = 1;
var lastObstacleSpawn = 0;
var lastCoinSpawn = 0;
var lastPowerupSpawn = 0;
var obstacleSpawnRate = 1500; // ms
var coinSpawnRate = 1000; // ms
var powerupSpawnRate = 10000; // ms
var playerSwipeStartY = 0;
var playerSwipeStartX = 0;
var MIN_SWIPE_DISTANCE = 50;
// Game elements
var player;
var obstacles = [];
var coinsArray = [];
var powerups = [];
var swipeDirection = null;
// Create lanes and background
var background = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0
});
game.addChild(background);
for (var i = 0; i < 3; i++) {
var lane = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0,
alpha: 0.3
});
lane.x = LANE_POSITIONS[i];
lane.y = 0;
game.addChild(lane);
}
// Create UI elements
var scoreText = new Text2('SCORE: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.x = GAME_WIDTH / 2;
scoreText.y = 50;
LK.gui.top.addChild(scoreText);
var coinText = new Text2('COINS: 0', {
size: 80,
fill: 0xFFD700
});
coinText.anchor.set(0, 0);
coinText.x = 150;
coinText.y = 50;
LK.gui.top.addChild(coinText);
var highScoreText = new Text2('HIGH SCORE: ' + storage.highScore, {
size: 60,
fill: 0xFFAA00
});
highScoreText.anchor.set(1, 0);
highScoreText.x = GAME_WIDTH - 150;
highScoreText.y = 50;
LK.gui.top.addChild(highScoreText);
var powerupText = new Text2('', {
size: 70,
fill: 0x83DE44
});
powerupText.anchor.set(0.5, 0);
powerupText.x = GAME_WIDTH / 2;
powerupText.y = 150;
powerupText.alpha = 0;
LK.gui.top.addChild(powerupText);
var tapToStartText = new Text2('TAP TO START', {
size: 120,
fill: 0xFFFFFF
});
tapToStartText.anchor.set(0.5, 0.5);
tapToStartText.x = GAME_WIDTH / 2;
tapToStartText.y = GAME_HEIGHT / 2;
LK.gui.center.addChild(tapToStartText);
// Initialize player
function initPlayer() {
player = new Player();
player.x = LANE_POSITIONS[1]; // Start in center lane
player.y = PLAYER_START_Y;
game.addChild(player);
}
// Spawn obstacle
function spawnObstacle() {
var now = Date.now();
if (now - lastObstacleSpawn < obstacleSpawnRate) {
return;
}
lastObstacleSpawn = now;
// Determine obstacle type
var types = ['regular', 'low', 'high'];
var type = types[Math.floor(Math.random() * types.length)];
var obstacle = new Obstacle(type);
obstacle.x = LANE_POSITIONS[obstacle.lane];
obstacle.y = SPAWN_Y;
obstacle.speed = gameSpeed;
obstacles.push(obstacle);
game.addChild(obstacle);
// Gradually increase spawn rate
obstacleSpawnRate = Math.max(800, obstacleSpawnRate - 5);
}
// Spawn coin
function spawnCoin() {
var now = Date.now();
if (now - lastCoinSpawn < coinSpawnRate) {
return;
}
lastCoinSpawn = now;
// Spawn 1-3 coins in a row or pattern
var coinCount = Math.floor(Math.random() * 3) + 1;
var lane = Math.floor(Math.random() * 3);
for (var i = 0; i < coinCount; i++) {
var coin = new Coin();
// Determine pattern type
var patternType = Math.floor(Math.random() * 3);
if (patternType === 0) {
// Straight line in same lane
coin.lane = lane;
} else if (patternType === 1) {
// Diagonal pattern
coin.lane = (lane + i) % 3;
} else {
// Random lanes
coin.lane = Math.floor(Math.random() * 3);
}
coin.x = LANE_POSITIONS[coin.lane];
coin.y = SPAWN_Y - i * 120; // Spaced out vertically
coin.speed = gameSpeed;
coinsArray.push(coin);
game.addChild(coin);
}
}
// Spawn powerup
function spawnPowerup() {
var now = Date.now();
if (now - lastPowerupSpawn < powerupSpawnRate) {
return;
}
lastPowerupSpawn = now;
var powerup = new Powerup();
powerup.x = LANE_POSITIONS[powerup.lane];
powerup.y = SPAWN_Y;
powerup.speed = gameSpeed;
powerups.push(powerup);
game.addChild(powerup);
}
// Check collision between two objects using their collision boxes
function checkCollision(obj1, obj2) {
var box1 = obj1.getCollisionBox();
var box2 = obj2.getCollisionBox();
return box1.x < box2.x + box2.width && box1.x + box1.width > box2.x && box1.y < box2.y + box2.height && box1.y + box1.height > box2.y;
}
// Handle collisions
function handleCollisions() {
if (!player) {
return;
}
// Check obstacle collisions
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (checkCollision(player, obstacle)) {
if (player.powerupActive && player.powerupType === 'invincibility') {
// Destroy obstacle if player is invincible
obstacle.destroy();
obstacles.splice(i, 1);
// Add points for destroying obstacle
addScore(50);
} else {
// Game over on collision
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 500);
// Update high score
if (score > storage.highScore) {
storage.highScore = score;
highScoreText.setText('HIGH SCORE: ' + storage.highScore);
}
// Update total coins
storage.coins += coins;
LK.showGameOver();
return;
}
}
}
// Check coin collisions
for (var j = coinsArray.length - 1; j >= 0; j--) {
var coin = coinsArray[j];
// For magnet powerup, attract nearby coins
if (player.powerupActive && player.powerupType === 'magnet') {
var dx = player.x - coin.x;
var dy = player.y - coin.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 400) {
// Move coin towards player
var speed = 0.1;
coin.x += dx * speed;
coin.y += dy * speed;
}
}
if (checkCollision(player, coin)) {
coin.collect();
coinsArray.splice(j, 1);
// Add coin and points
coins++;
coinText.setText('COINS: ' + coins);
addScore(10);
}
}
// Check powerup collisions
for (var k = powerups.length - 1; k >= 0; k--) {
var powerup = powerups[k];
if (checkCollision(player, powerup)) {
powerup.collect();
player.activatePowerup(powerup.type);
powerups.splice(k, 1);
// Show powerup text
var powerupName = powerup.type.charAt(0).toUpperCase() + powerup.type.slice(1);
powerupText.setText(powerupName + ' ACTIVATED!');
powerupText.alpha = 1;
// Fade out powerup text
tween(powerupText, {
alpha: 0
}, {
duration: 2000,
easing: tween.linear
});
// Set multiplier if applicable
if (powerup.type === 'multiplier') {
multiplier = 2;
}
}
}
}
// Add to score
function addScore(points) {
score += points * multiplier;
scoreText.setText('SCORE: ' + score);
}
// Handle touch/mouse events
game.down = function (x, y, obj) {
if (!gameStarted) {
startGame();
return;
}
playerSwipeStartX = x;
playerSwipeStartY = y;
swipeDirection = null;
};
game.move = function (x, y, obj) {
if (!gameStarted || !player) {
return;
}
// Make player follow mouse/touch position horizontally
// Find the closest lane based on x position
var closestLane = 0;
var closestDist = Math.abs(x - LANE_POSITIONS[0]);
for (var i = 1; i < LANE_POSITIONS.length; i++) {
var dist = Math.abs(x - LANE_POSITIONS[i]);
if (dist < closestDist) {
closestDist = dist;
closestLane = i;
}
}
// Only change lane if needed
if (player.lane !== closestLane) {
player.switchLane(closestLane);
}
};
game.up = function (x, y, obj) {
// Reset swipe state
swipeDirection = null;
};
// Start the game
function startGame() {
if (gameStarted) {
return;
}
gameStarted = true;
// Hide start text
tween(tapToStartText, {
alpha: 0
}, {
duration: 500,
easing: tween.easeOut
});
// Initialize game variables
score = 0;
distance = 0;
coins = 0;
multiplier = 1;
gameSpeed = 10;
// Update UI
scoreText.setText('SCORE: 0');
coinText.setText('COINS: 0');
highScoreText.setText('HIGH SCORE: ' + storage.highScore);
// Initialize player
initPlayer();
// Play music
LK.playMusic('gameMusic');
}
// Game update function
game.update = function () {
if (!gameStarted) {
return;
}
// Increase distance and score
distance += gameSpeed;
if (LK.ticks % 10 === 0) {
addScore(1);
}
// Gradually increase game speed
if (LK.ticks % 300 === 0) {
gameSpeed += 0.2;
}
// Spawn game elements
spawnObstacle();
spawnCoin();
spawnPowerup();
// Update powerup status
if (player) {
player.updatePowerup();
// Reset multiplier when powerup ends
if (!player.powerupActive && player.powerupType === 'multiplier') {
multiplier = 1;
}
}
// Update and clean up obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.y > DESPAWN_Y) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
// Update and clean up coins
for (var j = coinsArray.length - 1; j >= 0; j--) {
var coin = coinsArray[j];
if (coin.y > DESPAWN_Y || coin.collected) {
coin.destroy();
coinsArray.splice(j, 1);
}
}
// Update and clean up powerups
for (var k = powerups.length - 1; k >= 0; k--) {
var powerup = powerups[k];
if (powerup.y > DESPAWN_Y || powerup.collected) {
powerup.destroy();
powerups.splice(k, 1);
}
}
// Check for collisions
handleCollisions();
};