/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var Collectible = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'fuel'; var assetType = self.type === 'fuel' ? 'fuel' : 'speedBoost'; var collectibleGraphics = self.attachAsset(assetType, { anchorX: 0.5, anchorY: 0.5 }); self.active = true; self.pulseDirection = 1; self.pulseAmount = 0; self.update = function () { if (!self.active) { return; } self.x -= gameSpeed; // Pulsing animation self.pulseAmount += 0.02 * self.pulseDirection; if (self.pulseAmount > 0.2 || self.pulseAmount < 0) { self.pulseDirection *= -1; } collectibleGraphics.scaleX = 1 + self.pulseAmount; collectibleGraphics.scaleY = 1 + self.pulseAmount; // Remove if off screen if (self.x < -100) { self.active = false; } }; self.collect = function () { if (self.active) { self.active = false; LK.getSound('collect').play(); var effect = { alpha: 1, scaleX: 1, scaleY: 1, y: self.y }; tween(effect, { alpha: 0, scaleX: 2, scaleY: 2, y: self.y - 100 }, { duration: 600, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); return self.type; } return null; }; return self; }); var FareObstacle = Container.expand(function () { var self = Container.call(this); var fareObstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'fareObstacle'; self.active = true; self.update = function () { if (!self.active) { return; } self.x -= gameSpeed; if (self.x < -100) { self.active = false; } }; return self; }); var FuelItem = Container.expand(function () { var self = Container.call(this); var fuelItemGraphics = self.attachAsset('fuel', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'fuelItem'; self.active = true; self.update = function () { if (!self.active) { return; } self.x -= gameSpeed; if (self.x < -100) { self.active = false; } }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'obstacle'; self.active = true; self.update = function () { if (!self.active) { return; } self.x -= gameSpeed; // Remove if off screen if (self.x < -100) { self.active = false; } }; return self; }); var RoadLine = Container.expand(function () { var self = Container.call(this); var lineGraphics = self.attachAsset('roadLine', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x -= gameSpeed; // Reset position if off screen if (self.x < -100) { self.x = 2148; } }; return self; }); var Vehicle = Container.expand(function () { var self = Container.call(this); var vehicleGraphics = self.attachAsset('vehicle', { anchorX: 0.5, anchorY: 0.5 }); // Vehicle properties self.speed = 1; self.maxSpeed = 15; self.acceleration = 0.005; self.jumping = false; self.jumpHeight = 200; self.jumpSpeed = 15; self.jumpVelocity = 0; self.gravity = 0.8; self.crashed = false; // Movement control self.moveUp = function () { if (self.y > roadTop + 50) { self.y -= 20; } }; self.moveDown = function () { if (self.y < roadBottom - 50) { self.y += 20; } }; self.jump = function () { if (!self.jumping && !self.crashed) { self.jumping = true; self.jumpVelocity = -self.jumpSpeed; } }; self.crash = function () { if (!self.crashed) { self.crashed = true; LK.getSound('crash').play(); LK.effects.flashObject(self, 0xff0000, 1000); // Create explosion effect var explosion = LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y, alpha: 0.8 }); game.addChild(explosion); // Scale explosion and fade out tween(explosion, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { explosion.destroy(); } }); // Tilt vehicle tween(vehicleGraphics, { rotation: Math.PI / 4 }, { duration: 500, easing: tween.bounceOut }); // Game over after short delay LK.setTimeout(function () { if (distance > storage.highScore) { storage.highScore = Math.floor(distance); } LK.showGameOver(); }, 1200); } }; self.update = function () { if (self.crashed) { return; } // Update speed if (self.speed < self.maxSpeed) { self.speed += self.acceleration; } // Handle jumping if (self.jumping) { self.y += self.jumpVelocity; self.jumpVelocity += self.gravity; // Check if landing if (self.jumpVelocity > 0 && self.y >= self.jumpStartY) { self.y = self.jumpStartY; self.jumping = false; self.jumpVelocity = 0; } } // Small bounce effect if (!self.jumping && !self.tweening) { self.tweening = true; tween(vehicleGraphics, { rotation: -0.05 }, { duration: 300, easing: tween.linear, onFinish: function onFinish() { tween(vehicleGraphics, { rotation: 0 }, { duration: 300, easing: tween.linear, onFinish: function onFinish() { self.tweening = false; } }); } }); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB // Sky blue }); /**** * Game Code ****/ // Game variables var vehicle; var obstacles = []; var collectibles = []; var roadLines = []; var gameSpeed = 8; var baseSpeed = 8; var speedMultiplier = 1; var distance = 0; var fuelLevel = 100; var gameStarted = false; var roadTop = 2732 - 500; // Top of road area var roadBottom = 2732 - 200; // Bottom of road area var spawnTimer = 0; var obstacleSpawnRate = 180; // frames between obstacle spawns var collectibleSpawnRate = 180; // frames between collectible spawns var lastObstacleSpawn = 0; var lastCollectibleSpawn = 0; // Add background image var background = LK.getAsset('backgroundImage', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(background); // Create road var road = LK.getAsset('road', { anchorX: 0, anchorY: 0, x: 0, y: roadTop, width: 2048 }); game.addChild(road); // Create road lines for (var i = 0; i < 10; i++) { var roadLine = new RoadLine(); roadLine.x = i * 220; roadLine.y = roadTop + 150; roadLines.push(roadLine); game.addChild(roadLine); } // Create player vehicle vehicle = new Vehicle(); vehicle.x = 300; vehicle.y = roadTop + 150; vehicle.jumpStartY = vehicle.y; game.addChild(vehicle); // Create score text var scoreTxt = new Text2('Distance: 0m', { size: 70, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create fuel meter var fuelBarBg = LK.getAsset('road', { anchorX: 0, anchorY: 0, width: 300, height: 30, color: 0x555555, x: 0, y: 0 }); var fuelBar = LK.getAsset('road', { anchorX: 0, anchorY: 0, width: 300, height: 30, color: 0x2ecc71, x: 0, y: 0 }); var fuelText = new Text2('FUEL', { size: 20, fill: 0xFFFFFF }); fuelText.anchor.set(0.5, 0.5); fuelText.x = 150; fuelText.y = 15; var fuelContainer = new Container(); fuelContainer.addChild(fuelBarBg); fuelContainer.addChild(fuelBar); fuelContainer.addChild(fuelText); fuelContainer.x = 20; fuelContainer.y = 20; LK.gui.topLeft.addChild(fuelContainer); // Create high score display var highScoreTxt = new Text2('Best: ' + storage.highScore + 'm', { size: 50, fill: 0xFFFFFF }); highScoreTxt.anchor.set(1, 0); highScoreTxt.x = -20; highScoreTxt.y = 20; LK.gui.topRight.addChild(highScoreTxt); // Speed boost indicator var boostIndicator = new Text2('BOOST!', { size: 60, fill: 0xF1C40F }); boostIndicator.anchor.set(0.5, 0); boostIndicator.y = 100; boostIndicator.alpha = 0; LK.gui.top.addChild(boostIndicator); // Create tap controls function createControlButton(text, x, y, action) { var button = new Container(); var buttonBg = LK.getAsset('road', { anchorX: 0.5, anchorY: 0.5, width: 200, height: 200, color: 0x000000, alpha: 0.3 }); button.addChild(buttonBg); var buttonText = new Text2(text, { size: 60, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); button.addChild(buttonText); button.x = x; button.y = y; button.interactive = true; button.down = function () { buttonBg.alpha = 0.5; action(); }; button.up = function () { buttonBg.alpha = 0.3; }; return button; } var upButton = createControlButton("↑", -300, -200, function () { vehicle.moveUp(); }); var downButton = createControlButton("↓", -300, -50, function () { vehicle.moveDown(); }); var jumpButton = createControlButton("JUMP", 300, -125, function () { vehicle.jump(); }); LK.gui.bottom.addChild(upButton); LK.gui.bottom.addChild(downButton); LK.gui.bottom.addChild(jumpButton); // Start the game LK.playMusic('gameMusic'); gameStarted = true; // Spawn objects function spawnObstacle() { var obstacle = new Obstacle(); obstacle.x = 2200; // Random position on road obstacle.y = roadTop + 50 + Math.random() * (roadBottom - roadTop - 100); obstacles.push(obstacle); game.addChild(obstacle); lastObstacleSpawn = LK.ticks; } function spawnCollectible() { var type = Math.random() < 0.7 ? 'fuel' : 'speedBoost'; var collectible = new Collectible(type); collectible.x = 2200; // Random position on road collectible.y = roadTop + 50 + Math.random() * (roadBottom - roadTop - 100); collectibles.push(collectible); game.addChild(collectible); lastCollectibleSpawn = LK.ticks; } // Game update function game.update = function () { if (!gameStarted || vehicle.crashed) { return; } // Calculate game speed gameSpeed = baseSpeed * speedMultiplier; // Update vehicle vehicle.update(); // Update road lines for (var i = 0; i < roadLines.length; i++) { roadLines[i].update(); } // Spawn obstacles if (LK.ticks - lastObstacleSpawn > obstacleSpawnRate) { spawnObstacle(); // Gradually decrease spawn rate to increase difficulty obstacleSpawnRate = Math.max(60, obstacleSpawnRate - 0.5); // Randomly spawn fare obstacle with a lower probability if (Math.random() < 0.1) { var fareObstacle = new FareObstacle(); fareObstacle.x = 2200; fareObstacle.y = roadTop + 50 + Math.random() * (roadBottom - roadTop - 100); obstacles.push(fareObstacle); game.addChild(fareObstacle); } } // Spawn fuel items separately if (LK.ticks - lastCollectibleSpawn > collectibleSpawnRate) { // Randomly spawn fuel item with a lower probability if (Math.random() < 0.1) { var fuelItem = new FuelItem(); fuelItem.x = 2200; fuelItem.y = roadTop + 50 + Math.random() * (roadBottom - roadTop - 100); collectibles.push(fuelItem); game.addChild(fuelItem); } } // Spawn collectibles if (LK.ticks - lastCollectibleSpawn > collectibleSpawnRate) { spawnCollectible(); } // Update obstacles and check collisions for (var j = obstacles.length - 1; j >= 0; j--) { var obstacle = obstacles[j]; obstacle.update(); // Check collision with vehicle if (obstacle.active && !vehicle.crashed && !vehicle.invulnerable && vehicle.intersects(obstacle)) { vehicle.crash(); } // Remove inactive obstacles if (!obstacle.active) { obstacle.destroy(); obstacles.splice(j, 1); } } // Update collectibles and check collection for (var k = collectibles.length - 1; k >= 0; k--) { var collectible = collectibles[k]; collectible.update(); // Check collection if (collectible.active && vehicle.intersects(collectible)) { if (typeof collectible.collect === 'function') { var collectibleType = collectible.collect(); } if (collectibleType === 'fuel') { // Add fuel fuelLevel = Math.min(100, fuelLevel + 30); fuelBar.width = fuelLevel / 100 * 300; // Flash fuel text tween(fuelText, { tint: 0x2ecc71 }, { duration: 300, onFinish: function onFinish() { tween(fuelText, { tint: 0xffffff }, { duration: 300 }); } }); } else if (collectibleType === 'speedBoost') { // Speed boost LK.getSound('boost').play(); speedMultiplier = 1.5; // Show boost indicator boostIndicator.alpha = 1; // Reset multiplier after 3 seconds LK.setTimeout(function () { tween(boostIndicator, { alpha: 0 }, { duration: 500 }); speedMultiplier = 1; }, 3000); } collectibles.splice(k, 1); } } // Update distance and score distance += gameSpeed / 30; scoreTxt.setText('Distance: ' + Math.floor(distance) + 'm'); // Update fuel fuelLevel -= 0.05 * speedMultiplier; fuelBar.width = fuelLevel / 100 * 300; // Change fuel bar color based on level if (fuelLevel < 30) { fuelBar.tint = 0xe74c3c; // Red when low } else if (fuelLevel < 60) { fuelBar.tint = 0xf39c12; // Orange when medium } else { fuelBar.tint = 0x2ecc71; // Green when high } // Game over if fuel depleted if (fuelLevel <= 0) { vehicle.crash(); } // Increase speed over time (difficulty progression) if (LK.ticks % 300 === 0) { baseSpeed += 0.2; } }; // Game input handling game.down = function (x, y, obj) { // Jump if tap in the right half of the screen if (x > 1024 && !vehicle.jumping && !vehicle.crashed) { vehicle.jump(); } // Move up if tap in the top quarter of left half else if (x < 1024 && y < 683) { vehicle.moveUp(); } // Move down if tap in the bottom quarter of left half else if (x < 1024 && y >= 683) { vehicle.moveDown(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Collectible = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'fuel';
var assetType = self.type === 'fuel' ? 'fuel' : 'speedBoost';
var collectibleGraphics = self.attachAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
});
self.active = true;
self.pulseDirection = 1;
self.pulseAmount = 0;
self.update = function () {
if (!self.active) {
return;
}
self.x -= gameSpeed;
// Pulsing animation
self.pulseAmount += 0.02 * self.pulseDirection;
if (self.pulseAmount > 0.2 || self.pulseAmount < 0) {
self.pulseDirection *= -1;
}
collectibleGraphics.scaleX = 1 + self.pulseAmount;
collectibleGraphics.scaleY = 1 + self.pulseAmount;
// Remove if off screen
if (self.x < -100) {
self.active = false;
}
};
self.collect = function () {
if (self.active) {
self.active = false;
LK.getSound('collect').play();
var effect = {
alpha: 1,
scaleX: 1,
scaleY: 1,
y: self.y
};
tween(effect, {
alpha: 0,
scaleX: 2,
scaleY: 2,
y: self.y - 100
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
return self.type;
}
return null;
};
return self;
});
var FareObstacle = Container.expand(function () {
var self = Container.call(this);
var fareObstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'fareObstacle';
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.x -= gameSpeed;
if (self.x < -100) {
self.active = false;
}
};
return self;
});
var FuelItem = Container.expand(function () {
var self = Container.call(this);
var fuelItemGraphics = self.attachAsset('fuel', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'fuelItem';
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.x -= gameSpeed;
if (self.x < -100) {
self.active = false;
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'obstacle';
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.x -= gameSpeed;
// Remove if off screen
if (self.x < -100) {
self.active = false;
}
};
return self;
});
var RoadLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('roadLine', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.x -= gameSpeed;
// Reset position if off screen
if (self.x < -100) {
self.x = 2148;
}
};
return self;
});
var Vehicle = Container.expand(function () {
var self = Container.call(this);
var vehicleGraphics = self.attachAsset('vehicle', {
anchorX: 0.5,
anchorY: 0.5
});
// Vehicle properties
self.speed = 1;
self.maxSpeed = 15;
self.acceleration = 0.005;
self.jumping = false;
self.jumpHeight = 200;
self.jumpSpeed = 15;
self.jumpVelocity = 0;
self.gravity = 0.8;
self.crashed = false;
// Movement control
self.moveUp = function () {
if (self.y > roadTop + 50) {
self.y -= 20;
}
};
self.moveDown = function () {
if (self.y < roadBottom - 50) {
self.y += 20;
}
};
self.jump = function () {
if (!self.jumping && !self.crashed) {
self.jumping = true;
self.jumpVelocity = -self.jumpSpeed;
}
};
self.crash = function () {
if (!self.crashed) {
self.crashed = true;
LK.getSound('crash').play();
LK.effects.flashObject(self, 0xff0000, 1000);
// Create explosion effect
var explosion = LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y,
alpha: 0.8
});
game.addChild(explosion);
// Scale explosion and fade out
tween(explosion, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Tilt vehicle
tween(vehicleGraphics, {
rotation: Math.PI / 4
}, {
duration: 500,
easing: tween.bounceOut
});
// Game over after short delay
LK.setTimeout(function () {
if (distance > storage.highScore) {
storage.highScore = Math.floor(distance);
}
LK.showGameOver();
}, 1200);
}
};
self.update = function () {
if (self.crashed) {
return;
}
// Update speed
if (self.speed < self.maxSpeed) {
self.speed += self.acceleration;
}
// Handle jumping
if (self.jumping) {
self.y += self.jumpVelocity;
self.jumpVelocity += self.gravity;
// Check if landing
if (self.jumpVelocity > 0 && self.y >= self.jumpStartY) {
self.y = self.jumpStartY;
self.jumping = false;
self.jumpVelocity = 0;
}
}
// Small bounce effect
if (!self.jumping && !self.tweening) {
self.tweening = true;
tween(vehicleGraphics, {
rotation: -0.05
}, {
duration: 300,
easing: tween.linear,
onFinish: function onFinish() {
tween(vehicleGraphics, {
rotation: 0
}, {
duration: 300,
easing: tween.linear,
onFinish: function onFinish() {
self.tweening = false;
}
});
}
});
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue
});
/****
* Game Code
****/
// Game variables
var vehicle;
var obstacles = [];
var collectibles = [];
var roadLines = [];
var gameSpeed = 8;
var baseSpeed = 8;
var speedMultiplier = 1;
var distance = 0;
var fuelLevel = 100;
var gameStarted = false;
var roadTop = 2732 - 500; // Top of road area
var roadBottom = 2732 - 200; // Bottom of road area
var spawnTimer = 0;
var obstacleSpawnRate = 180; // frames between obstacle spawns
var collectibleSpawnRate = 180; // frames between collectible spawns
var lastObstacleSpawn = 0;
var lastCollectibleSpawn = 0;
// Add background image
var background = LK.getAsset('backgroundImage', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(background);
// Create road
var road = LK.getAsset('road', {
anchorX: 0,
anchorY: 0,
x: 0,
y: roadTop,
width: 2048
});
game.addChild(road);
// Create road lines
for (var i = 0; i < 10; i++) {
var roadLine = new RoadLine();
roadLine.x = i * 220;
roadLine.y = roadTop + 150;
roadLines.push(roadLine);
game.addChild(roadLine);
}
// Create player vehicle
vehicle = new Vehicle();
vehicle.x = 300;
vehicle.y = roadTop + 150;
vehicle.jumpStartY = vehicle.y;
game.addChild(vehicle);
// Create score text
var scoreTxt = new Text2('Distance: 0m', {
size: 70,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create fuel meter
var fuelBarBg = LK.getAsset('road', {
anchorX: 0,
anchorY: 0,
width: 300,
height: 30,
color: 0x555555,
x: 0,
y: 0
});
var fuelBar = LK.getAsset('road', {
anchorX: 0,
anchorY: 0,
width: 300,
height: 30,
color: 0x2ecc71,
x: 0,
y: 0
});
var fuelText = new Text2('FUEL', {
size: 20,
fill: 0xFFFFFF
});
fuelText.anchor.set(0.5, 0.5);
fuelText.x = 150;
fuelText.y = 15;
var fuelContainer = new Container();
fuelContainer.addChild(fuelBarBg);
fuelContainer.addChild(fuelBar);
fuelContainer.addChild(fuelText);
fuelContainer.x = 20;
fuelContainer.y = 20;
LK.gui.topLeft.addChild(fuelContainer);
// Create high score display
var highScoreTxt = new Text2('Best: ' + storage.highScore + 'm', {
size: 50,
fill: 0xFFFFFF
});
highScoreTxt.anchor.set(1, 0);
highScoreTxt.x = -20;
highScoreTxt.y = 20;
LK.gui.topRight.addChild(highScoreTxt);
// Speed boost indicator
var boostIndicator = new Text2('BOOST!', {
size: 60,
fill: 0xF1C40F
});
boostIndicator.anchor.set(0.5, 0);
boostIndicator.y = 100;
boostIndicator.alpha = 0;
LK.gui.top.addChild(boostIndicator);
// Create tap controls
function createControlButton(text, x, y, action) {
var button = new Container();
var buttonBg = LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
width: 200,
height: 200,
color: 0x000000,
alpha: 0.3
});
button.addChild(buttonBg);
var buttonText = new Text2(text, {
size: 60,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
button.addChild(buttonText);
button.x = x;
button.y = y;
button.interactive = true;
button.down = function () {
buttonBg.alpha = 0.5;
action();
};
button.up = function () {
buttonBg.alpha = 0.3;
};
return button;
}
var upButton = createControlButton("↑", -300, -200, function () {
vehicle.moveUp();
});
var downButton = createControlButton("↓", -300, -50, function () {
vehicle.moveDown();
});
var jumpButton = createControlButton("JUMP", 300, -125, function () {
vehicle.jump();
});
LK.gui.bottom.addChild(upButton);
LK.gui.bottom.addChild(downButton);
LK.gui.bottom.addChild(jumpButton);
// Start the game
LK.playMusic('gameMusic');
gameStarted = true;
// Spawn objects
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.x = 2200;
// Random position on road
obstacle.y = roadTop + 50 + Math.random() * (roadBottom - roadTop - 100);
obstacles.push(obstacle);
game.addChild(obstacle);
lastObstacleSpawn = LK.ticks;
}
function spawnCollectible() {
var type = Math.random() < 0.7 ? 'fuel' : 'speedBoost';
var collectible = new Collectible(type);
collectible.x = 2200;
// Random position on road
collectible.y = roadTop + 50 + Math.random() * (roadBottom - roadTop - 100);
collectibles.push(collectible);
game.addChild(collectible);
lastCollectibleSpawn = LK.ticks;
}
// Game update function
game.update = function () {
if (!gameStarted || vehicle.crashed) {
return;
}
// Calculate game speed
gameSpeed = baseSpeed * speedMultiplier;
// Update vehicle
vehicle.update();
// Update road lines
for (var i = 0; i < roadLines.length; i++) {
roadLines[i].update();
}
// Spawn obstacles
if (LK.ticks - lastObstacleSpawn > obstacleSpawnRate) {
spawnObstacle();
// Gradually decrease spawn rate to increase difficulty
obstacleSpawnRate = Math.max(60, obstacleSpawnRate - 0.5);
// Randomly spawn fare obstacle with a lower probability
if (Math.random() < 0.1) {
var fareObstacle = new FareObstacle();
fareObstacle.x = 2200;
fareObstacle.y = roadTop + 50 + Math.random() * (roadBottom - roadTop - 100);
obstacles.push(fareObstacle);
game.addChild(fareObstacle);
}
}
// Spawn fuel items separately
if (LK.ticks - lastCollectibleSpawn > collectibleSpawnRate) {
// Randomly spawn fuel item with a lower probability
if (Math.random() < 0.1) {
var fuelItem = new FuelItem();
fuelItem.x = 2200;
fuelItem.y = roadTop + 50 + Math.random() * (roadBottom - roadTop - 100);
collectibles.push(fuelItem);
game.addChild(fuelItem);
}
}
// Spawn collectibles
if (LK.ticks - lastCollectibleSpawn > collectibleSpawnRate) {
spawnCollectible();
}
// Update obstacles and check collisions
for (var j = obstacles.length - 1; j >= 0; j--) {
var obstacle = obstacles[j];
obstacle.update();
// Check collision with vehicle
if (obstacle.active && !vehicle.crashed && !vehicle.invulnerable && vehicle.intersects(obstacle)) {
vehicle.crash();
}
// Remove inactive obstacles
if (!obstacle.active) {
obstacle.destroy();
obstacles.splice(j, 1);
}
}
// Update collectibles and check collection
for (var k = collectibles.length - 1; k >= 0; k--) {
var collectible = collectibles[k];
collectible.update();
// Check collection
if (collectible.active && vehicle.intersects(collectible)) {
if (typeof collectible.collect === 'function') {
var collectibleType = collectible.collect();
}
if (collectibleType === 'fuel') {
// Add fuel
fuelLevel = Math.min(100, fuelLevel + 30);
fuelBar.width = fuelLevel / 100 * 300;
// Flash fuel text
tween(fuelText, {
tint: 0x2ecc71
}, {
duration: 300,
onFinish: function onFinish() {
tween(fuelText, {
tint: 0xffffff
}, {
duration: 300
});
}
});
} else if (collectibleType === 'speedBoost') {
// Speed boost
LK.getSound('boost').play();
speedMultiplier = 1.5;
// Show boost indicator
boostIndicator.alpha = 1;
// Reset multiplier after 3 seconds
LK.setTimeout(function () {
tween(boostIndicator, {
alpha: 0
}, {
duration: 500
});
speedMultiplier = 1;
}, 3000);
}
collectibles.splice(k, 1);
}
}
// Update distance and score
distance += gameSpeed / 30;
scoreTxt.setText('Distance: ' + Math.floor(distance) + 'm');
// Update fuel
fuelLevel -= 0.05 * speedMultiplier;
fuelBar.width = fuelLevel / 100 * 300;
// Change fuel bar color based on level
if (fuelLevel < 30) {
fuelBar.tint = 0xe74c3c; // Red when low
} else if (fuelLevel < 60) {
fuelBar.tint = 0xf39c12; // Orange when medium
} else {
fuelBar.tint = 0x2ecc71; // Green when high
}
// Game over if fuel depleted
if (fuelLevel <= 0) {
vehicle.crash();
}
// Increase speed over time (difficulty progression)
if (LK.ticks % 300 === 0) {
baseSpeed += 0.2;
}
};
// Game input handling
game.down = function (x, y, obj) {
// Jump if tap in the right half of the screen
if (x > 1024 && !vehicle.jumping && !vehicle.crashed) {
vehicle.jump();
}
// Move up if tap in the top quarter of left half
else if (x < 1024 && y < 683) {
vehicle.moveUp();
}
// Move down if tap in the bottom quarter of left half
else if (x < 1024 && y >= 683) {
vehicle.moveDown();
}
};