/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Dashboard = Container.expand(function () {
var self = Container.call(this);
var dashboardBase = self.attachAsset('dashboard', {
anchorX: 0.5,
anchorY: 1.0
});
var steeringWheel = self.attachAsset('steeringWheel', {
anchorX: 0.5,
anchorY: 0.5
});
steeringWheel.x = 0;
steeringWheel.y = -200;
var speedometer = self.attachAsset('speedometer', {
anchorX: 0.5,
anchorY: 0.5
});
speedometer.x = 600;
speedometer.y = -150;
var fuelGauge = new FuelGauge();
fuelGauge.x = -600;
fuelGauge.y = -150;
self.addChild(fuelGauge);
self.updateSteering = function (rotation) {
steeringWheel.rotation = rotation;
};
self.updateFuel = function (fuelLevel) {
fuelGauge.updateFuel(fuelLevel);
};
return self;
});
var FuelGauge = Container.expand(function () {
var self = Container.call(this);
var gaugeBase = self.attachAsset('speedometer', {
anchorX: 0.5,
anchorY: 0.5
});
gaugeBase.tint = 0x444444;
var fuelNeedle = LK.getAsset('roadLines', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.3,
scaleY: 2.0
});
fuelNeedle.tint = 0x00FF00;
self.addChild(fuelNeedle);
self.updateFuel = function (fuelLevel) {
var angle = -Math.PI * 0.75 + fuelLevel / 100 * Math.PI * 1.5;
fuelNeedle.rotation = angle;
if (fuelLevel < 25) {
fuelNeedle.tint = 0xFF0000;
} else if (fuelLevel < 50) {
fuelNeedle.tint = 0xFFFF00;
} else {
fuelNeedle.tint = 0x00FF00;
}
};
return self;
});
var GasCan = Container.expand(function () {
var self = Container.call(this);
var canGraphics = self.attachAsset('gasoline', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(canGraphics);
self.collected = false;
self.update = function () {
self.y += 15 * gameSpeed;
// Gentle bobbing animation
self.rotation = Math.sin(LK.ticks * 0.1) * 0.2;
};
return self;
});
var RoadLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('roadLines', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += 15 * gameSpeed;
if (self.y > 2832) {
self.y = -100;
}
};
return self;
});
var TrafficCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('trafficCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 3 + 2;
self.lane = 0;
self.update = function () {
self.y += self.speed * gameSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var gameSpeed = 1.5;
var playerLane = 0; // 0 = left, 1 = right
var lanePositions = [700, 1348];
var distance = 0;
var trafficCars = [];
var roadLines = [];
var gasCans = [];
var lastTrafficSpawn = 0;
var lastGasCanSpawn = 0;
var steeringRotation = 0;
var isChangingLanes = false;
var fuelLevel = 100;
var lastFuelDecrease = 0;
// Create road background
var roadBackground = game.addChild(LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
scaleY: 7
}));
roadBackground.x = 1024;
roadBackground.y = 1366;
// Create road lines
for (var i = 0; i < 30; i++) {
var roadLine = new RoadLine();
roadLine.x = 1024; // Center line between two lanes
roadLine.y = i * 150 - 100;
roadLines.push(roadLine);
game.addChild(roadLine);
}
// Create player car
var playerCar = game.addChild(LK.getAsset('car', {
anchorX: 0.5,
anchorY: 0.5
}));
playerCar.x = lanePositions[playerLane];
playerCar.y = 2000;
// Create dashboard
var dashboard = new Dashboard();
dashboard.x = 1024;
dashboard.y = 2732;
game.addChild(dashboard);
// Create speed display
var speedText = new Text2('Speed: 60 MPH', {
size: 60,
fill: 0x00FF00
});
speedText.anchor.set(0.5, 0.5);
speedText.x = 300;
speedText.y = 150;
LK.gui.bottomLeft.addChild(speedText);
// Create distance display
var distanceText = new Text2('Distance: 0 ft', {
size: 60,
fill: 0xFFFFFF
});
distanceText.anchor.set(0.5, 0);
LK.gui.top.addChild(distanceText);
// Create fuel display
var fuelText = new Text2('Fuel: 100%', {
size: 60,
fill: 0x00FF00
});
fuelText.anchor.set(0.5, 0.5);
fuelText.x = 300;
fuelText.y = 250;
LK.gui.bottomLeft.addChild(fuelText);
function spawnTrafficCar() {
if (LK.ticks - lastTrafficSpawn > 40) {
var lane = Math.floor(Math.random() * 2);
var trafficCar = new TrafficCar();
trafficCar.x = lanePositions[lane];
trafficCar.y = -200; // Spawn further up to avoid steering wheel area
trafficCar.lane = lane;
// Ensure cars don't spawn too close to each other
var canSpawn = true;
for (var i = 0; i < trafficCars.length; i++) {
var existingCar = trafficCars[i];
if (existingCar.lane === lane && Math.abs(existingCar.y - trafficCar.y) < 300) {
canSpawn = false;
break;
}
}
if (canSpawn) {
trafficCars.push(trafficCar);
game.addChild(trafficCar);
lastTrafficSpawn = LK.ticks;
}
}
}
function spawnGasCan() {
if (LK.ticks - lastGasCanSpawn > 900 && Math.random() < 0.3) {
// Spawn less frequently
var lane = Math.floor(Math.random() * 2);
var gasCan = new GasCan();
gasCan.x = lanePositions[lane];
gasCan.y = -200;
gasCan.lane = lane;
gasCans.push(gasCan);
game.addChild(gasCan);
lastGasCanSpawn = LK.ticks;
}
}
function changeLane(targetLane) {
if (!isChangingLanes && targetLane >= 0 && targetLane <= 1 && targetLane !== playerLane) {
isChangingLanes = true;
var oldLane = playerLane;
playerLane = targetLane;
var steerDirection = targetLane > oldLane ? 0.3 : -0.3;
steeringRotation = steerDirection;
dashboard.updateSteering(steerDirection);
tween(playerCar, {
x: lanePositions[playerLane]
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
isChangingLanes = false;
steeringRotation = 0;
dashboard.updateSteering(0);
}
});
}
}
function checkCollisions() {
for (var i = 0; i < trafficCars.length; i++) {
var car = trafficCars[i];
if (car.lane === playerLane) {
var carTop = car.y - 25;
var carBottom = car.y + 25;
var playerTop = playerCar.y - 30;
var playerBottom = playerCar.y + 30;
if (carBottom > playerTop && carTop < playerBottom) {
// Collision detected
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
// Near miss bonus
if (carBottom > playerTop - 50 && carTop < playerBottom + 50 && !car.nearMissAwarded) {
LK.setScore(LK.getScore() + 10);
car.nearMissAwarded = true;
}
}
}
}
game.down = function (x, y, obj) {
if (x < 1024) {
// Left side tap - move left
changeLane(playerLane - 1);
} else {
// Right side tap - move right
changeLane(playerLane + 1);
}
};
game.update = function () {
// Increase game speed over time
gameSpeed += 0.003;
// Update distance
distance += gameSpeed * 2;
distanceText.setText('Distance: ' + Math.floor(distance) + ' ft');
// Update speed display
var mph = Math.floor(60 + (gameSpeed - 1) * 40);
speedText.setText('Speed: ' + mph + ' MPH');
// Decrease fuel over time
if (LK.ticks - lastFuelDecrease > 60) {
// Decrease every second
fuelLevel -= 0.5;
if (fuelLevel <= 0) {
fuelLevel = 0;
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
lastFuelDecrease = LK.ticks;
dashboard.updateFuel(fuelLevel);
// Update fuel text color based on level
if (fuelLevel < 25) {
fuelText.tint = 0xFF0000;
} else if (fuelLevel < 50) {
fuelText.tint = 0xFFFF00;
} else {
fuelText.tint = 0x00FF00;
}
fuelText.setText('Fuel: ' + Math.floor(fuelLevel) + '%');
}
// Spawn traffic cars and gas cans
spawnTrafficCar();
spawnGasCan();
// Update road lines (handled in their update method)
// Remove off-screen traffic cars and update positions
for (var i = trafficCars.length - 1; i >= 0; i--) {
var car = trafficCars[i];
if (car.y > 2832) {
car.destroy();
trafficCars.splice(i, 1);
}
}
// Remove off-screen gas cans and check for collection
for (var i = gasCans.length - 1; i >= 0; i--) {
var gasCan = gasCans[i];
if (gasCan.y > 2832) {
gasCan.destroy();
gasCans.splice(i, 1);
} else if (gasCan.lane === playerLane && !gasCan.collected) {
var canTop = gasCan.y - 30;
var canBottom = gasCan.y + 30;
var playerTop = playerCar.y - 30;
var playerBottom = playerCar.y + 30;
if (canBottom > playerTop && canTop < playerBottom) {
// Gas can collected
gasCan.collected = true;
fuelLevel = Math.min(100, fuelLevel + 25);
dashboard.updateFuel(fuelLevel);
LK.setScore(LK.getScore() + 50);
tween(gasCan, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
gasCan.destroy();
}
});
gasCans.splice(i, 1);
}
}
}
// Check for collisions
checkCollisions();
// Update score based on distance
LK.setScore(Math.floor(distance / 10));
// Add screen shake effect at high speeds
if (gameSpeed > 2.0) {
var shakeAmount = (gameSpeed - 2.0) * 2;
game.x = (Math.random() - 0.5) * shakeAmount;
game.y = (Math.random() - 0.5) * shakeAmount;
}
};
// Play engine sound and background music
LK.getSound('engine').play();
LK.playMusic('highway'); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Dashboard = Container.expand(function () {
var self = Container.call(this);
var dashboardBase = self.attachAsset('dashboard', {
anchorX: 0.5,
anchorY: 1.0
});
var steeringWheel = self.attachAsset('steeringWheel', {
anchorX: 0.5,
anchorY: 0.5
});
steeringWheel.x = 0;
steeringWheel.y = -200;
var speedometer = self.attachAsset('speedometer', {
anchorX: 0.5,
anchorY: 0.5
});
speedometer.x = 600;
speedometer.y = -150;
var fuelGauge = new FuelGauge();
fuelGauge.x = -600;
fuelGauge.y = -150;
self.addChild(fuelGauge);
self.updateSteering = function (rotation) {
steeringWheel.rotation = rotation;
};
self.updateFuel = function (fuelLevel) {
fuelGauge.updateFuel(fuelLevel);
};
return self;
});
var FuelGauge = Container.expand(function () {
var self = Container.call(this);
var gaugeBase = self.attachAsset('speedometer', {
anchorX: 0.5,
anchorY: 0.5
});
gaugeBase.tint = 0x444444;
var fuelNeedle = LK.getAsset('roadLines', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.3,
scaleY: 2.0
});
fuelNeedle.tint = 0x00FF00;
self.addChild(fuelNeedle);
self.updateFuel = function (fuelLevel) {
var angle = -Math.PI * 0.75 + fuelLevel / 100 * Math.PI * 1.5;
fuelNeedle.rotation = angle;
if (fuelLevel < 25) {
fuelNeedle.tint = 0xFF0000;
} else if (fuelLevel < 50) {
fuelNeedle.tint = 0xFFFF00;
} else {
fuelNeedle.tint = 0x00FF00;
}
};
return self;
});
var GasCan = Container.expand(function () {
var self = Container.call(this);
var canGraphics = self.attachAsset('gasoline', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(canGraphics);
self.collected = false;
self.update = function () {
self.y += 15 * gameSpeed;
// Gentle bobbing animation
self.rotation = Math.sin(LK.ticks * 0.1) * 0.2;
};
return self;
});
var RoadLine = Container.expand(function () {
var self = Container.call(this);
var lineGraphics = self.attachAsset('roadLines', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += 15 * gameSpeed;
if (self.y > 2832) {
self.y = -100;
}
};
return self;
});
var TrafficCar = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('trafficCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 3 + 2;
self.lane = 0;
self.update = function () {
self.y += self.speed * gameSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var gameSpeed = 1.5;
var playerLane = 0; // 0 = left, 1 = right
var lanePositions = [700, 1348];
var distance = 0;
var trafficCars = [];
var roadLines = [];
var gasCans = [];
var lastTrafficSpawn = 0;
var lastGasCanSpawn = 0;
var steeringRotation = 0;
var isChangingLanes = false;
var fuelLevel = 100;
var lastFuelDecrease = 0;
// Create road background
var roadBackground = game.addChild(LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
scaleY: 7
}));
roadBackground.x = 1024;
roadBackground.y = 1366;
// Create road lines
for (var i = 0; i < 30; i++) {
var roadLine = new RoadLine();
roadLine.x = 1024; // Center line between two lanes
roadLine.y = i * 150 - 100;
roadLines.push(roadLine);
game.addChild(roadLine);
}
// Create player car
var playerCar = game.addChild(LK.getAsset('car', {
anchorX: 0.5,
anchorY: 0.5
}));
playerCar.x = lanePositions[playerLane];
playerCar.y = 2000;
// Create dashboard
var dashboard = new Dashboard();
dashboard.x = 1024;
dashboard.y = 2732;
game.addChild(dashboard);
// Create speed display
var speedText = new Text2('Speed: 60 MPH', {
size: 60,
fill: 0x00FF00
});
speedText.anchor.set(0.5, 0.5);
speedText.x = 300;
speedText.y = 150;
LK.gui.bottomLeft.addChild(speedText);
// Create distance display
var distanceText = new Text2('Distance: 0 ft', {
size: 60,
fill: 0xFFFFFF
});
distanceText.anchor.set(0.5, 0);
LK.gui.top.addChild(distanceText);
// Create fuel display
var fuelText = new Text2('Fuel: 100%', {
size: 60,
fill: 0x00FF00
});
fuelText.anchor.set(0.5, 0.5);
fuelText.x = 300;
fuelText.y = 250;
LK.gui.bottomLeft.addChild(fuelText);
function spawnTrafficCar() {
if (LK.ticks - lastTrafficSpawn > 40) {
var lane = Math.floor(Math.random() * 2);
var trafficCar = new TrafficCar();
trafficCar.x = lanePositions[lane];
trafficCar.y = -200; // Spawn further up to avoid steering wheel area
trafficCar.lane = lane;
// Ensure cars don't spawn too close to each other
var canSpawn = true;
for (var i = 0; i < trafficCars.length; i++) {
var existingCar = trafficCars[i];
if (existingCar.lane === lane && Math.abs(existingCar.y - trafficCar.y) < 300) {
canSpawn = false;
break;
}
}
if (canSpawn) {
trafficCars.push(trafficCar);
game.addChild(trafficCar);
lastTrafficSpawn = LK.ticks;
}
}
}
function spawnGasCan() {
if (LK.ticks - lastGasCanSpawn > 900 && Math.random() < 0.3) {
// Spawn less frequently
var lane = Math.floor(Math.random() * 2);
var gasCan = new GasCan();
gasCan.x = lanePositions[lane];
gasCan.y = -200;
gasCan.lane = lane;
gasCans.push(gasCan);
game.addChild(gasCan);
lastGasCanSpawn = LK.ticks;
}
}
function changeLane(targetLane) {
if (!isChangingLanes && targetLane >= 0 && targetLane <= 1 && targetLane !== playerLane) {
isChangingLanes = true;
var oldLane = playerLane;
playerLane = targetLane;
var steerDirection = targetLane > oldLane ? 0.3 : -0.3;
steeringRotation = steerDirection;
dashboard.updateSteering(steerDirection);
tween(playerCar, {
x: lanePositions[playerLane]
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
isChangingLanes = false;
steeringRotation = 0;
dashboard.updateSteering(0);
}
});
}
}
function checkCollisions() {
for (var i = 0; i < trafficCars.length; i++) {
var car = trafficCars[i];
if (car.lane === playerLane) {
var carTop = car.y - 25;
var carBottom = car.y + 25;
var playerTop = playerCar.y - 30;
var playerBottom = playerCar.y + 30;
if (carBottom > playerTop && carTop < playerBottom) {
// Collision detected
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
// Near miss bonus
if (carBottom > playerTop - 50 && carTop < playerBottom + 50 && !car.nearMissAwarded) {
LK.setScore(LK.getScore() + 10);
car.nearMissAwarded = true;
}
}
}
}
game.down = function (x, y, obj) {
if (x < 1024) {
// Left side tap - move left
changeLane(playerLane - 1);
} else {
// Right side tap - move right
changeLane(playerLane + 1);
}
};
game.update = function () {
// Increase game speed over time
gameSpeed += 0.003;
// Update distance
distance += gameSpeed * 2;
distanceText.setText('Distance: ' + Math.floor(distance) + ' ft');
// Update speed display
var mph = Math.floor(60 + (gameSpeed - 1) * 40);
speedText.setText('Speed: ' + mph + ' MPH');
// Decrease fuel over time
if (LK.ticks - lastFuelDecrease > 60) {
// Decrease every second
fuelLevel -= 0.5;
if (fuelLevel <= 0) {
fuelLevel = 0;
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
lastFuelDecrease = LK.ticks;
dashboard.updateFuel(fuelLevel);
// Update fuel text color based on level
if (fuelLevel < 25) {
fuelText.tint = 0xFF0000;
} else if (fuelLevel < 50) {
fuelText.tint = 0xFFFF00;
} else {
fuelText.tint = 0x00FF00;
}
fuelText.setText('Fuel: ' + Math.floor(fuelLevel) + '%');
}
// Spawn traffic cars and gas cans
spawnTrafficCar();
spawnGasCan();
// Update road lines (handled in their update method)
// Remove off-screen traffic cars and update positions
for (var i = trafficCars.length - 1; i >= 0; i--) {
var car = trafficCars[i];
if (car.y > 2832) {
car.destroy();
trafficCars.splice(i, 1);
}
}
// Remove off-screen gas cans and check for collection
for (var i = gasCans.length - 1; i >= 0; i--) {
var gasCan = gasCans[i];
if (gasCan.y > 2832) {
gasCan.destroy();
gasCans.splice(i, 1);
} else if (gasCan.lane === playerLane && !gasCan.collected) {
var canTop = gasCan.y - 30;
var canBottom = gasCan.y + 30;
var playerTop = playerCar.y - 30;
var playerBottom = playerCar.y + 30;
if (canBottom > playerTop && canTop < playerBottom) {
// Gas can collected
gasCan.collected = true;
fuelLevel = Math.min(100, fuelLevel + 25);
dashboard.updateFuel(fuelLevel);
LK.setScore(LK.getScore() + 50);
tween(gasCan, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
gasCan.destroy();
}
});
gasCans.splice(i, 1);
}
}
}
// Check for collisions
checkCollisions();
// Update score based on distance
LK.setScore(Math.floor(distance / 10));
// Add screen shake effect at high speeds
if (gameSpeed > 2.0) {
var shakeAmount = (gameSpeed - 2.0) * 2;
game.x = (Math.random() - 0.5) * shakeAmount;
game.y = (Math.random() - 0.5) * shakeAmount;
}
};
// Play engine sound and background music
LK.getSound('engine').play();
LK.playMusic('highway');