/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var EnemyCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('enemy_car', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4 + Math.random() * 4;
self.lane = Math.floor(Math.random() * 3);
self.update = function () {
self.y += self.speed;
};
return self;
});
var NitroPickup = Container.expand(function () {
var self = Container.call(this);
var nitroGraphics = self.attachAsset('nitro_pickup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.rotationSpeed = 0.1;
self.update = function () {
self.y += self.speed;
nitroGraphics.rotation += self.rotationSpeed;
// Pulsing effect
var scale = 1 + Math.sin(LK.ticks * 0.2) * 0.2;
nitroGraphics.scaleX = scale;
nitroGraphics.scaleY = scale;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('player_car', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1; // 0 = left, 1 = center, 2 = right
self.speed = 8;
self.baseSpeed = 8;
self.nitroSpeed = 16;
self.isNitro = false;
self.nitroTime = 0;
self.targetX = 2048 / 2;
self.moveToLane = function (newLane) {
if (newLane >= 0 && newLane <= 2) {
self.lane = newLane;
var lanePositions = [2048 * 0.25, 2048 * 0.5, 2048 * 0.75];
self.targetX = lanePositions[newLane];
}
};
self.activateNitro = function () {
if (!self.isNitro) {
self.isNitro = true;
self.nitroTime = 180; // 3 seconds at 60fps
self.speed = self.nitroSpeed;
carGraphics.tint = 0xffff00;
LK.getSound('nitro').play();
}
};
self.update = function () {
// Move towards target lane
var diff = self.targetX - self.x;
if (Math.abs(diff) > 5) {
self.x += diff * 0.15;
}
// Handle nitro
if (self.isNitro) {
self.nitroTime--;
if (self.nitroTime <= 0) {
self.isNitro = false;
self.speed = self.baseSpeed;
carGraphics.tint = 0xffffff;
}
}
// Create speed trail effect
if (LK.ticks % 5 === 0) {
var trail = LK.getAsset('player_car', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3,
scaleX: 0.8,
scaleY: 0.8
});
trail.x = self.x;
trail.y = self.y + 50;
trail.tint = self.isNitro ? 0xffff00 : 0x00ffff;
game.addChild(trail);
tween(trail, {
alpha: 0,
y: trail.y + 100
}, {
duration: 500,
onFinish: function onFinish() {
trail.destroy();
}
});
}
};
return self;
});
var TrackLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('track_line', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a1a
});
/****
* Game Code
****/
// Game variables
var playerCar;
var enemyCars = [];
var obstacles = [];
var nitroPickups = [];
var trackLines = [];
var raceDistance = 0;
var totalRaceDistance = 5000;
var currentSpeed = 8;
var isGameRunning = true;
// Lane positions
var lanePositions = [2048 * 0.25, 2048 * 0.5, 2048 * 0.75];
// UI Elements
var speedText = new Text2('SPEED: 0', {
size: 60,
fill: 0x00FFFF
});
speedText.anchor.set(0, 0);
speedText.x = 100;
speedText.y = 100;
LK.gui.topLeft.addChild(speedText);
var distanceText = new Text2('DISTANCE: 0', {
size: 60,
fill: 0xFFFFFF
});
distanceText.anchor.set(0.5, 0);
LK.gui.top.addChild(distanceText);
var positionText = new Text2('POSITION: 1st', {
size: 60,
fill: 0xFFFF00
});
positionText.anchor.set(1, 0);
positionText.x = -100;
positionText.y = 100;
LK.gui.topRight.addChild(positionText);
// Create player car
playerCar = game.addChild(new PlayerCar());
playerCar.x = 2048 / 2;
playerCar.y = 2732 - 300;
// Touch controls
var touchStartX = 0;
var touchStartY = 0;
var isTouching = false;
game.down = function (x, y, obj) {
touchStartX = x;
touchStartY = y;
isTouching = true;
// Tap to activate nitro
if (!playerCar.isNitro) {
playerCar.activateNitro();
}
};
game.move = function (x, y, obj) {
if (isTouching) {
var deltaX = x - touchStartX;
var deltaY = y - touchStartY;
// Swipe detection for lane changes
if (Math.abs(deltaX) > 100 && Math.abs(deltaX) > Math.abs(deltaY)) {
if (deltaX > 0 && playerCar.lane < 2) {
playerCar.moveToLane(playerCar.lane + 1);
touchStartX = x; // Reset to prevent multiple lane changes
} else if (deltaX < 0 && playerCar.lane > 0) {
playerCar.moveToLane(playerCar.lane - 1);
touchStartX = x; // Reset to prevent multiple lane changes
}
}
}
};
game.up = function (x, y, obj) {
isTouching = false;
};
// Create initial track lines
function createTrackLines() {
for (var i = 0; i < 30; i++) {
var line = new TrackLine();
line.x = 2048 * 0.167; // Left lane divider
line.y = i * 150 - 500;
trackLines.push(line);
game.addChild(line);
var line2 = new TrackLine();
line2.x = 2048 * 0.5; // Center lane divider
line2.y = i * 150 - 500;
trackLines.push(line2);
game.addChild(line2);
var line3 = new TrackLine();
line3.x = 2048 * 0.833; // Right lane divider
line3.y = i * 150 - 500;
trackLines.push(line3);
game.addChild(line3);
}
}
createTrackLines();
// Spawn enemy cars
function spawnEnemyCar() {
var enemyCar = new EnemyCar();
enemyCar.x = lanePositions[enemyCar.lane];
enemyCar.y = -100;
enemyCars.push(enemyCar);
game.addChild(enemyCar);
}
// Spawn obstacles
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.x = lanePositions[Math.floor(Math.random() * 3)];
obstacle.y = -100;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn nitro pickups
function spawnNitroPickup() {
var nitro = new NitroPickup();
nitro.x = lanePositions[Math.floor(Math.random() * 3)];
nitro.y = -100;
nitroPickups.push(nitro);
game.addChild(nitro);
}
// Play background music
LK.playMusic('race_music');
// Main game update
game.update = function () {
if (!isGameRunning) return;
// Update race distance
raceDistance += currentSpeed;
currentSpeed = playerCar.speed;
// Update UI
speedText.setText('SPEED: ' + Math.floor(currentSpeed * 10));
distanceText.setText('DISTANCE: ' + Math.floor(raceDistance / 50) + 'm');
// Check win condition
if (raceDistance >= totalRaceDistance) {
isGameRunning = false;
LK.showYouWin();
return;
}
// Spawn enemies
if (LK.ticks % 90 === 0) {
spawnEnemyCar();
}
// Spawn obstacles
if (LK.ticks % 120 === 0) {
spawnObstacle();
}
// Spawn nitro pickups
if (LK.ticks % 300 === 0) {
spawnNitroPickup();
}
// Update and check enemy cars
for (var i = enemyCars.length - 1; i >= 0; i--) {
var enemy = enemyCars[i];
if (enemy.lastY === undefined) enemy.lastY = enemy.y;
// Remove off-screen enemies
if (enemy.lastY < 2732 && enemy.y >= 2732) {
enemy.destroy();
enemyCars.splice(i, 1);
continue;
}
// Check collision with player
if (enemy.intersects(playerCar)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 500);
isGameRunning = false;
LK.showGameOver();
return;
}
enemy.lastY = enemy.y;
}
// Update and check obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.lastY === undefined) obstacle.lastY = obstacle.y;
// Remove off-screen obstacles
if (obstacle.lastY < 2732 && obstacle.y >= 2732) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Check collision with player
if (obstacle.intersects(playerCar)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 500);
isGameRunning = false;
LK.showGameOver();
return;
}
obstacle.lastY = obstacle.y;
}
// Update and check nitro pickups
for (var i = nitroPickups.length - 1; i >= 0; i--) {
var nitro = nitroPickups[i];
if (nitro.lastY === undefined) nitro.lastY = nitro.y;
if (nitro.lastCollected === undefined) nitro.lastCollected = false;
// Remove off-screen nitro
if (nitro.lastY < 2732 && nitro.y >= 2732) {
nitro.destroy();
nitroPickups.splice(i, 1);
continue;
}
// Check collection by player
var currentCollected = nitro.intersects(playerCar);
if (!nitro.lastCollected && currentCollected) {
LK.setScore(LK.getScore() + 100);
playerCar.activateNitro();
nitro.destroy();
nitroPickups.splice(i, 1);
continue;
}
nitro.lastY = nitro.y;
nitro.lastCollected = currentCollected;
}
// Update and recycle track lines
for (var i = trackLines.length - 1; i >= 0; i--) {
var line = trackLines[i];
if (line.y > 2732 + 100) {
line.y = -100;
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var EnemyCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('enemy_car', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4 + Math.random() * 4;
self.lane = Math.floor(Math.random() * 3);
self.update = function () {
self.y += self.speed;
};
return self;
});
var NitroPickup = Container.expand(function () {
var self = Container.call(this);
var nitroGraphics = self.attachAsset('nitro_pickup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.rotationSpeed = 0.1;
self.update = function () {
self.y += self.speed;
nitroGraphics.rotation += self.rotationSpeed;
// Pulsing effect
var scale = 1 + Math.sin(LK.ticks * 0.2) * 0.2;
nitroGraphics.scaleX = scale;
nitroGraphics.scaleY = scale;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('player_car', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1; // 0 = left, 1 = center, 2 = right
self.speed = 8;
self.baseSpeed = 8;
self.nitroSpeed = 16;
self.isNitro = false;
self.nitroTime = 0;
self.targetX = 2048 / 2;
self.moveToLane = function (newLane) {
if (newLane >= 0 && newLane <= 2) {
self.lane = newLane;
var lanePositions = [2048 * 0.25, 2048 * 0.5, 2048 * 0.75];
self.targetX = lanePositions[newLane];
}
};
self.activateNitro = function () {
if (!self.isNitro) {
self.isNitro = true;
self.nitroTime = 180; // 3 seconds at 60fps
self.speed = self.nitroSpeed;
carGraphics.tint = 0xffff00;
LK.getSound('nitro').play();
}
};
self.update = function () {
// Move towards target lane
var diff = self.targetX - self.x;
if (Math.abs(diff) > 5) {
self.x += diff * 0.15;
}
// Handle nitro
if (self.isNitro) {
self.nitroTime--;
if (self.nitroTime <= 0) {
self.isNitro = false;
self.speed = self.baseSpeed;
carGraphics.tint = 0xffffff;
}
}
// Create speed trail effect
if (LK.ticks % 5 === 0) {
var trail = LK.getAsset('player_car', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3,
scaleX: 0.8,
scaleY: 0.8
});
trail.x = self.x;
trail.y = self.y + 50;
trail.tint = self.isNitro ? 0xffff00 : 0x00ffff;
game.addChild(trail);
tween(trail, {
alpha: 0,
y: trail.y + 100
}, {
duration: 500,
onFinish: function onFinish() {
trail.destroy();
}
});
}
};
return self;
});
var TrackLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('track_line', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a1a
});
/****
* Game Code
****/
// Game variables
var playerCar;
var enemyCars = [];
var obstacles = [];
var nitroPickups = [];
var trackLines = [];
var raceDistance = 0;
var totalRaceDistance = 5000;
var currentSpeed = 8;
var isGameRunning = true;
// Lane positions
var lanePositions = [2048 * 0.25, 2048 * 0.5, 2048 * 0.75];
// UI Elements
var speedText = new Text2('SPEED: 0', {
size: 60,
fill: 0x00FFFF
});
speedText.anchor.set(0, 0);
speedText.x = 100;
speedText.y = 100;
LK.gui.topLeft.addChild(speedText);
var distanceText = new Text2('DISTANCE: 0', {
size: 60,
fill: 0xFFFFFF
});
distanceText.anchor.set(0.5, 0);
LK.gui.top.addChild(distanceText);
var positionText = new Text2('POSITION: 1st', {
size: 60,
fill: 0xFFFF00
});
positionText.anchor.set(1, 0);
positionText.x = -100;
positionText.y = 100;
LK.gui.topRight.addChild(positionText);
// Create player car
playerCar = game.addChild(new PlayerCar());
playerCar.x = 2048 / 2;
playerCar.y = 2732 - 300;
// Touch controls
var touchStartX = 0;
var touchStartY = 0;
var isTouching = false;
game.down = function (x, y, obj) {
touchStartX = x;
touchStartY = y;
isTouching = true;
// Tap to activate nitro
if (!playerCar.isNitro) {
playerCar.activateNitro();
}
};
game.move = function (x, y, obj) {
if (isTouching) {
var deltaX = x - touchStartX;
var deltaY = y - touchStartY;
// Swipe detection for lane changes
if (Math.abs(deltaX) > 100 && Math.abs(deltaX) > Math.abs(deltaY)) {
if (deltaX > 0 && playerCar.lane < 2) {
playerCar.moveToLane(playerCar.lane + 1);
touchStartX = x; // Reset to prevent multiple lane changes
} else if (deltaX < 0 && playerCar.lane > 0) {
playerCar.moveToLane(playerCar.lane - 1);
touchStartX = x; // Reset to prevent multiple lane changes
}
}
}
};
game.up = function (x, y, obj) {
isTouching = false;
};
// Create initial track lines
function createTrackLines() {
for (var i = 0; i < 30; i++) {
var line = new TrackLine();
line.x = 2048 * 0.167; // Left lane divider
line.y = i * 150 - 500;
trackLines.push(line);
game.addChild(line);
var line2 = new TrackLine();
line2.x = 2048 * 0.5; // Center lane divider
line2.y = i * 150 - 500;
trackLines.push(line2);
game.addChild(line2);
var line3 = new TrackLine();
line3.x = 2048 * 0.833; // Right lane divider
line3.y = i * 150 - 500;
trackLines.push(line3);
game.addChild(line3);
}
}
createTrackLines();
// Spawn enemy cars
function spawnEnemyCar() {
var enemyCar = new EnemyCar();
enemyCar.x = lanePositions[enemyCar.lane];
enemyCar.y = -100;
enemyCars.push(enemyCar);
game.addChild(enemyCar);
}
// Spawn obstacles
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.x = lanePositions[Math.floor(Math.random() * 3)];
obstacle.y = -100;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn nitro pickups
function spawnNitroPickup() {
var nitro = new NitroPickup();
nitro.x = lanePositions[Math.floor(Math.random() * 3)];
nitro.y = -100;
nitroPickups.push(nitro);
game.addChild(nitro);
}
// Play background music
LK.playMusic('race_music');
// Main game update
game.update = function () {
if (!isGameRunning) return;
// Update race distance
raceDistance += currentSpeed;
currentSpeed = playerCar.speed;
// Update UI
speedText.setText('SPEED: ' + Math.floor(currentSpeed * 10));
distanceText.setText('DISTANCE: ' + Math.floor(raceDistance / 50) + 'm');
// Check win condition
if (raceDistance >= totalRaceDistance) {
isGameRunning = false;
LK.showYouWin();
return;
}
// Spawn enemies
if (LK.ticks % 90 === 0) {
spawnEnemyCar();
}
// Spawn obstacles
if (LK.ticks % 120 === 0) {
spawnObstacle();
}
// Spawn nitro pickups
if (LK.ticks % 300 === 0) {
spawnNitroPickup();
}
// Update and check enemy cars
for (var i = enemyCars.length - 1; i >= 0; i--) {
var enemy = enemyCars[i];
if (enemy.lastY === undefined) enemy.lastY = enemy.y;
// Remove off-screen enemies
if (enemy.lastY < 2732 && enemy.y >= 2732) {
enemy.destroy();
enemyCars.splice(i, 1);
continue;
}
// Check collision with player
if (enemy.intersects(playerCar)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 500);
isGameRunning = false;
LK.showGameOver();
return;
}
enemy.lastY = enemy.y;
}
// Update and check obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.lastY === undefined) obstacle.lastY = obstacle.y;
// Remove off-screen obstacles
if (obstacle.lastY < 2732 && obstacle.y >= 2732) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Check collision with player
if (obstacle.intersects(playerCar)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 500);
isGameRunning = false;
LK.showGameOver();
return;
}
obstacle.lastY = obstacle.y;
}
// Update and check nitro pickups
for (var i = nitroPickups.length - 1; i >= 0; i--) {
var nitro = nitroPickups[i];
if (nitro.lastY === undefined) nitro.lastY = nitro.y;
if (nitro.lastCollected === undefined) nitro.lastCollected = false;
// Remove off-screen nitro
if (nitro.lastY < 2732 && nitro.y >= 2732) {
nitro.destroy();
nitroPickups.splice(i, 1);
continue;
}
// Check collection by player
var currentCollected = nitro.intersects(playerCar);
if (!nitro.lastCollected && currentCollected) {
LK.setScore(LK.getScore() + 100);
playerCar.activateNitro();
nitro.destroy();
nitroPickups.splice(i, 1);
continue;
}
nitro.lastY = nitro.y;
nitro.lastCollected = currentCollected;
}
// Update and recycle track lines
for (var i = trackLines.length - 1; i >= 0; i--) {
var line = trackLines[i];
if (line.y > 2732 + 100) {
line.y = -100;
}
}
};