User prompt
move the start run button down a little bit and the garage button up a little bit
User prompt
take it a little higher
User prompt
Move the garage menu up a little bit
User prompt
We lost the game, don't count it as just pressing the garage, everything in the game stops, including the coins and enemies in front of us.
User prompt
We lost the game, don't count it, just press the garage and everything in the game stops.
User prompt
Don't consider that we lost the game
User prompt
When I press the garage menu, it counts as a lost game and the game stops.
User prompt
Please fix the bug: 'window.addEventListener is not a function' in or related to this line: 'window.addEventListener('keydown', function (e) {' Line Number: 200
User prompt
Make this a PC game not a mobile game
User prompt
To open the garage menu, add a button called garage under the game again, and when we press it, the garage menu will open. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add a garage menu to the game so we can strengthen our car with the coins we collect from there ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage.loginMenu is not a function' in or related to this line: 'storage.loginMenu(function onLoginComplete() {' Line Number: 430
User prompt
add in game login menu
User prompt
Please fix the bug: 'LK.showMainMenu is not a function' in or related to this line: 'LK.showMainMenu({' Line Number: 430
User prompt
add a main menu
User prompt
slow down a little more
User prompt
slow down a little more
User prompt
slow down a little more
User prompt
slow down a little more
User prompt
slow down the game a little bit
Code edit (1 edits merged)
Please save this source code
User prompt
Drive to Survive
Initial prompt
Can you make a game similar to earn to die?
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
coins: 0,
bestDistance: 0,
upgrade_fuel: 0,
upgrade_armor: 0,
upgrade_power: 0
});
/****
* Classes
****/
// Car (player vehicle)
var Car = Container.expand(function () {
var self = Container.call(this);
var carSprite = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = carSprite.width;
self.height = carSprite.height;
self.fuel = 100;
self.maxFuel = 100;
self.health = 100;
self.maxHealth = 100;
self.speed = 1.3;
self.alive = true;
// For drag
self.isDragging = false;
// For upgrades
self.applyUpgrades = function () {
self.maxFuel = 100 + storage.upgrade_fuel * 30;
self.fuel = self.maxFuel;
self.maxHealth = 100 + storage.upgrade_armor * 40;
self.health = self.maxHealth;
self.speed = 16 + storage.upgrade_power * 2;
};
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health < 0) self.health = 0;
if (self.health === 0) {
self.alive = false;
}
};
self.refuel = function (amount) {
self.fuel += amount;
if (self.fuel > self.maxFuel) self.fuel = self.maxFuel;
};
self.update = function () {
// Car movement is handled in game.update
};
return self;
});
// Coin
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinSprite = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = coinSprite.width;
self.height = coinSprite.height;
self.speed = 1.5;
self.collected = false;
self.update = function () {
self.x -= self.speed;
};
return self;
});
// Zombie
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieSprite = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = zombieSprite.width;
self.height = zombieSprite.height;
self.speed = 0.7 + Math.random() * 0.3;
self.alive = true;
self.update = function () {
self.x -= self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Music
// Sound effects
// Road
// Health Bar FG
// Health Bar BG
// Fuel Bar FG
// Fuel Bar BG
// Coin
// Zombie
// Car (player vehicle)
// Road
var road = LK.getAsset('road', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2200
});
game.addChild(road);
// Car
var car = new Car();
car.x = 400;
car.y = 2200 + 100; // Centered on road
car.applyUpgrades();
game.addChild(car);
// Arrays for zombies and coins
var zombies = [];
var coins = [];
// Distance tracking
var distance = 0;
var runActive = true;
// GUI: Distance
var distanceTxt = new Text2('0 m', {
size: 90,
fill: 0xFFFFFF
});
distanceTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(distanceTxt);
// GUI: Coins
var coinsTxt = new Text2(storage.coins + '', {
size: 90,
fill: 0xFFD700
});
coinsTxt.anchor.set(0.5, 0);
LK.gui.topRight.addChild(coinsTxt);
// GUI: Fuel Bar
var fuelBarBG = LK.getAsset('fuelBarBG', {
anchorX: 0,
anchorY: 0.5,
x: 100,
y: 120
});
var fuelBarFG = LK.getAsset('fuelBarFG', {
anchorX: 0,
anchorY: 0.5,
x: 100,
y: 120
});
LK.gui.top.addChild(fuelBarBG);
LK.gui.top.addChild(fuelBarFG);
// GUI: Health Bar
var healthBarBG = LK.getAsset('healthBarBG', {
anchorX: 0,
anchorY: 0.5,
x: 100,
y: 200
});
var healthBarFG = LK.getAsset('healthBarFG', {
anchorX: 0,
anchorY: 0.5,
x: 100,
y: 200
});
LK.gui.top.addChild(healthBarBG);
LK.gui.top.addChild(healthBarFG);
// PC controls: keyboard arrow keys or WASD for car movement
var keyState = {
up: false,
down: false
};
// Listen for keydown and keyup events using LK.on (simulated for PC)
// LK does not provide keyboard events, so we simulate with a global object for testing
// NOTE: In the FRVR/LK environment, keyboard events are not natively supported.
// For PC testing, you may need to use a custom event system or test with touch/mouse events.
// Here, we provide a fallback for environments that do support document events.
if (typeof document !== "undefined" && typeof document.addEventListener === "function") {
document.addEventListener('keydown', function (e) {
if (!runActive) return;
if (e.code === 'ArrowUp' || e.code === 'KeyW') keyState.up = true;
if (e.code === 'ArrowDown' || e.code === 'KeyS') keyState.down = true;
});
document.addEventListener('keyup', function (e) {
if (e.code === 'ArrowUp' || e.code === 'KeyW') keyState.up = false;
if (e.code === 'ArrowDown' || e.code === 'KeyS') keyState.down = false;
});
}
// Spawn zombies
function spawnZombie() {
var zombie = new Zombie();
zombie.x = 2048 + 100;
// Random vertical position on road
var minY = road.y + zombie.height / 2;
var maxY = road.y + road.height - zombie.height / 2;
zombie.y = minY + Math.random() * (maxY - minY);
zombies.push(zombie);
game.addChild(zombie);
}
// Spawn coins
function spawnCoin() {
var coin = new Coin();
coin.x = 2048 + 60;
// Random vertical position on road
var minY = road.y + coin.height / 2;
var maxY = road.y + road.height - coin.height / 2;
coin.y = minY + Math.random() * (maxY - minY);
coins.push(coin);
game.addChild(coin);
}
// Reset run
function startRun() {
// Remove all zombies and coins
for (var i = 0; i < zombies.length; ++i) zombies[i].destroy();
for (var i = 0; i < coins.length; ++i) coins[i].destroy();
zombies = [];
coins = [];
// Reset car
car.applyUpgrades();
car.x = 400;
car.y = 2200 + 100;
car.alive = true;
// Reset distance
distance = 0;
runActive = true;
// Update GUI
distanceTxt.setText('0 m');
coinsTxt.setText(storage.coins + '');
// Reset bars
updateBars();
// Play music
LK.playMusic('bgmusic');
}
// Update fuel and health bars
function updateBars() {
// Fuel
var fuelFrac = car.fuel / car.maxFuel;
if (fuelFrac < 0) fuelFrac = 0;
if (fuelFrac > 1) fuelFrac = 1;
fuelBarFG.width = 400 * fuelFrac;
// Health
var healthFrac = car.health / car.maxHealth;
if (healthFrac < 0) healthFrac = 0;
if (healthFrac > 1) healthFrac = 1;
healthBarFG.width = 400 * healthFrac;
}
// Game update
game.update = function () {
if (!runActive) return;
// PC controls: move car up/down with keyboard
var moveAmount = 18 + storage.upgrade_power * 1.5;
if (keyState.up) {
car.y -= moveAmount;
}
if (keyState.down) {
car.y += moveAmount;
}
// Clamp car to road
var minY = road.y + car.height / 2;
var maxY = road.y + road.height - car.height / 2;
if (car.y < minY) car.y = minY;
if (car.y > maxY) car.y = maxY;
// Move car forward
car.x += car.speed * 0.22;
if (car.x > 800) car.x = 800; // Car stays at 800, world scrolls
// Scroll world: move all objects left by car.speed
for (var i = 0; i < zombies.length; ++i) zombies[i].x -= car.speed * 0.13;
for (var i = 0; i < coins.length; ++i) coins[i].x -= car.speed * 0.13;
// Fuel consumption
car.fuel -= 0.022 + 0.0015 * car.speed;
if (car.fuel < 0) car.fuel = 0;
// Distance
distance += car.speed * 0.13;
distanceTxt.setText(parseInt(distance / 10) + ' m');
// Spawn zombies
if (LK.ticks % 45 === 0) {
spawnZombie();
}
// Spawn coins
if (LK.ticks % 90 === 0) {
spawnCoin();
}
// Update zombies
for (var i = zombies.length - 1; i >= 0; --i) {
var z = zombies[i];
z.update();
// Remove if off screen
if (z.x < -200) {
z.destroy();
zombies.splice(i, 1);
continue;
}
// Collision with car
if (car.alive && z.alive && car.intersects(z)) {
z.alive = false;
LK.getSound('zombiehit').play();
tween(z, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
z.destroy();
}
});
zombies.splice(i, 1);
// Damage car
car.takeDamage(20 - storage.upgrade_armor * 3);
// Flash car
LK.effects.flashObject(car, 0xff0000, 300);
// Bump car back
tween(car, {
x: car.x - 40
}, {
duration: 120,
easing: tween.easeOut
});
// If car dead, end run
if (!car.alive) {
endRun();
return;
}
}
}
// Update coins
for (var i = coins.length - 1; i >= 0; --i) {
var c = coins[i];
c.update();
// Remove if off screen
if (c.x < -100) {
c.destroy();
coins.splice(i, 1);
continue;
}
// Collect coin
if (!c.collected && car.intersects(c)) {
c.collected = true;
LK.getSound('coin').play();
storage.coins += 1;
coinsTxt.setText(storage.coins + '');
tween(c, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
onFinish: function onFinish() {
c.destroy();
}
});
coins.splice(i, 1);
}
}
// Update bars
updateBars();
// Out of fuel
if (car.fuel <= 0) {
car.fuel = 0;
endRun();
return;
}
};
// End run
function endRun() {
runActive = false;
// Save best distance
var meters = parseInt(distance / 10);
if (meters > storage.bestDistance) storage.bestDistance = meters;
// Show game over
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
LK.stopMusic();
}
// On game over, reset run
LK.on('gameover', function () {
startRun();
});
// On you win (not used, but for completeness)
LK.on('youwin', function () {
startRun();
});
// Garage menu logic
function showGarageMenu(onDone) {
// Simple garage menu using Text2 and GUI overlay
// Remove any previous garage UI
if (typeof garageUI !== "undefined" && garageUI) {
LK.gui.center.removeChild(garageUI);
garageUI = null;
}
var garageUI = new Container();
// Title
var title = new Text2("Garage", {
size: 120,
fill: "#fff"
});
title.anchor.set(0.5, 0);
title.x = 0;
title.y = 0;
garageUI.addChild(title);
// Coin display
var coinsLabel = new Text2("Coins: " + storage.coins, {
size: 80,
fill: 0xFFD700
});
coinsLabel.anchor.set(0.5, 0);
coinsLabel.x = 0;
coinsLabel.y = 140;
garageUI.addChild(coinsLabel);
// Upgrade buttons and labels
var upgrades = [{
key: "upgrade_fuel",
label: "Fuel",
cost: 10,
y: 300,
desc: "+30 max fuel"
}, {
key: "upgrade_armor",
label: "Armor",
cost: 15,
y: 500,
desc: "+40 max health"
}, {
key: "upgrade_power",
label: "Power",
cost: 20,
y: 700,
desc: "+2 speed"
}];
var upgradeButtons = [];
for (var i = 0; i < upgrades.length; ++i) {
(function (i) {
var upg = upgrades[i];
// Label
var upgLabel = new Text2(upg.label + " Lv." + (storage[upg.key] || 0) + " (" + upg.desc + ")", {
size: 70,
fill: "#fff"
});
upgLabel.anchor.set(0.5, 0);
upgLabel.x = 0;
upgLabel.y = upg.y;
garageUI.addChild(upgLabel);
// Cost
var costLabel = new Text2("Cost: " + upg.cost, {
size: 60,
fill: 0xFFD700
});
costLabel.anchor.set(0.5, 0);
costLabel.x = -200;
costLabel.y = upg.y + 90;
garageUI.addChild(costLabel);
// Upgrade button
var btn = LK.getAsset('fuelBarFG', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: upg.y + 120,
width: 220,
height: 80
});
btn.tint = 0x44ff44;
garageUI.addChild(btn);
// Button label
var btnLabel = new Text2("Upgrade", {
size: 50,
fill: "#222"
});
btnLabel.anchor.set(0.5, 0.5);
btnLabel.x = btn.x;
btnLabel.y = btn.y;
garageUI.addChild(btnLabel);
// Touch/click handler
btn.interactive = true;
btn.down = function (x, y, obj) {
if (storage.coins >= upg.cost) {
storage.coins -= upg.cost;
storage[upg.key] = (storage[upg.key] || 0) + 1;
coinsLabel.setText("Coins: " + storage.coins);
upgLabel.setText(upg.label + " Lv." + storage[upg.key] + " (" + upg.desc + ")");
}
};
upgradeButtons.push(btn);
})(i);
}
// Start button
var startBtn = LK.getAsset('fuelBarFG', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 1000,
width: 400,
height: 120
});
startBtn.tint = 0x4488ff;
garageUI.addChild(startBtn);
var startLabel = new Text2("Start Run", {
size: 70,
fill: "#fff"
});
startLabel.anchor.set(0.5, 0.5);
startLabel.x = startBtn.x;
startLabel.y = startBtn.y;
garageUI.addChild(startLabel);
startBtn.interactive = true;
startBtn.down = function (x, y, obj) {
// Remove garage UI and start run
LK.gui.center.removeChild(garageUI);
garageUI = null;
if (typeof onDone === "function") onDone();
};
// Center garage UI
garageUI.x = 0;
garageUI.y = 0;
LK.gui.center.addChild(garageUI);
}
// Show garage menu before starting run
showGarageMenu(function () {
startRun();
});
// Add a garage button under the game that opens the garage menu when pressed
var garageBtn = LK.getAsset('fuelBarFG', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0,
width: 400,
height: 120
});
garageBtn.tint = 0x8888ff;
var garageBtnLabel = new Text2("Garage", {
size: 70,
fill: "#fff"
});
garageBtnLabel.anchor.set(0.5, 0.5);
garageBtnLabel.x = garageBtn.x;
garageBtnLabel.y = garageBtn.y;
// Container for button and label
var garageBtnContainer = new Container();
garageBtnContainer.addChild(garageBtn);
garageBtnContainer.addChild(garageBtnLabel);
// Place the button at the bottom center of the GUI
LK.gui.bottom.addChild(garageBtnContainer);
// Button handler to open garage menu
garageBtn.interactive = true;
garageBtn.down = function (x, y, obj) {
// Open garage menu without ending the run or stopping the game
showGarageMenu(function () {
// Do not resume run, just close garage menu and return to game
});
}; ===================================================================
--- original.js
+++ change.js
@@ -546,12 +546,9 @@
LK.gui.bottom.addChild(garageBtnContainer);
// Button handler to open garage menu
garageBtn.interactive = true;
garageBtn.down = function (x, y, obj) {
- // Treat opening garage as a lost game and stop the game
- if (runActive) {
- endRun();
- }
+ // Open garage menu without ending the run or stopping the game
showGarageMenu(function () {
- // Do not resume run, as game is over
+ // Do not resume run, just close garage menu and return to game
});
};
\ No newline at end of file