/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var AICar = Container.expand(function () { var self = Container.call(this); var carGraphics = self.attachAsset('aiCar', { anchorX: 0.5, anchorY: 0.5 }); self.lane = Math.floor(Math.random() * 3); self.speed = (8 + Math.random() * 4) * 0.8; self.update = function () { self.y += self.speed; // Random lane changes if (Math.random() < 0.005) { var newLane = Math.floor(Math.random() * 3); if (newLane !== self.lane) { self.lane = newLane; tween(self, { x: 600 + self.lane * 400 }, { duration: 400, easing: tween.easeInOut }); } } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -20; self.update = function () { self.y += self.speed; }; return self; }); var BulletPowerup = Container.expand(function () { var self = Container.call(this); var bulletPowerupGraphics = self.attachAsset('bulletPowerup', { anchorX: 0.5, anchorY: 0.5 }); self.lane = Math.floor(Math.random() * 3); self.speed = 10; self.update = function () { self.y += self.speed; }; return self; }); var NitroPowerup = Container.expand(function () { var self = Container.call(this); var nitroGraphics = self.attachAsset('nitro', { anchorX: 0.5, anchorY: 0.5 }); self.lane = Math.floor(Math.random() * 3); self.speed = 10; self.update = function () { self.y += self.speed; }; return self; }); var PlayerCar = Container.expand(function () { var self = Container.call(this); self.carType = storage.selectedCar || 'car1'; var carGraphics = self.attachAsset(self.carType, { anchorX: 0.5, anchorY: 0.5 }); self.lane = 1; // 0, 1, 2 for three lanes self.nitroActive = false; self.nitroTime = 0; self.speed = 10; self.baseSpeed = 10; self.maxSpeed = 20; self.minSpeed = 5; self.nitroCount = 0; self.bulletCount = 0; self.update = function () { if (self.nitroActive) { self.nitroTime--; if (self.nitroTime <= 0) { self.nitroActive = false; self.speed = 10; } } }; self.changeLane = function (direction) { if (direction === 'left' && self.lane > 0) { self.lane--; tween(self, { x: 600 + self.lane * 400 }, { duration: 200, easing: tween.easeOut }); } else if (direction === 'right' && self.lane < 2) { self.lane++; tween(self, { x: 600 + self.lane * 400 }, { duration: 200, easing: tween.easeOut }); } }; self.activateNitro = function () { if (!self.nitroActive) { self.nitroActive = true; self.nitroTime = 180; // 3 seconds at 60fps self.speed = 20; LK.effects.flashObject(self, 0xffff00, 500); } }; self.accelerate = function () { if (!self.nitroActive && self.speed < self.maxSpeed) { self.speed = Math.min(self.speed + 0.5, self.maxSpeed); } }; self.brake = function () { if (!self.nitroActive && self.speed > self.minSpeed) { self.speed = Math.max(self.speed - 0.5, self.minSpeed); } }; return self; }); var TrackLine = Container.expand(function () { var self = Container.call(this); var lineGraphics = self.attachAsset('trackLine', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2d5016 }); /**** * Game Code ****/ // Game states var gameState = 'menu'; // menu, playing, rearview var selectedMenuOption = 0; var selectedCarOption = storage.selectedCar || 'car1'; var audioEnabled = storage.audioEnabled !== false; var raceTime = 0; var trackType = 0; // Game containers var menuContainer = null; var gameContainer = null; var uiContainer = null; // Game objects var player = null; var aiCars = []; var nitroPowerups = []; var bulletPowerups = []; var trackLines = []; var bullets = []; // UI elements var timerText = null; var nitroCounterText = null; var bulletCounterText = null; var minimap = null; var dpadLeft = null; var dpadRight = null; var buttonA = null; var buttonB = null; function createMainMenu() { menuContainer = game.addChild(new Container()); menuContainer.interactive = true; if (audioEnabled) { LK.playMusic('menuMusic'); } var bg = menuContainer.attachAsset('menuBg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); var titleText = new Text2('RETRO RACER', { size: 200, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 400; menuContainer.addChild(titleText); // Menu options var menuOptions = ['GAME PLAY', 'OPTIONS', 'EXIT']; var menuButtons = []; for (var i = 0; i < menuOptions.length; i++) { var button = menuContainer.attachAsset('menuButton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 900 + i * 200 }); button.interactive = true; button.buttonDown = true; button.menuIndex = i; var buttonText = new Text2(menuOptions[i], { size: 60, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); buttonText.x = 1024; buttonText.y = 900 + i * 200; menuContainer.addChild(buttonText); menuButtons.push({ button: button, text: buttonText, index: i }); } // Highlight selected option function updateMenuSelection() { for (var i = 0; i < menuButtons.length; i++) { if (i === selectedMenuOption) { menuButtons[i].button.tint = 0x8bac0f; menuButtons[i].text.tint = 0x000000; } else { menuButtons[i].button.tint = 0xffffff; menuButtons[i].text.tint = 0xffffff; } } } updateMenuSelection(); // Add event handlers to individual buttons for (var i = 0; i < menuButtons.length; i++) { (function (index) { menuButtons[index].button.down = function (x, y, obj) { if (audioEnabled) { LK.getSound('menuClick').play(); } selectedMenuOption = index; updateMenuSelection(); selectMenuOption(); }; })(i); } } function createOptionsMenu() { menuContainer = game.addChild(new Container()); menuContainer.interactive = true; var bg = menuContainer.attachAsset('menuBg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); var titleText = new Text2('OPTIONS', { size: 120, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 400; menuContainer.addChild(titleText); // Car selection var carText = new Text2('SELECT CAR:', { size: 60, fill: 0x8BAC0F }); carText.anchor.set(0.5, 0.5); carText.x = 1024; carText.y = 700; menuContainer.addChild(carText); var carOptions = ['car1', 'car2', 'car3']; var carButtons = []; for (var i = 0; i < carOptions.length; i++) { var carButton = menuContainer.attachAsset(carOptions[i], { anchorX: 0.5, anchorY: 0.5, x: 700 + i * 300, y: 900 }); carButton.interactive = true; carButton.buttonDown = true; carButton.carType = carOptions[i]; if (carOptions[i] === selectedCarOption) { carButton.scale.set(1.5); } carButtons.push({ button: carButton, type: carOptions[i] }); } // Audio toggle var audioText = new Text2('AUDIO: ' + (audioEnabled ? 'ON' : 'OFF'), { size: 60, fill: 0xFFFFFF }); audioText.anchor.set(0.5, 0.5); audioText.x = 1024; audioText.y = 1200; menuContainer.addChild(audioText); // Audio toggle button var audioButton = menuContainer.attachAsset('menuButton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1200 }); audioButton.interactive = true; audioButton.buttonDown = true; // Back button var backButton = menuContainer.attachAsset('menuButton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1600 }); backButton.interactive = true; backButton.buttonDown = true; var backText = new Text2('BACK', { size: 60, fill: 0xFFFFFF }); backText.anchor.set(0.5, 0.5); backText.x = 1024; backText.y = 1600; menuContainer.addChild(backText); // Add event handlers to car buttons for (var i = 0; i < carButtons.length; i++) { (function (index) { carButtons[index].button.down = function (x, y, obj) { if (audioEnabled) { LK.getSound('menuClick').play(); } selectedCarOption = carButtons[index].type; storage.selectedCar = selectedCarOption; menuContainer.destroy(); createOptionsMenu(); }; })(i); } // Add event handler to audio button audioButton.down = function (x, y, obj) { if (audioEnabled) { LK.getSound('menuClick').play(); } audioEnabled = !audioEnabled; storage.audioEnabled = audioEnabled; audioText.text = 'AUDIO: ' + (audioEnabled ? 'ON' : 'OFF'); }; // Add event handler to back button backButton.down = function (x, y, obj) { if (audioEnabled) { LK.getSound('menuClick').play(); } menuContainer.destroy(); createMainMenu(); }; } function selectMenuOption() { if (selectedMenuOption === 0) { // Game Play menuContainer.destroy(); startGame(); } else if (selectedMenuOption === 1) { // Options menuContainer.destroy(); createOptionsMenu(); } else if (selectedMenuOption === 2) { // Exit LK.showGameOver(); } } function startGame() { gameState = 'playing'; raceTime = 0; if (audioEnabled) { LK.playMusic('raceMusic'); } // Create game container gameContainer = game.addChild(new Container()); // Create track var track = gameContainer.attachAsset('track', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); gameContainer.setChildIndex(track, 0); // Send track to bottom layer // Create player player = gameContainer.addChild(new PlayerCar()); player.x = 600 + player.lane * 400; player.y = 1700; // Create UI createUI(); // Start spawning game objects spawnTrackLines(); spawnAICars(); spawnNitroPowerups(); spawnBulletPowerups(); } function createUI() { uiContainer = game.addChild(new Container()); uiContainer.interactive = true; // Timer timerText = new Text2('TIME: 0:00', { size: 60, fill: 0x000000 }); timerText.anchor.set(1, 0); timerText.x = 1948; timerText.y = 150; uiContainer.addChild(timerText); // Nitro counter nitroCounterText = new Text2('NITRO: 0', { size: 50, fill: 0x000000 }); nitroCounterText.anchor.set(1, 0); nitroCounterText.x = 1948; nitroCounterText.y = 220; uiContainer.addChild(nitroCounterText); // Bullet counter bulletCounterText = new Text2('BULLETS: 0', { size: 50, fill: 0x000000 }); bulletCounterText.anchor.set(1, 0); bulletCounterText.x = 1948; bulletCounterText.y = 290; uiContainer.addChild(bulletCounterText); // Minimap minimap = uiContainer.attachAsset('minimap', { anchorX: 0, anchorY: 0, x: 150, y: 150 }); var playerDot = uiContainer.attachAsset('minimapDot', { anchorX: 0.5, anchorY: 0.5, x: 300, y: 500 }); // D-pad buttons only (no base) - further increased spacing for larger D-pad area dpadLeft = uiContainer.attachAsset('leftButton', { anchorX: 0.5, anchorY: 0.5, x: 180, y: 2300, alpha: 0.5 }); dpadLeft.interactive = true; dpadLeft.buttonDown = true; dpadRight = uiContainer.attachAsset('rightButton', { anchorX: 0.5, anchorY: 0.5, x: 620, y: 2300, alpha: 0.5 }); dpadRight.interactive = true; dpadRight.buttonDown = true; var dpadUp = uiContainer.attachAsset('upButton', { anchorX: 0.5, anchorY: 0.5, x: 400, y: 2080, alpha: 0.5 }); dpadUp.interactive = true; dpadUp.buttonDown = true; var dpadDown = uiContainer.attachAsset('downButton', { anchorX: 0.5, anchorY: 0.5, x: 400, y: 2520, alpha: 0.5 }); dpadDown.interactive = true; dpadDown.buttonDown = true; // A/B buttons buttonA = uiContainer.attachAsset('aButton', { anchorX: 0.5, anchorY: 0.5, x: 1850, y: 2350, alpha: 0.5 }); buttonA.interactive = true; buttonA.buttonDown = true; var aText = new Text2('A', { size: 40, fill: 0xFFFFFF }); aText.anchor.set(0.5, 0.5); aText.x = 1850; aText.y = 2350; uiContainer.addChild(aText); buttonB = uiContainer.attachAsset('bButton', { anchorX: 0.5, anchorY: 0.5, x: 1450, y: 2480, alpha: 0.5 }); buttonB.interactive = true; buttonB.buttonDown = true; var bText = new Text2('B', { size: 40, fill: 0xFFFFFF }); bText.anchor.set(0.5, 0.5); bText.x = 1450; bText.y = 2480; uiContainer.addChild(bText); // Add event handlers to UI buttons dpadLeft.down = function (x, y, obj) { player.changeLane('left'); dpadLeft.alpha = 0.8; }; dpadLeft.up = function (x, y, obj) { dpadLeft.alpha = 0.5; }; dpadRight.down = function (x, y, obj) { player.changeLane('right'); dpadRight.alpha = 0.8; }; dpadRight.up = function (x, y, obj) { dpadRight.alpha = 0.5; }; buttonA.down = function (x, y, obj) { if (player.nitroCount > 0) { player.activateNitro(); player.nitroCount--; nitroCounterText.setText('NITRO: ' + player.nitroCount); } buttonA.alpha = 0.8; }; buttonA.up = function (x, y, obj) { buttonA.alpha = 0.5; }; buttonB.down = function (x, y, obj) { fireBullet(); buttonB.alpha = 0.8; }; buttonB.up = function (x, y, obj) { buttonB.alpha = 0.5; }; dpadUp.down = function (x, y, obj) { player.accelerate(); dpadUp.alpha = 0.8; }; dpadUp.up = function (x, y, obj) { dpadUp.alpha = 0.5; }; dpadDown.down = function (x, y, obj) { player.brake(); dpadDown.alpha = 0.8; }; dpadDown.up = function (x, y, obj) { dpadDown.alpha = 0.5; }; } function fireBullet() { if (gameState === 'playing' && player.bulletCount > 0) { var bullet = gameContainer.addChild(new Bullet()); bullet.x = player.x; bullet.y = player.y - 100; bullets.push(bullet); player.bulletCount--; bulletCounterText.setText('BULLETS: ' + player.bulletCount); } } function toggleRearView() { if (gameState === 'playing') { gameState = 'rearview'; // Flip view gameContainer.scale.y = -1; gameContainer.y = 2732; } else if (gameState === 'rearview') { gameState = 'playing'; // Restore view gameContainer.scale.y = 1; gameContainer.y = 0; } } function spawnTrackLines() { var lineTimer = LK.setInterval(function () { if (gameState !== 'menu') { // Calculate spawn interval based on player speed to maintain consistent spacing var shouldSpawn = trackLines.length === 0 || trackLines[trackLines.length - 1] && trackLines[trackLines.length - 1].y > 200; if (shouldSpawn) { for (var i = 0; i < 3; i++) { var line = gameContainer.addChild(new TrackLine()); line.x = 600 + i * 400; line.y = -100; line.speed = player.speed; gameContainer.setChildIndex(line, 1); // Send tracklines above track but below other elements trackLines.push(line); } } } }, 100); // Check more frequently for spawning } function spawnAICars() { var carTimer = LK.setInterval(function () { if (gameState !== 'menu' && aiCars.length < 5) { var aiCar = gameContainer.addChild(new AICar()); aiCar.x = 600 + aiCar.lane * 400; aiCar.y = -200; aiCars.push(aiCar); } }, 2000); } function spawnNitroPowerups() { var nitroTimer = LK.setInterval(function () { if (gameState !== 'menu') { var nitro = gameContainer.addChild(new NitroPowerup()); nitro.x = 600 + nitro.lane * 400; nitro.y = -100; nitro.speed = player.speed; nitroPowerups.push(nitro); } }, 5000); } function spawnBulletPowerups() { var bulletTimer = LK.setInterval(function () { if (gameState !== 'menu') { var bulletPowerup = gameContainer.addChild(new BulletPowerup()); bulletPowerup.x = 600 + bulletPowerup.lane * 400; bulletPowerup.y = -100; bulletPowerup.speed = player.speed; bulletPowerups.push(bulletPowerup); } }, 3000); } function completeRace() { trackType = (trackType + 1) % 3; // Change track color based on type var trackColors = [0x4a4a4a, 0x8b4513, 0x2f4f4f]; game.setBackgroundColor(trackColors[trackType]); // Reset race raceTime = 0; // Clear existing objects for (var i = aiCars.length - 1; i >= 0; i--) { aiCars[i].destroy(); } aiCars = []; for (var j = nitroPowerups.length - 1; j >= 0; j--) { nitroPowerups[j].destroy(); } nitroPowerups = []; for (var k = bulletPowerups.length - 1; k >= 0; k--) { bulletPowerups[k].destroy(); } bulletPowerups = []; } // Main game update game.update = function () { if (gameState === 'menu') return; // Update timer raceTime++; var minutes = Math.floor(raceTime / 3600); var seconds = Math.floor(raceTime % 3600 / 60); timerText.setText('TIME: ' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds); // Update track lines for (var i = trackLines.length - 1; i >= 0; i--) { var line = trackLines[i]; line.speed = player.speed; if (line.y > 2832) { line.destroy(); trackLines.splice(i, 1); } } // Update bullets for (var b = bullets.length - 1; b >= 0; b--) { var bullet = bullets[b]; if (bullet.y < -100) { bullet.destroy(); bullets.splice(b, 1); continue; } // Check bullet collision with AI cars for (var c = aiCars.length - 1; c >= 0; c--) { var aiCar = aiCars[c]; if (bullet.intersects(aiCar)) { if (audioEnabled) { LK.getSound('explosion').play(); } // Explosion effect LK.effects.flashObject(aiCar, 0xff4500, 300); tween(aiCar, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 300, onFinish: function onFinish() { aiCar.destroy(); } }); aiCars.splice(c, 1); bullet.destroy(); bullets.splice(b, 1); break; } } } // Update AI cars for (var j = aiCars.length - 1; j >= 0; j--) { var aiCar = aiCars[j]; if (aiCar.y > 2832) { aiCar.destroy(); aiCars.splice(j, 1); continue; } // Check collision with player if (player.intersects(aiCar)) { if (audioEnabled) { LK.getSound('crash').play(); } LK.effects.flashScreen(0xff0000, 500); LK.showGameOver(); } } // Update nitro powerups for (var k = nitroPowerups.length - 1; k >= 0; k--) { var nitro = nitroPowerups[k]; nitro.speed = player.speed; if (nitro.y > 2832) { nitro.destroy(); nitroPowerups.splice(k, 1); continue; } // Check collection if (player.intersects(nitro)) { if (audioEnabled) { LK.getSound('coinPickup').play(); } // Increase nitro and bullet counts player.nitroCount++; player.bulletCount += 3; nitroCounterText.setText('NITRO: ' + player.nitroCount); bulletCounterText.setText('BULLETS: ' + player.bulletCount); nitro.destroy(); nitroPowerups.splice(k, 1); } } // Update bullet powerups for (var l = bulletPowerups.length - 1; l >= 0; l--) { var bulletPowerup = bulletPowerups[l]; bulletPowerup.speed = player.speed; if (bulletPowerup.y > 2832) { bulletPowerup.destroy(); bulletPowerups.splice(l, 1); continue; } // Check collection if (player.intersects(bulletPowerup)) { if (audioEnabled) { LK.getSound('coinPickup').play(); } // Increase bullet count only player.bulletCount += 5; bulletCounterText.setText('BULLETS: ' + player.bulletCount); bulletPowerup.destroy(); bulletPowerups.splice(l, 1); } } // Complete race after 2 minutes if (raceTime >= 7200) { completeRace(); } }; // Start with main menu createMainMenu();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var AICar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('aiCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = Math.floor(Math.random() * 3);
self.speed = (8 + Math.random() * 4) * 0.8;
self.update = function () {
self.y += self.speed;
// Random lane changes
if (Math.random() < 0.005) {
var newLane = Math.floor(Math.random() * 3);
if (newLane !== self.lane) {
self.lane = newLane;
tween(self, {
x: 600 + self.lane * 400
}, {
duration: 400,
easing: tween.easeInOut
});
}
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -20;
self.update = function () {
self.y += self.speed;
};
return self;
});
var BulletPowerup = Container.expand(function () {
var self = Container.call(this);
var bulletPowerupGraphics = self.attachAsset('bulletPowerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = Math.floor(Math.random() * 3);
self.speed = 10;
self.update = function () {
self.y += self.speed;
};
return self;
});
var NitroPowerup = Container.expand(function () {
var self = Container.call(this);
var nitroGraphics = self.attachAsset('nitro', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = Math.floor(Math.random() * 3);
self.speed = 10;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
self.carType = storage.selectedCar || 'car1';
var carGraphics = self.attachAsset(self.carType, {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1; // 0, 1, 2 for three lanes
self.nitroActive = false;
self.nitroTime = 0;
self.speed = 10;
self.baseSpeed = 10;
self.maxSpeed = 20;
self.minSpeed = 5;
self.nitroCount = 0;
self.bulletCount = 0;
self.update = function () {
if (self.nitroActive) {
self.nitroTime--;
if (self.nitroTime <= 0) {
self.nitroActive = false;
self.speed = 10;
}
}
};
self.changeLane = function (direction) {
if (direction === 'left' && self.lane > 0) {
self.lane--;
tween(self, {
x: 600 + self.lane * 400
}, {
duration: 200,
easing: tween.easeOut
});
} else if (direction === 'right' && self.lane < 2) {
self.lane++;
tween(self, {
x: 600 + self.lane * 400
}, {
duration: 200,
easing: tween.easeOut
});
}
};
self.activateNitro = function () {
if (!self.nitroActive) {
self.nitroActive = true;
self.nitroTime = 180; // 3 seconds at 60fps
self.speed = 20;
LK.effects.flashObject(self, 0xffff00, 500);
}
};
self.accelerate = function () {
if (!self.nitroActive && self.speed < self.maxSpeed) {
self.speed = Math.min(self.speed + 0.5, self.maxSpeed);
}
};
self.brake = function () {
if (!self.nitroActive && self.speed > self.minSpeed) {
self.speed = Math.max(self.speed - 0.5, self.minSpeed);
}
};
return self;
});
var TrackLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('trackLine', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5016
});
/****
* Game Code
****/
// Game states
var gameState = 'menu'; // menu, playing, rearview
var selectedMenuOption = 0;
var selectedCarOption = storage.selectedCar || 'car1';
var audioEnabled = storage.audioEnabled !== false;
var raceTime = 0;
var trackType = 0;
// Game containers
var menuContainer = null;
var gameContainer = null;
var uiContainer = null;
// Game objects
var player = null;
var aiCars = [];
var nitroPowerups = [];
var bulletPowerups = [];
var trackLines = [];
var bullets = [];
// UI elements
var timerText = null;
var nitroCounterText = null;
var bulletCounterText = null;
var minimap = null;
var dpadLeft = null;
var dpadRight = null;
var buttonA = null;
var buttonB = null;
function createMainMenu() {
menuContainer = game.addChild(new Container());
menuContainer.interactive = true;
if (audioEnabled) {
LK.playMusic('menuMusic');
}
var bg = menuContainer.attachAsset('menuBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
var titleText = new Text2('RETRO RACER', {
size: 200,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
menuContainer.addChild(titleText);
// Menu options
var menuOptions = ['GAME PLAY', 'OPTIONS', 'EXIT'];
var menuButtons = [];
for (var i = 0; i < menuOptions.length; i++) {
var button = menuContainer.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 900 + i * 200
});
button.interactive = true;
button.buttonDown = true;
button.menuIndex = i;
var buttonText = new Text2(menuOptions[i], {
size: 60,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = 1024;
buttonText.y = 900 + i * 200;
menuContainer.addChild(buttonText);
menuButtons.push({
button: button,
text: buttonText,
index: i
});
}
// Highlight selected option
function updateMenuSelection() {
for (var i = 0; i < menuButtons.length; i++) {
if (i === selectedMenuOption) {
menuButtons[i].button.tint = 0x8bac0f;
menuButtons[i].text.tint = 0x000000;
} else {
menuButtons[i].button.tint = 0xffffff;
menuButtons[i].text.tint = 0xffffff;
}
}
}
updateMenuSelection();
// Add event handlers to individual buttons
for (var i = 0; i < menuButtons.length; i++) {
(function (index) {
menuButtons[index].button.down = function (x, y, obj) {
if (audioEnabled) {
LK.getSound('menuClick').play();
}
selectedMenuOption = index;
updateMenuSelection();
selectMenuOption();
};
})(i);
}
}
function createOptionsMenu() {
menuContainer = game.addChild(new Container());
menuContainer.interactive = true;
var bg = menuContainer.attachAsset('menuBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
var titleText = new Text2('OPTIONS', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
menuContainer.addChild(titleText);
// Car selection
var carText = new Text2('SELECT CAR:', {
size: 60,
fill: 0x8BAC0F
});
carText.anchor.set(0.5, 0.5);
carText.x = 1024;
carText.y = 700;
menuContainer.addChild(carText);
var carOptions = ['car1', 'car2', 'car3'];
var carButtons = [];
for (var i = 0; i < carOptions.length; i++) {
var carButton = menuContainer.attachAsset(carOptions[i], {
anchorX: 0.5,
anchorY: 0.5,
x: 700 + i * 300,
y: 900
});
carButton.interactive = true;
carButton.buttonDown = true;
carButton.carType = carOptions[i];
if (carOptions[i] === selectedCarOption) {
carButton.scale.set(1.5);
}
carButtons.push({
button: carButton,
type: carOptions[i]
});
}
// Audio toggle
var audioText = new Text2('AUDIO: ' + (audioEnabled ? 'ON' : 'OFF'), {
size: 60,
fill: 0xFFFFFF
});
audioText.anchor.set(0.5, 0.5);
audioText.x = 1024;
audioText.y = 1200;
menuContainer.addChild(audioText);
// Audio toggle button
var audioButton = menuContainer.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200
});
audioButton.interactive = true;
audioButton.buttonDown = true;
// Back button
var backButton = menuContainer.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1600
});
backButton.interactive = true;
backButton.buttonDown = true;
var backText = new Text2('BACK', {
size: 60,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = 1024;
backText.y = 1600;
menuContainer.addChild(backText);
// Add event handlers to car buttons
for (var i = 0; i < carButtons.length; i++) {
(function (index) {
carButtons[index].button.down = function (x, y, obj) {
if (audioEnabled) {
LK.getSound('menuClick').play();
}
selectedCarOption = carButtons[index].type;
storage.selectedCar = selectedCarOption;
menuContainer.destroy();
createOptionsMenu();
};
})(i);
}
// Add event handler to audio button
audioButton.down = function (x, y, obj) {
if (audioEnabled) {
LK.getSound('menuClick').play();
}
audioEnabled = !audioEnabled;
storage.audioEnabled = audioEnabled;
audioText.text = 'AUDIO: ' + (audioEnabled ? 'ON' : 'OFF');
};
// Add event handler to back button
backButton.down = function (x, y, obj) {
if (audioEnabled) {
LK.getSound('menuClick').play();
}
menuContainer.destroy();
createMainMenu();
};
}
function selectMenuOption() {
if (selectedMenuOption === 0) {
// Game Play
menuContainer.destroy();
startGame();
} else if (selectedMenuOption === 1) {
// Options
menuContainer.destroy();
createOptionsMenu();
} else if (selectedMenuOption === 2) {
// Exit
LK.showGameOver();
}
}
function startGame() {
gameState = 'playing';
raceTime = 0;
if (audioEnabled) {
LK.playMusic('raceMusic');
}
// Create game container
gameContainer = game.addChild(new Container());
// Create track
var track = gameContainer.attachAsset('track', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
gameContainer.setChildIndex(track, 0); // Send track to bottom layer
// Create player
player = gameContainer.addChild(new PlayerCar());
player.x = 600 + player.lane * 400;
player.y = 1700;
// Create UI
createUI();
// Start spawning game objects
spawnTrackLines();
spawnAICars();
spawnNitroPowerups();
spawnBulletPowerups();
}
function createUI() {
uiContainer = game.addChild(new Container());
uiContainer.interactive = true;
// Timer
timerText = new Text2('TIME: 0:00', {
size: 60,
fill: 0x000000
});
timerText.anchor.set(1, 0);
timerText.x = 1948;
timerText.y = 150;
uiContainer.addChild(timerText);
// Nitro counter
nitroCounterText = new Text2('NITRO: 0', {
size: 50,
fill: 0x000000
});
nitroCounterText.anchor.set(1, 0);
nitroCounterText.x = 1948;
nitroCounterText.y = 220;
uiContainer.addChild(nitroCounterText);
// Bullet counter
bulletCounterText = new Text2('BULLETS: 0', {
size: 50,
fill: 0x000000
});
bulletCounterText.anchor.set(1, 0);
bulletCounterText.x = 1948;
bulletCounterText.y = 290;
uiContainer.addChild(bulletCounterText);
// Minimap
minimap = uiContainer.attachAsset('minimap', {
anchorX: 0,
anchorY: 0,
x: 150,
y: 150
});
var playerDot = uiContainer.attachAsset('minimapDot', {
anchorX: 0.5,
anchorY: 0.5,
x: 300,
y: 500
});
// D-pad buttons only (no base) - further increased spacing for larger D-pad area
dpadLeft = uiContainer.attachAsset('leftButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 180,
y: 2300,
alpha: 0.5
});
dpadLeft.interactive = true;
dpadLeft.buttonDown = true;
dpadRight = uiContainer.attachAsset('rightButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 620,
y: 2300,
alpha: 0.5
});
dpadRight.interactive = true;
dpadRight.buttonDown = true;
var dpadUp = uiContainer.attachAsset('upButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 400,
y: 2080,
alpha: 0.5
});
dpadUp.interactive = true;
dpadUp.buttonDown = true;
var dpadDown = uiContainer.attachAsset('downButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 400,
y: 2520,
alpha: 0.5
});
dpadDown.interactive = true;
dpadDown.buttonDown = true;
// A/B buttons
buttonA = uiContainer.attachAsset('aButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1850,
y: 2350,
alpha: 0.5
});
buttonA.interactive = true;
buttonA.buttonDown = true;
var aText = new Text2('A', {
size: 40,
fill: 0xFFFFFF
});
aText.anchor.set(0.5, 0.5);
aText.x = 1850;
aText.y = 2350;
uiContainer.addChild(aText);
buttonB = uiContainer.attachAsset('bButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1450,
y: 2480,
alpha: 0.5
});
buttonB.interactive = true;
buttonB.buttonDown = true;
var bText = new Text2('B', {
size: 40,
fill: 0xFFFFFF
});
bText.anchor.set(0.5, 0.5);
bText.x = 1450;
bText.y = 2480;
uiContainer.addChild(bText);
// Add event handlers to UI buttons
dpadLeft.down = function (x, y, obj) {
player.changeLane('left');
dpadLeft.alpha = 0.8;
};
dpadLeft.up = function (x, y, obj) {
dpadLeft.alpha = 0.5;
};
dpadRight.down = function (x, y, obj) {
player.changeLane('right');
dpadRight.alpha = 0.8;
};
dpadRight.up = function (x, y, obj) {
dpadRight.alpha = 0.5;
};
buttonA.down = function (x, y, obj) {
if (player.nitroCount > 0) {
player.activateNitro();
player.nitroCount--;
nitroCounterText.setText('NITRO: ' + player.nitroCount);
}
buttonA.alpha = 0.8;
};
buttonA.up = function (x, y, obj) {
buttonA.alpha = 0.5;
};
buttonB.down = function (x, y, obj) {
fireBullet();
buttonB.alpha = 0.8;
};
buttonB.up = function (x, y, obj) {
buttonB.alpha = 0.5;
};
dpadUp.down = function (x, y, obj) {
player.accelerate();
dpadUp.alpha = 0.8;
};
dpadUp.up = function (x, y, obj) {
dpadUp.alpha = 0.5;
};
dpadDown.down = function (x, y, obj) {
player.brake();
dpadDown.alpha = 0.8;
};
dpadDown.up = function (x, y, obj) {
dpadDown.alpha = 0.5;
};
}
function fireBullet() {
if (gameState === 'playing' && player.bulletCount > 0) {
var bullet = gameContainer.addChild(new Bullet());
bullet.x = player.x;
bullet.y = player.y - 100;
bullets.push(bullet);
player.bulletCount--;
bulletCounterText.setText('BULLETS: ' + player.bulletCount);
}
}
function toggleRearView() {
if (gameState === 'playing') {
gameState = 'rearview';
// Flip view
gameContainer.scale.y = -1;
gameContainer.y = 2732;
} else if (gameState === 'rearview') {
gameState = 'playing';
// Restore view
gameContainer.scale.y = 1;
gameContainer.y = 0;
}
}
function spawnTrackLines() {
var lineTimer = LK.setInterval(function () {
if (gameState !== 'menu') {
// Calculate spawn interval based on player speed to maintain consistent spacing
var shouldSpawn = trackLines.length === 0 || trackLines[trackLines.length - 1] && trackLines[trackLines.length - 1].y > 200;
if (shouldSpawn) {
for (var i = 0; i < 3; i++) {
var line = gameContainer.addChild(new TrackLine());
line.x = 600 + i * 400;
line.y = -100;
line.speed = player.speed;
gameContainer.setChildIndex(line, 1); // Send tracklines above track but below other elements
trackLines.push(line);
}
}
}
}, 100); // Check more frequently for spawning
}
function spawnAICars() {
var carTimer = LK.setInterval(function () {
if (gameState !== 'menu' && aiCars.length < 5) {
var aiCar = gameContainer.addChild(new AICar());
aiCar.x = 600 + aiCar.lane * 400;
aiCar.y = -200;
aiCars.push(aiCar);
}
}, 2000);
}
function spawnNitroPowerups() {
var nitroTimer = LK.setInterval(function () {
if (gameState !== 'menu') {
var nitro = gameContainer.addChild(new NitroPowerup());
nitro.x = 600 + nitro.lane * 400;
nitro.y = -100;
nitro.speed = player.speed;
nitroPowerups.push(nitro);
}
}, 5000);
}
function spawnBulletPowerups() {
var bulletTimer = LK.setInterval(function () {
if (gameState !== 'menu') {
var bulletPowerup = gameContainer.addChild(new BulletPowerup());
bulletPowerup.x = 600 + bulletPowerup.lane * 400;
bulletPowerup.y = -100;
bulletPowerup.speed = player.speed;
bulletPowerups.push(bulletPowerup);
}
}, 3000);
}
function completeRace() {
trackType = (trackType + 1) % 3;
// Change track color based on type
var trackColors = [0x4a4a4a, 0x8b4513, 0x2f4f4f];
game.setBackgroundColor(trackColors[trackType]);
// Reset race
raceTime = 0;
// Clear existing objects
for (var i = aiCars.length - 1; i >= 0; i--) {
aiCars[i].destroy();
}
aiCars = [];
for (var j = nitroPowerups.length - 1; j >= 0; j--) {
nitroPowerups[j].destroy();
}
nitroPowerups = [];
for (var k = bulletPowerups.length - 1; k >= 0; k--) {
bulletPowerups[k].destroy();
}
bulletPowerups = [];
}
// Main game update
game.update = function () {
if (gameState === 'menu') return;
// Update timer
raceTime++;
var minutes = Math.floor(raceTime / 3600);
var seconds = Math.floor(raceTime % 3600 / 60);
timerText.setText('TIME: ' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds);
// Update track lines
for (var i = trackLines.length - 1; i >= 0; i--) {
var line = trackLines[i];
line.speed = player.speed;
if (line.y > 2832) {
line.destroy();
trackLines.splice(i, 1);
}
}
// Update bullets
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
if (bullet.y < -100) {
bullet.destroy();
bullets.splice(b, 1);
continue;
}
// Check bullet collision with AI cars
for (var c = aiCars.length - 1; c >= 0; c--) {
var aiCar = aiCars[c];
if (bullet.intersects(aiCar)) {
if (audioEnabled) {
LK.getSound('explosion').play();
}
// Explosion effect
LK.effects.flashObject(aiCar, 0xff4500, 300);
tween(aiCar, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
aiCar.destroy();
}
});
aiCars.splice(c, 1);
bullet.destroy();
bullets.splice(b, 1);
break;
}
}
}
// Update AI cars
for (var j = aiCars.length - 1; j >= 0; j--) {
var aiCar = aiCars[j];
if (aiCar.y > 2832) {
aiCar.destroy();
aiCars.splice(j, 1);
continue;
}
// Check collision with player
if (player.intersects(aiCar)) {
if (audioEnabled) {
LK.getSound('crash').play();
}
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
}
}
// Update nitro powerups
for (var k = nitroPowerups.length - 1; k >= 0; k--) {
var nitro = nitroPowerups[k];
nitro.speed = player.speed;
if (nitro.y > 2832) {
nitro.destroy();
nitroPowerups.splice(k, 1);
continue;
}
// Check collection
if (player.intersects(nitro)) {
if (audioEnabled) {
LK.getSound('coinPickup').play();
}
// Increase nitro and bullet counts
player.nitroCount++;
player.bulletCount += 3;
nitroCounterText.setText('NITRO: ' + player.nitroCount);
bulletCounterText.setText('BULLETS: ' + player.bulletCount);
nitro.destroy();
nitroPowerups.splice(k, 1);
}
}
// Update bullet powerups
for (var l = bulletPowerups.length - 1; l >= 0; l--) {
var bulletPowerup = bulletPowerups[l];
bulletPowerup.speed = player.speed;
if (bulletPowerup.y > 2832) {
bulletPowerup.destroy();
bulletPowerups.splice(l, 1);
continue;
}
// Check collection
if (player.intersects(bulletPowerup)) {
if (audioEnabled) {
LK.getSound('coinPickup').play();
}
// Increase bullet count only
player.bulletCount += 5;
bulletCounterText.setText('BULLETS: ' + player.bulletCount);
bulletPowerup.destroy();
bulletPowerups.splice(l, 1);
}
}
// Complete race after 2 minutes
if (raceTime >= 7200) {
completeRace();
}
};
// Start with main menu
createMainMenu();
plastic, realistic,shiny, black, only one arrow-shaped buttons. In-Game asset. 2d. High contrast. No shadows
white sports car arcade top view. In-Game asset. 2d. High contrast. No shadows
Blue sports car arcade top view. In-Game asset. 2d. High contrast. No shadows
Grey sports car arcade top view. In-Game asset. 2d. High contrast. No shadows
Yellow sports car arcade top view. In-Game asset. 2d. High contrast. No shadows
asphalt road. In-Game asset. 2d. High contrast. No shadows
Nitro image blue In-Game asset. 2d. High contrast. No shadows
Racing background wallpaper blue 2500x3125 1080p. In-Game asset. 2d. High contrast. No shadows
realistic, plastic, gray, rectangular. In-Game asset. 2d. High contrast. No shadows
Racing floor background wallpaper light grey 2500x3125 1080p. In-Game asset. 2d. High contrast. No shadows
Circle realistic plastic green. In-Game asset. 2d. High contrast. No shadows
Circle realistic plastic blue. In-Game asset. 2d. High contrast. No shadows
yellow bullet icon. In-Game asset. 2d. High contrast. No shadows
Bullet realistic icon light red color In-Game asset. 2d. High contrast. No shadows