/****
* 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;
}
// Calculate swipe distance
var dx = x - playerSwipeStartX;
var dy = y - playerSwipeStartY;
var absDx = Math.abs(dx);
var absDy = Math.abs(dy);
// Only register swipe if it's long enough and we haven't already processed this swipe
if (swipeDirection === null && (absDx > MIN_SWIPE_DISTANCE || absDy > MIN_SWIPE_DISTANCE)) {
if (absDx > absDy) {
// Horizontal swipe (lane change)
swipeDirection = dx > 0 ? 'right' : 'left';
var newLane = player.lane + (dx > 0 ? 1 : -1);
if (newLane >= 0 && newLane <= 2) {
player.switchLane(newLane);
}
} else {
// Vertical swipe (jump or slide)
swipeDirection = dy > 0 ? 'down' : 'up';
if (dy < 0) {
player.jump();
} else {
player.slide();
}
}
}
};
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();
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,650 @@
-/****
+/****
+* 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: 0x000000
-});
\ No newline at end of file
+ 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;
+ }
+ // Calculate swipe distance
+ var dx = x - playerSwipeStartX;
+ var dy = y - playerSwipeStartY;
+ var absDx = Math.abs(dx);
+ var absDy = Math.abs(dy);
+ // Only register swipe if it's long enough and we haven't already processed this swipe
+ if (swipeDirection === null && (absDx > MIN_SWIPE_DISTANCE || absDy > MIN_SWIPE_DISTANCE)) {
+ if (absDx > absDy) {
+ // Horizontal swipe (lane change)
+ swipeDirection = dx > 0 ? 'right' : 'left';
+ var newLane = player.lane + (dx > 0 ? 1 : -1);
+ if (newLane >= 0 && newLane <= 2) {
+ player.switchLane(newLane);
+ }
+ } else {
+ // Vertical swipe (jump or slide)
+ swipeDirection = dy > 0 ? 'down' : 'up';
+ if (dy < 0) {
+ player.jump();
+ } else {
+ player.slide();
+ }
+ }
+ }
+};
+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();
+};
\ No newline at end of file