/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Explosion = Container.expand(function () { var self = Container.call(this); // Create multiple explosion particles var particles = []; for (var i = 0; i < 8; i++) { var particle = LK.getAsset('barrier', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); particle.tint = Math.random() < 0.5 ? 0xff4444 : 0xffaa00; particles.push(particle); self.addChild(particle); } self.explode = function () { // Animate particles outward for (var i = 0; i < particles.length; i++) { var particle = particles[i]; var angle = i / particles.length * Math.PI * 2; var distance = 200 + Math.random() * 100; var targetX = Math.cos(angle) * distance; var targetY = Math.sin(angle) * distance; // Animate particle movement and fade tween(particle, { x: targetX, y: targetY, alpha: 0, scaleX: 0.1, scaleY: 0.1, rotation: Math.random() * Math.PI * 2 }, { duration: 1000, easing: tween.easeOut }); } // Remove explosion after animation LK.setTimeout(function () { self.destroy(); }, 1000); }; return self; }); var Obstacle = Container.expand(function (type) { var self = Container.call(this); var assetName = type || 'enemyCar'; var obstacleGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.speed = gameSpeed; self.type = type; self.update = function () { self.y += self.speed; }; return self; }); var PlayerCar = Container.expand(function () { var self = Container.call(this); var carGraphics = self.attachAsset('playerCar', { anchorX: 0.5, anchorY: 0.5 }); self.currentLane = 1; // 0 = left, 1 = center, 2 = right self.targetX = 0; self.moveSpeed = 15; self.update = function () { // Smooth movement towards target lane if (Math.abs(self.x - self.targetX) > 5) { if (self.x < self.targetX) { self.x += self.moveSpeed; } else { self.x -= self.moveSpeed; } } else { self.x = self.targetX; } }; self.moveToLane = function (lane) { if (lane >= 0 && lane <= 3) { self.currentLane = lane; self.targetX = lanePositions[lane]; } }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphics = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); self.speed = gameSpeed; self.collected = false; self.update = function () { self.y += self.speed; // Rotate for visual effect powerUpGraphics.rotation += 0.1; }; return self; }); var SmokeParticle = Container.expand(function () { var self = Container.call(this); var smoke = LK.getAsset('powerUp', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); smoke.tint = 0x000000; smoke.alpha = 0.6; self.addChild(smoke); self.speed = 2; self.lifeTime = 60; // 1 second at 60fps self.update = function () { self.y += self.speed; self.lifeTime--; // Fade out and expand over time smoke.alpha = self.lifeTime / 60 * 0.6; smoke.scaleX += 0.01; smoke.scaleY += 0.01; // Remove when lifetime is over if (self.lifeTime <= 0) { self.destroy(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ // Game constants var lanePositions = [2048 / 2 - 450, 2048 / 2 - 150, 2048 / 2 + 150, 2048 / 2 + 450]; var gameSpeed = 8; var spawnRate = 0.01; var powerUpSpawnRate = 0.005; var difficultyIncrease = 0.0005; var invulnerableTime = 0; // Game variables var obstacles = []; var powerUps = []; var smokeParticles = []; var distanceScore = 0; var isGameRunning = true; var lastSpawnLane = -1; var spawnCooldown = 0; // Create lane dividers var leftLane1 = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0.5, x: lanePositions[0] + 75, y: 2732 / 2 }); var leftLane2 = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0.5, x: lanePositions[1] + 75, y: 2732 / 2 }); var rightLane1 = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0.5, x: lanePositions[2] + 75, y: 2732 / 2 }); var rightLane2 = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0.5, x: lanePositions[3] + 75, y: 2732 / 2 }); game.addChild(leftLane1); game.addChild(leftLane2); game.addChild(rightLane1); game.addChild(rightLane2); // Create player car var playerCar = game.addChild(new PlayerCar()); playerCar.x = lanePositions[1]; playerCar.y = 2732 - 300; playerCar.targetX = lanePositions[1]; // Create score display var scoreText = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Input handling game.down = function (x, y, obj) { if (!isGameRunning) return; // Left side tap - move left if (x < 2048 / 2) { if (playerCar.currentLane > 0) { playerCar.moveToLane(playerCar.currentLane - 1); } } // Right side tap - move right else { if (playerCar.currentLane < 3) { playerCar.moveToLane(playerCar.currentLane + 1); } } }; // Spawn obstacles function spawnObstacle() { var obstacleType = Math.random() < 0.7 ? 'enemyCar' : 'barrier'; var obstacle = new Obstacle(obstacleType); // Choose a different lane than the last spawn to spread out cars var lane; do { lane = Math.floor(Math.random() * 4); } while (lane === lastSpawnLane && Math.random() < 0.8); lastSpawnLane = lane; obstacle.x = lanePositions[lane]; obstacle.y = -100; obstacle.speed = gameSpeed; obstacles.push(obstacle); game.addChild(obstacle); } // Spawn power-ups function spawnPowerUp() { var powerUp = new PowerUp(); var lane = Math.floor(Math.random() * 4); powerUp.x = lanePositions[lane]; powerUp.y = -100; powerUp.speed = gameSpeed; powerUps.push(powerUp); game.addChild(powerUp); } // Generate smoke particles from player car function generateSmoke() { var smoke = new SmokeParticle(); smoke.x = playerCar.x + (Math.random() - 0.5) * 30; smoke.y = playerCar.y + 100; // Behind the car smokeParticles.push(smoke); game.addChild(smoke); } // Check collisions function checkCollisions() { // Check obstacle collisions for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; if (playerCar.intersects(obstacle) && invulnerableTime <= 0) { // Create explosion effect at player car position var explosion = new Explosion(); explosion.x = playerCar.x; explosion.y = playerCar.y; game.addChild(explosion); explosion.explode(); // Game over LK.getSound('crash').play(); LK.effects.flashScreen(0xff0000, 1000); isGameRunning = false; LK.showGameOver(); return; } } // Check power-up collisions for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; if (playerCar.intersects(powerUp) && !powerUp.collected) { powerUp.collected = true; LK.getSound('powerup').play(); LK.effects.flashObject(powerUp, 0xffffff, 300); // Add bonus points LK.setScore(LK.getScore() + 50); // Grant temporary invulnerability invulnerableTime = 120; // 2 seconds at 60fps // Remove power-up powerUp.destroy(); powerUps.splice(i, 1); } } } // Clean up off-screen objects function cleanupObjects() { // Clean up obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; if (obstacle.y > 2732 + 100) { obstacle.destroy(); obstacles.splice(i, 1); } } // Clean up power-ups for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; if (powerUp.y > 2732 + 100) { powerUp.destroy(); powerUps.splice(i, 1); } } // Clean up smoke particles for (var i = smokeParticles.length - 1; i >= 0; i--) { var smoke = smokeParticles[i]; if (smoke.y > 2732 + 100 || smoke.lifeTime <= 0) { smoke.destroy(); smokeParticles.splice(i, 1); } } } // Main game loop game.update = function () { if (!isGameRunning) return; // Update distance score distanceScore += 1; LK.setScore(Math.floor(distanceScore / 10)); scoreText.setText(LK.getScore()); // Decrease invulnerability timer if (invulnerableTime > 0) { invulnerableTime--; // Flash player during invulnerability if (invulnerableTime % 10 < 5) { playerCar.alpha = 0.5; } else { playerCar.alpha = 1.0; } } else { playerCar.alpha = 1.0; } // Spawn obstacles if (spawnCooldown > 0) { spawnCooldown--; } if (Math.random() < spawnRate && Math.random() < 0.7 && spawnCooldown <= 0) { spawnObstacle(); spawnCooldown = 30; // Prevent spawning for 30 frames to reduce density } // Spawn power-ups if (Math.random() < powerUpSpawnRate) { spawnPowerUp(); } // Increase difficulty over time gameSpeed += difficultyIncrease; spawnRate += difficultyIncrease * 0.3; // Update obstacle speeds for (var i = 0; i < obstacles.length; i++) { obstacles[i].speed = gameSpeed; } for (var i = 0; i < powerUps.length; i++) { powerUps[i].speed = gameSpeed; } // Check collisions checkCollisions(); // Generate smoke particles from player car if (LK.ticks % 8 === 0) { // Generate smoke every 8 frames generateSmoke(); } // Clean up off-screen objects cleanupObjects(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Explosion = Container.expand(function () {
var self = Container.call(this);
// Create multiple explosion particles
var particles = [];
for (var i = 0; i < 8; i++) {
var particle = LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
particle.tint = Math.random() < 0.5 ? 0xff4444 : 0xffaa00;
particles.push(particle);
self.addChild(particle);
}
self.explode = function () {
// Animate particles outward
for (var i = 0; i < particles.length; i++) {
var particle = particles[i];
var angle = i / particles.length * Math.PI * 2;
var distance = 200 + Math.random() * 100;
var targetX = Math.cos(angle) * distance;
var targetY = Math.sin(angle) * distance;
// Animate particle movement and fade
tween(particle, {
x: targetX,
y: targetY,
alpha: 0,
scaleX: 0.1,
scaleY: 0.1,
rotation: Math.random() * Math.PI * 2
}, {
duration: 1000,
easing: tween.easeOut
});
}
// Remove explosion after animation
LK.setTimeout(function () {
self.destroy();
}, 1000);
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
var assetName = type || 'enemyCar';
var obstacleGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.type = type;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.currentLane = 1; // 0 = left, 1 = center, 2 = right
self.targetX = 0;
self.moveSpeed = 15;
self.update = function () {
// Smooth movement towards target lane
if (Math.abs(self.x - self.targetX) > 5) {
if (self.x < self.targetX) {
self.x += self.moveSpeed;
} else {
self.x -= self.moveSpeed;
}
} else {
self.x = self.targetX;
}
};
self.moveToLane = function (lane) {
if (lane >= 0 && lane <= 3) {
self.currentLane = lane;
self.targetX = lanePositions[lane];
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.collected = false;
self.update = function () {
self.y += self.speed;
// Rotate for visual effect
powerUpGraphics.rotation += 0.1;
};
return self;
});
var SmokeParticle = Container.expand(function () {
var self = Container.call(this);
var smoke = LK.getAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
smoke.tint = 0x000000;
smoke.alpha = 0.6;
self.addChild(smoke);
self.speed = 2;
self.lifeTime = 60; // 1 second at 60fps
self.update = function () {
self.y += self.speed;
self.lifeTime--;
// Fade out and expand over time
smoke.alpha = self.lifeTime / 60 * 0.6;
smoke.scaleX += 0.01;
smoke.scaleY += 0.01;
// Remove when lifetime is over
if (self.lifeTime <= 0) {
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Game constants
var lanePositions = [2048 / 2 - 450, 2048 / 2 - 150, 2048 / 2 + 150, 2048 / 2 + 450];
var gameSpeed = 8;
var spawnRate = 0.01;
var powerUpSpawnRate = 0.005;
var difficultyIncrease = 0.0005;
var invulnerableTime = 0;
// Game variables
var obstacles = [];
var powerUps = [];
var smokeParticles = [];
var distanceScore = 0;
var isGameRunning = true;
var lastSpawnLane = -1;
var spawnCooldown = 0;
// Create lane dividers
var leftLane1 = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
x: lanePositions[0] + 75,
y: 2732 / 2
});
var leftLane2 = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
x: lanePositions[1] + 75,
y: 2732 / 2
});
var rightLane1 = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
x: lanePositions[2] + 75,
y: 2732 / 2
});
var rightLane2 = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
x: lanePositions[3] + 75,
y: 2732 / 2
});
game.addChild(leftLane1);
game.addChild(leftLane2);
game.addChild(rightLane1);
game.addChild(rightLane2);
// Create player car
var playerCar = game.addChild(new PlayerCar());
playerCar.x = lanePositions[1];
playerCar.y = 2732 - 300;
playerCar.targetX = lanePositions[1];
// Create score display
var scoreText = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Input handling
game.down = function (x, y, obj) {
if (!isGameRunning) return;
// Left side tap - move left
if (x < 2048 / 2) {
if (playerCar.currentLane > 0) {
playerCar.moveToLane(playerCar.currentLane - 1);
}
}
// Right side tap - move right
else {
if (playerCar.currentLane < 3) {
playerCar.moveToLane(playerCar.currentLane + 1);
}
}
};
// Spawn obstacles
function spawnObstacle() {
var obstacleType = Math.random() < 0.7 ? 'enemyCar' : 'barrier';
var obstacle = new Obstacle(obstacleType);
// Choose a different lane than the last spawn to spread out cars
var lane;
do {
lane = Math.floor(Math.random() * 4);
} while (lane === lastSpawnLane && Math.random() < 0.8);
lastSpawnLane = lane;
obstacle.x = lanePositions[lane];
obstacle.y = -100;
obstacle.speed = gameSpeed;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn power-ups
function spawnPowerUp() {
var powerUp = new PowerUp();
var lane = Math.floor(Math.random() * 4);
powerUp.x = lanePositions[lane];
powerUp.y = -100;
powerUp.speed = gameSpeed;
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Generate smoke particles from player car
function generateSmoke() {
var smoke = new SmokeParticle();
smoke.x = playerCar.x + (Math.random() - 0.5) * 30;
smoke.y = playerCar.y + 100; // Behind the car
smokeParticles.push(smoke);
game.addChild(smoke);
}
// Check collisions
function checkCollisions() {
// Check obstacle collisions
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (playerCar.intersects(obstacle) && invulnerableTime <= 0) {
// Create explosion effect at player car position
var explosion = new Explosion();
explosion.x = playerCar.x;
explosion.y = playerCar.y;
game.addChild(explosion);
explosion.explode();
// Game over
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
isGameRunning = false;
LK.showGameOver();
return;
}
}
// Check power-up collisions
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (playerCar.intersects(powerUp) && !powerUp.collected) {
powerUp.collected = true;
LK.getSound('powerup').play();
LK.effects.flashObject(powerUp, 0xffffff, 300);
// Add bonus points
LK.setScore(LK.getScore() + 50);
// Grant temporary invulnerability
invulnerableTime = 120; // 2 seconds at 60fps
// Remove power-up
powerUp.destroy();
powerUps.splice(i, 1);
}
}
}
// Clean up off-screen objects
function cleanupObjects() {
// Clean up obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.y > 2732 + 100) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
// Clean up power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (powerUp.y > 2732 + 100) {
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Clean up smoke particles
for (var i = smokeParticles.length - 1; i >= 0; i--) {
var smoke = smokeParticles[i];
if (smoke.y > 2732 + 100 || smoke.lifeTime <= 0) {
smoke.destroy();
smokeParticles.splice(i, 1);
}
}
}
// Main game loop
game.update = function () {
if (!isGameRunning) return;
// Update distance score
distanceScore += 1;
LK.setScore(Math.floor(distanceScore / 10));
scoreText.setText(LK.getScore());
// Decrease invulnerability timer
if (invulnerableTime > 0) {
invulnerableTime--;
// Flash player during invulnerability
if (invulnerableTime % 10 < 5) {
playerCar.alpha = 0.5;
} else {
playerCar.alpha = 1.0;
}
} else {
playerCar.alpha = 1.0;
}
// Spawn obstacles
if (spawnCooldown > 0) {
spawnCooldown--;
}
if (Math.random() < spawnRate && Math.random() < 0.7 && spawnCooldown <= 0) {
spawnObstacle();
spawnCooldown = 30; // Prevent spawning for 30 frames to reduce density
}
// Spawn power-ups
if (Math.random() < powerUpSpawnRate) {
spawnPowerUp();
}
// Increase difficulty over time
gameSpeed += difficultyIncrease;
spawnRate += difficultyIncrease * 0.3;
// Update obstacle speeds
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed = gameSpeed;
}
for (var i = 0; i < powerUps.length; i++) {
powerUps[i].speed = gameSpeed;
}
// Check collisions
checkCollisions();
// Generate smoke particles from player car
if (LK.ticks % 8 === 0) {
// Generate smoke every 8 frames
generateSmoke();
}
// Clean up off-screen objects
cleanupObjects();
};