/****
* Classes
****/
var F1Car = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('f1Car', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.maxSpeed = 15;
self.acceleration = 0.8;
self.friction = 0.9;
self.boostMultiplier = 1.0;
self.boostTimer = 0;
self.steerDirection = 0; // -1 for left, 1 for right, 0 for straight
self.steerSpeed = 6;
self.rotation = 0; // Car's current rotation angle
self.update = function () {
// Apply friction
self.speed *= self.friction;
// Update boost
if (self.boostTimer > 0) {
self.boostTimer--;
self.boostMultiplier = 1.5;
carGraphics.tint = 0x00FF00;
} else {
self.boostMultiplier = 1.0;
carGraphics.tint = 0xFFFFFF;
}
// Apply speed with boost
self.y -= self.speed * self.boostMultiplier;
// Apply steering with pressure intensity
var steerIntensity = touchPressure || 1;
self.x += self.steerDirection * self.steerSpeed * steerIntensity;
// Update car rotation based on steering
if (self.steerDirection !== 0) {
var targetRotation = self.steerDirection * 0.3; // Max 0.3 radians rotation
self.rotation += (targetRotation - self.rotation) * 0.1; // Smooth rotation
} else {
// Return to straight position when not steering
self.rotation += (0 - self.rotation) * 0.1;
}
carGraphics.rotation = self.rotation;
// Keep car on screen
if (self.x < 40) self.x = 40;
if (self.x > 2008) self.x = 2008;
if (self.y < 100) self.y = 100;
if (self.y > 2632) self.y = 2632;
// Engine sound based on speed
if (self.speed > 5) {
LK.getSound('engine').play();
}
};
self.accelerate = function (pressureMultiplier) {
if (self.speed < self.maxSpeed) {
var accel = self.acceleration * (pressureMultiplier || 1);
self.speed += accel;
}
};
self.activateBoost = function () {
self.boostTimer = 120; // 2 seconds at 60fps
LK.getSound('boost').play();
};
return self;
});
var OpponentCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('opponent', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3 + Math.random() * 4;
self.lastY = 0;
self.update = function () {
self.y += self.speed;
// Slight horizontal movement for realism
self.x += (Math.random() - 0.5) * 2;
// Keep on track
if (self.x < 200) self.x = 200;
if (self.x > 1848) self.x = 1848;
};
return self;
});
var SpeedBoost = Container.expand(function () {
var self = Container.call(this);
var boostGraphics = self.attachAsset('speedBoost', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.collected = false;
self.lastIntersecting = false;
self.update = function () {
self.y += self.speed;
// Pulsing effect
var pulse = Math.sin(LK.ticks * 0.2) * 0.3 + 0.7;
boostGraphics.alpha = pulse;
boostGraphics.rotation += 0.1;
};
return self;
});
/****
* Initialize Game
****/
// Create track background
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Create track background
var trackLeft = game.addChild(LK.getAsset('track', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
var trackRight = game.addChild(LK.getAsset('track', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2532
}));
// Track lines for visual effect
var centerLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: 0
}));
var leftLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 300,
y: 0
}));
var rightLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 1748,
y: 0
}));
// Create F1 car
var f1Car = game.addChild(new F1Car());
f1Car.x = 1024;
f1Car.y = 2200;
// Game arrays
var opponents = [];
var speedBoosts = [];
var trackLines = [centerLine, leftLine, rightLine];
var trackSections = []; // Array to hold track sections
var lastTrackY = 0; // Track the last generated track section position
// Score and UI
var scoreTxt = new Text2('Speed: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var distanceTxt = new Text2('Distance: 0m', {
size: 60,
fill: 0xFFFF00
});
distanceTxt.anchor.set(0, 0);
distanceTxt.x = 50;
distanceTxt.y = 100;
LK.gui.topLeft.addChild(distanceTxt);
// Position display
var positionTxt = new Text2('Position: 1/20', {
size: 70,
fill: 0x00FF00
});
positionTxt.anchor.set(1, 0);
positionTxt.x = -50;
positionTxt.y = 50;
LK.gui.topRight.addChild(positionTxt);
// Camera display
var cameraTxt = new Text2('Camera: Behind Car', {
size: 50,
fill: 0x00FFFF
});
cameraTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(cameraTxt);
// Camera switch button
var cameraButton = new Text2('📷 SWITCH', {
size: 60,
fill: 0xFFFF00
});
cameraButton.anchor.set(0.5, 0);
cameraButton.x = 0;
cameraButton.y = 200;
LK.gui.topRight.addChild(cameraButton);
// Game variables
var distance = 0;
var gameSpeed = 1;
var spawnTimer = 0;
var boostSpawnTimer = 0;
var trackOffset = 0;
var playerPosition = 1; // Player's current position in race
var totalCars = 20; // Total number of cars in race
var touchPressure = 0; // How hard the screen is being pressed
var isPressed = false; // Whether screen is currently being pressed
// Camera system
var currentCamera = 0; // 0: behind, 1: above, 2: driver's eye
var cameraNames = ['Behind Car', 'Bird\'s Eye View', 'Driver View'];
var cameraOffset = {
x: 0,
y: 0
};
var cameraZoom = 1;
var cameraAngle = 0;
// Touch controls - pressure-based acceleration system
game.down = function (x, y, obj) {
// Check if camera button was pressed (top right area)
var globalPos = game.toGlobal({
x: x,
y: y
});
if (globalPos.x > 1800 && globalPos.y < 300) {
// Switch camera
currentCamera = (currentCamera + 1) % 3;
cameraTxt.setText('Camera: ' + cameraNames[currentCamera]);
return;
}
// Only allow acceleration if touching upper part of screen
if (y < 1366) {
// Start pressure-based acceleration
isPressed = true;
touchPressure = 0.1; // Initial pressure
} else {
// Start pressure-based steering for lower screen touches
isPressed = true;
touchPressure = 0.1; // Initial pressure for steering
var centerX = 1024; // Center of screen
if (x < centerX - 100) {
f1Car.steerDirection = -1; // Steer left
} else if (x > centerX + 100) {
f1Car.steerDirection = 1; // Steer right
} else {
f1Car.steerDirection = 0; // Go straight
}
}
};
game.move = function (x, y, obj) {
// Update steering direction only for lower screen touches and if touch is held
if (y >= 1366 && isPressed) {
var centerX = 1024; // Center of screen
if (x < centerX - 100) {
f1Car.steerDirection = -1; // Steer left
} else if (x > centerX + 100) {
f1Car.steerDirection = 1; // Steer right
} else {
f1Car.steerDirection = 0; // Go straight
}
}
};
game.up = function (x, y, obj) {
// Stop pressure-based acceleration
isPressed = false;
touchPressure = 0;
// Stop steering
f1Car.steerDirection = 0;
};
// Camera update function
function updateCamera() {
switch (currentCamera) {
case 0:
// Behind car camera
cameraOffset.x = 0;
cameraOffset.y = 300;
cameraZoom = 1;
cameraAngle = 0;
game.scale.set(1, 1);
game.rotation = 0;
game.x = -f1Car.x + 1024;
game.y = -f1Car.y + 2000;
break;
case 1:
// Above car camera (bird's eye view)
cameraOffset.x = 0;
cameraOffset.y = 0;
cameraZoom = 0.6;
cameraAngle = 0;
game.scale.set(cameraZoom, cameraZoom);
game.rotation = 0;
game.x = (-f1Car.x + 1024) * cameraZoom;
game.y = (-f1Car.y + 1366) * cameraZoom;
break;
case 2:
// Driver's eye view
cameraOffset.x = 0;
cameraOffset.y = -80;
cameraZoom = 1.5;
cameraAngle = 0;
game.scale.set(cameraZoom, cameraZoom);
game.rotation = 0;
game.x = (-f1Car.x + 1024) * cameraZoom;
game.y = (-f1Car.y + 1000) * cameraZoom;
break;
}
}
// Start race music
LK.playMusic('raceMusic');
game.update = function () {
// Handle pressure-based acceleration and steering
if (isPressed) {
// Increase pressure over time (longer press = more acceleration/steering)
touchPressure = Math.min(touchPressure + 0.02, 2.0); // Max 2x acceleration
f1Car.accelerate(touchPressure);
}
// Update distance and speed
distance += f1Car.speed;
gameSpeed = 1 + distance / 10000;
// Calculate player position based on speed and distance
var basePosition = Math.max(1, Math.min(totalCars, Math.floor(totalCars - distance / 5000 - f1Car.speed / 2)));
playerPosition = basePosition;
// Update camera system
updateCamera();
// Update UI
scoreTxt.setText('Speed: ' + Math.floor(f1Car.speed * 10) + ' km/h');
distanceTxt.setText('Distance: ' + Math.floor(distance / 10) + 'm');
positionTxt.setText('Position: ' + playerPosition + '/' + totalCars);
// Animate track lines moving
trackOffset += f1Car.speed * 2;
for (var i = 0; i < trackLines.length; i++) {
var line = trackLines[i];
line.y = trackOffset % 400 - 200;
}
// Generate new track sections ahead of the player
while (lastTrackY < f1Car.y - 1000) {
// Create new track section
var newCenterLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: lastTrackY - 2732
}));
var newLeftLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 300,
y: lastTrackY - 2732
}));
var newRightLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 1748,
y: lastTrackY - 2732
}));
trackSections.push({
center: newCenterLine,
left: newLeftLine,
right: newRightLine,
y: lastTrackY - 2732
});
lastTrackY -= 2732;
}
// Remove old track sections that are far behind
for (var i = trackSections.length - 1; i >= 0; i--) {
var section = trackSections[i];
if (section.y > f1Car.y + 1000) {
section.center.destroy();
section.left.destroy();
section.right.destroy();
trackSections.splice(i, 1);
}
}
// Spawn opponents
spawnTimer++;
if (spawnTimer > 60 / gameSpeed) {
spawnTimer = 0;
var opponent = new OpponentCar();
opponent.x = 300 + Math.random() * 1448;
opponent.y = -100;
opponent.lastY = opponent.y;
opponents.push(opponent);
game.addChild(opponent);
}
// Spawn speed boosts
boostSpawnTimer++;
if (boostSpawnTimer > 300) {
boostSpawnTimer = 0;
var boost = new SpeedBoost();
boost.x = 400 + Math.random() * 1248;
boost.y = -50;
boost.lastIntersecting = false;
speedBoosts.push(boost);
game.addChild(boost);
}
// Update and check opponents
for (var i = opponents.length - 1; i >= 0; i--) {
var opponent = opponents[i];
// Remove off-screen opponents
if (opponent.lastY < 2800 && opponent.y >= 2800) {
opponent.destroy();
opponents.splice(i, 1);
continue;
}
// Check collision with player
if (f1Car.intersects(opponent)) {
LK.effects.flashScreen(0xFF0000, 500);
LK.showGameOver();
return;
}
opponent.lastY = opponent.y;
}
// Update and check speed boosts
for (var i = speedBoosts.length - 1; i >= 0; i--) {
var boost = speedBoosts[i];
// Remove off-screen boosts
if (boost.y > 2800) {
boost.destroy();
speedBoosts.splice(i, 1);
continue;
}
// Check collection
var currentIntersecting = f1Car.intersects(boost);
if (!boost.lastIntersecting && currentIntersecting) {
f1Car.activateBoost();
boost.destroy();
speedBoosts.splice(i, 1);
continue;
}
boost.lastIntersecting = currentIntersecting;
}
// Win condition - reach 50km
if (distance >= 500000) {
LK.showYouWin();
}
}; /****
* Classes
****/
var F1Car = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('f1Car', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.maxSpeed = 15;
self.acceleration = 0.8;
self.friction = 0.9;
self.boostMultiplier = 1.0;
self.boostTimer = 0;
self.steerDirection = 0; // -1 for left, 1 for right, 0 for straight
self.steerSpeed = 6;
self.rotation = 0; // Car's current rotation angle
self.update = function () {
// Apply friction
self.speed *= self.friction;
// Update boost
if (self.boostTimer > 0) {
self.boostTimer--;
self.boostMultiplier = 1.5;
carGraphics.tint = 0x00FF00;
} else {
self.boostMultiplier = 1.0;
carGraphics.tint = 0xFFFFFF;
}
// Apply speed with boost
self.y -= self.speed * self.boostMultiplier;
// Apply steering with pressure intensity
var steerIntensity = touchPressure || 1;
self.x += self.steerDirection * self.steerSpeed * steerIntensity;
// Update car rotation based on steering
if (self.steerDirection !== 0) {
var targetRotation = self.steerDirection * 0.3; // Max 0.3 radians rotation
self.rotation += (targetRotation - self.rotation) * 0.1; // Smooth rotation
} else {
// Return to straight position when not steering
self.rotation += (0 - self.rotation) * 0.1;
}
carGraphics.rotation = self.rotation;
// Keep car on screen
if (self.x < 40) self.x = 40;
if (self.x > 2008) self.x = 2008;
if (self.y < 100) self.y = 100;
if (self.y > 2632) self.y = 2632;
// Engine sound based on speed
if (self.speed > 5) {
LK.getSound('engine').play();
}
};
self.accelerate = function (pressureMultiplier) {
if (self.speed < self.maxSpeed) {
var accel = self.acceleration * (pressureMultiplier || 1);
self.speed += accel;
}
};
self.activateBoost = function () {
self.boostTimer = 120; // 2 seconds at 60fps
LK.getSound('boost').play();
};
return self;
});
var OpponentCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('opponent', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3 + Math.random() * 4;
self.lastY = 0;
self.update = function () {
self.y += self.speed;
// Slight horizontal movement for realism
self.x += (Math.random() - 0.5) * 2;
// Keep on track
if (self.x < 200) self.x = 200;
if (self.x > 1848) self.x = 1848;
};
return self;
});
var SpeedBoost = Container.expand(function () {
var self = Container.call(this);
var boostGraphics = self.attachAsset('speedBoost', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.collected = false;
self.lastIntersecting = false;
self.update = function () {
self.y += self.speed;
// Pulsing effect
var pulse = Math.sin(LK.ticks * 0.2) * 0.3 + 0.7;
boostGraphics.alpha = pulse;
boostGraphics.rotation += 0.1;
};
return self;
});
/****
* Initialize Game
****/
// Create track background
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Create track background
var trackLeft = game.addChild(LK.getAsset('track', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
var trackRight = game.addChild(LK.getAsset('track', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2532
}));
// Track lines for visual effect
var centerLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: 0
}));
var leftLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 300,
y: 0
}));
var rightLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 1748,
y: 0
}));
// Create F1 car
var f1Car = game.addChild(new F1Car());
f1Car.x = 1024;
f1Car.y = 2200;
// Game arrays
var opponents = [];
var speedBoosts = [];
var trackLines = [centerLine, leftLine, rightLine];
var trackSections = []; // Array to hold track sections
var lastTrackY = 0; // Track the last generated track section position
// Score and UI
var scoreTxt = new Text2('Speed: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var distanceTxt = new Text2('Distance: 0m', {
size: 60,
fill: 0xFFFF00
});
distanceTxt.anchor.set(0, 0);
distanceTxt.x = 50;
distanceTxt.y = 100;
LK.gui.topLeft.addChild(distanceTxt);
// Position display
var positionTxt = new Text2('Position: 1/20', {
size: 70,
fill: 0x00FF00
});
positionTxt.anchor.set(1, 0);
positionTxt.x = -50;
positionTxt.y = 50;
LK.gui.topRight.addChild(positionTxt);
// Camera display
var cameraTxt = new Text2('Camera: Behind Car', {
size: 50,
fill: 0x00FFFF
});
cameraTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(cameraTxt);
// Camera switch button
var cameraButton = new Text2('📷 SWITCH', {
size: 60,
fill: 0xFFFF00
});
cameraButton.anchor.set(0.5, 0);
cameraButton.x = 0;
cameraButton.y = 200;
LK.gui.topRight.addChild(cameraButton);
// Game variables
var distance = 0;
var gameSpeed = 1;
var spawnTimer = 0;
var boostSpawnTimer = 0;
var trackOffset = 0;
var playerPosition = 1; // Player's current position in race
var totalCars = 20; // Total number of cars in race
var touchPressure = 0; // How hard the screen is being pressed
var isPressed = false; // Whether screen is currently being pressed
// Camera system
var currentCamera = 0; // 0: behind, 1: above, 2: driver's eye
var cameraNames = ['Behind Car', 'Bird\'s Eye View', 'Driver View'];
var cameraOffset = {
x: 0,
y: 0
};
var cameraZoom = 1;
var cameraAngle = 0;
// Touch controls - pressure-based acceleration system
game.down = function (x, y, obj) {
// Check if camera button was pressed (top right area)
var globalPos = game.toGlobal({
x: x,
y: y
});
if (globalPos.x > 1800 && globalPos.y < 300) {
// Switch camera
currentCamera = (currentCamera + 1) % 3;
cameraTxt.setText('Camera: ' + cameraNames[currentCamera]);
return;
}
// Only allow acceleration if touching upper part of screen
if (y < 1366) {
// Start pressure-based acceleration
isPressed = true;
touchPressure = 0.1; // Initial pressure
} else {
// Start pressure-based steering for lower screen touches
isPressed = true;
touchPressure = 0.1; // Initial pressure for steering
var centerX = 1024; // Center of screen
if (x < centerX - 100) {
f1Car.steerDirection = -1; // Steer left
} else if (x > centerX + 100) {
f1Car.steerDirection = 1; // Steer right
} else {
f1Car.steerDirection = 0; // Go straight
}
}
};
game.move = function (x, y, obj) {
// Update steering direction only for lower screen touches and if touch is held
if (y >= 1366 && isPressed) {
var centerX = 1024; // Center of screen
if (x < centerX - 100) {
f1Car.steerDirection = -1; // Steer left
} else if (x > centerX + 100) {
f1Car.steerDirection = 1; // Steer right
} else {
f1Car.steerDirection = 0; // Go straight
}
}
};
game.up = function (x, y, obj) {
// Stop pressure-based acceleration
isPressed = false;
touchPressure = 0;
// Stop steering
f1Car.steerDirection = 0;
};
// Camera update function
function updateCamera() {
switch (currentCamera) {
case 0:
// Behind car camera
cameraOffset.x = 0;
cameraOffset.y = 300;
cameraZoom = 1;
cameraAngle = 0;
game.scale.set(1, 1);
game.rotation = 0;
game.x = -f1Car.x + 1024;
game.y = -f1Car.y + 2000;
break;
case 1:
// Above car camera (bird's eye view)
cameraOffset.x = 0;
cameraOffset.y = 0;
cameraZoom = 0.6;
cameraAngle = 0;
game.scale.set(cameraZoom, cameraZoom);
game.rotation = 0;
game.x = (-f1Car.x + 1024) * cameraZoom;
game.y = (-f1Car.y + 1366) * cameraZoom;
break;
case 2:
// Driver's eye view
cameraOffset.x = 0;
cameraOffset.y = -80;
cameraZoom = 1.5;
cameraAngle = 0;
game.scale.set(cameraZoom, cameraZoom);
game.rotation = 0;
game.x = (-f1Car.x + 1024) * cameraZoom;
game.y = (-f1Car.y + 1000) * cameraZoom;
break;
}
}
// Start race music
LK.playMusic('raceMusic');
game.update = function () {
// Handle pressure-based acceleration and steering
if (isPressed) {
// Increase pressure over time (longer press = more acceleration/steering)
touchPressure = Math.min(touchPressure + 0.02, 2.0); // Max 2x acceleration
f1Car.accelerate(touchPressure);
}
// Update distance and speed
distance += f1Car.speed;
gameSpeed = 1 + distance / 10000;
// Calculate player position based on speed and distance
var basePosition = Math.max(1, Math.min(totalCars, Math.floor(totalCars - distance / 5000 - f1Car.speed / 2)));
playerPosition = basePosition;
// Update camera system
updateCamera();
// Update UI
scoreTxt.setText('Speed: ' + Math.floor(f1Car.speed * 10) + ' km/h');
distanceTxt.setText('Distance: ' + Math.floor(distance / 10) + 'm');
positionTxt.setText('Position: ' + playerPosition + '/' + totalCars);
// Animate track lines moving
trackOffset += f1Car.speed * 2;
for (var i = 0; i < trackLines.length; i++) {
var line = trackLines[i];
line.y = trackOffset % 400 - 200;
}
// Generate new track sections ahead of the player
while (lastTrackY < f1Car.y - 1000) {
// Create new track section
var newCenterLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: lastTrackY - 2732
}));
var newLeftLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 300,
y: lastTrackY - 2732
}));
var newRightLine = game.addChild(LK.getAsset('trackLine', {
anchorX: 0.5,
anchorY: 0,
x: 1748,
y: lastTrackY - 2732
}));
trackSections.push({
center: newCenterLine,
left: newLeftLine,
right: newRightLine,
y: lastTrackY - 2732
});
lastTrackY -= 2732;
}
// Remove old track sections that are far behind
for (var i = trackSections.length - 1; i >= 0; i--) {
var section = trackSections[i];
if (section.y > f1Car.y + 1000) {
section.center.destroy();
section.left.destroy();
section.right.destroy();
trackSections.splice(i, 1);
}
}
// Spawn opponents
spawnTimer++;
if (spawnTimer > 60 / gameSpeed) {
spawnTimer = 0;
var opponent = new OpponentCar();
opponent.x = 300 + Math.random() * 1448;
opponent.y = -100;
opponent.lastY = opponent.y;
opponents.push(opponent);
game.addChild(opponent);
}
// Spawn speed boosts
boostSpawnTimer++;
if (boostSpawnTimer > 300) {
boostSpawnTimer = 0;
var boost = new SpeedBoost();
boost.x = 400 + Math.random() * 1248;
boost.y = -50;
boost.lastIntersecting = false;
speedBoosts.push(boost);
game.addChild(boost);
}
// Update and check opponents
for (var i = opponents.length - 1; i >= 0; i--) {
var opponent = opponents[i];
// Remove off-screen opponents
if (opponent.lastY < 2800 && opponent.y >= 2800) {
opponent.destroy();
opponents.splice(i, 1);
continue;
}
// Check collision with player
if (f1Car.intersects(opponent)) {
LK.effects.flashScreen(0xFF0000, 500);
LK.showGameOver();
return;
}
opponent.lastY = opponent.y;
}
// Update and check speed boosts
for (var i = speedBoosts.length - 1; i >= 0; i--) {
var boost = speedBoosts[i];
// Remove off-screen boosts
if (boost.y > 2800) {
boost.destroy();
speedBoosts.splice(i, 1);
continue;
}
// Check collection
var currentIntersecting = f1Car.intersects(boost);
if (!boost.lastIntersecting && currentIntersecting) {
f1Car.activateBoost();
boost.destroy();
speedBoosts.splice(i, 1);
continue;
}
boost.lastIntersecting = currentIntersecting;
}
// Win condition - reach 50km
if (distance >= 500000) {
LK.showYouWin();
}
};