User prompt
2 arabyıda azcık küçükt
User prompt
Arabalırın boyutunu eşitle
User prompt
Kırmızı arabayla mavi arabaıyı mavi arabaya göre eşitle
User prompt
Arabayı azıcık küçült
User prompt
Şerit çizgilerini azalt
User prompt
Şerit çizgilerini kes
User prompt
Şertileri büyükt
User prompt
Bi daha yap
User prompt
Bi daha yap
User prompt
Şerit çizgilerini çok çok azcık küçült
User prompt
Arabaları çok çok azcık küçült
User prompt
Şeritleri küçült
User prompt
Ağacı çok azcık çoğalt
User prompt
Ağacı çok azcık çoğalt
User prompt
Ağacı ççok az koy
User prompt
Ağacı azalt
User prompt
Ağacı azalt
User prompt
Geçilmeyen yola ağaç ekle
User prompt
Engel arabalır ve oyuncu arabadını büyült ve eşit yap
Code edit (1 edits merged)
Please save this source code
User prompt
Yol Yarışı: Araba Kaçışı
Initial prompt
Yol olsun araba olsun araba gitsin sağ basılı tutuğumuzda sağ sola basılı tutuğumzda sola gitsin trafik racer gibi
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Banknote = Container.expand(function () { var self = Container.call(this); var banknoteAsset = self.attachAsset('banknote', { anchorX: 0.5, anchorY: 0.5 }); banknoteAsset.width = banknoteWidth; banknoteAsset.height = banknoteHeight; self.width = banknoteAsset.width; self.height = banknoteAsset.height; self.speedY = 0; self.update = function () { self.y += self.speedY; }; return self; }); // Coin for road var Coin = Container.expand(function () { var self = Container.call(this); // Use a simple yellow ellipse as the coin var coinAsset = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); coinAsset.width = coinWidth; coinAsset.height = coinHeight; self.width = coinAsset.width; self.height = coinAsset.height; self.speedY = 0; self.update = function () { self.y += self.speedY; }; return self; }); // Banknote (paper money) for road // Road Lane Marking var LaneMarking = Container.expand(function () { var self = Container.call(this); var marking = self.attachAsset('laneMarking', { anchorX: 0.5, anchorY: 0.5 }); marking.width = laneMarkingWidth; marking.height = laneMarkingHeight; self.width = marking.width; self.height = marking.height; self.speedY = 0; self.update = function () { self.y += self.speedY; }; return self; }); // Obstacle Car var ObstacleCar = Container.expand(function () { var self = Container.call(this); var carAsset = self.attachAsset('obstacleCar', { anchorX: 0.5, anchorY: 0.5 }); carAsset.width = obstacleCarWidth; carAsset.height = obstacleCarHeight; self.width = carAsset.width; self.height = carAsset.height; self.speedY = 0; // Vertical speed self.update = function () { self.y += self.speedY; }; return self; }); // Player's Car var PlayerCar = Container.expand(function () { var self = Container.call(this); var carAsset = self.attachAsset('playerCar', { anchorX: 0.5, anchorY: 0.5 }); carAsset.width = playerCarWidth; carAsset.height = playerCarHeight; self.width = carAsset.width; self.height = carAsset.height; self.speedX = 0; // Horizontal speed // Update method called every tick self.update = function () { // --- DRIFT/SKID EFFECT --- // Initialize drift/skid state variables if not present if (self.slideAngle === undefined) self.slideAngle = 0; if (self.targetAngle === undefined) self.targetAngle = 0; if (self.driftOffset === undefined) self.driftOffset = 0; if (self.driftTargetOffset === undefined) self.driftTargetOffset = 0; // Calculate target angle and lateral offset based on speedX (simulate drift) // The more the player turns, the more the car visually rotates and slides sideways var maxDriftAngle = Math.PI / 7; // maximum visual drift angle (radians) var maxDriftOffset = 60; // maximum sideways offset (pixels) var driftSpeed = 0.18; // how quickly the car rotates to the drift angle var offsetSpeed = 0.12; // how quickly the car slides to the drift offset // Set drift targets based on speedX if (self.speedX < -1) { self.targetAngle = -maxDriftAngle; self.driftTargetOffset = -maxDriftOffset; } else if (self.speedX > 1) { self.targetAngle = maxDriftAngle; self.driftTargetOffset = maxDriftOffset; } else { self.targetAngle = 0; self.driftTargetOffset = 0; } // Smoothly interpolate slideAngle and driftOffset towards their targets self.slideAngle += (self.targetAngle - self.slideAngle) * driftSpeed; self.driftOffset += (self.driftTargetOffset - self.driftOffset) * offsetSpeed; // Apply rotation and lateral offset to car asset (visual only, not affecting movement) if (self.children && self.children.length > 0) { self.children[0].rotation = self.slideAngle; self.children[0].x = self.driftOffset; } // Move car horizontally self.x += self.speedX; // Clamp to road bounds if (self.x < roadLeft + self.width / 2) self.x = roadLeft + self.width / 2; if (self.x > roadRight - self.width / 2) self.x = roadRight - self.width / 2; }; return self; }); // Tree for road edge var Tree = Container.expand(function () { var self = Container.call(this); var treeAsset = self.attachAsset('tree', { anchorX: 0.5, anchorY: 0.5 }); self.width = treeAsset.width; self.height = treeAsset.height; self.speedY = 0; self.update = function () { self.y += self.speedY; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Road dimensions // Banknote (paper money) for road var banknoteWidth = 120; var banknoteHeight = 60; var roadWidth = 900; var roadLeft = (2048 - roadWidth) / 2; var roadRight = roadLeft + roadWidth; // Lane count and positions var laneCount = 3; var laneWidth = roadWidth / laneCount; var laneCenters = [roadLeft + laneWidth / 2, roadLeft + laneWidth * 1.5, roadLeft + laneWidth * 2.5]; // Player and obstacle car size (equalized, made slightly larger) var playerCarWidth = 200; var playerCarHeight = 320; var obstacleCarWidth = 200; var obstacleCarHeight = 320; // Lane marking size var laneMarkingWidth = 54; var laneMarkingHeight = 330; // Tree size and spacing var treeWidth = 180; var treeHeight = 270; var treeSpacing = 220; // Asset initialization (shapes) // Game variables var playerCar; var obstacles = []; var laneMarkings = []; var trees = []; var coins = []; var banknotes = []; var coinSpawnTimer = 0; var coinSpawnInterval = 45; // frames, coins spawn more frequently var banknoteSpawnTimer = 0; var banknoteSpawnInterval = 120; // frames, less frequent than coins var coinWidth = 80; var coinHeight = 80; var obstacleSpawnTimer = 0; var obstacleSpawnInterval = 60; // frames var laneMarkingSpacing = 320; var speed = 18; // vertical speed (pixels per frame) var score = 0; var distance = 0; var isGameOver = false; // Add coin score indicator to the GUI var coinScoreTxt = new Text2('0', { size: 120, fill: 0xFFE066 }); coinScoreTxt.anchor.set(0.5, 0); // Centered at top // Place at top center, but not in the top left 100x100 px LK.gui.top.addChild(coinScoreTxt); // Initialize player car playerCar = new PlayerCar(); playerCar.x = laneCenters[1]; playerCar.y = 2732 - 400; game.addChild(playerCar); // Initialize lane markings as dashed (split into short segments) var dashLength = 80; var dashGap = 80; var dashesPerMarking = Math.floor(laneMarkingHeight / (dashLength + dashGap)); for (var i = 0; i < laneCount - 1; i++) { for (var j = 0; j < Math.ceil(2732 / laneMarkingSpacing) + 2; j++) { var baseY = j * laneMarkingSpacing - laneMarkingHeight / 2; for (var d = 0; d < dashesPerMarking; d++) { var marking = new LaneMarking(); marking.x = roadLeft + laneWidth * (i + 1); marking.y = baseY + d * (dashLength + dashGap); marking.speedY = speed; marking.height = dashLength; marking.width = laneMarkingWidth; laneMarkings.push(marking); game.addChild(marking); } } } // Initialize trees along both sides of the road (slightly more trees) for (var side = 0; side < 2; side++) { var xPos = side === 0 ? roadLeft - treeWidth / 2 - 30 : roadRight + treeWidth / 2 + 30; for (var j = 0; j < 6; j++) { // 6 trees per side! var tree = new Tree(); tree.x = xPos; tree.y = j * (2732 / 6) + 100; tree.speedY = speed; trees.push(tree); game.addChild(tree); } } // Touch controls var moveLeft = false; var moveRight = false; // Helper: get which side of the screen is pressed function getSide(x) { if (x < 2048 / 2) return 'left'; return 'right'; } // Touch down game.down = function (x, y, obj) { if (isGameOver) return; var side = getSide(x); if (side === 'left') { moveLeft = true; moveRight = false; } else { moveRight = true; moveLeft = false; } updatePlayerSpeed(); }; // Touch up game.up = function (x, y, obj) { moveLeft = false; moveRight = false; updatePlayerSpeed(); }; // Touch move (optional, for smoother control) game.move = function (x, y, obj) { if (isGameOver) return; var side = getSide(x); if (side === 'left') { moveLeft = true; moveRight = false; } else { moveRight = true; moveLeft = false; } updatePlayerSpeed(); }; // Update player car speedX based on input function updatePlayerSpeed() { if (moveLeft && !moveRight) { playerCar.speedX = -22; } else if (moveRight && !moveLeft) { playerCar.speedX = 22; } else { playerCar.speedX = 0; } } // Main game update loop game.update = function () { if (isGameOver) return; // Update lane markings for (var i = 0; i < laneMarkings.length; i++) { var marking = laneMarkings[i]; marking.speedY = speed; marking.update(); if (marking.y > 2732 + laneMarkingHeight / 2) { marking.y -= (Math.ceil(2732 / laneMarkingSpacing) + 2) * laneMarkingSpacing; } } // Update trees for (var i = 0; i < trees.length; i++) { var tree = trees[i]; tree.speedY = speed; tree.update(); if (tree.y > 2732 + treeHeight / 2) { tree.y -= (Math.ceil(2732 / treeSpacing) + 3) * treeSpacing; } } // Update player car playerCar.update(); // Spawn coins coinSpawnTimer++; if (coinSpawnTimer >= coinSpawnInterval) { coinSpawnTimer = 0; // Spawn coin in a random lane var coin = new Coin(); var laneIdx = Math.floor(Math.random() * laneCount); coin.x = laneCenters[laneIdx]; coin.y = -coinHeight / 2; coin.speedY = speed; coins.push(coin); game.addChild(coin); } // Spawn banknotes banknoteSpawnTimer++; if (banknoteSpawnTimer >= banknoteSpawnInterval) { banknoteSpawnTimer = 0; var banknote = new Banknote(); var laneIdx = Math.floor(Math.random() * laneCount); banknote.x = laneCenters[laneIdx]; banknote.y = -banknoteHeight / 2; banknote.speedY = speed; banknotes.push(banknote); game.addChild(banknote); } // Update coins for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; coin.speedY = speed; coin.update(); // Remove if off screen if (coin.y > 2732 + coinHeight) { coin.destroy(); coins.splice(i, 1); continue; } // Collect coin if (playerCar.intersects(coin)) { coin.destroy(); coins.splice(i, 1); score += 1; // Add 1 point for each coin coinScoreTxt.setText(score); // Update coin score indicator continue; } } // Update banknotes for (var i = banknotes.length - 1; i >= 0; i--) { var banknote = banknotes[i]; banknote.speedY = speed; banknote.update(); if (banknote.y > 2732 + banknoteHeight) { banknote.destroy(); banknotes.splice(i, 1); continue; } // Collect banknote if (playerCar.intersects(banknote)) { banknote.destroy(); banknotes.splice(i, 1); score += 200; // Add 200 points for each banknote coinScoreTxt.setText(score); continue; } } // Spawn obstacles obstacleSpawnTimer++; if (obstacleSpawnTimer >= obstacleSpawnInterval) { obstacleSpawnTimer = 0; spawnObstacle(); } // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.update(); // Remove if off screen if (obs.y > 2732 + obstacleCarHeight) { obs.destroy(); obstacles.splice(i, 1); continue; } // Collision detection if (playerCar.intersects(obs)) { gameOver(); return; } } // Update distance (for possible future use) distance += speed; // Do not update score or coinScoreTxt here; only update when collecting coins // scoreTxt.setText(score);//{2B} (removed) // Gradually increase speed for difficulty if (LK.ticks % 180 === 0 && speed < 36) { speed += 1; } }; // Spawn an obstacle car in a random lane function spawnObstacle() { // Synchronize the red car (obstacle) to the blue car (player) on spawn var obs = new ObstacleCar(); obs.x = playerCar.x; obs.y = -obstacleCarHeight / 2; obs.speedY = speed; obstacles.push(obs); game.addChild(obs); } // Game over logic function gameOver() { isGameOver = true; LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); } // Reset on game restart game.on('reset', function () { // Remove all obstacles for (var i = 0; i < obstacles.length; i++) { obstacles[i].destroy(); } obstacles = []; // Remove all coins for (var i = 0; i < coins.length; i++) { coins[i].destroy(); } coins = []; // Remove all banknotes for (var i = 0; i < banknotes.length; i++) { banknotes[i].destroy(); } banknotes = []; // Remove all lane markings for (var i = 0; i < laneMarkings.length; i++) { laneMarkings[i].destroy(); } laneMarkings = []; // Remove all trees for (var i = 0; i < trees.length; i++) { trees[i].destroy(); } trees = []; // Recreate lane markings as dashed var dashLength = 80; var dashGap = 80; var dashesPerMarking = Math.floor(laneMarkingHeight / (dashLength + dashGap)); for (var i = 0; i < laneCount - 1; i++) { for (var j = 0; j < Math.ceil(2732 / laneMarkingSpacing) + 2; j++) { var baseY = j * laneMarkingSpacing - laneMarkingHeight / 2; for (var d = 0; d < dashesPerMarking; d++) { var marking = new LaneMarking(); marking.x = roadLeft + laneWidth * (i + 1); marking.y = baseY + d * (dashLength + dashGap); marking.speedY = speed; marking.height = dashLength; marking.width = laneMarkingWidth; laneMarkings.push(marking); game.addChild(marking); } } } // Recreate trees (slightly more trees) for (var side = 0; side < 2; side++) { var xPos = side === 0 ? roadLeft - treeWidth / 2 - 30 : roadRight + treeWidth / 2 + 30; for (var j = 0; j < 6; j++) { // 6 trees per side! var tree = new Tree(); tree.x = xPos; tree.y = j * (2732 / 6) + 100; tree.speedY = speed; trees.push(tree); game.addChild(tree); } } // Reset player position playerCar.x = laneCenters[1]; playerCar.y = 2732 - 400; playerCar.speedX = 0; moveLeft = false; moveRight = false; updatePlayerSpeed(); // Reset score and distance score = 0; distance = 0; coinScoreTxt.setText('0'); // Reset coin score indicator isGameOver = false; speed = 18; obstacleSpawnTimer = 0; }); // Prevent placing anything in top left 100x100 px (no code needed, just a reminder)
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Banknote = Container.expand(function () {
var self = Container.call(this);
var banknoteAsset = self.attachAsset('banknote', {
anchorX: 0.5,
anchorY: 0.5
});
banknoteAsset.width = banknoteWidth;
banknoteAsset.height = banknoteHeight;
self.width = banknoteAsset.width;
self.height = banknoteAsset.height;
self.speedY = 0;
self.update = function () {
self.y += self.speedY;
};
return self;
});
// Coin for road
var Coin = Container.expand(function () {
var self = Container.call(this);
// Use a simple yellow ellipse as the coin
var coinAsset = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
coinAsset.width = coinWidth;
coinAsset.height = coinHeight;
self.width = coinAsset.width;
self.height = coinAsset.height;
self.speedY = 0;
self.update = function () {
self.y += self.speedY;
};
return self;
});
// Banknote (paper money) for road
// Road Lane Marking
var LaneMarking = Container.expand(function () {
var self = Container.call(this);
var marking = self.attachAsset('laneMarking', {
anchorX: 0.5,
anchorY: 0.5
});
marking.width = laneMarkingWidth;
marking.height = laneMarkingHeight;
self.width = marking.width;
self.height = marking.height;
self.speedY = 0;
self.update = function () {
self.y += self.speedY;
};
return self;
});
// Obstacle Car
var ObstacleCar = Container.expand(function () {
var self = Container.call(this);
var carAsset = self.attachAsset('obstacleCar', {
anchorX: 0.5,
anchorY: 0.5
});
carAsset.width = obstacleCarWidth;
carAsset.height = obstacleCarHeight;
self.width = carAsset.width;
self.height = carAsset.height;
self.speedY = 0; // Vertical speed
self.update = function () {
self.y += self.speedY;
};
return self;
});
// Player's Car
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var carAsset = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
carAsset.width = playerCarWidth;
carAsset.height = playerCarHeight;
self.width = carAsset.width;
self.height = carAsset.height;
self.speedX = 0; // Horizontal speed
// Update method called every tick
self.update = function () {
// --- DRIFT/SKID EFFECT ---
// Initialize drift/skid state variables if not present
if (self.slideAngle === undefined) self.slideAngle = 0;
if (self.targetAngle === undefined) self.targetAngle = 0;
if (self.driftOffset === undefined) self.driftOffset = 0;
if (self.driftTargetOffset === undefined) self.driftTargetOffset = 0;
// Calculate target angle and lateral offset based on speedX (simulate drift)
// The more the player turns, the more the car visually rotates and slides sideways
var maxDriftAngle = Math.PI / 7; // maximum visual drift angle (radians)
var maxDriftOffset = 60; // maximum sideways offset (pixels)
var driftSpeed = 0.18; // how quickly the car rotates to the drift angle
var offsetSpeed = 0.12; // how quickly the car slides to the drift offset
// Set drift targets based on speedX
if (self.speedX < -1) {
self.targetAngle = -maxDriftAngle;
self.driftTargetOffset = -maxDriftOffset;
} else if (self.speedX > 1) {
self.targetAngle = maxDriftAngle;
self.driftTargetOffset = maxDriftOffset;
} else {
self.targetAngle = 0;
self.driftTargetOffset = 0;
}
// Smoothly interpolate slideAngle and driftOffset towards their targets
self.slideAngle += (self.targetAngle - self.slideAngle) * driftSpeed;
self.driftOffset += (self.driftTargetOffset - self.driftOffset) * offsetSpeed;
// Apply rotation and lateral offset to car asset (visual only, not affecting movement)
if (self.children && self.children.length > 0) {
self.children[0].rotation = self.slideAngle;
self.children[0].x = self.driftOffset;
}
// Move car horizontally
self.x += self.speedX;
// Clamp to road bounds
if (self.x < roadLeft + self.width / 2) self.x = roadLeft + self.width / 2;
if (self.x > roadRight - self.width / 2) self.x = roadRight - self.width / 2;
};
return self;
});
// Tree for road edge
var Tree = Container.expand(function () {
var self = Container.call(this);
var treeAsset = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = treeAsset.width;
self.height = treeAsset.height;
self.speedY = 0;
self.update = function () {
self.y += self.speedY;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Road dimensions
// Banknote (paper money) for road
var banknoteWidth = 120;
var banknoteHeight = 60;
var roadWidth = 900;
var roadLeft = (2048 - roadWidth) / 2;
var roadRight = roadLeft + roadWidth;
// Lane count and positions
var laneCount = 3;
var laneWidth = roadWidth / laneCount;
var laneCenters = [roadLeft + laneWidth / 2, roadLeft + laneWidth * 1.5, roadLeft + laneWidth * 2.5];
// Player and obstacle car size (equalized, made slightly larger)
var playerCarWidth = 200;
var playerCarHeight = 320;
var obstacleCarWidth = 200;
var obstacleCarHeight = 320;
// Lane marking size
var laneMarkingWidth = 54;
var laneMarkingHeight = 330;
// Tree size and spacing
var treeWidth = 180;
var treeHeight = 270;
var treeSpacing = 220;
// Asset initialization (shapes)
// Game variables
var playerCar;
var obstacles = [];
var laneMarkings = [];
var trees = [];
var coins = [];
var banknotes = [];
var coinSpawnTimer = 0;
var coinSpawnInterval = 45; // frames, coins spawn more frequently
var banknoteSpawnTimer = 0;
var banknoteSpawnInterval = 120; // frames, less frequent than coins
var coinWidth = 80;
var coinHeight = 80;
var obstacleSpawnTimer = 0;
var obstacleSpawnInterval = 60; // frames
var laneMarkingSpacing = 320;
var speed = 18; // vertical speed (pixels per frame)
var score = 0;
var distance = 0;
var isGameOver = false;
// Add coin score indicator to the GUI
var coinScoreTxt = new Text2('0', {
size: 120,
fill: 0xFFE066
});
coinScoreTxt.anchor.set(0.5, 0); // Centered at top
// Place at top center, but not in the top left 100x100 px
LK.gui.top.addChild(coinScoreTxt);
// Initialize player car
playerCar = new PlayerCar();
playerCar.x = laneCenters[1];
playerCar.y = 2732 - 400;
game.addChild(playerCar);
// Initialize lane markings as dashed (split into short segments)
var dashLength = 80;
var dashGap = 80;
var dashesPerMarking = Math.floor(laneMarkingHeight / (dashLength + dashGap));
for (var i = 0; i < laneCount - 1; i++) {
for (var j = 0; j < Math.ceil(2732 / laneMarkingSpacing) + 2; j++) {
var baseY = j * laneMarkingSpacing - laneMarkingHeight / 2;
for (var d = 0; d < dashesPerMarking; d++) {
var marking = new LaneMarking();
marking.x = roadLeft + laneWidth * (i + 1);
marking.y = baseY + d * (dashLength + dashGap);
marking.speedY = speed;
marking.height = dashLength;
marking.width = laneMarkingWidth;
laneMarkings.push(marking);
game.addChild(marking);
}
}
}
// Initialize trees along both sides of the road (slightly more trees)
for (var side = 0; side < 2; side++) {
var xPos = side === 0 ? roadLeft - treeWidth / 2 - 30 : roadRight + treeWidth / 2 + 30;
for (var j = 0; j < 6; j++) {
// 6 trees per side!
var tree = new Tree();
tree.x = xPos;
tree.y = j * (2732 / 6) + 100;
tree.speedY = speed;
trees.push(tree);
game.addChild(tree);
}
}
// Touch controls
var moveLeft = false;
var moveRight = false;
// Helper: get which side of the screen is pressed
function getSide(x) {
if (x < 2048 / 2) return 'left';
return 'right';
}
// Touch down
game.down = function (x, y, obj) {
if (isGameOver) return;
var side = getSide(x);
if (side === 'left') {
moveLeft = true;
moveRight = false;
} else {
moveRight = true;
moveLeft = false;
}
updatePlayerSpeed();
};
// Touch up
game.up = function (x, y, obj) {
moveLeft = false;
moveRight = false;
updatePlayerSpeed();
};
// Touch move (optional, for smoother control)
game.move = function (x, y, obj) {
if (isGameOver) return;
var side = getSide(x);
if (side === 'left') {
moveLeft = true;
moveRight = false;
} else {
moveRight = true;
moveLeft = false;
}
updatePlayerSpeed();
};
// Update player car speedX based on input
function updatePlayerSpeed() {
if (moveLeft && !moveRight) {
playerCar.speedX = -22;
} else if (moveRight && !moveLeft) {
playerCar.speedX = 22;
} else {
playerCar.speedX = 0;
}
}
// Main game update loop
game.update = function () {
if (isGameOver) return;
// Update lane markings
for (var i = 0; i < laneMarkings.length; i++) {
var marking = laneMarkings[i];
marking.speedY = speed;
marking.update();
if (marking.y > 2732 + laneMarkingHeight / 2) {
marking.y -= (Math.ceil(2732 / laneMarkingSpacing) + 2) * laneMarkingSpacing;
}
}
// Update trees
for (var i = 0; i < trees.length; i++) {
var tree = trees[i];
tree.speedY = speed;
tree.update();
if (tree.y > 2732 + treeHeight / 2) {
tree.y -= (Math.ceil(2732 / treeSpacing) + 3) * treeSpacing;
}
}
// Update player car
playerCar.update();
// Spawn coins
coinSpawnTimer++;
if (coinSpawnTimer >= coinSpawnInterval) {
coinSpawnTimer = 0;
// Spawn coin in a random lane
var coin = new Coin();
var laneIdx = Math.floor(Math.random() * laneCount);
coin.x = laneCenters[laneIdx];
coin.y = -coinHeight / 2;
coin.speedY = speed;
coins.push(coin);
game.addChild(coin);
}
// Spawn banknotes
banknoteSpawnTimer++;
if (banknoteSpawnTimer >= banknoteSpawnInterval) {
banknoteSpawnTimer = 0;
var banknote = new Banknote();
var laneIdx = Math.floor(Math.random() * laneCount);
banknote.x = laneCenters[laneIdx];
banknote.y = -banknoteHeight / 2;
banknote.speedY = speed;
banknotes.push(banknote);
game.addChild(banknote);
}
// Update coins
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
coin.speedY = speed;
coin.update();
// Remove if off screen
if (coin.y > 2732 + coinHeight) {
coin.destroy();
coins.splice(i, 1);
continue;
}
// Collect coin
if (playerCar.intersects(coin)) {
coin.destroy();
coins.splice(i, 1);
score += 1; // Add 1 point for each coin
coinScoreTxt.setText(score); // Update coin score indicator
continue;
}
}
// Update banknotes
for (var i = banknotes.length - 1; i >= 0; i--) {
var banknote = banknotes[i];
banknote.speedY = speed;
banknote.update();
if (banknote.y > 2732 + banknoteHeight) {
banknote.destroy();
banknotes.splice(i, 1);
continue;
}
// Collect banknote
if (playerCar.intersects(banknote)) {
banknote.destroy();
banknotes.splice(i, 1);
score += 200; // Add 200 points for each banknote
coinScoreTxt.setText(score);
continue;
}
}
// Spawn obstacles
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= obstacleSpawnInterval) {
obstacleSpawnTimer = 0;
spawnObstacle();
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.update();
// Remove if off screen
if (obs.y > 2732 + obstacleCarHeight) {
obs.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision detection
if (playerCar.intersects(obs)) {
gameOver();
return;
}
}
// Update distance (for possible future use)
distance += speed;
// Do not update score or coinScoreTxt here; only update when collecting coins
// scoreTxt.setText(score);//{2B} (removed)
// Gradually increase speed for difficulty
if (LK.ticks % 180 === 0 && speed < 36) {
speed += 1;
}
};
// Spawn an obstacle car in a random lane
function spawnObstacle() {
// Synchronize the red car (obstacle) to the blue car (player) on spawn
var obs = new ObstacleCar();
obs.x = playerCar.x;
obs.y = -obstacleCarHeight / 2;
obs.speedY = speed;
obstacles.push(obs);
game.addChild(obs);
}
// Game over logic
function gameOver() {
isGameOver = true;
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
}
// Reset on game restart
game.on('reset', function () {
// Remove all obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].destroy();
}
obstacles = [];
// Remove all coins
for (var i = 0; i < coins.length; i++) {
coins[i].destroy();
}
coins = [];
// Remove all banknotes
for (var i = 0; i < banknotes.length; i++) {
banknotes[i].destroy();
}
banknotes = [];
// Remove all lane markings
for (var i = 0; i < laneMarkings.length; i++) {
laneMarkings[i].destroy();
}
laneMarkings = [];
// Remove all trees
for (var i = 0; i < trees.length; i++) {
trees[i].destroy();
}
trees = [];
// Recreate lane markings as dashed
var dashLength = 80;
var dashGap = 80;
var dashesPerMarking = Math.floor(laneMarkingHeight / (dashLength + dashGap));
for (var i = 0; i < laneCount - 1; i++) {
for (var j = 0; j < Math.ceil(2732 / laneMarkingSpacing) + 2; j++) {
var baseY = j * laneMarkingSpacing - laneMarkingHeight / 2;
for (var d = 0; d < dashesPerMarking; d++) {
var marking = new LaneMarking();
marking.x = roadLeft + laneWidth * (i + 1);
marking.y = baseY + d * (dashLength + dashGap);
marking.speedY = speed;
marking.height = dashLength;
marking.width = laneMarkingWidth;
laneMarkings.push(marking);
game.addChild(marking);
}
}
}
// Recreate trees (slightly more trees)
for (var side = 0; side < 2; side++) {
var xPos = side === 0 ? roadLeft - treeWidth / 2 - 30 : roadRight + treeWidth / 2 + 30;
for (var j = 0; j < 6; j++) {
// 6 trees per side!
var tree = new Tree();
tree.x = xPos;
tree.y = j * (2732 / 6) + 100;
tree.speedY = speed;
trees.push(tree);
game.addChild(tree);
}
}
// Reset player position
playerCar.x = laneCenters[1];
playerCar.y = 2732 - 400;
playerCar.speedX = 0;
moveLeft = false;
moveRight = false;
updatePlayerSpeed();
// Reset score and distance
score = 0;
distance = 0;
coinScoreTxt.setText('0'); // Reset coin score indicator
isGameOver = false;
speed = 18;
obstacleSpawnTimer = 0;
});
// Prevent placing anything in top left 100x100 px (no code needed, just a reminder)