/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var CenterLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('centerLine', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += gameSpeed + 2;
// Reset position when off screen
if (self.y > 2800) {
self.y = -100;
}
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.update = function () {
self.y += self.speed + gameSpeed;
};
return self;
});
var EnemyCar = Container.expand(function (carType) {
var self = Container.call(this);
var assetId = carType || 'enemyCar1';
var carGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3 + Math.random() * 4;
self.lane = 0;
self.checkedForNearMiss = false;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.maxSpeed = 8;
self.targetX = 0;
self.update = function () {
// Smooth drag movement - more responsive than lane switching
var diff = self.targetX - self.x;
self.x += diff * 0.15;
// Keep car within road bounds
if (self.x < 600) self.x = 600;
if (self.x > 1448) self.x = 1448;
};
return self;
});
var RoadLane = Container.expand(function () {
var self = Container.call(this);
var laneGraphics = self.attachAsset('roadLane', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += gameSpeed + 2;
// Reset position when off screen
if (self.y > 2800) {
self.y = -100;
}
};
return self;
});
var RoadSurface = Container.expand(function () {
var self = Container.call(this);
var roadGraphics = self.attachAsset('roadSurface', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Tree = Container.expand(function () {
var self = Container.call(this);
// Create tree trunk
var trunkGraphics = self.attachAsset('treeTrunk', {
anchorX: 0.5,
anchorY: 1.0
});
trunkGraphics.y = 0;
// Create tree foliage
var treeGraphics = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 1.0
});
treeGraphics.y = -40;
self.update = function () {
self.y += gameSpeed + 1;
// Reset position when off screen with random placement
if (self.y > 2800) {
self.y = -400 - Math.random() * 400; // Random spawn height above screen
// Randomize horizontal position too
if (self.x < 1000) {
// Left side tree
self.x = 100 + Math.random() * 400;
} else {
// Right side tree
self.x = 1550 + Math.random() * 400;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x00ff00
});
/****
* Game Code
****/
// Game variables
var player;
var enemyCars = [];
var roadLanes = [];
var centerLines = [];
var gameSpeed = 2;
var maxGameSpeed = 12;
var speedIncreaseRate = 0.00175;
var spawnTimer = 0;
var spawnRate = 120;
var distance = 0;
var isGameActive = true;
var dragActive = false;
var gameTime = 0;
var coins = [];
var coinCount = 0;
var nearMissCount = 0;
var nearMissResetTimer = null;
var trees = [];
// Lane positions (3 lanes)
var lanePositions = [700, 1024, 1348];
// Create road surface background
var roadSurface = new RoadSurface();
roadSurface.x = 1024;
roadSurface.y = 1366;
game.addChild(roadSurface);
// Create center lane dividers
for (var i = 0; i < 40; i++) {
// Left center line (between lane 1 and 2)
var leftLine = new CenterLine();
leftLine.x = 862; // Between positions 700 and 1024
leftLine.y = i * 100 - 500;
centerLines.push(leftLine);
game.addChild(leftLine);
// Right center line (between lane 2 and 3)
var rightLine = new CenterLine();
rightLine.x = 1186; // Between positions 1024 and 1348
rightLine.y = i * 100 - 500;
centerLines.push(rightLine);
game.addChild(rightLine);
}
// Create road edge lanes for visual effect
for (var i = 0; i < 20; i++) {
// Left edge
var leftEdge = new RoadLane();
leftEdge.x = 575; // Left side of road
leftEdge.y = i * 150 - 300;
roadLanes.push(leftEdge);
game.addChild(leftEdge);
// Right edge
var rightEdge = new RoadLane();
rightEdge.x = 1473; // Right side of road
rightEdge.y = i * 150 - 300;
roadLanes.push(rightEdge);
game.addChild(rightEdge);
}
// Create background trees with random positioning
for (var i = 0; i < 50; i++) {
// Left side trees - completely random placement
var leftTree = new Tree();
leftTree.x = 100 + Math.random() * 400; // Random position on left side (100-500px)
leftTree.y = Math.random() * 3000 - 800; // Random vertical position
trees.push(leftTree);
game.addChild(leftTree);
// Right side trees - completely random placement
var rightTree = new Tree();
rightTree.x = 1550 + Math.random() * 400; // Random position on right side (1550-1950px)
rightTree.y = Math.random() * 3000 - 800; // Random vertical position
trees.push(rightTree);
game.addChild(rightTree);
}
// Create player car
player = new PlayerCar();
player.x = 1024;
player.y = 2200;
player.targetX = player.x;
game.addChild(player);
// Score display
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Generate random colors for counters
var randomColors = [0xff6b6b,
// Red
0x4ecdc4,
// Teal
0x45b7d1,
// Blue
0x96ceb4,
// Green
0xffeaa7,
// Yellow
0xdda0dd,
// Plum
0xff7675,
// Light Red
0x74b9ff,
// Light Blue
0x00b894,
// Emerald
0xfdcb6e,
// Orange
0xe17055,
// Terracotta
0x6c5ce7 // Purple
];
// Distance display
var distanceText = new Text2('Distance: 0m', {
size: 45,
fill: 0x000000
});
distanceText.anchor.set(0, 0);
distanceText.x = 50;
distanceText.y = 100;
LK.gui.addChild(distanceText);
// Timer display
var timerText = new Text2('Time: 00:00', {
size: 45,
fill: 0x000000
});
timerText.anchor.set(0, 0);
timerText.x = 50;
timerText.y = 200;
LK.gui.addChild(timerText);
// Coin counter display
var coinText = new Text2('Coins: 0', {
size: 45,
fill: 0x000000
});
coinText.anchor.set(1, 0);
coinText.x = LK.gui.width - 50;
coinText.y = 200;
LK.gui.addChild(coinText);
// Speed display
var speedText = new Text2('Speed: 0 km/h', {
size: 45,
fill: 0x000000
});
speedText.anchor.set(1, 0);
speedText.x = LK.gui.width - 50;
speedText.y = 100;
LK.gui.addChild(speedText);
// Near miss counter display
var nearMissText = new Text2('Near Miss: 0', {
size: 45,
fill: 0x000000
});
nearMissText.anchor.set(0, 0);
nearMissText.x = 50;
nearMissText.y = 300;
LK.gui.addChild(nearMissText);
function spawnEnemyCar() {
if (!isGameActive) return;
var carTypes = ['enemyCar1', 'enemyCar2', 'truck', 'bus'];
var randomType = carTypes[Math.floor(Math.random() * carTypes.length)];
var enemy = new EnemyCar(randomType);
// Choose random lane
var laneIndex = Math.floor(Math.random() * lanePositions.length);
enemy.x = lanePositions[laneIndex];
enemy.y = -200;
enemy.lane = laneIndex;
enemy.checkedForOvertake = false;
enemy.lastY = enemy.y;
enemyCars.push(enemy);
game.addChild(enemy);
}
function checkCollisions() {
if (!isGameActive) return;
for (var i = enemyCars.length - 1; i >= 0; i--) {
var enemy = enemyCars[i];
// Check collision with player
if (player.intersects(enemy)) {
// Game over
isGameActive = false;
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
// Show game statistics before game over
showGameStats();
LK.showGameOver();
return;
}
// Check for near miss bonus
if (!enemy.checkedForNearMiss && Math.abs(enemy.y - player.y) < 100 && Math.abs(enemy.x - player.x) < 150) {
enemy.checkedForNearMiss = true;
nearMissCount++;
// Cancel existing reset timer if running
if (nearMissResetTimer) {
tween.stop(nearMissResetTimer);
}
// Start new 5 second reset timer
nearMissResetTimer = {};
tween(nearMissResetTimer, {
dummy: 1
}, {
duration: 5000,
onFinish: function onFinish() {
nearMissCount = 0;
nearMissResetTimer = null;
}
});
LK.setScore(LK.getScore() + 10);
LK.getSound('nearMiss').play();
LK.effects.flashObject(player, 0x00ff00, 200);
// Flash screen with subtle white flash for near miss
LK.effects.flashScreen(0xffffff, 300);
}
// Check for close overtaking bonus - when player passes enemy car closely
if (!enemy.checkedForOvertake && enemy.y > player.y && enemy.lastY <= player.y && Math.abs(enemy.x - player.x) < 120) {
enemy.checkedForOvertake = true;
LK.getSound('nearMiss').play();
LK.effects.flashObject(player, 0xffff00, 300);
}
// Update last position for overtaking detection
enemy.lastY = enemy.y;
// Remove cars that are off screen
if (enemy.y > 2900) {
enemy.destroy();
enemyCars.splice(i, 1);
}
}
}
function showGameStats() {
// Calculate final statistics
var finalScore = LK.getScore();
var finalMinutes = Math.floor(gameTime / 3600);
var finalSeconds = Math.floor(gameTime % 3600 / 60);
var finalTimeText = (finalMinutes < 10 ? '0' : '') + finalMinutes + ':' + (finalSeconds < 10 ? '0' : '') + finalSeconds;
var finalDistance = (Math.floor(distance) / 10).toFixed(1);
// Create statistics display container
var statsContainer = new Container();
statsContainer.x = 1024;
statsContainer.y = 1366;
// Background for stats
var statsBg = LK.getAsset('roadSurface', {
anchorX: 0.5,
anchorY: 0.5,
width: 800,
height: 600,
alpha: 0.9
});
statsBg.tint = 0x2c3e50;
statsContainer.addChild(statsBg);
// Title
var titleText = new Text2('GAME OVER - FINAL STATS', {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -200;
statsContainer.addChild(titleText);
// Score
var finalScoreText = new Text2('Total Score: ' + finalScore, {
size: 50,
fill: 0xffd700
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.y = -100;
statsContainer.addChild(finalScoreText);
// Time
var finalTimeDisplayText = new Text2('Total Time: ' + finalTimeText, {
size: 50,
fill: 0x74b9ff
});
finalTimeDisplayText.anchor.set(0.5, 0.5);
finalTimeDisplayText.y = -25;
statsContainer.addChild(finalTimeDisplayText);
// Near Misses
var finalNearMissText = new Text2('Total Near Misses: ' + nearMissCount, {
size: 50,
fill: 0xff6b6b
});
finalNearMissText.anchor.set(0.5, 0.5);
finalNearMissText.y = 50;
statsContainer.addChild(finalNearMissText);
// Coins
var finalCoinText = new Text2('Total Coins: ' + coinCount, {
size: 50,
fill: 0x00b894
});
finalCoinText.anchor.set(0.5, 0.5);
finalCoinText.y = 125;
statsContainer.addChild(finalCoinText);
// Distance
var finalDistanceText = new Text2('Distance: ' + finalDistance + ' km', {
size: 50,
fill: 0x96ceb4
});
finalDistanceText.anchor.set(0.5, 0.5);
finalDistanceText.y = 200;
statsContainer.addChild(finalDistanceText);
game.addChild(statsContainer);
// Auto-remove stats after 3 seconds
LK.setTimeout(function () {
if (statsContainer && statsContainer.parent) {
statsContainer.destroy();
}
}, 3000);
}
function updateUI() {
scoreText.setText('Score: ' + LK.getScore());
// Change score color to green when speed exceeds 65 km/h
var currentSpeedKmh = Math.floor(gameSpeed * 10);
if (currentSpeedKmh > 65) {
scoreText.tint = 0x00ff00;
} else {
scoreText.tint = 0xFFFFFF;
}
distanceText.setText('Distance: ' + (Math.floor(distance) / 10).toFixed(1) + ' km');
// Cap speed display at 250 km/h
var displaySpeed = Math.min(Math.floor(gameSpeed * 10), 250);
speedText.setText('Speed: ' + displaySpeed + ' km/h');
var minutes = Math.floor(gameTime / 3600);
var seconds = Math.floor(gameTime % 3600 / 60);
timerText.setText('Time: ' + (minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds);
coinText.setText('Coins: ' + coinCount);
nearMissText.setText('Near Miss: ' + nearMissCount);
}
// Drag controls - start dragging
game.down = function (x, y, obj) {
if (!isGameActive) return;
dragActive = true;
player.targetX = x;
};
game.move = function (x, y, obj) {
if (!isGameActive || !dragActive) return;
// Smooth drag movement
player.targetX = x;
// Constrain to road bounds
if (player.targetX < 600) player.targetX = 600;
if (player.targetX > 1448) player.targetX = 1448;
};
game.up = function (x, y, obj) {
dragActive = false;
};
// Main game loop
game.update = function () {
if (!isGameActive) return;
// Update game time (60 FPS)
gameTime++;
// Increase game speed gradually
if (gameSpeed < maxGameSpeed) {
gameSpeed += speedIncreaseRate;
}
// Update distance
distance += gameSpeed * 0.1 * 0.045;
// Add distance points - score increases with speed, but only start scoring at 25 km/h
if (LK.ticks % 40 === 0) {
var speedBonus = Math.floor(gameSpeed);
var currentSpeedKmh = Math.floor(gameSpeed * 10);
if (currentSpeedKmh >= 25) {
// Only start scoring when speed is 25 km/h or higher
if (currentSpeedKmh > 65) {
LK.setScore(LK.getScore() + 4);
} else {
LK.setScore(LK.getScore() + 2);
}
}
}
// Check if we crossed a 5 km threshold for coins
var currentKm = Math.floor(Math.floor(distance) / 10 / 5);
var lastKm = Math.floor(Math.floor(distance - gameSpeed * 0.1 * 0.045) / 10 / 5);
if (currentKm > lastKm) {
coinCount += currentKm - lastKm;
}
// Spawn enemy cars
spawnTimer++;
var currentSpawnRate = Math.max(30, spawnRate - Math.floor(gameSpeed * 8));
if (spawnTimer >= currentSpawnRate) {
spawnEnemyCar();
spawnTimer = 0;
}
// Check collisions
checkCollisions();
// Update UI
updateUI();
// Victory condition - survive for very long distance
if (distance >= 10000) {
isGameActive = false;
LK.showYouWin();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var CenterLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('centerLine', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += gameSpeed + 2;
// Reset position when off screen
if (self.y > 2800) {
self.y = -100;
}
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.update = function () {
self.y += self.speed + gameSpeed;
};
return self;
});
var EnemyCar = Container.expand(function (carType) {
var self = Container.call(this);
var assetId = carType || 'enemyCar1';
var carGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3 + Math.random() * 4;
self.lane = 0;
self.checkedForNearMiss = false;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.maxSpeed = 8;
self.targetX = 0;
self.update = function () {
// Smooth drag movement - more responsive than lane switching
var diff = self.targetX - self.x;
self.x += diff * 0.15;
// Keep car within road bounds
if (self.x < 600) self.x = 600;
if (self.x > 1448) self.x = 1448;
};
return self;
});
var RoadLane = Container.expand(function () {
var self = Container.call(this);
var laneGraphics = self.attachAsset('roadLane', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += gameSpeed + 2;
// Reset position when off screen
if (self.y > 2800) {
self.y = -100;
}
};
return self;
});
var RoadSurface = Container.expand(function () {
var self = Container.call(this);
var roadGraphics = self.attachAsset('roadSurface', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Tree = Container.expand(function () {
var self = Container.call(this);
// Create tree trunk
var trunkGraphics = self.attachAsset('treeTrunk', {
anchorX: 0.5,
anchorY: 1.0
});
trunkGraphics.y = 0;
// Create tree foliage
var treeGraphics = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 1.0
});
treeGraphics.y = -40;
self.update = function () {
self.y += gameSpeed + 1;
// Reset position when off screen with random placement
if (self.y > 2800) {
self.y = -400 - Math.random() * 400; // Random spawn height above screen
// Randomize horizontal position too
if (self.x < 1000) {
// Left side tree
self.x = 100 + Math.random() * 400;
} else {
// Right side tree
self.x = 1550 + Math.random() * 400;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x00ff00
});
/****
* Game Code
****/
// Game variables
var player;
var enemyCars = [];
var roadLanes = [];
var centerLines = [];
var gameSpeed = 2;
var maxGameSpeed = 12;
var speedIncreaseRate = 0.00175;
var spawnTimer = 0;
var spawnRate = 120;
var distance = 0;
var isGameActive = true;
var dragActive = false;
var gameTime = 0;
var coins = [];
var coinCount = 0;
var nearMissCount = 0;
var nearMissResetTimer = null;
var trees = [];
// Lane positions (3 lanes)
var lanePositions = [700, 1024, 1348];
// Create road surface background
var roadSurface = new RoadSurface();
roadSurface.x = 1024;
roadSurface.y = 1366;
game.addChild(roadSurface);
// Create center lane dividers
for (var i = 0; i < 40; i++) {
// Left center line (between lane 1 and 2)
var leftLine = new CenterLine();
leftLine.x = 862; // Between positions 700 and 1024
leftLine.y = i * 100 - 500;
centerLines.push(leftLine);
game.addChild(leftLine);
// Right center line (between lane 2 and 3)
var rightLine = new CenterLine();
rightLine.x = 1186; // Between positions 1024 and 1348
rightLine.y = i * 100 - 500;
centerLines.push(rightLine);
game.addChild(rightLine);
}
// Create road edge lanes for visual effect
for (var i = 0; i < 20; i++) {
// Left edge
var leftEdge = new RoadLane();
leftEdge.x = 575; // Left side of road
leftEdge.y = i * 150 - 300;
roadLanes.push(leftEdge);
game.addChild(leftEdge);
// Right edge
var rightEdge = new RoadLane();
rightEdge.x = 1473; // Right side of road
rightEdge.y = i * 150 - 300;
roadLanes.push(rightEdge);
game.addChild(rightEdge);
}
// Create background trees with random positioning
for (var i = 0; i < 50; i++) {
// Left side trees - completely random placement
var leftTree = new Tree();
leftTree.x = 100 + Math.random() * 400; // Random position on left side (100-500px)
leftTree.y = Math.random() * 3000 - 800; // Random vertical position
trees.push(leftTree);
game.addChild(leftTree);
// Right side trees - completely random placement
var rightTree = new Tree();
rightTree.x = 1550 + Math.random() * 400; // Random position on right side (1550-1950px)
rightTree.y = Math.random() * 3000 - 800; // Random vertical position
trees.push(rightTree);
game.addChild(rightTree);
}
// Create player car
player = new PlayerCar();
player.x = 1024;
player.y = 2200;
player.targetX = player.x;
game.addChild(player);
// Score display
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Generate random colors for counters
var randomColors = [0xff6b6b,
// Red
0x4ecdc4,
// Teal
0x45b7d1,
// Blue
0x96ceb4,
// Green
0xffeaa7,
// Yellow
0xdda0dd,
// Plum
0xff7675,
// Light Red
0x74b9ff,
// Light Blue
0x00b894,
// Emerald
0xfdcb6e,
// Orange
0xe17055,
// Terracotta
0x6c5ce7 // Purple
];
// Distance display
var distanceText = new Text2('Distance: 0m', {
size: 45,
fill: 0x000000
});
distanceText.anchor.set(0, 0);
distanceText.x = 50;
distanceText.y = 100;
LK.gui.addChild(distanceText);
// Timer display
var timerText = new Text2('Time: 00:00', {
size: 45,
fill: 0x000000
});
timerText.anchor.set(0, 0);
timerText.x = 50;
timerText.y = 200;
LK.gui.addChild(timerText);
// Coin counter display
var coinText = new Text2('Coins: 0', {
size: 45,
fill: 0x000000
});
coinText.anchor.set(1, 0);
coinText.x = LK.gui.width - 50;
coinText.y = 200;
LK.gui.addChild(coinText);
// Speed display
var speedText = new Text2('Speed: 0 km/h', {
size: 45,
fill: 0x000000
});
speedText.anchor.set(1, 0);
speedText.x = LK.gui.width - 50;
speedText.y = 100;
LK.gui.addChild(speedText);
// Near miss counter display
var nearMissText = new Text2('Near Miss: 0', {
size: 45,
fill: 0x000000
});
nearMissText.anchor.set(0, 0);
nearMissText.x = 50;
nearMissText.y = 300;
LK.gui.addChild(nearMissText);
function spawnEnemyCar() {
if (!isGameActive) return;
var carTypes = ['enemyCar1', 'enemyCar2', 'truck', 'bus'];
var randomType = carTypes[Math.floor(Math.random() * carTypes.length)];
var enemy = new EnemyCar(randomType);
// Choose random lane
var laneIndex = Math.floor(Math.random() * lanePositions.length);
enemy.x = lanePositions[laneIndex];
enemy.y = -200;
enemy.lane = laneIndex;
enemy.checkedForOvertake = false;
enemy.lastY = enemy.y;
enemyCars.push(enemy);
game.addChild(enemy);
}
function checkCollisions() {
if (!isGameActive) return;
for (var i = enemyCars.length - 1; i >= 0; i--) {
var enemy = enemyCars[i];
// Check collision with player
if (player.intersects(enemy)) {
// Game over
isGameActive = false;
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
// Show game statistics before game over
showGameStats();
LK.showGameOver();
return;
}
// Check for near miss bonus
if (!enemy.checkedForNearMiss && Math.abs(enemy.y - player.y) < 100 && Math.abs(enemy.x - player.x) < 150) {
enemy.checkedForNearMiss = true;
nearMissCount++;
// Cancel existing reset timer if running
if (nearMissResetTimer) {
tween.stop(nearMissResetTimer);
}
// Start new 5 second reset timer
nearMissResetTimer = {};
tween(nearMissResetTimer, {
dummy: 1
}, {
duration: 5000,
onFinish: function onFinish() {
nearMissCount = 0;
nearMissResetTimer = null;
}
});
LK.setScore(LK.getScore() + 10);
LK.getSound('nearMiss').play();
LK.effects.flashObject(player, 0x00ff00, 200);
// Flash screen with subtle white flash for near miss
LK.effects.flashScreen(0xffffff, 300);
}
// Check for close overtaking bonus - when player passes enemy car closely
if (!enemy.checkedForOvertake && enemy.y > player.y && enemy.lastY <= player.y && Math.abs(enemy.x - player.x) < 120) {
enemy.checkedForOvertake = true;
LK.getSound('nearMiss').play();
LK.effects.flashObject(player, 0xffff00, 300);
}
// Update last position for overtaking detection
enemy.lastY = enemy.y;
// Remove cars that are off screen
if (enemy.y > 2900) {
enemy.destroy();
enemyCars.splice(i, 1);
}
}
}
function showGameStats() {
// Calculate final statistics
var finalScore = LK.getScore();
var finalMinutes = Math.floor(gameTime / 3600);
var finalSeconds = Math.floor(gameTime % 3600 / 60);
var finalTimeText = (finalMinutes < 10 ? '0' : '') + finalMinutes + ':' + (finalSeconds < 10 ? '0' : '') + finalSeconds;
var finalDistance = (Math.floor(distance) / 10).toFixed(1);
// Create statistics display container
var statsContainer = new Container();
statsContainer.x = 1024;
statsContainer.y = 1366;
// Background for stats
var statsBg = LK.getAsset('roadSurface', {
anchorX: 0.5,
anchorY: 0.5,
width: 800,
height: 600,
alpha: 0.9
});
statsBg.tint = 0x2c3e50;
statsContainer.addChild(statsBg);
// Title
var titleText = new Text2('GAME OVER - FINAL STATS', {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -200;
statsContainer.addChild(titleText);
// Score
var finalScoreText = new Text2('Total Score: ' + finalScore, {
size: 50,
fill: 0xffd700
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.y = -100;
statsContainer.addChild(finalScoreText);
// Time
var finalTimeDisplayText = new Text2('Total Time: ' + finalTimeText, {
size: 50,
fill: 0x74b9ff
});
finalTimeDisplayText.anchor.set(0.5, 0.5);
finalTimeDisplayText.y = -25;
statsContainer.addChild(finalTimeDisplayText);
// Near Misses
var finalNearMissText = new Text2('Total Near Misses: ' + nearMissCount, {
size: 50,
fill: 0xff6b6b
});
finalNearMissText.anchor.set(0.5, 0.5);
finalNearMissText.y = 50;
statsContainer.addChild(finalNearMissText);
// Coins
var finalCoinText = new Text2('Total Coins: ' + coinCount, {
size: 50,
fill: 0x00b894
});
finalCoinText.anchor.set(0.5, 0.5);
finalCoinText.y = 125;
statsContainer.addChild(finalCoinText);
// Distance
var finalDistanceText = new Text2('Distance: ' + finalDistance + ' km', {
size: 50,
fill: 0x96ceb4
});
finalDistanceText.anchor.set(0.5, 0.5);
finalDistanceText.y = 200;
statsContainer.addChild(finalDistanceText);
game.addChild(statsContainer);
// Auto-remove stats after 3 seconds
LK.setTimeout(function () {
if (statsContainer && statsContainer.parent) {
statsContainer.destroy();
}
}, 3000);
}
function updateUI() {
scoreText.setText('Score: ' + LK.getScore());
// Change score color to green when speed exceeds 65 km/h
var currentSpeedKmh = Math.floor(gameSpeed * 10);
if (currentSpeedKmh > 65) {
scoreText.tint = 0x00ff00;
} else {
scoreText.tint = 0xFFFFFF;
}
distanceText.setText('Distance: ' + (Math.floor(distance) / 10).toFixed(1) + ' km');
// Cap speed display at 250 km/h
var displaySpeed = Math.min(Math.floor(gameSpeed * 10), 250);
speedText.setText('Speed: ' + displaySpeed + ' km/h');
var minutes = Math.floor(gameTime / 3600);
var seconds = Math.floor(gameTime % 3600 / 60);
timerText.setText('Time: ' + (minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds);
coinText.setText('Coins: ' + coinCount);
nearMissText.setText('Near Miss: ' + nearMissCount);
}
// Drag controls - start dragging
game.down = function (x, y, obj) {
if (!isGameActive) return;
dragActive = true;
player.targetX = x;
};
game.move = function (x, y, obj) {
if (!isGameActive || !dragActive) return;
// Smooth drag movement
player.targetX = x;
// Constrain to road bounds
if (player.targetX < 600) player.targetX = 600;
if (player.targetX > 1448) player.targetX = 1448;
};
game.up = function (x, y, obj) {
dragActive = false;
};
// Main game loop
game.update = function () {
if (!isGameActive) return;
// Update game time (60 FPS)
gameTime++;
// Increase game speed gradually
if (gameSpeed < maxGameSpeed) {
gameSpeed += speedIncreaseRate;
}
// Update distance
distance += gameSpeed * 0.1 * 0.045;
// Add distance points - score increases with speed, but only start scoring at 25 km/h
if (LK.ticks % 40 === 0) {
var speedBonus = Math.floor(gameSpeed);
var currentSpeedKmh = Math.floor(gameSpeed * 10);
if (currentSpeedKmh >= 25) {
// Only start scoring when speed is 25 km/h or higher
if (currentSpeedKmh > 65) {
LK.setScore(LK.getScore() + 4);
} else {
LK.setScore(LK.getScore() + 2);
}
}
}
// Check if we crossed a 5 km threshold for coins
var currentKm = Math.floor(Math.floor(distance) / 10 / 5);
var lastKm = Math.floor(Math.floor(distance - gameSpeed * 0.1 * 0.045) / 10 / 5);
if (currentKm > lastKm) {
coinCount += currentKm - lastKm;
}
// Spawn enemy cars
spawnTimer++;
var currentSpawnRate = Math.max(30, spawnRate - Math.floor(gameSpeed * 8));
if (spawnTimer >= currentSpawnRate) {
spawnEnemyCar();
spawnTimer = 0;
}
// Check collisions
checkCollisions();
// Update UI
updateUI();
// Victory condition - survive for very long distance
if (distance >= 10000) {
isGameActive = false;
LK.showYouWin();
}
};
Pixel art Araba kuş bakışı şeklinde olsun. In-Game asset. 2d. High contrast. No shadows
Pixel art mavi araba kuş bakışı. In-Game asset. 2d. High contrast. No shadows
Pixel art kamyon kuş bakışı. In-Game asset. 2d. High contrast. No shadows
Pixel art mavi otobüs kuş bakışı. In-Game asset. 2d. High contrast. No shadows
Pixel art spor araba kus bakışı. In-Game asset. 2d. High contrast. No shadows