/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1; // 0 = left, 1 = center, 2 = right
self.isMoving = false;
self.targetX = 1024; // center lane
self.setLane = function (newLane) {
if (newLane === self.lane || newLane < 0 || newLane > 2) return;
self.lane = newLane;
var lanePositions = [512, 1024, 1536];
self.targetX = lanePositions[newLane];
self.isMoving = true;
tween(self, {
x: self.targetX
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.isMoving = false;
}
});
};
self.down = function (x, y, obj) {};
self.up = function (x, y, obj) {};
self.move = function (x, y, obj) {};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = Math.floor(Math.random() * 3);
self.speed = 15;
self.lastY = self.y;
self.collected = false;
var lanePositions = [512, 1024, 1536];
self.x = lanePositions[self.lane];
self.y = -60;
self.update = function () {
self.lastY = self.y;
self.y += self.speed;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = Math.floor(Math.random() * 3);
self.speed = 15;
self.lastY = self.y;
var lanePositions = [512, 1024, 1536];
self.x = lanePositions[self.lane];
self.y = -100;
self.update = function () {
self.lastY = self.y;
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state variables
var character = null;
var obstacles = [];
var coins = [];
var gameSpeed = 10;
var baseSpeed = 10;
var maxSpeed = 25;
var scoreMultiplier = 1;
var tickCounter = 0;
var lastSwipeX = 0;
var swipeThreshold = 200;
// Initialize UI
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var speedTxt = new Text2('Speed: 1.0x', {
size: 80,
fill: 0xFFD700
});
speedTxt.anchor.set(0.5, 0);
speedTxt.y = 150;
LK.gui.top.addChild(speedTxt);
// Add track visuals
var track1 = game.addChild(LK.getAsset('track', {
anchorX: 0.5,
anchorY: 0
}));
track1.x = 1024;
track1.y = 0;
var track2 = game.addChild(LK.getAsset('track', {
anchorX: 0.5,
anchorY: 0
}));
track2.x = 1024;
track2.y = -400;
// Initialize character
character = game.addChild(new Character());
character.x = 1024;
character.y = 2400;
// Game input handling
var swipeStartX = null;
game.down = function (x, y, obj) {
swipeStartX = x;
};
game.up = function (x, y, obj) {
if (swipeStartX !== null) {
var swipeDelta = x - swipeStartX;
if (Math.abs(swipeDelta) > swipeThreshold) {
if (swipeDelta < 0) {
// Swipe left
if (character.lane > 0) {
character.setLane(character.lane - 1);
}
} else {
// Swipe right
if (character.lane < 2) {
character.setLane(character.lane + 1);
}
}
}
swipeStartX = null;
}
};
game.move = function (x, y, obj) {
// No continuous movement needed for this game
};
// Spawn obstacles
var obstacleSpawnRate = 60;
var obstacleCounter = 0;
// Spawn coins
var coinSpawnRate = 80;
var coinCounter = 0;
// Main game loop
game.update = function () {
tickCounter++;
// Gradually increase speed
if (tickCounter % 300 === 0 && gameSpeed < maxSpeed) {
gameSpeed += 0.5;
baseSpeed = gameSpeed;
scoreMultiplier = (gameSpeed / 10).toFixed(1);
speedTxt.setText('Speed: ' + scoreMultiplier + 'x');
}
// Update obstacle speed
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed = gameSpeed;
}
// Update coin speed
for (var i = 0; i < coins.length; i++) {
coins[i].speed = gameSpeed;
}
// Spawn obstacles
obstacleCounter++;
if (obstacleCounter >= obstacleSpawnRate) {
var newObstacle = new Obstacle();
newObstacle.speed = gameSpeed;
game.addChild(newObstacle);
obstacles.push(newObstacle);
obstacleCounter = 0;
}
// Spawn coins
coinCounter++;
if (coinCounter >= coinSpawnRate) {
var newCoin = new Coin();
newCoin.speed = gameSpeed;
game.addChild(newCoin);
coins.push(newCoin);
coinCounter = 0;
}
// Update and check obstacles
for (var a = obstacles.length - 1; a >= 0; a--) {
var obstacle = obstacles[a];
if (obstacle.lastY === undefined) {
obstacle.lastY = obstacle.y;
obstacle.lastIntersecting = false;
}
// Check collision with character
var currentIntersecting = obstacle.intersects(character);
if (!obstacle.lastIntersecting && currentIntersecting) {
// Collision detected
LK.getSound('crash').play();
LK.effects.flashScreen(0xFF0000, 500);
LK.showGameOver();
}
// Remove obstacle if off-screen
if (obstacle.y > 2800) {
obstacle.destroy();
obstacles.splice(a, 1);
continue;
}
obstacle.lastIntersecting = currentIntersecting;
obstacle.lastY = obstacle.y;
}
// Update and check coins
for (var b = coins.length - 1; b >= 0; b--) {
var coin = coins[b];
if (coin.lastY === undefined) {
coin.lastY = coin.y;
coin.lastIntersecting = false;
}
// Check collision with character
var coinIntersecting = coin.intersects(character);
if (!coin.lastIntersecting && coinIntersecting && !coin.collected) {
// Coin collected
coin.collected = true;
LK.getSound('coinCollect').play();
var points = Math.round(10 * scoreMultiplier);
LK.setScore(LK.getScore() + points);
scoreTxt.setText(LK.getScore());
// Flash coin
LK.effects.flashObject(coin, 0xFFFFFF, 200);
coin.destroy();
coins.splice(b, 1);
continue;
}
// Remove coin if off-screen
if (coin.y > 2800) {
coin.destroy();
coins.splice(b, 1);
continue;
}
coin.lastIntersecting = coinIntersecting;
coin.lastY = coin.y;
}
// Update track position (parallax effect)
track1.y += gameSpeed;
track2.y += gameSpeed;
if (track1.y > 2732) {
track1.y = track2.y - 400;
}
if (track2.y > 2732) {
track2.y = track1.y - 400;
}
};
// Start background music
LK.playMusic('bgmusic'); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1; // 0 = left, 1 = center, 2 = right
self.isMoving = false;
self.targetX = 1024; // center lane
self.setLane = function (newLane) {
if (newLane === self.lane || newLane < 0 || newLane > 2) return;
self.lane = newLane;
var lanePositions = [512, 1024, 1536];
self.targetX = lanePositions[newLane];
self.isMoving = true;
tween(self, {
x: self.targetX
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.isMoving = false;
}
});
};
self.down = function (x, y, obj) {};
self.up = function (x, y, obj) {};
self.move = function (x, y, obj) {};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = Math.floor(Math.random() * 3);
self.speed = 15;
self.lastY = self.y;
self.collected = false;
var lanePositions = [512, 1024, 1536];
self.x = lanePositions[self.lane];
self.y = -60;
self.update = function () {
self.lastY = self.y;
self.y += self.speed;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = Math.floor(Math.random() * 3);
self.speed = 15;
self.lastY = self.y;
var lanePositions = [512, 1024, 1536];
self.x = lanePositions[self.lane];
self.y = -100;
self.update = function () {
self.lastY = self.y;
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state variables
var character = null;
var obstacles = [];
var coins = [];
var gameSpeed = 10;
var baseSpeed = 10;
var maxSpeed = 25;
var scoreMultiplier = 1;
var tickCounter = 0;
var lastSwipeX = 0;
var swipeThreshold = 200;
// Initialize UI
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var speedTxt = new Text2('Speed: 1.0x', {
size: 80,
fill: 0xFFD700
});
speedTxt.anchor.set(0.5, 0);
speedTxt.y = 150;
LK.gui.top.addChild(speedTxt);
// Add track visuals
var track1 = game.addChild(LK.getAsset('track', {
anchorX: 0.5,
anchorY: 0
}));
track1.x = 1024;
track1.y = 0;
var track2 = game.addChild(LK.getAsset('track', {
anchorX: 0.5,
anchorY: 0
}));
track2.x = 1024;
track2.y = -400;
// Initialize character
character = game.addChild(new Character());
character.x = 1024;
character.y = 2400;
// Game input handling
var swipeStartX = null;
game.down = function (x, y, obj) {
swipeStartX = x;
};
game.up = function (x, y, obj) {
if (swipeStartX !== null) {
var swipeDelta = x - swipeStartX;
if (Math.abs(swipeDelta) > swipeThreshold) {
if (swipeDelta < 0) {
// Swipe left
if (character.lane > 0) {
character.setLane(character.lane - 1);
}
} else {
// Swipe right
if (character.lane < 2) {
character.setLane(character.lane + 1);
}
}
}
swipeStartX = null;
}
};
game.move = function (x, y, obj) {
// No continuous movement needed for this game
};
// Spawn obstacles
var obstacleSpawnRate = 60;
var obstacleCounter = 0;
// Spawn coins
var coinSpawnRate = 80;
var coinCounter = 0;
// Main game loop
game.update = function () {
tickCounter++;
// Gradually increase speed
if (tickCounter % 300 === 0 && gameSpeed < maxSpeed) {
gameSpeed += 0.5;
baseSpeed = gameSpeed;
scoreMultiplier = (gameSpeed / 10).toFixed(1);
speedTxt.setText('Speed: ' + scoreMultiplier + 'x');
}
// Update obstacle speed
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed = gameSpeed;
}
// Update coin speed
for (var i = 0; i < coins.length; i++) {
coins[i].speed = gameSpeed;
}
// Spawn obstacles
obstacleCounter++;
if (obstacleCounter >= obstacleSpawnRate) {
var newObstacle = new Obstacle();
newObstacle.speed = gameSpeed;
game.addChild(newObstacle);
obstacles.push(newObstacle);
obstacleCounter = 0;
}
// Spawn coins
coinCounter++;
if (coinCounter >= coinSpawnRate) {
var newCoin = new Coin();
newCoin.speed = gameSpeed;
game.addChild(newCoin);
coins.push(newCoin);
coinCounter = 0;
}
// Update and check obstacles
for (var a = obstacles.length - 1; a >= 0; a--) {
var obstacle = obstacles[a];
if (obstacle.lastY === undefined) {
obstacle.lastY = obstacle.y;
obstacle.lastIntersecting = false;
}
// Check collision with character
var currentIntersecting = obstacle.intersects(character);
if (!obstacle.lastIntersecting && currentIntersecting) {
// Collision detected
LK.getSound('crash').play();
LK.effects.flashScreen(0xFF0000, 500);
LK.showGameOver();
}
// Remove obstacle if off-screen
if (obstacle.y > 2800) {
obstacle.destroy();
obstacles.splice(a, 1);
continue;
}
obstacle.lastIntersecting = currentIntersecting;
obstacle.lastY = obstacle.y;
}
// Update and check coins
for (var b = coins.length - 1; b >= 0; b--) {
var coin = coins[b];
if (coin.lastY === undefined) {
coin.lastY = coin.y;
coin.lastIntersecting = false;
}
// Check collision with character
var coinIntersecting = coin.intersects(character);
if (!coin.lastIntersecting && coinIntersecting && !coin.collected) {
// Coin collected
coin.collected = true;
LK.getSound('coinCollect').play();
var points = Math.round(10 * scoreMultiplier);
LK.setScore(LK.getScore() + points);
scoreTxt.setText(LK.getScore());
// Flash coin
LK.effects.flashObject(coin, 0xFFFFFF, 200);
coin.destroy();
coins.splice(b, 1);
continue;
}
// Remove coin if off-screen
if (coin.y > 2800) {
coin.destroy();
coins.splice(b, 1);
continue;
}
coin.lastIntersecting = coinIntersecting;
coin.lastY = coin.y;
}
// Update track position (parallax effect)
track1.y += gameSpeed;
track2.y += gameSpeed;
if (track1.y > 2732) {
track1.y = track2.y - 400;
}
if (track2.y > 2732) {
track2.y = track1.y - 400;
}
};
// Start background music
LK.playMusic('bgmusic');