/**** * Classes ****/ // Barrier class for left/right road edges var Barrier = Container.expand(function () { var self = Container.call(this); // Use the 'barriyer' image asset for the barrier var barrier = self.attachAsset('barriyer', { anchorX: 0.5, anchorY: 0.5 }); // Scale barrier to match road height barrier.height = 2732; barrier.width = 100; // Keep original width or adjust as needed self.width = barrier.width; self.height = barrier.height; // Animate the barrier up and down slightly for a dynamic effect if (typeof tween !== "undefined") { // Save original y for oscillation reference var baseY = 0; self.on('added', function () { baseY = self.y; function animateBarrier() { tween(self, { y: baseY + 30 }, { duration: 1200, easing: tween.sineInOut, onFinish: function onFinish() { tween(self, { y: baseY - 30 }, { duration: 1200, easing: tween.sineInOut, onFinish: animateBarrier }); } }); } animateBarrier(); }); } return self; }); // Player's car class var PlayerCar = Container.expand(function () { var self = Container.call(this); var car = self.attachAsset('playerCar', { anchorX: 0.5, anchorY: 0.5 }); self.width = car.width; self.height = car.height; self.lane = 1; // 0: left, 1: center, 2: right self.lastX = 0; self.lastY = 0; self.update = function () { self.lastX = self.x; self.lastY = self.y; }; return self; }); // Police car class var PoliceCar = Container.expand(function () { var self = Container.call(this); var car = self.attachAsset('policeCar', { anchorX: 0.5, anchorY: 0.5 }); self.width = car.width; self.height = car.height; // Police car now chases from behind: negative speed (moves upward, slower than before) self.speed = -(10 + Math.random() * 5); self.lastY = 0; self.update = function () { self.lastY = self.y; // Police car steering logic: steer toward playerCar.x if (typeof playerCar !== "undefined") { // Only steer if not already close to player var dx = playerCar.x - self.x; // Steer a bit each frame, but not too fast var steerAmount = Math.max(-18, Math.min(18, dx * 0.12)); self.x += steerAmount; } else if (typeof getLaneX === "function" && typeof self.lane !== "undefined") { // Defensive: if no playerCar, reset to lane self.x = getLaneX(self.lane); } self.y += self.speed; }; return self; }); // Power-up class var PowerUp = Container.expand(function () { var self = Container.call(this); var pu = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.width = pu.width; self.height = pu.height; self.speed = 22; self.lastY = 0; self.update = function () { self.lastY = self.y; self.y += self.speed; }; return self; }); // Traffic car class var TrafficCar = Container.expand(function () { var self = Container.call(this); var car = self.attachAsset('trafficCar', { anchorX: 0.5, anchorY: 0.5 }); self.width = car.width; self.height = car.height; self.speed = 20 + Math.random() * 10; self.lastY = 0; self.update = function () { self.lastY = self.y; self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // --- Add Animated Road Background --- // We'll use two road images stacked vertically and move them downward to create a looping animation. var roadBg1 = LK.getAsset('Road', { anchorX: 0.5, anchorY: 0.5, width: 2048, height: 2732, x: 2048 / 2, y: 2732 / 2 }); var roadBg2 = LK.getAsset('Road', { anchorX: 0.5, anchorY: 0.5, width: 2048, height: 2732, x: 2048 / 2, y: -2732 / 2 // Start above the first image }); game.addChild(roadBg1); game.addChild(roadBg2); // --- Car Chase Game Variables --- // Add barriers array var barriers = []; var playerCar; var policeCars = []; var trafficCars = []; var powerUps = []; var roadLines = []; var score = 0; var gameSpeed = 22; var laneCount = 3; var laneWidth = 600; var roadLeft = (2048 - laneCount * laneWidth) / 2 + laneWidth / 2; var roadRight = 2048 - roadLeft; var dragNode = null; var lastTouchX = 0; var scoreTxt; // --- Helper: Get lane X position --- function getLaneX(lane) { return roadLeft + lane * laneWidth; } // Move both road backgrounds to the bottom of the display list so they're always behind if (game.children && game.children.length > 1) { game.setChildIndex(roadBg1, 0); game.setChildIndex(roadBg2, 1); } // --- Setup Barriers --- var leftBarrier = new Barrier(); leftBarrier.x = roadLeft - laneWidth / 2 - leftBarrier.width / 2; leftBarrier.y = 2732 / 2; barriers.push(leftBarrier); game.addChild(leftBarrier); var rightBarrier = new Barrier(); rightBarrier.x = roadRight + laneWidth / 2 + rightBarrier.width / 2; rightBarrier.y = 2732 / 2; barriers.push(rightBarrier); game.addChild(rightBarrier); // --- Setup Player Car --- playerCar = new PlayerCar(); playerCar.x = getLaneX(1); playerCar.y = 2732 - 400; game.addChild(playerCar); // --- Setup Score Text --- scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Setup Road Lines --- // (road lines removed) // --- Touch Controls for Player Car --- game.down = function (x, y, obj) { if (x > playerCar.x - playerCar.width / 2 && x < playerCar.x + playerCar.width / 2 && y > playerCar.y - playerCar.height / 2 && y < playerCar.y + playerCar.height / 2) { dragNode = playerCar; lastTouchX = x; } }; game.move = function (x, y, obj) { if (dragNode === playerCar) { var dx = x - lastTouchX; playerCar.x += dx; // Clamp to road if (playerCar.x < roadLeft) playerCar.x = roadLeft; if (playerCar.x > roadRight) playerCar.x = roadRight; lastTouchX = x; } }; game.up = function (x, y, obj) { dragNode = null; }; // --- Main Game Update Loop --- game.update = function () { // Animate road background roadBg1.y += gameSpeed; roadBg2.y += gameSpeed; // If a background image moves off the bottom, move it above the other if (roadBg1.y >= 2732 + 2732 / 2) { roadBg1.y = roadBg2.y - 2732; } if (roadBg2.y >= 2732 + 2732 / 2) { roadBg2.y = roadBg1.y - 2732; } // Move road lines // (road line movement removed) // Spawn more traffic cars more frequently if (LK.ticks % 20 === 0) { // Spawn 1-2 cars per tick, but never in the same lane var lanes = [0, 1, 2]; // Shuffle lanes for (var i = lanes.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = lanes[i]; lanes[i] = lanes[j]; lanes[j] = temp; } var carsToSpawn = 1 + (Math.random() < 0.7 ? 1 : 0); // 70% chance to spawn 2 cars for (var c = 0; c < carsToSpawn; c++) { var lane = lanes[c]; var tcar = new TrafficCar(); tcar.x = getLaneX(lane); tcar.y = -200; trafficCars.push(tcar); game.addChild(tcar); } } // Spawn police cars, but only after 5 seconds (300 ticks) have passed since game start if (LK.ticks > 300 && LK.ticks % 180 === 0) { var lane = Math.floor(Math.random() * laneCount); var pcar = new PoliceCar(); pcar.lane = lane; // Assign lane for defensive code pcar.x = getLaneX(lane); // Spawn at the top, just off screen, to chase the player downward pcar.y = -220; policeCars.push(pcar); game.addChild(pcar); } // Spawn power-ups if (LK.ticks % 300 === 0) { var lane = Math.floor(Math.random() * laneCount); var pu = new PowerUp(); pu.x = getLaneX(lane); pu.y = -100; powerUps.push(pu); game.addChild(pu); } // Update player car playerCar.update(); // Check collision with barriers for (var b = 0; b < barriers.length; b++) { if (playerCar.intersects(barriers[b])) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } } // Update and remove off-screen traffic cars for (var i = trafficCars.length - 1; i >= 0; i--) { var tcar = trafficCars[i]; tcar.update(); if (tcar.y > 2732 + 200) { tcar.destroy(); trafficCars.splice(i, 1); continue; } // Collision with player if (tcar.intersects(playerCar)) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } } // Update and remove off-screen police cars for (var i = policeCars.length - 1; i >= 0; i--) { var pcar = policeCars[i]; pcar.update(); // Remove if off the top of the screen (since police now move upward) if (pcar.y < -220) { pcar.destroy(); policeCars.splice(i, 1); continue; } // Collision with player if (pcar.intersects(playerCar)) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } } // Update and remove off-screen power-ups for (var i = powerUps.length - 1; i >= 0; i--) { var pu = powerUps[i]; pu.update(); if (pu.y > 2732 + 100) { pu.destroy(); powerUps.splice(i, 1); continue; } // Collision with player if (pu.intersects(playerCar)) { score += 10; scoreTxt.setText(score); LK.effects.flashObject(playerCar, 0xffeb3b, 500); pu.destroy(); powerUps.splice(i, 1); continue; } } // Score increases with distance if (LK.ticks % 6 === 0) { score += 1; scoreTxt.setText(score); } // Gradually increase game speed if (LK.ticks % 180 === 0 && gameSpeed < 40) { gameSpeed += 1; } };
/****
* Classes
****/
// Barrier class for left/right road edges
var Barrier = Container.expand(function () {
var self = Container.call(this);
// Use the 'barriyer' image asset for the barrier
var barrier = self.attachAsset('barriyer', {
anchorX: 0.5,
anchorY: 0.5
});
// Scale barrier to match road height
barrier.height = 2732;
barrier.width = 100; // Keep original width or adjust as needed
self.width = barrier.width;
self.height = barrier.height;
// Animate the barrier up and down slightly for a dynamic effect
if (typeof tween !== "undefined") {
// Save original y for oscillation reference
var baseY = 0;
self.on('added', function () {
baseY = self.y;
function animateBarrier() {
tween(self, {
y: baseY + 30
}, {
duration: 1200,
easing: tween.sineInOut,
onFinish: function onFinish() {
tween(self, {
y: baseY - 30
}, {
duration: 1200,
easing: tween.sineInOut,
onFinish: animateBarrier
});
}
});
}
animateBarrier();
});
}
return self;
});
// Player's car class
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var car = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = car.width;
self.height = car.height;
self.lane = 1; // 0: left, 1: center, 2: right
self.lastX = 0;
self.lastY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
// Police car class
var PoliceCar = Container.expand(function () {
var self = Container.call(this);
var car = self.attachAsset('policeCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = car.width;
self.height = car.height;
// Police car now chases from behind: negative speed (moves upward, slower than before)
self.speed = -(10 + Math.random() * 5);
self.lastY = 0;
self.update = function () {
self.lastY = self.y;
// Police car steering logic: steer toward playerCar.x
if (typeof playerCar !== "undefined") {
// Only steer if not already close to player
var dx = playerCar.x - self.x;
// Steer a bit each frame, but not too fast
var steerAmount = Math.max(-18, Math.min(18, dx * 0.12));
self.x += steerAmount;
} else if (typeof getLaneX === "function" && typeof self.lane !== "undefined") {
// Defensive: if no playerCar, reset to lane
self.x = getLaneX(self.lane);
}
self.y += self.speed;
};
return self;
});
// Power-up class
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var pu = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = pu.width;
self.height = pu.height;
self.speed = 22;
self.lastY = 0;
self.update = function () {
self.lastY = self.y;
self.y += self.speed;
};
return self;
});
// Traffic car class
var TrafficCar = Container.expand(function () {
var self = Container.call(this);
var car = self.attachAsset('trafficCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = car.width;
self.height = car.height;
self.speed = 20 + Math.random() * 10;
self.lastY = 0;
self.update = function () {
self.lastY = self.y;
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// --- Add Animated Road Background ---
// We'll use two road images stacked vertically and move them downward to create a looping animation.
var roadBg1 = LK.getAsset('Road', {
anchorX: 0.5,
anchorY: 0.5,
width: 2048,
height: 2732,
x: 2048 / 2,
y: 2732 / 2
});
var roadBg2 = LK.getAsset('Road', {
anchorX: 0.5,
anchorY: 0.5,
width: 2048,
height: 2732,
x: 2048 / 2,
y: -2732 / 2 // Start above the first image
});
game.addChild(roadBg1);
game.addChild(roadBg2);
// --- Car Chase Game Variables ---
// Add barriers array
var barriers = [];
var playerCar;
var policeCars = [];
var trafficCars = [];
var powerUps = [];
var roadLines = [];
var score = 0;
var gameSpeed = 22;
var laneCount = 3;
var laneWidth = 600;
var roadLeft = (2048 - laneCount * laneWidth) / 2 + laneWidth / 2;
var roadRight = 2048 - roadLeft;
var dragNode = null;
var lastTouchX = 0;
var scoreTxt;
// --- Helper: Get lane X position ---
function getLaneX(lane) {
return roadLeft + lane * laneWidth;
}
// Move both road backgrounds to the bottom of the display list so they're always behind
if (game.children && game.children.length > 1) {
game.setChildIndex(roadBg1, 0);
game.setChildIndex(roadBg2, 1);
}
// --- Setup Barriers ---
var leftBarrier = new Barrier();
leftBarrier.x = roadLeft - laneWidth / 2 - leftBarrier.width / 2;
leftBarrier.y = 2732 / 2;
barriers.push(leftBarrier);
game.addChild(leftBarrier);
var rightBarrier = new Barrier();
rightBarrier.x = roadRight + laneWidth / 2 + rightBarrier.width / 2;
rightBarrier.y = 2732 / 2;
barriers.push(rightBarrier);
game.addChild(rightBarrier);
// --- Setup Player Car ---
playerCar = new PlayerCar();
playerCar.x = getLaneX(1);
playerCar.y = 2732 - 400;
game.addChild(playerCar);
// --- Setup Score Text ---
scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// --- Setup Road Lines ---
// (road lines removed)
// --- Touch Controls for Player Car ---
game.down = function (x, y, obj) {
if (x > playerCar.x - playerCar.width / 2 && x < playerCar.x + playerCar.width / 2 && y > playerCar.y - playerCar.height / 2 && y < playerCar.y + playerCar.height / 2) {
dragNode = playerCar;
lastTouchX = x;
}
};
game.move = function (x, y, obj) {
if (dragNode === playerCar) {
var dx = x - lastTouchX;
playerCar.x += dx;
// Clamp to road
if (playerCar.x < roadLeft) playerCar.x = roadLeft;
if (playerCar.x > roadRight) playerCar.x = roadRight;
lastTouchX = x;
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// --- Main Game Update Loop ---
game.update = function () {
// Animate road background
roadBg1.y += gameSpeed;
roadBg2.y += gameSpeed;
// If a background image moves off the bottom, move it above the other
if (roadBg1.y >= 2732 + 2732 / 2) {
roadBg1.y = roadBg2.y - 2732;
}
if (roadBg2.y >= 2732 + 2732 / 2) {
roadBg2.y = roadBg1.y - 2732;
}
// Move road lines
// (road line movement removed)
// Spawn more traffic cars more frequently
if (LK.ticks % 20 === 0) {
// Spawn 1-2 cars per tick, but never in the same lane
var lanes = [0, 1, 2];
// Shuffle lanes
for (var i = lanes.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = lanes[i];
lanes[i] = lanes[j];
lanes[j] = temp;
}
var carsToSpawn = 1 + (Math.random() < 0.7 ? 1 : 0); // 70% chance to spawn 2 cars
for (var c = 0; c < carsToSpawn; c++) {
var lane = lanes[c];
var tcar = new TrafficCar();
tcar.x = getLaneX(lane);
tcar.y = -200;
trafficCars.push(tcar);
game.addChild(tcar);
}
}
// Spawn police cars, but only after 5 seconds (300 ticks) have passed since game start
if (LK.ticks > 300 && LK.ticks % 180 === 0) {
var lane = Math.floor(Math.random() * laneCount);
var pcar = new PoliceCar();
pcar.lane = lane; // Assign lane for defensive code
pcar.x = getLaneX(lane);
// Spawn at the top, just off screen, to chase the player downward
pcar.y = -220;
policeCars.push(pcar);
game.addChild(pcar);
}
// Spawn power-ups
if (LK.ticks % 300 === 0) {
var lane = Math.floor(Math.random() * laneCount);
var pu = new PowerUp();
pu.x = getLaneX(lane);
pu.y = -100;
powerUps.push(pu);
game.addChild(pu);
}
// Update player car
playerCar.update();
// Check collision with barriers
for (var b = 0; b < barriers.length; b++) {
if (playerCar.intersects(barriers[b])) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
// Update and remove off-screen traffic cars
for (var i = trafficCars.length - 1; i >= 0; i--) {
var tcar = trafficCars[i];
tcar.update();
if (tcar.y > 2732 + 200) {
tcar.destroy();
trafficCars.splice(i, 1);
continue;
}
// Collision with player
if (tcar.intersects(playerCar)) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
// Update and remove off-screen police cars
for (var i = policeCars.length - 1; i >= 0; i--) {
var pcar = policeCars[i];
pcar.update();
// Remove if off the top of the screen (since police now move upward)
if (pcar.y < -220) {
pcar.destroy();
policeCars.splice(i, 1);
continue;
}
// Collision with player
if (pcar.intersects(playerCar)) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
// Update and remove off-screen power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var pu = powerUps[i];
pu.update();
if (pu.y > 2732 + 100) {
pu.destroy();
powerUps.splice(i, 1);
continue;
}
// Collision with player
if (pu.intersects(playerCar)) {
score += 10;
scoreTxt.setText(score);
LK.effects.flashObject(playerCar, 0xffeb3b, 500);
pu.destroy();
powerUps.splice(i, 1);
continue;
}
}
// Score increases with distance
if (LK.ticks % 6 === 0) {
score += 1;
scoreTxt.setText(score);
}
// Gradually increase game speed
if (LK.ticks % 180 === 0 && gameSpeed < 40) {
gameSpeed += 1;
}
};
car top view. In-Game asset. 2d. High contrast. No shadows
police car top view. In-Game asset. 2d. High contrast. No shadows
add highway barrier top view. In-Game asset. 2d. High contrast. No shadows
power coin. In-Game asset. 2d. High contrast. No shadows. power coin
a highway road but top view. In-Game asset. 2d. High contrast. No shadows