User prompt
araba farlarını daha küçük yap ve nitroyu kaldır
User prompt
biraz daha yenilik olsun ve farları daha güzel yao ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
nitro alınca ölüyoz olum onu düzelt ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
arabalara değidiğinde patlama efekti koy ve değme ayarını hassas yap yakınından geçince patlamasın tam anlamıyla çarpınca patlasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
noss koy ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Bazı yerlere nitro gibi güçlendiriciler koy bazı yerlere 2x 3x coinler koy ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
kanka butonları tam ayarlasana
User prompt
oyunu biraz daha geliştir menü biraz daha büyük ve okunur olsun yazılar daha düzgün olsun daha insanları çekecek şeyler ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
coinlerle bir şeyler alabilelim ve menüyü daha düzenli yap herşey iç içe yapmışsın ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
oyundaki ışık efektini kaldır arabadaki dursun
User prompt
peki o zaman görüntü kalitesini baya arttır ve oyuna bir sürü yenilik ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
bariyerleri ve düşman arabaları başta az yap skor arttıkça oyun zorlaşsın
User prompt
araba seçme ekranını düzelt ve düzenle arabaları seçilir duruma getir yol seçeneği de ekle
User prompt
hala seçilmiyor düzelt
User prompt
arabaların üstüne basınca seçilsin ve birbirlerinden uzak yap
User prompt
araba seçilmiyor oyunu durduruyor
User prompt
araba seçme ekranı ve ultra gerçekçi arabalar
User prompt
biraz daha gerçekçi yollar ve ara yüz ekranı
User prompt
arabalar daha detaylı olsun
Code edit (1 edits merged)
Please save this source code
User prompt
Highway Dodge
Initial prompt
A 2D top-down car game where the player drives along a two-lane road and dodges incoming obstacles.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CarPreview = Container.expand(function (carType) {
var self = Container.call(this);
if (carType === 'sports') {
// Sports car preview
var body = self.attachAsset('sportsCar', {
anchorX: 0.5,
anchorY: 0.5
});
var frontWindow = self.attachAsset('sportsCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
frontWindow.y = -40;
var rearWindow = self.attachAsset('sportsCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rearWindow.y = 40;
var leftWindow = self.attachAsset('sportsCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
leftWindow.x = -30;
leftWindow.y = -10;
var rightWindow = self.attachAsset('sportsCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rightWindow.x = 30;
rightWindow.y = -10;
var spoiler = self.attachAsset('sportsCarSpoiler', {
anchorX: 0.5,
anchorY: 0.5
});
spoiler.y = 80;
var stripe = self.attachAsset('sportsCarStripe', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (carType === 'luxury') {
// Luxury car preview
var body = self.attachAsset('luxuryCar', {
anchorX: 0.5,
anchorY: 0.5
});
var frontWindow = self.attachAsset('luxuryCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
frontWindow.y = -45;
var rearWindow = self.attachAsset('luxuryCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rearWindow.y = 45;
var leftWindow = self.attachAsset('luxuryCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
leftWindow.x = -35;
leftWindow.y = -15;
var rightWindow = self.attachAsset('luxuryCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rightWindow.x = 35;
rightWindow.y = -15;
var grill = self.attachAsset('luxuryCarGrill', {
anchorX: 0.5,
anchorY: 0.5
});
grill.y = -90;
var trim = self.attachAsset('luxuryCarTrim', {
anchorX: 0.5,
anchorY: 0.5
});
trim.y = 90;
} else if (carType === 'race') {
// Race car preview
var body = self.attachAsset('raceCar', {
anchorX: 0.5,
anchorY: 0.5
});
var frontWindow = self.attachAsset('raceCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
frontWindow.y = -35;
var rearWindow = self.attachAsset('raceCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rearWindow.y = 35;
var leftWindow = self.attachAsset('raceCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
leftWindow.x = -25;
leftWindow.y = -5;
var rightWindow = self.attachAsset('raceCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rightWindow.x = 25;
rightWindow.y = -5;
var wing = self.attachAsset('raceCarWing', {
anchorX: 0.5,
anchorY: 0.5
});
wing.y = 75;
var number = self.attachAsset('raceCarNumber', {
anchorX: 0.5,
anchorY: 0.5
});
number.y = -60;
} else if (carType === 'classic') {
// Classic car preview
var body = self.attachAsset('classicCar', {
anchorX: 0.5,
anchorY: 0.5
});
var frontWindow = self.attachAsset('classicCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
frontWindow.y = -42;
var rearWindow = self.attachAsset('classicCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rearWindow.y = 42;
var leftWindow = self.attachAsset('classicCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
leftWindow.x = -32;
leftWindow.y = -12;
var rightWindow = self.attachAsset('classicCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rightWindow.x = 32;
rightWindow.y = -12;
var bumper = self.attachAsset('classicCarBumper', {
anchorX: 0.5,
anchorY: 0.5
});
bumper.y = 87;
var trim = self.attachAsset('classicCarTrim', {
anchorX: 0.5,
anchorY: 0.5
});
trim.y = -87;
}
return self;
});
var CarSelectionScreen = Container.expand(function () {
var self = Container.call(this);
// Background panel
var panel = self.attachAsset('carSelectPanel', {
anchorX: 0.5,
anchorY: 0.5
});
panel.alpha = 0.95;
// Title
var titleBg = self.attachAsset('carSelectTitle', {
anchorX: 0.5,
anchorY: 0.5
});
titleBg.y = -450;
titleBg.alpha = 0.8;
var titleText = new Text2('SELECT YOUR CAR', {
size: 80,
fill: '#ffffff'
});
titleText.anchor.set(0.5, 0.5);
titleBg.addChild(titleText);
// Back button
var backButton = self.attachAsset('carSelectButton', {
anchorX: 0.5,
anchorY: 0.5
});
backButton.y = -370;
backButton.alpha = 0.9;
backButton.scaleX = 0.8;
backButton.scaleY = 0.8;
var backText = new Text2('BACK', {
size: 30,
fill: '#ffffff'
});
backText.anchor.set(0.5, 0.5);
backButton.addChild(backText);
// Road selection section
var roadTitleBg = self.attachAsset('carSelectTitle', {
anchorX: 0.5,
anchorY: 0.5
});
roadTitleBg.y = 350;
roadTitleBg.alpha = 0.8;
var roadTitleText = new Text2('SELECT ROAD TYPE', {
size: 60,
fill: '#ffffff'
});
roadTitleText.anchor.set(0.5, 0.5);
roadTitleBg.addChild(roadTitleText);
// Road type buttons
var roadTypes = [{
type: 'highway',
name: 'HIGHWAY',
description: 'Fast traffic'
}, {
type: 'city',
name: 'CITY ROAD',
description: 'Heavy traffic'
}];
var roadButtons = [];
for (var r = 0; r < roadTypes.length; r++) {
var roadButton = self.attachAsset('carSelectButton', {
anchorX: 0.5,
anchorY: 0.5
});
roadButton.x = (r - 0.5) * 400;
roadButton.y = 450;
roadButton.alpha = 0.9;
roadButton.roadType = roadTypes[r].type;
var roadButtonText = new Text2(roadTypes[r].name, {
size: 35,
fill: '#ffffff'
});
roadButtonText.anchor.set(0.5, 0.5);
roadButton.addChild(roadButtonText);
roadButtons.push(roadButton);
}
// Get owned cars from storage
var ownedCars = storage.ownedCars || ['default'];
var allCarTypes = [{
type: 'default',
name: 'DEFAULT CAR',
speed: 'MEDIUM',
handling: 'GOOD'
}, {
type: 'sports',
name: 'SPORTS CAR',
speed: 'HIGH',
handling: 'EXCELLENT'
}, {
type: 'luxury',
name: 'LUXURY CAR',
speed: 'MEDIUM',
handling: 'GOOD'
}, {
type: 'race',
name: 'RACE CAR',
speed: 'EXTREME',
handling: 'PERFECT'
}, {
type: 'classic',
name: 'CLASSIC CAR',
speed: 'LOW',
handling: 'STABLE'
}];
// Filter to only show owned cars
var availableCarTypes = [];
for (var a = 0; a < allCarTypes.length; a++) {
if (ownedCars.indexOf(allCarTypes[a].type) !== -1) {
availableCarTypes.push(allCarTypes[a]);
}
}
var cards = [];
for (var i = 0; i < availableCarTypes.length; i++) {
var carType = availableCarTypes[i];
var card = self.addChild(new Container());
var cardBg = card.attachAsset('carSelectCard', {
anchorX: 0.5,
anchorY: 0.5
});
cardBg.alpha = 0.8;
// Position cards in rows, up to 3 per row
var col = i % 3;
var row = Math.floor(i / 3);
card.x = (col - 1) * 400;
card.y = (row - 0.5) * 350 - 100;
// Car preview
var carPreview = card.addChild(new CarPreview(carType.type));
carPreview.y = -80;
carPreview.scaleX = 0.7;
carPreview.scaleY = 0.7;
// Car name
var nameText = new Text2(carType.name, {
size: 35,
fill: '#ffffff'
});
nameText.anchor.set(0.5, 0.5);
card.addChild(nameText);
nameText.y = 50;
// Stats
var speedText = new Text2('SPEED: ' + carType.speed, {
size: 22,
fill: '#f39c12'
});
speedText.anchor.set(0.5, 0.5);
card.addChild(speedText);
speedText.y = 80;
var handlingText = new Text2('HANDLING: ' + carType.handling, {
size: 22,
fill: '#3498db'
});
handlingText.anchor.set(0.5, 0.5);
card.addChild(handlingText);
handlingText.y = 110;
// Select button
var selectButton = card.attachAsset('carSelectButton', {
anchorX: 0.5,
anchorY: 0.5
});
selectButton.y = 160;
selectButton.alpha = 0.9;
var buttonText = new Text2('SELECT', {
size: 30,
fill: '#ffffff'
});
buttonText.anchor.set(0.5, 0.5);
selectButton.addChild(buttonText);
// Store car type for selection
selectButton.carType = carType.type;
cards.push({
card: card,
button: selectButton,
type: carType.type
});
}
self.cards = cards;
self.roadButtons = roadButtons;
self.selectedCar = null;
self.selectedRoad = null;
self.down = function (x, y, obj) {
// Check back button
var backBounds = {
left: backButton.x - 120,
right: backButton.x + 120,
top: backButton.y - 32,
bottom: backButton.y + 32
};
if (x >= backBounds.left && x <= backBounds.right && y >= backBounds.top && y <= backBounds.bottom) {
LK.effects.flashObject(backButton, 0x00ff00, 200);
self.goBackToMenu();
return;
}
// Check if any car card was clicked
for (var i = 0; i < self.cards.length; i++) {
var card = self.cards[i].card;
// Check entire card bounds for easier selection
var cardBounds = {
left: card.x - 200,
right: card.x + 200,
top: card.y - 175,
bottom: card.y + 175
};
// Check if touch is within card bounds
if (x >= cardBounds.left && x <= cardBounds.right && y >= cardBounds.top && y <= cardBounds.bottom) {
// Flash the selected card for visual feedback
LK.effects.flashObject(card, 0x00ff00, 200);
self.selectedCar = self.cards[i].type;
selectedCarType = self.cards[i].type;
// Check if both car and road are selected
if (self.selectedCar && self.selectedRoad) {
self.startGameWithSelections();
}
break;
}
}
// Check if any road button was clicked
for (var r = 0; r < self.roadButtons.length; r++) {
var roadBtn = self.roadButtons[r];
var roadBounds = {
left: roadBtn.x - 150,
right: roadBtn.x + 150,
top: roadBtn.y - 40,
bottom: roadBtn.y + 40
};
if (x >= roadBounds.left && x <= roadBounds.right && y >= roadBounds.top && y <= roadBounds.bottom) {
// Flash the selected road button
LK.effects.flashObject(roadBtn, 0x00ff00, 200);
self.selectedRoad = roadBtn.roadType;
selectedRoadType = roadBtn.roadType;
// Check if both car and road are selected
if (self.selectedCar && self.selectedRoad) {
self.startGameWithSelections();
}
break;
}
}
};
self.goBackToMenu = function () {
LK.setTimeout(function () {
if (carSelectionScreen) {
carSelectionScreen.destroy();
carSelectionScreen = null;
}
initMainMenu();
}, 300);
};
self.startGameWithSelections = function () {
// Small delay before starting game
LK.setTimeout(function () {
if (carSelectionScreen) {
carSelectionScreen.destroy();
carSelectionScreen = null;
}
startGame();
}, 300);
};
return self;
});
var LaneDivider = Container.expand(function () {
var self = Container.call(this);
var dividerGraphics = self.attachAsset('laneDivider', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.update = function () {
self.y += self.speed + gameSpeed;
};
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Background panel
var panel = self.attachAsset('carSelectPanel', {
anchorX: 0.5,
anchorY: 0.5
});
panel.alpha = 0.95;
// Title
var titleBg = self.attachAsset('carSelectTitle', {
anchorX: 0.5,
anchorY: 0.5
});
titleBg.y = -400;
titleBg.alpha = 0.8;
var titleText = new Text2('RACING GAME', {
size: 80,
fill: '#ffffff'
});
titleText.anchor.set(0.5, 0.5);
titleBg.addChild(titleText);
// Coins display
var coinsBg = self.attachAsset('carSelectButton', {
anchorX: 0.5,
anchorY: 0.5
});
coinsBg.y = -280;
coinsBg.alpha = 0.9;
var coinsText = new Text2('COINS: ' + (storage.totalCoins || 0), {
size: 40,
fill: '#ffd700'
});
coinsText.anchor.set(0.5, 0.5);
coinsBg.addChild(coinsText);
// Menu buttons
var playButton = self.attachAsset('carSelectButton', {
anchorX: 0.5,
anchorY: 0.5
});
playButton.y = -150;
playButton.alpha = 0.9;
var playText = new Text2('PLAY GAME', {
size: 50,
fill: '#ffffff'
});
playText.anchor.set(0.5, 0.5);
playButton.addChild(playText);
var shopButton = self.attachAsset('carSelectButton', {
anchorX: 0.5,
anchorY: 0.5
});
shopButton.y = -50;
shopButton.alpha = 0.9;
var shopText = new Text2('SHOP', {
size: 50,
fill: '#ffffff'
});
shopText.anchor.set(0.5, 0.5);
shopButton.addChild(shopText);
var statsButton = self.attachAsset('carSelectButton', {
anchorX: 0.5,
anchorY: 0.5
});
statsButton.y = 50;
statsButton.alpha = 0.9;
var statsText = new Text2('STATS', {
size: 50,
fill: '#ffffff'
});
statsText.anchor.set(0.5, 0.5);
statsButton.addChild(statsText);
// Stats display
var stats = storage.playerStats || {
totalDistance: 0,
totalCoins: 0,
bestScore: 0,
gamesPlayed: 0
};
var statsBg = self.attachAsset('carSelectCard', {
anchorX: 0.5,
anchorY: 0.5
});
statsBg.y = 250;
statsBg.alpha = 0.8;
statsBg.scaleY = 0.6;
var statsTitle = new Text2('YOUR STATS', {
size: 35,
fill: '#ffffff'
});
statsTitle.anchor.set(0.5, 0.5);
statsBg.addChild(statsTitle);
statsTitle.y = -80;
var bestScoreText = new Text2('BEST: ' + stats.bestScore + 'M', {
size: 25,
fill: '#00ff00'
});
bestScoreText.anchor.set(0.5, 0.5);
statsBg.addChild(bestScoreText);
bestScoreText.y = -40;
var totalDistanceText = new Text2('TOTAL: ' + stats.totalDistance + 'M', {
size: 25,
fill: '#ffff00'
});
totalDistanceText.anchor.set(0.5, 0.5);
statsBg.addChild(totalDistanceText);
totalDistanceText.y = -10;
var gamesPlayedText = new Text2('GAMES: ' + stats.gamesPlayed, {
size: 25,
fill: '#ff9900'
});
gamesPlayedText.anchor.set(0.5, 0.5);
statsBg.addChild(gamesPlayedText);
gamesPlayedText.y = 20;
self.playButton = playButton;
self.shopButton = shopButton;
self.statsButton = statsButton;
self.down = function (x, y, obj) {
// Check play button
var playBounds = {
left: self.playButton.x - 150,
right: self.playButton.x + 150,
top: self.playButton.y - 40,
bottom: self.playButton.y + 40
};
if (x >= playBounds.left && x <= playBounds.right && y >= playBounds.top && y <= playBounds.bottom) {
LK.effects.flashObject(self.playButton, 0x00ff00, 200);
self.startCarSelection();
return;
}
// Check shop button
var shopBounds = {
left: self.shopButton.x - 150,
right: self.shopButton.x + 150,
top: self.shopButton.y - 40,
bottom: self.shopButton.y + 40
};
if (x >= shopBounds.left && x <= shopBounds.right && y >= shopBounds.top && y <= shopBounds.bottom) {
LK.effects.flashObject(self.shopButton, 0x00ff00, 200);
self.openShop();
return;
}
};
self.startCarSelection = function () {
LK.setTimeout(function () {
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
initCarSelection();
}, 300);
};
self.openShop = function () {
LK.setTimeout(function () {
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
shop = game.addChild(new Shop());
shop.x = 1024;
shop.y = 1366;
}, 300);
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
// Add details based on vehicle type
if (type === 'enemyCar') {
// Add windows to enemy car
var frontWindow = self.attachAsset('enemyCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
frontWindow.y = -40;
var rearWindow = self.attachAsset('enemyCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rearWindow.y = 40;
var leftWindow = self.attachAsset('enemyCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
leftWindow.x = -25;
leftWindow.y = -5;
var rightWindow = self.attachAsset('enemyCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rightWindow.x = 25;
rightWindow.y = -5;
} else if (type === 'truck') {
// Add truck cab windows
var truckWindow = self.attachAsset('truckWindow', {
anchorX: 0.5,
anchorY: 0.5
});
truckWindow.y = -60;
// Add truck cargo area details
var cargoDetail = self.attachAsset('truckCargo', {
anchorX: 0.5,
anchorY: 0.5
});
cargoDetail.y = 30;
} else if (type === 'barrier') {
// Add warning stripes to barrier
var stripe1 = self.attachAsset('barrierStripe', {
anchorX: 0.5,
anchorY: 0.5
});
stripe1.y = -15;
var stripe2 = self.attachAsset('barrierStripe', {
anchorX: 0.5,
anchorY: 0.5
});
stripe2.y = 15;
}
self.speed = 8;
self.obstacleType = type;
self.passed = false;
self.update = function () {
self.y += self.speed + gameSpeed;
};
return self;
});
var ParticleSystem = Container.expand(function (particleType, count) {
var self = Container.call(this);
self.particles = [];
self.particleType = particleType;
for (var i = 0; i < count; i++) {
var particle = self.attachAsset(particleType, {
anchorX: 0.5,
anchorY: 0.5
});
particle.vx = (Math.random() - 0.5) * 4;
particle.vy = (Math.random() - 0.5) * 4;
particle.life = 1.0;
particle.maxLife = 1.0;
particle.alpha = 0;
self.particles.push(particle);
}
self.emit = function (x, y, force) {
force = force || 1;
for (var i = 0; i < self.particles.length; i++) {
var particle = self.particles[i];
if (particle.life <= 0) {
particle.x = x + (Math.random() - 0.5) * 20;
particle.y = y + (Math.random() - 0.5) * 20;
particle.vx = (Math.random() - 0.5) * 6 * force;
particle.vy = (Math.random() - 0.5) * 6 * force;
particle.life = 1.0;
particle.alpha = 1.0;
break;
}
}
};
self.update = function () {
for (var i = 0; i < self.particles.length; i++) {
var particle = self.particles[i];
if (particle.life > 0) {
particle.x += particle.vx;
particle.y += particle.vy;
particle.life -= 0.02;
particle.alpha = particle.life;
particle.scaleX = particle.life;
particle.scaleY = particle.life;
}
}
};
return self;
});
var PlayerCar = Container.expand(function (carType) {
var self = Container.call(this);
carType = carType || 'default';
if (carType === 'sports') {
// Sports car with ultra-realistic details
var carGraphics = self.attachAsset('sportsCar', {
anchorX: 0.5,
anchorY: 0.5
});
var frontWindow = self.attachAsset('sportsCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
frontWindow.y = -40;
var rearWindow = self.attachAsset('sportsCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rearWindow.y = 40;
var leftWindow = self.attachAsset('sportsCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
leftWindow.x = -30;
leftWindow.y = -10;
var rightWindow = self.attachAsset('sportsCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rightWindow.x = 30;
rightWindow.y = -10;
var spoiler = self.attachAsset('sportsCarSpoiler', {
anchorX: 0.5,
anchorY: 0.5
});
spoiler.y = 80;
var stripe = self.attachAsset('sportsCarStripe', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (carType === 'luxury') {
// Luxury car with ultra-realistic details
var carGraphics = self.attachAsset('luxuryCar', {
anchorX: 0.5,
anchorY: 0.5
});
var frontWindow = self.attachAsset('luxuryCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
frontWindow.y = -45;
var rearWindow = self.attachAsset('luxuryCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rearWindow.y = 45;
var leftWindow = self.attachAsset('luxuryCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
leftWindow.x = -35;
leftWindow.y = -15;
var rightWindow = self.attachAsset('luxuryCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rightWindow.x = 35;
rightWindow.y = -15;
var grill = self.attachAsset('luxuryCarGrill', {
anchorX: 0.5,
anchorY: 0.5
});
grill.y = -90;
var trim = self.attachAsset('luxuryCarTrim', {
anchorX: 0.5,
anchorY: 0.5
});
trim.y = 90;
} else if (carType === 'race') {
// Race car with ultra-realistic details
var carGraphics = self.attachAsset('raceCar', {
anchorX: 0.5,
anchorY: 0.5
});
var frontWindow = self.attachAsset('raceCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
frontWindow.y = -35;
var rearWindow = self.attachAsset('raceCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rearWindow.y = 35;
var leftWindow = self.attachAsset('raceCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
leftWindow.x = -25;
leftWindow.y = -5;
var rightWindow = self.attachAsset('raceCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rightWindow.x = 25;
rightWindow.y = -5;
var wing = self.attachAsset('raceCarWing', {
anchorX: 0.5,
anchorY: 0.5
});
wing.y = 75;
var number = self.attachAsset('raceCarNumber', {
anchorX: 0.5,
anchorY: 0.5
});
number.y = -60;
} else if (carType === 'classic') {
// Classic car with ultra-realistic details
var carGraphics = self.attachAsset('classicCar', {
anchorX: 0.5,
anchorY: 0.5
});
var frontWindow = self.attachAsset('classicCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
frontWindow.y = -42;
var rearWindow = self.attachAsset('classicCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rearWindow.y = 42;
var leftWindow = self.attachAsset('classicCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
leftWindow.x = -32;
leftWindow.y = -12;
var rightWindow = self.attachAsset('classicCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rightWindow.x = 32;
rightWindow.y = -12;
var bumper = self.attachAsset('classicCarBumper', {
anchorX: 0.5,
anchorY: 0.5
});
bumper.y = 87;
var trim = self.attachAsset('classicCarTrim', {
anchorX: 0.5,
anchorY: 0.5
});
trim.y = -87;
} else {
// Default car
var carGraphics = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
var frontWindow = self.attachAsset('playerCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
frontWindow.y = -40;
var rearWindow = self.attachAsset('playerCarWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rearWindow.y = 40;
var leftWindow = self.attachAsset('playerCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
leftWindow.x = -30;
leftWindow.y = -10;
var rightWindow = self.attachAsset('playerCarSideWindow', {
anchorX: 0.5,
anchorY: 0.5
});
rightWindow.x = 30;
rightWindow.y = -10;
}
self.currentLane = 0; // 0 = left lane, 1 = right lane
self.targetX = 0;
self.speed = 0;
self.carType = carType;
self.shieldActive = false;
self.shieldTime = 0;
self.boostActive = false;
self.boostTime = 0;
// Add headlight beams
var leftHeadlight = self.attachAsset('lightBeam', {
anchorX: 0.5,
anchorY: 1
});
leftHeadlight.x = -25;
leftHeadlight.y = -80;
leftHeadlight.alpha = 0.6;
var rightHeadlight = self.attachAsset('lightBeam', {
anchorX: 0.5,
anchorY: 1
});
rightHeadlight.x = 25;
rightHeadlight.y = -80;
rightHeadlight.alpha = 0.6;
// Add exhaust particles
self.exhaustSystem = self.addChild(new ParticleSystem('exhaustParticle', 15));
self.exhaustSystem.y = 90;
// Add shield effect (initially hidden)
self.shieldEffect = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5
});
self.shieldEffect.alpha = 0;
self.shieldEffect.scaleX = 1.5;
self.shieldEffect.scaleY = 1.5;
self.switchLane = function (lane) {
if (self.currentLane !== lane) {
self.currentLane = lane;
self.targetX = lane === 0 ? leftLaneX : rightLaneX;
LK.getSound('switch').play();
}
};
self.activateShield = function () {
self.shieldActive = true;
self.shieldTime = 300; // 5 seconds at 60fps
tween(self.shieldEffect, {
alpha: 0.6
}, {
duration: 200
});
LK.getSound('powerup').play();
};
self.activateBoost = function () {
self.boostActive = true;
self.boostTime = 180; // 3 seconds at 60fps
gameSpeed += 3;
LK.getSound('boost').play();
// Screen effect
tween(game, {
tint: 0x00ffff
}, {
duration: 100,
onFinish: function onFinish() {
tween(game, {
tint: 0xffffff
}, {
duration: 100
});
}
});
};
self.update = function () {
// Smooth lane switching with tween animation
var diff = self.targetX - self.x;
if (Math.abs(diff) > 2) {
self.x += diff * 0.15;
} else {
self.x = self.targetX;
}
// Update exhaust particles
if (self.exhaustSystem) {
self.exhaustSystem.emit(0, 90, 0.5);
self.exhaustSystem.update();
}
// Update shield effect
if (self.shieldActive) {
self.shieldTime--;
if (self.shieldTime <= 0) {
self.shieldActive = false;
tween(self.shieldEffect, {
alpha: 0
}, {
duration: 300
});
} else {
self.shieldEffect.rotation += 0.1;
self.shieldEffect.alpha = 0.6 + Math.sin(LK.ticks * 0.2) * 0.2;
}
}
// Update boost effect
if (self.boostActive) {
self.boostTime--;
if (self.boostTime <= 0) {
self.boostActive = false;
gameSpeed = Math.max(gameSpeed - 3, 2);
}
// Emit nitro flames
if (self.exhaustSystem) {
self.exhaustSystem.emit(-10, 90, 2);
self.exhaustSystem.emit(10, 90, 2);
}
}
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
self.powerType = type;
var powerGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
// Add glow effect
var glow = self.attachAsset('glowEffect', {
anchorX: 0.5,
anchorY: 0.5
});
glow.alpha = 0.3;
glow.scaleX = 0.5;
glow.scaleY = 0.5;
self.speed = 8;
self.collected = false;
self.rotationSpeed = 0.1;
self.update = function () {
self.y += self.speed + gameSpeed;
self.rotation += self.rotationSpeed;
// Pulsing glow effect
glow.alpha = 0.3 + Math.sin(LK.ticks * 0.1) * 0.2;
glow.scaleX = 0.5 + Math.sin(LK.ticks * 0.1) * 0.1;
glow.scaleY = 0.5 + Math.sin(LK.ticks * 0.1) * 0.1;
};
return self;
});
var RoadLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('roadLine', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.update = function () {
self.y += self.speed + gameSpeed;
};
return self;
});
var Shop = Container.expand(function () {
var self = Container.call(this);
// Background panel
var panel = self.attachAsset('carSelectPanel', {
anchorX: 0.5,
anchorY: 0.5
});
panel.alpha = 0.95;
// Title
var titleBg = self.attachAsset('carSelectTitle', {
anchorX: 0.5,
anchorY: 0.5
});
titleBg.y = -500;
titleBg.alpha = 0.8;
var titleText = new Text2('SHOP', {
size: 80,
fill: '#ffffff'
});
titleText.anchor.set(0.5, 0.5);
titleBg.addChild(titleText);
// Coins display
var coinsBg = self.attachAsset('carSelectButton', {
anchorX: 0.5,
anchorY: 0.5
});
coinsBg.y = -400;
coinsBg.alpha = 0.9;
var coinsText = new Text2('COINS: ' + (storage.totalCoins || 0), {
size: 50,
fill: '#ffd700'
});
coinsText.anchor.set(0.5, 0.5);
coinsBg.addChild(coinsText);
// Shop items
var shopItems = [{
name: 'SPORTS CAR',
type: 'sports',
price: 500,
description: 'High speed racing car'
}, {
name: 'LUXURY CAR',
type: 'luxury',
price: 1000,
description: 'Premium comfort vehicle'
}, {
name: 'RACE CAR',
type: 'race',
price: 2000,
description: 'Professional racing machine'
}, {
name: 'CLASSIC CAR',
type: 'classic',
price: 750,
description: 'Vintage style automobile'
}];
var itemCards = [];
for (var i = 0; i < shopItems.length; i++) {
var item = shopItems[i];
var card = self.addChild(new Container());
var cardBg = card.attachAsset('carSelectCard', {
anchorX: 0.5,
anchorY: 0.5
});
cardBg.alpha = 0.8;
// Position cards in 2x2 grid
var col = i % 2;
var row = Math.floor(i / 2);
card.x = (col - 0.5) * 500;
card.y = (row - 0.5) * 300 - 50;
// Car preview
var carPreview = card.addChild(new CarPreview(item.type));
carPreview.y = -100;
carPreview.scaleX = 0.6;
carPreview.scaleY = 0.6;
// Item name
var nameText = new Text2(item.name, {
size: 30,
fill: '#ffffff'
});
nameText.anchor.set(0.5, 0.5);
card.addChild(nameText);
nameText.y = 20;
// Price
var priceText = new Text2(item.price + ' COINS', {
size: 25,
fill: '#ffd700'
});
priceText.anchor.set(0.5, 0.5);
card.addChild(priceText);
priceText.y = 50;
// Description
var descText = new Text2(item.description, {
size: 18,
fill: '#cccccc'
});
descText.anchor.set(0.5, 0.5);
card.addChild(descText);
descText.y = 80;
// Buy/Owned button
var buyButton = card.attachAsset('carSelectButton', {
anchorX: 0.5,
anchorY: 0.5
});
buyButton.y = 120;
buyButton.alpha = 0.9;
var ownedCars = storage.ownedCars || ['default'];
var isOwned = ownedCars.indexOf(item.type) !== -1;
var canAfford = (storage.totalCoins || 0) >= item.price;
var buttonText = new Text2(isOwned ? 'OWNED' : canAfford ? 'BUY' : 'NOT ENOUGH COINS', {
size: 20,
fill: isOwned ? '#00ff00' : canAfford ? '#ffffff' : '#ff0000'
});
buttonText.anchor.set(0.5, 0.5);
buyButton.addChild(buttonText);
buyButton.itemType = item.type;
buyButton.itemPrice = item.price;
buyButton.isOwned = isOwned;
buyButton.canAfford = canAfford;
itemCards.push({
card: card,
button: buyButton,
item: item
});
}
// Back button
var backButton = self.attachAsset('carSelectButton', {
anchorX: 0.5,
anchorY: 0.5
});
backButton.y = 400;
backButton.alpha = 0.9;
var backText = new Text2('BACK TO MENU', {
size: 30,
fill: '#ffffff'
});
backText.anchor.set(0.5, 0.5);
backButton.addChild(backText);
self.itemCards = itemCards;
self.backButton = backButton;
self.coinsText = coinsText;
self.down = function (x, y, obj) {
// Check back button
var backBounds = {
left: self.backButton.x - 150,
right: self.backButton.x + 150,
top: self.backButton.y - 40,
bottom: self.backButton.y + 40
};
if (x >= backBounds.left && x <= backBounds.right && y >= backBounds.top && y <= backBounds.bottom) {
LK.effects.flashObject(self.backButton, 0x00ff00, 200);
self.goBackToMenu();
return;
}
// Check item cards
for (var i = 0; i < self.itemCards.length; i++) {
var cardData = self.itemCards[i];
var button = cardData.button;
var buttonBounds = {
left: cardData.card.x + button.x - 150,
right: cardData.card.x + button.x + 150,
top: cardData.card.y + button.y - 40,
bottom: cardData.card.y + button.y + 40
};
if (x >= buttonBounds.left && x <= buttonBounds.right && y >= buttonBounds.top && y <= buttonBounds.bottom) {
if (!button.isOwned && button.canAfford) {
self.purchaseItem(cardData.item);
LK.effects.flashObject(button, 0x00ff00, 200);
} else {
LK.effects.flashObject(button, 0xff0000, 200);
}
break;
}
}
};
self.purchaseItem = function (item) {
var currentCoins = storage.totalCoins || 0;
if (currentCoins >= item.price) {
// Deduct coins
storage.totalCoins = currentCoins - item.price;
// Add car to owned cars
var ownedCars = storage.ownedCars || ['default'];
ownedCars.push(item.type);
storage.ownedCars = ownedCars;
// Update display
self.coinsText.setText('COINS: ' + storage.totalCoins);
// Refresh shop display
self.destroy();
shop = game.addChild(new Shop());
shop.x = 1024;
shop.y = 1366;
}
};
self.goBackToMenu = function () {
LK.setTimeout(function () {
if (shop) {
shop.destroy();
shop = null;
}
initMainMenu();
}, 300);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Car selection UI assets
// Car selection assets
// Barrier detail assets
// Truck detail assets
// Enemy car detail assets
// Player car detail assets
// Game state variables
var gameState = 'mainMenu'; // 'mainMenu', 'carSelection', 'playing', 'shop'
var selectedCarType = 'default';
var selectedRoadType = 'highway';
var mainMenu = null;
var carSelectionScreen = null;
var shop = null;
// Enhanced game features
var rainSystem = null;
var sparkleSystem = null;
var powerUps = [];
var coins = [];
var playerStats = storage.playerStats || {
totalDistance: 0,
totalCoins: 0,
bestScore: 0,
gamesPlayed: 0
};
var currentCoins = 0;
// Initialize storage defaults
if (!storage.totalCoins) storage.totalCoins = 0;
if (!storage.ownedCars) storage.ownedCars = ['default'];
var weatherEnabled = true;
var lightingEnabled = true;
// Game variables
var gameSpeed = 2;
var difficultyTimer = 0;
var obstacleTimer = 0;
var roadLineTimer = 0;
var leftLaneX = 1024 - 200;
var rightLaneX = 1024 + 200;
// Game objects arrays
var obstacles = [];
var roadLines = [];
var obstacleTypes = ['enemyCar', 'truck', 'barrier'];
// Create road surface
var roadSurface = game.addChild(LK.getAsset('roadSurface', {
anchorX: 0.5,
anchorY: 0.5
}));
roadSurface.x = 1024;
roadSurface.y = 1366;
// Add road texture patterns for realism
for (var i = 0; i < 60; i++) {
var textureStripe = game.addChild(LK.getAsset('roadTexture', {
anchorX: 0.5,
anchorY: 0.5
}));
textureStripe.x = 1024;
textureStripe.y = i * 50;
textureStripe.alpha = 0.3;
}
// Add asphalt pattern details
for (var i = 0; i < 200; i++) {
var pattern = game.addChild(LK.getAsset('asphaltPattern', {
anchorX: 0.5,
anchorY: 0.5
}));
pattern.x = 424 + Math.random() * 1200;
pattern.y = Math.random() * 2732;
pattern.alpha = 0.2;
pattern.rotation = Math.random() * Math.PI;
}
// Create road sides
var leftSide = game.addChild(LK.getAsset('roadSide', {
anchorX: 0.5,
anchorY: 0.5
}));
leftSide.x = 374;
leftSide.y = 1366;
var rightSide = game.addChild(LK.getAsset('roadSide', {
anchorX: 0.5,
anchorY: 0.5
}));
rightSide.x = 1674;
rightSide.y = 1366;
// Add road edge lines for realism
var leftEdge = game.addChild(LK.getAsset('roadEdge', {
anchorX: 0.5,
anchorY: 0.5
}));
leftEdge.x = 424;
leftEdge.y = 1366;
var rightEdge = game.addChild(LK.getAsset('roadEdge', {
anchorX: 0.5,
anchorY: 0.5
}));
rightEdge.x = 1624;
rightEdge.y = 1366;
// Initialize main menu
function initMainMenu() {
mainMenu = game.addChild(new MainMenu());
mainMenu.x = 1024;
mainMenu.y = 1366;
}
// Initialize car selection screen
function initCarSelection() {
carSelectionScreen = game.addChild(new CarSelectionScreen());
carSelectionScreen.x = 1024;
carSelectionScreen.y = 1366;
}
initMainMenu();
// Game start function
function startGame() {
gameState = 'playing';
// Create player car with selected type
playerCar = game.addChild(new PlayerCar(selectedCarType));
playerCar.x = leftLaneX;
playerCar.y = 2400;
playerCar.targetX = leftLaneX;
// Make playerCar globally accessible
game.playerCar = playerCar;
// Initialize particle systems
rainSystem = game.addChild(new ParticleSystem('rainDrop', 50));
sparkleSystem = game.addChild(new ParticleSystem('sparkleParticle', 30));
// Lighting effects removed from game environment
// Car headlights remain intact in PlayerCar class
// Adjust game difficulty based on road type
if (selectedRoadType === 'city') {
gameSpeed = 3;
obstacleTypes = ['enemyCar', 'truck', 'barrier']; // Start with balanced obstacles
} else {
gameSpeed = 2;
obstacleTypes = ['enemyCar', 'truck', 'barrier']; // Default highway
}
}
// Placeholder for player car (will be created after car selection)
var playerCar = null;
// Create dashboard panel
var dashboardPanel = LK.getAsset('dashboardPanel', {
anchorX: 0.5,
anchorY: 0
});
LK.gui.top.addChild(dashboardPanel);
dashboardPanel.y = 20;
dashboardPanel.alpha = 0.8;
// Create speedometer
var speedometer = LK.getAsset('speedometer', {
anchorX: 0.5,
anchorY: 0.5
});
LK.gui.topRight.addChild(speedometer);
speedometer.x = -150;
speedometer.y = 100;
speedometer.alpha = 0.9;
// Create speedometer needle
var speedometerNeedle = LK.getAsset('speedometerNeedle', {
anchorX: 0.5,
anchorY: 1
});
speedometer.addChild(speedometerNeedle);
speedometerNeedle.y = 20;
// Create mini map
var miniMap = LK.getAsset('miniMap', {
anchorX: 0,
anchorY: 0
});
LK.gui.topLeft.addChild(miniMap);
miniMap.x = 120;
miniMap.y = 50;
miniMap.alpha = 0.7;
// Create score display with dashboard styling
var scoreText = new Text2('DISTANCE: 0', {
size: 50,
fill: '#00ff00'
});
scoreText.anchor.set(0.5, 0.5);
dashboardPanel.addChild(scoreText);
scoreText.y = -15;
// Create speed display with dashboard styling
var speedText = new Text2('SPEED: 1', {
size: 40,
fill: '#ffff00'
});
speedText.anchor.set(0.5, 0.5);
dashboardPanel.addChild(speedText);
speedText.y = 25;
// Create coin counter display
var coinText = new Text2('COINS: 0', {
size: 35,
fill: '#ffd700'
});
coinText.anchor.set(0.5, 0.5);
dashboardPanel.addChild(coinText);
coinText.y = 55;
// Touch controls
game.down = function (x, y, obj) {
if (gameState === 'carSelection' && carSelectionScreen) {
// Convert touch coordinates to car selection screen coordinates
var localPos = carSelectionScreen.toLocal({
x: x,
y: y
});
carSelectionScreen.down(localPos.x, localPos.y, obj);
return;
} else if (gameState === 'playing' && game.playerCar) {
if (x < 1024) {
// Left side of screen - switch to left lane
game.playerCar.switchLane(0);
} else {
// Right side of screen - switch to right lane
game.playerCar.switchLane(1);
}
}
};
// Spawn obstacle function
function spawnObstacle() {
// Difficulty scaling based on score
var currentScore = LK.getScore();
var difficultyLevel = Math.floor(currentScore / 100); // Every 100 points increases difficulty
var barrierChance = Math.min(0.1 + difficultyLevel * 0.05, 0.4); // Start with 10% barriers, max 40%
var enemyChance = Math.min(0.6 + difficultyLevel * 0.1, 0.8); // Start with 60% enemies, max 80%
// Select obstacle type based on difficulty
var obstacleType;
var rand = Math.random();
if (rand < barrierChance) {
obstacleType = 'barrier';
} else if (rand < barrierChance + enemyChance) {
obstacleType = 'enemyCar';
} else {
obstacleType = 'truck';
}
var obstacle = new Obstacle(obstacleType);
// Randomly place in left or right lane
var lane = Math.floor(Math.random() * 2);
obstacle.x = lane === 0 ? leftLaneX : rightLaneX;
obstacle.y = -200;
obstacle.lane = lane;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn road line function
function spawnRoadLine() {
var roadLine = new RoadLine();
roadLine.x = 1024;
roadLine.y = -50;
roadLines.push(roadLine);
game.addChild(roadLine);
}
// Spawn power-up function
function spawnPowerUp() {
var powerUpTypes = ['speedBoost', 'shield'];
var powerUpType = powerUpTypes[Math.floor(Math.random() * powerUpTypes.length)];
var powerUp = new PowerUp(powerUpType);
var lane = Math.floor(Math.random() * 2);
powerUp.x = lane === 0 ? leftLaneX : rightLaneX;
powerUp.y = -200;
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Spawn coin function
function spawnCoin() {
var coin = new PowerUp('coin');
var lane = Math.floor(Math.random() * 2);
coin.x = lane === 0 ? leftLaneX : rightLaneX;
coin.y = -200;
coins.push(coin);
game.addChild(coin);
}
// Main game update loop
game.update = function () {
if (gameState === 'mainMenu' || gameState === 'carSelection' || gameState === 'shop') {
// Menu screens are active, don't update game logic
return;
}
if (gameState === 'playing' && game.playerCar) {
// Update difficulty
difficultyTimer++;
if (difficultyTimer % 600 === 0) {
// Every 10 seconds
gameSpeed += 0.5;
speedText.setText('SPEED: ' + Math.floor(gameSpeed) + ' KM/H');
}
// Update score
LK.setScore(Math.floor(LK.ticks / 10));
scoreText.setText('DISTANCE: ' + LK.getScore() + ' M');
coinText.setText('COINS: ' + currentCoins);
// Update environmental effects
if (weatherEnabled && rainSystem) {
for (var r = 0; r < 3; r++) {
rainSystem.emit(Math.random() * 2048, -50, 1.5);
}
rainSystem.update();
}
if (sparkleSystem) {
if (Math.random() < 0.1) {
sparkleSystem.emit(Math.random() * 2048, Math.random() * 2732, 0.5);
}
sparkleSystem.update();
}
// Spawn obstacles
obstacleTimer++;
// Progressive difficulty: spawn rate increases with score
var currentScore = LK.getScore();
var difficultyLevel = Math.floor(currentScore / 50); // Every 50 points increases spawn rate
var baseSpawnRate = 120; // Start with slower spawn rate (2 seconds)
var spawnRate = Math.max(baseSpawnRate - difficultyLevel * 10, 45); // Minimum 0.75 seconds between spawns
if (obstacleTimer % spawnRate === 0) {
spawnObstacle();
}
// Spawn power-ups occasionally
if (LK.ticks % 900 === 0) {
// Every 15 seconds
spawnPowerUp();
}
// Spawn coins frequently
if (LK.ticks % 180 === 0) {
// Every 3 seconds
spawnCoin();
}
// Spawn road lines
roadLineTimer++;
if (roadLineTimer % 40 === 0) {
spawnRoadLine();
}
// Spawn lane dividers for center line
if (roadLineTimer % 30 === 0) {
var laneDivider = new LaneDivider();
laneDivider.x = 1024;
laneDivider.y = -50;
roadLines.push(laneDivider);
game.addChild(laneDivider);
}
// Update speedometer needle rotation based on speed
speedometerNeedle.rotation = gameSpeed / 10 * Math.PI * 0.5;
// Update and check obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
// Check if obstacle is off screen
if (obstacle.y > 2800) {
// Give points for passing obstacle
if (!obstacle.passed) {
LK.setScore(LK.getScore() + 10);
obstacle.passed = true;
}
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Check collision with player (skip if shield is active)
if (obstacle.intersects(game.playerCar) && !game.playerCar.shieldActive) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
// Update player stats and storage
playerStats.totalDistance += LK.getScore();
playerStats.totalCoins += currentCoins;
playerStats.gamesPlayed++;
if (LK.getScore() > playerStats.bestScore) {
playerStats.bestScore = LK.getScore();
}
storage.playerStats = playerStats;
// Add coins to total storage
storage.totalCoins = (storage.totalCoins || 0) + currentCoins;
// Reset game state
gameState = 'mainMenu';
LK.showGameOver();
return;
}
// Check if obstacle was passed for scoring
if (!obstacle.passed && obstacle.y > game.playerCar.y + 100) {
obstacle.passed = true;
LK.setScore(LK.getScore() + 5);
}
}
// Update and check power-ups
for (var p = powerUps.length - 1; p >= 0; p--) {
var powerUp = powerUps[p];
if (powerUp.y > 2800) {
powerUp.destroy();
powerUps.splice(p, 1);
continue;
}
// Check collection
if (powerUp.intersects(game.playerCar) && !powerUp.collected) {
powerUp.collected = true;
// Activate power-up effect
if (powerUp.powerType === 'speedBoost') {
game.playerCar.activateBoost();
} else if (powerUp.powerType === 'shield') {
game.playerCar.activateShield();
}
// Visual feedback
sparkleSystem.emit(powerUp.x, powerUp.y, 2);
tween(powerUp, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
powerUp.destroy();
}
});
powerUps.splice(p, 1);
}
}
// Update and check coins
for (var c = coins.length - 1; c >= 0; c--) {
var coin = coins[c];
if (coin.y > 2800) {
coin.destroy();
coins.splice(c, 1);
continue;
}
// Check collection
if (coin.intersects(game.playerCar) && !coin.collected) {
coin.collected = true;
currentCoins++;
LK.getSound('coin').play();
// Visual feedback
sparkleSystem.emit(coin.x, coin.y, 1.5);
tween(coin, {
alpha: 0,
y: coin.y - 50
}, {
duration: 500,
onFinish: function onFinish() {
coin.destroy();
}
});
coins.splice(c, 1);
}
}
// Update and clean up road lines
for (var j = roadLines.length - 1; j >= 0; j--) {
var roadLine = roadLines[j];
if (roadLine.y > 2800) {
roadLine.destroy();
roadLines.splice(j, 1);
}
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -183,8 +183,23 @@
fill: '#ffffff'
});
titleText.anchor.set(0.5, 0.5);
titleBg.addChild(titleText);
+ // Back button
+ var backButton = self.attachAsset('carSelectButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ backButton.y = -370;
+ backButton.alpha = 0.9;
+ backButton.scaleX = 0.8;
+ backButton.scaleY = 0.8;
+ var backText = new Text2('BACK', {
+ size: 30,
+ fill: '#ffffff'
+ });
+ backText.anchor.set(0.5, 0.5);
+ backButton.addChild(backText);
// Road selection section
var roadTitleBg = self.attachAsset('carSelectTitle', {
anchorX: 0.5,
anchorY: 0.5
@@ -224,10 +239,16 @@
roadButtonText.anchor.set(0.5, 0.5);
roadButton.addChild(roadButtonText);
roadButtons.push(roadButton);
}
- // Car selection cards
- var carTypes = [{
+ // Get owned cars from storage
+ var ownedCars = storage.ownedCars || ['default'];
+ var allCarTypes = [{
+ type: 'default',
+ name: 'DEFAULT CAR',
+ speed: 'MEDIUM',
+ handling: 'GOOD'
+ }, {
type: 'sports',
name: 'SPORTS CAR',
speed: 'HIGH',
handling: 'EXCELLENT'
@@ -246,43 +267,51 @@
name: 'CLASSIC CAR',
speed: 'LOW',
handling: 'STABLE'
}];
+ // Filter to only show owned cars
+ var availableCarTypes = [];
+ for (var a = 0; a < allCarTypes.length; a++) {
+ if (ownedCars.indexOf(allCarTypes[a].type) !== -1) {
+ availableCarTypes.push(allCarTypes[a]);
+ }
+ }
var cards = [];
- for (var i = 0; i < carTypes.length; i++) {
+ for (var i = 0; i < availableCarTypes.length; i++) {
+ var carType = availableCarTypes[i];
var card = self.addChild(new Container());
var cardBg = card.attachAsset('carSelectCard', {
anchorX: 0.5,
anchorY: 0.5
});
cardBg.alpha = 0.8;
- // Position cards in 2x2 grid with better spacing
- var col = i % 2;
- var row = Math.floor(i / 2);
- card.x = (col - 0.5) * 500;
+ // Position cards in rows, up to 3 per row
+ var col = i % 3;
+ var row = Math.floor(i / 3);
+ card.x = (col - 1) * 400;
card.y = (row - 0.5) * 350 - 100;
// Car preview
- var carPreview = card.addChild(new CarPreview(carTypes[i].type));
+ var carPreview = card.addChild(new CarPreview(carType.type));
carPreview.y = -80;
carPreview.scaleX = 0.7;
carPreview.scaleY = 0.7;
// Car name
- var nameText = new Text2(carTypes[i].name, {
+ var nameText = new Text2(carType.name, {
size: 35,
fill: '#ffffff'
});
nameText.anchor.set(0.5, 0.5);
card.addChild(nameText);
nameText.y = 50;
// Stats
- var speedText = new Text2('SPEED: ' + carTypes[i].speed, {
+ var speedText = new Text2('SPEED: ' + carType.speed, {
size: 22,
fill: '#f39c12'
});
speedText.anchor.set(0.5, 0.5);
card.addChild(speedText);
speedText.y = 80;
- var handlingText = new Text2('HANDLING: ' + carTypes[i].handling, {
+ var handlingText = new Text2('HANDLING: ' + carType.handling, {
size: 22,
fill: '#3498db'
});
handlingText.anchor.set(0.5, 0.5);
@@ -301,20 +330,32 @@
});
buttonText.anchor.set(0.5, 0.5);
selectButton.addChild(buttonText);
// Store car type for selection
- selectButton.carType = carTypes[i].type;
+ selectButton.carType = carType.type;
cards.push({
card: card,
button: selectButton,
- type: carTypes[i].type
+ type: carType.type
});
}
self.cards = cards;
self.roadButtons = roadButtons;
self.selectedCar = null;
self.selectedRoad = null;
self.down = function (x, y, obj) {
+ // Check back button
+ var backBounds = {
+ left: backButton.x - 120,
+ right: backButton.x + 120,
+ top: backButton.y - 32,
+ bottom: backButton.y + 32
+ };
+ if (x >= backBounds.left && x <= backBounds.right && y >= backBounds.top && y <= backBounds.bottom) {
+ LK.effects.flashObject(backButton, 0x00ff00, 200);
+ self.goBackToMenu();
+ return;
+ }
// Check if any car card was clicked
for (var i = 0; i < self.cards.length; i++) {
var card = self.cards[i].card;
// Check entire card bounds for easier selection
@@ -358,8 +399,17 @@
break;
}
}
};
+ self.goBackToMenu = function () {
+ LK.setTimeout(function () {
+ if (carSelectionScreen) {
+ carSelectionScreen.destroy();
+ carSelectionScreen = null;
+ }
+ initMainMenu();
+ }, 300);
+ };
self.startGameWithSelections = function () {
// Small delay before starting game
LK.setTimeout(function () {
if (carSelectionScreen) {
@@ -382,8 +432,172 @@
self.y += self.speed + gameSpeed;
};
return self;
});
+var MainMenu = Container.expand(function () {
+ var self = Container.call(this);
+ // Background panel
+ var panel = self.attachAsset('carSelectPanel', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ panel.alpha = 0.95;
+ // Title
+ var titleBg = self.attachAsset('carSelectTitle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ titleBg.y = -400;
+ titleBg.alpha = 0.8;
+ var titleText = new Text2('RACING GAME', {
+ size: 80,
+ fill: '#ffffff'
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleBg.addChild(titleText);
+ // Coins display
+ var coinsBg = self.attachAsset('carSelectButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ coinsBg.y = -280;
+ coinsBg.alpha = 0.9;
+ var coinsText = new Text2('COINS: ' + (storage.totalCoins || 0), {
+ size: 40,
+ fill: '#ffd700'
+ });
+ coinsText.anchor.set(0.5, 0.5);
+ coinsBg.addChild(coinsText);
+ // Menu buttons
+ var playButton = self.attachAsset('carSelectButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ playButton.y = -150;
+ playButton.alpha = 0.9;
+ var playText = new Text2('PLAY GAME', {
+ size: 50,
+ fill: '#ffffff'
+ });
+ playText.anchor.set(0.5, 0.5);
+ playButton.addChild(playText);
+ var shopButton = self.attachAsset('carSelectButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ shopButton.y = -50;
+ shopButton.alpha = 0.9;
+ var shopText = new Text2('SHOP', {
+ size: 50,
+ fill: '#ffffff'
+ });
+ shopText.anchor.set(0.5, 0.5);
+ shopButton.addChild(shopText);
+ var statsButton = self.attachAsset('carSelectButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ statsButton.y = 50;
+ statsButton.alpha = 0.9;
+ var statsText = new Text2('STATS', {
+ size: 50,
+ fill: '#ffffff'
+ });
+ statsText.anchor.set(0.5, 0.5);
+ statsButton.addChild(statsText);
+ // Stats display
+ var stats = storage.playerStats || {
+ totalDistance: 0,
+ totalCoins: 0,
+ bestScore: 0,
+ gamesPlayed: 0
+ };
+ var statsBg = self.attachAsset('carSelectCard', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ statsBg.y = 250;
+ statsBg.alpha = 0.8;
+ statsBg.scaleY = 0.6;
+ var statsTitle = new Text2('YOUR STATS', {
+ size: 35,
+ fill: '#ffffff'
+ });
+ statsTitle.anchor.set(0.5, 0.5);
+ statsBg.addChild(statsTitle);
+ statsTitle.y = -80;
+ var bestScoreText = new Text2('BEST: ' + stats.bestScore + 'M', {
+ size: 25,
+ fill: '#00ff00'
+ });
+ bestScoreText.anchor.set(0.5, 0.5);
+ statsBg.addChild(bestScoreText);
+ bestScoreText.y = -40;
+ var totalDistanceText = new Text2('TOTAL: ' + stats.totalDistance + 'M', {
+ size: 25,
+ fill: '#ffff00'
+ });
+ totalDistanceText.anchor.set(0.5, 0.5);
+ statsBg.addChild(totalDistanceText);
+ totalDistanceText.y = -10;
+ var gamesPlayedText = new Text2('GAMES: ' + stats.gamesPlayed, {
+ size: 25,
+ fill: '#ff9900'
+ });
+ gamesPlayedText.anchor.set(0.5, 0.5);
+ statsBg.addChild(gamesPlayedText);
+ gamesPlayedText.y = 20;
+ self.playButton = playButton;
+ self.shopButton = shopButton;
+ self.statsButton = statsButton;
+ self.down = function (x, y, obj) {
+ // Check play button
+ var playBounds = {
+ left: self.playButton.x - 150,
+ right: self.playButton.x + 150,
+ top: self.playButton.y - 40,
+ bottom: self.playButton.y + 40
+ };
+ if (x >= playBounds.left && x <= playBounds.right && y >= playBounds.top && y <= playBounds.bottom) {
+ LK.effects.flashObject(self.playButton, 0x00ff00, 200);
+ self.startCarSelection();
+ return;
+ }
+ // Check shop button
+ var shopBounds = {
+ left: self.shopButton.x - 150,
+ right: self.shopButton.x + 150,
+ top: self.shopButton.y - 40,
+ bottom: self.shopButton.y + 40
+ };
+ if (x >= shopBounds.left && x <= shopBounds.right && y >= shopBounds.top && y <= shopBounds.bottom) {
+ LK.effects.flashObject(self.shopButton, 0x00ff00, 200);
+ self.openShop();
+ return;
+ }
+ };
+ self.startCarSelection = function () {
+ LK.setTimeout(function () {
+ if (mainMenu) {
+ mainMenu.destroy();
+ mainMenu = null;
+ }
+ initCarSelection();
+ }, 300);
+ };
+ self.openShop = function () {
+ LK.setTimeout(function () {
+ if (mainMenu) {
+ mainMenu.destroy();
+ mainMenu = null;
+ }
+ shop = game.addChild(new Shop());
+ shop.x = 1024;
+ shop.y = 1366;
+ }, 300);
+ };
+ return self;
+});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset(type, {
anchorX: 0.5,
@@ -830,8 +1044,212 @@
self.y += self.speed + gameSpeed;
};
return self;
});
+var Shop = Container.expand(function () {
+ var self = Container.call(this);
+ // Background panel
+ var panel = self.attachAsset('carSelectPanel', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ panel.alpha = 0.95;
+ // Title
+ var titleBg = self.attachAsset('carSelectTitle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ titleBg.y = -500;
+ titleBg.alpha = 0.8;
+ var titleText = new Text2('SHOP', {
+ size: 80,
+ fill: '#ffffff'
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleBg.addChild(titleText);
+ // Coins display
+ var coinsBg = self.attachAsset('carSelectButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ coinsBg.y = -400;
+ coinsBg.alpha = 0.9;
+ var coinsText = new Text2('COINS: ' + (storage.totalCoins || 0), {
+ size: 50,
+ fill: '#ffd700'
+ });
+ coinsText.anchor.set(0.5, 0.5);
+ coinsBg.addChild(coinsText);
+ // Shop items
+ var shopItems = [{
+ name: 'SPORTS CAR',
+ type: 'sports',
+ price: 500,
+ description: 'High speed racing car'
+ }, {
+ name: 'LUXURY CAR',
+ type: 'luxury',
+ price: 1000,
+ description: 'Premium comfort vehicle'
+ }, {
+ name: 'RACE CAR',
+ type: 'race',
+ price: 2000,
+ description: 'Professional racing machine'
+ }, {
+ name: 'CLASSIC CAR',
+ type: 'classic',
+ price: 750,
+ description: 'Vintage style automobile'
+ }];
+ var itemCards = [];
+ for (var i = 0; i < shopItems.length; i++) {
+ var item = shopItems[i];
+ var card = self.addChild(new Container());
+ var cardBg = card.attachAsset('carSelectCard', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ cardBg.alpha = 0.8;
+ // Position cards in 2x2 grid
+ var col = i % 2;
+ var row = Math.floor(i / 2);
+ card.x = (col - 0.5) * 500;
+ card.y = (row - 0.5) * 300 - 50;
+ // Car preview
+ var carPreview = card.addChild(new CarPreview(item.type));
+ carPreview.y = -100;
+ carPreview.scaleX = 0.6;
+ carPreview.scaleY = 0.6;
+ // Item name
+ var nameText = new Text2(item.name, {
+ size: 30,
+ fill: '#ffffff'
+ });
+ nameText.anchor.set(0.5, 0.5);
+ card.addChild(nameText);
+ nameText.y = 20;
+ // Price
+ var priceText = new Text2(item.price + ' COINS', {
+ size: 25,
+ fill: '#ffd700'
+ });
+ priceText.anchor.set(0.5, 0.5);
+ card.addChild(priceText);
+ priceText.y = 50;
+ // Description
+ var descText = new Text2(item.description, {
+ size: 18,
+ fill: '#cccccc'
+ });
+ descText.anchor.set(0.5, 0.5);
+ card.addChild(descText);
+ descText.y = 80;
+ // Buy/Owned button
+ var buyButton = card.attachAsset('carSelectButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ buyButton.y = 120;
+ buyButton.alpha = 0.9;
+ var ownedCars = storage.ownedCars || ['default'];
+ var isOwned = ownedCars.indexOf(item.type) !== -1;
+ var canAfford = (storage.totalCoins || 0) >= item.price;
+ var buttonText = new Text2(isOwned ? 'OWNED' : canAfford ? 'BUY' : 'NOT ENOUGH COINS', {
+ size: 20,
+ fill: isOwned ? '#00ff00' : canAfford ? '#ffffff' : '#ff0000'
+ });
+ buttonText.anchor.set(0.5, 0.5);
+ buyButton.addChild(buttonText);
+ buyButton.itemType = item.type;
+ buyButton.itemPrice = item.price;
+ buyButton.isOwned = isOwned;
+ buyButton.canAfford = canAfford;
+ itemCards.push({
+ card: card,
+ button: buyButton,
+ item: item
+ });
+ }
+ // Back button
+ var backButton = self.attachAsset('carSelectButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ backButton.y = 400;
+ backButton.alpha = 0.9;
+ var backText = new Text2('BACK TO MENU', {
+ size: 30,
+ fill: '#ffffff'
+ });
+ backText.anchor.set(0.5, 0.5);
+ backButton.addChild(backText);
+ self.itemCards = itemCards;
+ self.backButton = backButton;
+ self.coinsText = coinsText;
+ self.down = function (x, y, obj) {
+ // Check back button
+ var backBounds = {
+ left: self.backButton.x - 150,
+ right: self.backButton.x + 150,
+ top: self.backButton.y - 40,
+ bottom: self.backButton.y + 40
+ };
+ if (x >= backBounds.left && x <= backBounds.right && y >= backBounds.top && y <= backBounds.bottom) {
+ LK.effects.flashObject(self.backButton, 0x00ff00, 200);
+ self.goBackToMenu();
+ return;
+ }
+ // Check item cards
+ for (var i = 0; i < self.itemCards.length; i++) {
+ var cardData = self.itemCards[i];
+ var button = cardData.button;
+ var buttonBounds = {
+ left: cardData.card.x + button.x - 150,
+ right: cardData.card.x + button.x + 150,
+ top: cardData.card.y + button.y - 40,
+ bottom: cardData.card.y + button.y + 40
+ };
+ if (x >= buttonBounds.left && x <= buttonBounds.right && y >= buttonBounds.top && y <= buttonBounds.bottom) {
+ if (!button.isOwned && button.canAfford) {
+ self.purchaseItem(cardData.item);
+ LK.effects.flashObject(button, 0x00ff00, 200);
+ } else {
+ LK.effects.flashObject(button, 0xff0000, 200);
+ }
+ break;
+ }
+ }
+ };
+ self.purchaseItem = function (item) {
+ var currentCoins = storage.totalCoins || 0;
+ if (currentCoins >= item.price) {
+ // Deduct coins
+ storage.totalCoins = currentCoins - item.price;
+ // Add car to owned cars
+ var ownedCars = storage.ownedCars || ['default'];
+ ownedCars.push(item.type);
+ storage.ownedCars = ownedCars;
+ // Update display
+ self.coinsText.setText('COINS: ' + storage.totalCoins);
+ // Refresh shop display
+ self.destroy();
+ shop = game.addChild(new Shop());
+ shop.x = 1024;
+ shop.y = 1366;
+ }
+ };
+ self.goBackToMenu = function () {
+ LK.setTimeout(function () {
+ if (shop) {
+ shop.destroy();
+ shop = null;
+ }
+ initMainMenu();
+ }, 300);
+ };
+ return self;
+});
/****
* Initialize Game
****/
@@ -848,12 +1266,14 @@
// Truck detail assets
// Enemy car detail assets
// Player car detail assets
// Game state variables
-var gameState = 'carSelection'; // 'carSelection', 'playing'
+var gameState = 'mainMenu'; // 'mainMenu', 'carSelection', 'playing', 'shop'
var selectedCarType = 'default';
var selectedRoadType = 'highway';
+var mainMenu = null;
var carSelectionScreen = null;
+var shop = null;
// Enhanced game features
var rainSystem = null;
var sparkleSystem = null;
var powerUps = [];
@@ -864,8 +1284,11 @@
bestScore: 0,
gamesPlayed: 0
};
var currentCoins = 0;
+// Initialize storage defaults
+if (!storage.totalCoins) storage.totalCoins = 0;
+if (!storage.ownedCars) storage.ownedCars = ['default'];
var weatherEnabled = true;
var lightingEnabled = true;
// Game variables
var gameSpeed = 2;
@@ -931,15 +1354,21 @@
anchorY: 0.5
}));
rightEdge.x = 1624;
rightEdge.y = 1366;
+// Initialize main menu
+function initMainMenu() {
+ mainMenu = game.addChild(new MainMenu());
+ mainMenu.x = 1024;
+ mainMenu.y = 1366;
+}
// Initialize car selection screen
function initCarSelection() {
carSelectionScreen = game.addChild(new CarSelectionScreen());
carSelectionScreen.x = 1024;
carSelectionScreen.y = 1366;
}
-initCarSelection();
+initMainMenu();
// Game start function
function startGame() {
gameState = 'playing';
// Create player car with selected type
@@ -1097,10 +1526,10 @@
game.addChild(coin);
}
// Main game update loop
game.update = function () {
- if (gameState === 'carSelection') {
- // Car selection screen is active, don't update game logic
+ if (gameState === 'mainMenu' || gameState === 'carSelection' || gameState === 'shop') {
+ // Menu screens are active, don't update game logic
return;
}
if (gameState === 'playing' && game.playerCar) {
// Update difficulty
@@ -1179,16 +1608,20 @@
// Check collision with player (skip if shield is active)
if (obstacle.intersects(game.playerCar) && !game.playerCar.shieldActive) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
- // Update player stats
+ // Update player stats and storage
playerStats.totalDistance += LK.getScore();
playerStats.totalCoins += currentCoins;
playerStats.gamesPlayed++;
if (LK.getScore() > playerStats.bestScore) {
playerStats.bestScore = LK.getScore();
}
storage.playerStats = playerStats;
+ // Add coins to total storage
+ storage.totalCoins = (storage.totalCoins || 0) + currentCoins;
+ // Reset game state
+ gameState = 'mainMenu';
LK.showGameOver();
return;
}
// Check if obstacle was passed for scoring
Modern App Store icon, high definition, square with rounded corners, for a game titled "Highway Dodge" and with the description "A fast-paced 2D top-down car game where players dodge obstacles on a two-lane highway by switching lanes, with increasing speed and difficulty for endless replayability.". No text on icon!
madeni para. In-Game asset. 2d. High contrast. No shadows
glow effect. In-Game asset. 2d. High contrast. No shadows