/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Coin var Coin = Container.expand(function () { var self = Container.call(this); var coin = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.width = coin.width; self.height = coin.height; self.speed = 28; self.lane = 1; self.update = function () { self.y += self.speed; }; return self; }); // Enemy Car var EnemyCar = Container.expand(function () { var self = Container.call(this); var car = self.attachAsset('enemyCar', { anchorX: 0.5, anchorY: 0.5 }); self.width = car.width; self.height = car.height; self.speed = 28 + Math.random() * 8; self.lane = 1; self.update = function () { self.y += self.speed; }; return self; }); // Player Car 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.invincible = false; self.update = function () { // No movement here; handled by input }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Road and lanes setup // Car (player) // Enemy car // Coin collectible // Fuel collectible // Road lane // Road background var roadWidth = 900; var laneCount = 3; var laneWidth = roadWidth / laneCount; var roadX = (2048 - roadWidth) / 2; var roadY = 0; // Road background var road = LK.getAsset('road', { anchorX: 0, anchorY: 0, x: roadX, y: roadY }); game.addChild(road); // Lane markers var laneMarkers = []; for (var i = 1; i < laneCount; i++) { var laneMarker = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0, x: roadX + i * laneWidth, y: 0 }); game.addChild(laneMarker); laneMarkers.push(laneMarker); } // Player car var player = new PlayerCar(); player.x = roadX + laneWidth * 1.5; player.y = 2732 - 400; game.addChild(player); // Score and fuel UI var score = 0; var distance = 0; var coinsCollected = 0; var scoreTxt = new Text2('Score: 0', { size: 90, fill: "#fff" }); scoreTxt.anchor.set(1, 0); // top right scoreTxt.x = 2048 - 100; scoreTxt.y = 20; LK.gui.top.addChild(scoreTxt); // Remove coinsTxt, show only score at top right // Timer to update score every second var scoreUpdateTimer = LK.setInterval(function () { scoreTxt.setText('Score: ' + score); }, 1000); // Lane positions var lanePositions = [roadX + laneWidth * 0.5, roadX + laneWidth * 1.5, roadX + laneWidth * 2.5]; // Touch controls // Use square placeholder assets for left/right buttons (replace 'leftBtnSquare' and 'rightBtnSquare' with your asset ids when available) var leftBtn = LK.getAsset('leftBtnSquare', { anchorX: 0.5, anchorY: 0.5, x: 200, y: -250 }); LK.gui.bottomLeft.addChild(leftBtn); var rightBtn = LK.getAsset('rightBtnSquare', { anchorX: 0.5, anchorY: 0.5, x: -200, y: -250 }); LK.gui.bottomRight.addChild(rightBtn); // Control handlers leftBtn.down = function () { if (player.lane > 0) { player.lane--; tween(player, { x: lanePositions[player.lane] }, { duration: 120, easing: tween.cubicOut }); } }; rightBtn.down = function () { if (player.lane < laneCount - 1) { player.lane++; tween(player, { x: lanePositions[player.lane] }, { duration: 120, easing: tween.cubicOut }); } }; // Touch drag to move car left/right var dragStartX = null; var dragStartLane = null; game.down = function (x, y, obj) { if (x > roadX && x < roadX + roadWidth && y > 2732 - 700) { dragStartX = x; dragStartLane = player.lane; } }; game.move = function (x, y, obj) { if (dragStartX !== null) { var dx = x - dragStartX; if (Math.abs(dx) > laneWidth * 0.7) { if (dx < 0 && player.lane > 0) { player.lane--; tween(player, { x: lanePositions[player.lane] }, { duration: 120, easing: tween.cubicOut }); dragStartX = x; dragStartLane = player.lane; } else if (dx > 0 && player.lane < laneCount - 1) { player.lane++; tween(player, { x: lanePositions[player.lane] }, { duration: 120, easing: tween.cubicOut }); dragStartX = x; dragStartLane = player.lane; } } } }; game.up = function (x, y, obj) { dragStartX = null; dragStartLane = null; }; // Game objects var enemies = []; var coins = []; var fuels = []; // (no longer used, but kept for code safety) // Spawning timers var enemySpawnTick = 0; var coinSpawnTick = 0; var fuelSpawnTick = 0; // Main game update game.update = function () { // Distance and fuel distance += 1; player.fuel -= 0.025; if (player.fuel < 0) player.fuel = 0; // Update UI score = Math.floor(distance / 5) + coinsCollected * 10; if (score >= 999) { // Stop the score update timer if (typeof scoreUpdateTimer !== "undefined") LK.clearInterval(scoreUpdateTimer); // Show Congratulations overlay var congratsTxt = new Text2('Congratulations', { size: 180, fill: 0xFFD600 }); congratsTxt.anchor.set(0.5, 0.5); congratsTxt.x = 2048 / 2; congratsTxt.y = 900; var playAgainBtn = new Text2('Play Again', { size: 120, fill: "#fff" }); playAgainBtn.anchor.set(0.5, 0.5); playAgainBtn.x = 2048 / 2; playAgainBtn.y = 1200; // Overlay container var overlay = new Container(); overlay.addChild(congratsTxt); overlay.addChild(playAgainBtn); game.addChild(overlay); playAgainBtn.down = function () { // Remove overlay and restart game overlay.destroy(); LK.showGameOver(); // Triggers game reset }; // Pause game logic game.update = function () {}; return; } // Spawn enemy cars enemySpawnTick++; if (enemySpawnTick > 38 + Math.random() * 18) { enemySpawnTick = 0; var enemy = new EnemyCar(); enemy.lane = Math.floor(Math.random() * laneCount); enemy.x = lanePositions[enemy.lane]; enemy.y = -200; enemies.push(enemy); game.addChild(enemy); } // Spawn coins coinSpawnTick++; if (coinSpawnTick > 80 + Math.random() * 60) { coinSpawnTick = 0; var coin = new Coin(); coin.lane = Math.floor(Math.random() * laneCount); coin.x = lanePositions[coin.lane]; coin.y = -120; coins.push(coin); game.addChild(coin); } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; e.update(); if (e.y > 2732 + 200) { e.destroy(); enemies.splice(i, 1); continue; } // Collision with player if (e.intersects(player)) { LK.effects.flashObject(player, 0xff0000, 600); LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } } // Update coins for (var i = coins.length - 1; i >= 0; i--) { var c = coins[i]; c.update(); if (c.y > 2732 + 120) { c.destroy(); coins.splice(i, 1); continue; } if (c.intersects(player)) { coinsCollected++; score = Math.floor(distance / 5) + coinsCollected * 10; scoreTxt.setText('Score: ' + score); LK.effects.flashObject(player, 0xFFD600, 300); c.destroy(); coins.splice(i, 1); continue; } } }; // Center UI elements // scoreTxt is always at top right, do not move it to center // Prevent UI from overlapping top left menu // (already handled by not placing anything at gui.topLeft or at x < 100, y < 100)
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Coin
var Coin = Container.expand(function () {
var self = Container.call(this);
var coin = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = coin.width;
self.height = coin.height;
self.speed = 28;
self.lane = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Enemy Car
var EnemyCar = Container.expand(function () {
var self = Container.call(this);
var car = self.attachAsset('enemyCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = car.width;
self.height = car.height;
self.speed = 28 + Math.random() * 8;
self.lane = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Player Car
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.invincible = false;
self.update = function () {
// No movement here; handled by input
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Road and lanes setup
// Car (player)
// Enemy car
// Coin collectible
// Fuel collectible
// Road lane
// Road background
var roadWidth = 900;
var laneCount = 3;
var laneWidth = roadWidth / laneCount;
var roadX = (2048 - roadWidth) / 2;
var roadY = 0;
// Road background
var road = LK.getAsset('road', {
anchorX: 0,
anchorY: 0,
x: roadX,
y: roadY
});
game.addChild(road);
// Lane markers
var laneMarkers = [];
for (var i = 1; i < laneCount; i++) {
var laneMarker = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0,
x: roadX + i * laneWidth,
y: 0
});
game.addChild(laneMarker);
laneMarkers.push(laneMarker);
}
// Player car
var player = new PlayerCar();
player.x = roadX + laneWidth * 1.5;
player.y = 2732 - 400;
game.addChild(player);
// Score and fuel UI
var score = 0;
var distance = 0;
var coinsCollected = 0;
var scoreTxt = new Text2('Score: 0', {
size: 90,
fill: "#fff"
});
scoreTxt.anchor.set(1, 0); // top right
scoreTxt.x = 2048 - 100;
scoreTxt.y = 20;
LK.gui.top.addChild(scoreTxt);
// Remove coinsTxt, show only score at top right
// Timer to update score every second
var scoreUpdateTimer = LK.setInterval(function () {
scoreTxt.setText('Score: ' + score);
}, 1000);
// Lane positions
var lanePositions = [roadX + laneWidth * 0.5, roadX + laneWidth * 1.5, roadX + laneWidth * 2.5];
// Touch controls
// Use square placeholder assets for left/right buttons (replace 'leftBtnSquare' and 'rightBtnSquare' with your asset ids when available)
var leftBtn = LK.getAsset('leftBtnSquare', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: -250
});
LK.gui.bottomLeft.addChild(leftBtn);
var rightBtn = LK.getAsset('rightBtnSquare', {
anchorX: 0.5,
anchorY: 0.5,
x: -200,
y: -250
});
LK.gui.bottomRight.addChild(rightBtn);
// Control handlers
leftBtn.down = function () {
if (player.lane > 0) {
player.lane--;
tween(player, {
x: lanePositions[player.lane]
}, {
duration: 120,
easing: tween.cubicOut
});
}
};
rightBtn.down = function () {
if (player.lane < laneCount - 1) {
player.lane++;
tween(player, {
x: lanePositions[player.lane]
}, {
duration: 120,
easing: tween.cubicOut
});
}
};
// Touch drag to move car left/right
var dragStartX = null;
var dragStartLane = null;
game.down = function (x, y, obj) {
if (x > roadX && x < roadX + roadWidth && y > 2732 - 700) {
dragStartX = x;
dragStartLane = player.lane;
}
};
game.move = function (x, y, obj) {
if (dragStartX !== null) {
var dx = x - dragStartX;
if (Math.abs(dx) > laneWidth * 0.7) {
if (dx < 0 && player.lane > 0) {
player.lane--;
tween(player, {
x: lanePositions[player.lane]
}, {
duration: 120,
easing: tween.cubicOut
});
dragStartX = x;
dragStartLane = player.lane;
} else if (dx > 0 && player.lane < laneCount - 1) {
player.lane++;
tween(player, {
x: lanePositions[player.lane]
}, {
duration: 120,
easing: tween.cubicOut
});
dragStartX = x;
dragStartLane = player.lane;
}
}
}
};
game.up = function (x, y, obj) {
dragStartX = null;
dragStartLane = null;
};
// Game objects
var enemies = [];
var coins = [];
var fuels = []; // (no longer used, but kept for code safety)
// Spawning timers
var enemySpawnTick = 0;
var coinSpawnTick = 0;
var fuelSpawnTick = 0;
// Main game update
game.update = function () {
// Distance and fuel
distance += 1;
player.fuel -= 0.025;
if (player.fuel < 0) player.fuel = 0;
// Update UI
score = Math.floor(distance / 5) + coinsCollected * 10;
if (score >= 999) {
// Stop the score update timer
if (typeof scoreUpdateTimer !== "undefined") LK.clearInterval(scoreUpdateTimer);
// Show Congratulations overlay
var congratsTxt = new Text2('Congratulations', {
size: 180,
fill: 0xFFD600
});
congratsTxt.anchor.set(0.5, 0.5);
congratsTxt.x = 2048 / 2;
congratsTxt.y = 900;
var playAgainBtn = new Text2('Play Again', {
size: 120,
fill: "#fff"
});
playAgainBtn.anchor.set(0.5, 0.5);
playAgainBtn.x = 2048 / 2;
playAgainBtn.y = 1200;
// Overlay container
var overlay = new Container();
overlay.addChild(congratsTxt);
overlay.addChild(playAgainBtn);
game.addChild(overlay);
playAgainBtn.down = function () {
// Remove overlay and restart game
overlay.destroy();
LK.showGameOver(); // Triggers game reset
};
// Pause game logic
game.update = function () {};
return;
}
// Spawn enemy cars
enemySpawnTick++;
if (enemySpawnTick > 38 + Math.random() * 18) {
enemySpawnTick = 0;
var enemy = new EnemyCar();
enemy.lane = Math.floor(Math.random() * laneCount);
enemy.x = lanePositions[enemy.lane];
enemy.y = -200;
enemies.push(enemy);
game.addChild(enemy);
}
// Spawn coins
coinSpawnTick++;
if (coinSpawnTick > 80 + Math.random() * 60) {
coinSpawnTick = 0;
var coin = new Coin();
coin.lane = Math.floor(Math.random() * laneCount);
coin.x = lanePositions[coin.lane];
coin.y = -120;
coins.push(coin);
game.addChild(coin);
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
e.update();
if (e.y > 2732 + 200) {
e.destroy();
enemies.splice(i, 1);
continue;
}
// Collision with player
if (e.intersects(player)) {
LK.effects.flashObject(player, 0xff0000, 600);
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
// Update coins
for (var i = coins.length - 1; i >= 0; i--) {
var c = coins[i];
c.update();
if (c.y > 2732 + 120) {
c.destroy();
coins.splice(i, 1);
continue;
}
if (c.intersects(player)) {
coinsCollected++;
score = Math.floor(distance / 5) + coinsCollected * 10;
scoreTxt.setText('Score: ' + score);
LK.effects.flashObject(player, 0xFFD600, 300);
c.destroy();
coins.splice(i, 1);
continue;
}
}
};
// Center UI elements
// scoreTxt is always at top right, do not move it to center
// Prevent UI from overlapping top left menu
// (already handled by not placing anything at gui.topLeft or at x < 100, y < 100)
Make me a coin 2d pixel. In-Game asset. 2d. High contrast. No shadows
Draw 2d pixel car top view Red. In-Game asset. 2d. High contrast. No shadows
Draw 2d pixel car top view Blue. In-Game asset. 2d. High contrast. No shadows
draw a left facing 2d pixel game button. Yellow. Like this ▶️. In-Game asset. 2d. High contrast. No shadows
Try to do this photo again
Do this again but green