User prompt
Wait 800ms before showing game over
User prompt
Ensure crash sound plays when hitting an object
User prompt
When hitting an obstacle set gamestarted to false before calling gameover
User prompt
Max speed = 50
User prompt
Don’t delay game over screen
User prompt
Stop all objects and road lines from moving at game over
User prompt
Stop truck from moving when it hits an obstacle
User prompt
Stop accessing camera on game over screen
User prompt
Wait 1 second before showing game over screen
User prompt
Make tap to start text larger and yellow
User prompt
Remove tap to start when gameplay starts
User prompt
Move tap to start to middle of screen
User prompt
Add tap to start text to face guide text
User prompt
Display tap to start message before starting game
User prompt
Remove timeout from showgameover
User prompt
Remove quit button
User prompt
Set a 5 second timeout on the quit button
User prompt
Remove the timeout from the quit button
User prompt
It’s still not being displayed
User prompt
It still isn’t visible
User prompt
The button isn’t visible
User prompt
Add a quit button to game over screen
User prompt
Remove shadow from truck
User prompt
Double the size of the obstacle sprite
User prompt
Triple the size of the obstacle sprite
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var RoadLine = Container.expand(function () { var self = Container.call(this); self.speed = 0; // Will be set when spawned var lineGraphics = self.attachAsset('roadLine', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.y += self.speed; // Reset position when off screen if (self.y > 2732 + lineGraphics.height) { self.y = -lineGraphics.height; } }; return self; }); var RoadObject = Container.expand(function () { var self = Container.call(this); self.type = 'obstacle'; // Default type self.speed = 0; // Will be set when spawned // Create a shadow underneath the object var shadow = null; self.init = function (objectType, initialY) { self.type = objectType; self.y = initialY; // Remove any previous children while (self.children.length > 0) { self.removeChildAt(0); } // Create appropriate graphics based on type if (objectType === 'obstacle') { shadow = self.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3, y: 50 }); self.graphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, // Double the width scaleY: 2 // Double the height }); } else if (objectType === 'fuel') { shadow = self.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3, scaleX: 0.7, scaleY: 0.7, y: 60 }); self.graphics = self.attachAsset('fuel', { anchorX: 0.5, anchorY: 0.5 }); } else if (objectType === 'speedBoost') { shadow = self.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3, scaleX: 0.6, scaleY: 0.6, y: 40 }); self.graphics = self.attachAsset('speedBoost', { anchorX: 0.5, anchorY: 0.5 }); } // Add floating animation for collectibles if (objectType !== 'obstacle') { self.startFloatingAnimation(); } else { // Randomly rotate obstacles slightly self.graphics.rotation = (Math.random() - 0.5) * 0.5; } }; self.startFloatingAnimation = function () { tween(self.graphics, { y: -10 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.graphics, { y: 10 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { if (self.parent) { // Check if still in scene self.startFloatingAnimation(); } } }); } }); }; self.update = function () { self.y += self.speed; }; return self; }); var Truck = Container.expand(function () { var self = Container.call(this); // Create main truck asset var truckGraphics = self.attachAsset('truck', { anchorX: 0.5, anchorY: 0.5 }); // Set initial lane (middle lane) self.lane = 1; self.targetX = 0; self.moving = false; self.invulnerable = false; // Move to a specific lane (1-left, 2-middle, 3-right) self.moveToLane = function (laneIndex) { if (laneIndex < 1) { laneIndex = 1; } if (self.lane === laneIndex || self.moving) { return; } self.lane = laneIndex; self.moving = true; // Calculate lane position self.targetX = (laneIndex - 2) * LANE_WIDTH + GAME_WIDTH / 2; // Animate truck move tween(self, { x: self.targetX }, { duration: 250, easing: tween.easeInOut, onFinish: function onFinish() { self.moving = false; } }); }; // Make truck temporarily invulnerable self.setInvulnerable = function (duration) { self.invulnerable = true; // Flash effect var flashCount = 0; var flashInterval = LK.setInterval(function () { truckGraphics.alpha = truckGraphics.alpha === 1 ? 0.5 : 1; flashCount++; if (flashCount >= 10) { LK.clearInterval(flashInterval); truckGraphics.alpha = 1; self.invulnerable = false; } }, duration / 10); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x555555 }); /**** * Game Code ****/ // Game constants if (typeof document !== 'undefined') { document.addEventListener('DOMContentLoaded', function () { var GAME_WIDTH = window.innerWidth * window.devicePixelRatio; }); } else { var GAME_WIDTH = 2048; // Default width if not in a browser environment } var LANE_WIDTH = GAME_WIDTH / 3; var GAME_HEIGHT = 2732; var INITIAL_SPEED = 10; var MAX_SPEED = 25; var ACCELERATION = 0.001; var BASE_SPAWN_INTERVAL = 1200; // milliseconds var MIN_SPAWN_INTERVAL = 600; // Game variables var gameSpeed = INITIAL_SPEED; var distance = 0; var spawnInterval = BASE_SPAWN_INTERVAL; var lastObjectSpawn = 0; var objectPool = []; var leftLaneLines = []; var rightLaneLines = []; var activeObjects = []; var gameStarted = false; var isGameOver = false; // Create road background var road = game.addChild(LK.getAsset('road', { anchorX: 0.5, anchorY: 0, x: GAME_WIDTH / 2, y: 0, alpha: 0.9 })); // Create lane dividers function createRoadLines() { // Left lane divider var leftX = GAME_WIDTH / 2 - LANE_WIDTH / 2; for (var i = 0; i < 20; i++) { var leftLine = new RoadLine(); leftLine.x = leftX; leftLine.y = -150 + i * 300; leftLine.speed = gameSpeed; leftLaneLines.push(leftLine); game.addChild(leftLine); } // Right lane divider var rightX = GAME_WIDTH / 2 + LANE_WIDTH / 2; for (var j = 0; j < 20; j++) { var rightLine = new RoadLine(); rightLine.x = rightX; rightLine.y = -150 + j * 300; rightLine.speed = gameSpeed; rightLaneLines.push(rightLine); game.addChild(rightLine); } } // Create our truck var truck = new Truck(); truck.x = GAME_WIDTH / 2; // Middle lane truck.y = GAME_HEIGHT - 400; // Near bottom of screen // Add score display var scoreText = new Text2('Distance: 0m', { size: 70, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Add high score display var highScoreText = new Text2('Best: 0m', { size: 50, fill: 0xFFFFFF }); highScoreText.anchor.set(0.5, 0); highScoreText.y = 80; LK.gui.top.addChild(highScoreText); // Face guidance text var faceGuideText = new Text2('Tilt your head to steer', { size: 60, fill: 0xFFFFFF }); faceGuideText.anchor.set(0.5, 0); faceGuideText.y = 150; LK.gui.top.addChild(faceGuideText); // Add 'Tap to Start' text below face guide text var tapToStartText = new Text2('Tap to Start', { size: 100, fill: 0xFFFF00 }); tapToStartText.anchor.set(0.5, 0); tapToStartText.y = GAME_HEIGHT / 2; LK.gui.top.addChild(tapToStartText); // Function to get a reusable object from the pool or create a new one function getObjectFromPool() { for (var i = 0; i < objectPool.length; i++) { if (!objectPool[i].parent) { return objectPool[i]; } } // Create a new object if none available var newObject = new RoadObject(); objectPool.push(newObject); return newObject; } // Function to spawn a random object on the road function spawnRoadObject() { // Determine object type (mostly obstacles, sometimes collectibles) var objectType = Math.random() < 0.7 ? 'obstacle' : Math.random() < 0.5 ? 'fuel' : 'speedBoost'; // Determine lane var lane = Math.floor(Math.random() * 3) + 1; // 1, 2, or 3 var laneX = (lane - 2) * LANE_WIDTH + GAME_WIDTH / 2; // Get object from pool and configure it var roadObject = getObjectFromPool(); roadObject.init(objectType, -200); // Start above the screen roadObject.x = laneX; roadObject.speed = gameSpeed; // Add to game and active objects list game.addChild(roadObject); activeObjects.push(roadObject); // Schedule next spawn lastObjectSpawn = LK.ticks; spawnInterval = Math.max(MIN_SPAWN_INTERVAL, BASE_SPAWN_INTERVAL - distance / 100); } // Initialize the high score function initHighScore() { highScoreText.setText('Best: ' + storage.highScore + 'm'); } // Start or restart the game function startGame() { // Reset game variables gameSpeed = INITIAL_SPEED; distance = 0; spawnInterval = BASE_SPAWN_INTERVAL; lastObjectSpawn = 0; isGameOver = false; // Clear any active objects while (activeObjects.length > 0) { var obj = activeObjects.pop(); if (obj.parent) { obj.parent.removeChild(obj); } } // Create road lines if not already created if (leftLaneLines.length === 0) { createRoadLines(); } // Reset truck position truck.lane = 2; truck.x = GAME_WIDTH / 2; truck.moveToLane(2); // Ensure truck starts in the center lane game.addChild(truck); // Update score display scoreText.setText('Distance: 0m'); initHighScore(); // Remove 'Tap to Start' text if (tapToStartText.parent) { tapToStartText.parent.removeChild(tapToStartText); } // Mark game as started gameStarted = true; // Play background music LK.playMusic('bgMusic', { fade: { start: 0, end: 0.3, duration: 1000 } }); } // Handle game over function gameOver() { if (isGameOver) { return; } isGameOver = true; LK.getSound('crash').play(); // Fade out music LK.playMusic('bgMusic', { fade: { start: 0.3, end: 0, duration: 800 } }); // Update high score if needed if (distance > storage.highScore) { storage.highScore = Math.floor(distance); highScoreText.setText('Best: ' + storage.highScore + 'm'); } // Show red flash effect LK.effects.flashScreen(0xFF0000, 1000); LK.setTimeout(function () { LK.showGameOver(); }, 800); } // Handle face tracking for truck steering function updateTruckPosition() { if (!gameStarted || isGameOver) { return; } // Get face position var headPosition = facekit.noseTip; if (headPosition && headPosition.x > 0) { // Normalize position and map to lanes var relativeX = headPosition.x / GAME_WIDTH; if (relativeX < 0.45) { truck.moveToLane(1); // Left lane } else if (relativeX > 0.55) { truck.moveToLane(3); // Right lane } else { truck.moveToLane(2); // Center lane } } else { // If no head position detected, pause game and show message if (!isGameOver) { // Pause the game by setting gameStarted to false gameStarted = false; // Display a message in the middle of the screen var pauseMessage = new Text2('Face tracking lost. Please adjust your position.', { size: 100, // Increased size for better visibility fill: 0xFFFF00 // Changed color to yellow for better contrast }); pauseMessage.anchor.set(0.5, 0.5); pauseMessage.x = GAME_WIDTH / 2; pauseMessage.y = GAME_HEIGHT / 2; LK.gui.center.addChild(pauseMessage); // Optionally, set a timeout to remove the message after a few seconds LK.setTimeout(function () { if (pauseMessage.parent) { pauseMessage.parent.removeChild(pauseMessage); } }, 3000); } } // Hide face guide text after player has moved if (faceGuideText.parent) { faceGuideText.parent.removeChild(faceGuideText); } } // Check collisions between truck and road objects function checkCollisions() { if (isGameOver) { return; } for (var i = activeObjects.length - 1; i >= 0; i--) { var obj = activeObjects[i]; // Check if object is on screen if (obj.y > GAME_HEIGHT + 200) { game.removeChild(obj); activeObjects.splice(i, 1); continue; } // Check for collision with truck if (truck.intersects(obj)) { if (obj.type === 'obstacle') { // Hit obstacle if (!truck.invulnerable) { gameStarted = false; // Stop the truck from moving LK.getSound('crash').play(); // Play crash sound gameOver(); } } else if (obj.type === 'fuel') { // Collected fuel LK.getSound('collect').play(); LK.setScore(LK.getScore() + 50); truck.setInvulnerable(2000); } else if (obj.type === 'speedBoost') { // Speed boost LK.getSound('speedUp').play(); gameSpeed += 5; if (gameSpeed > MAX_SPEED) { gameSpeed = MAX_SPEED; } } // Remove collected/hit object game.removeChild(obj); activeObjects.splice(i, 1); } } } // Game start with face detection game.down = function (x, y, obj) { if (!gameStarted) { startGame(); } }; // Game update loop game.update = function () { if (!gameStarted) { return; } // Update game speed and distance gameSpeed = Math.min(MAX_SPEED, INITIAL_SPEED + distance * ACCELERATION); distance += gameSpeed / 60; // Update score display scoreText.setText('Distance: ' + Math.floor(distance) + 'm'); LK.setScore(Math.floor(distance)); // Update road lines speed for (var i = 0; i < leftLaneLines.length; i++) { leftLaneLines[i].speed = isGameOver ? 0 : gameSpeed; rightLaneLines[i].speed = isGameOver ? 0 : gameSpeed; } // Update all active objects' speed for (var j = 0; j < activeObjects.length; j++) { activeObjects[j].speed = isGameOver ? 0 : gameSpeed; } // Handle face tracking for truck steering updateTruckPosition(); // Check if it's time to spawn a new object if (LK.ticks - lastObjectSpawn > spawnInterval / (1000 / 60)) { spawnRoadObject(); } // Check for collisions checkCollisions(); }; // Initialize high score on load initHighScore();
===================================================================
--- original.js
+++ change.js
@@ -369,9 +369,11 @@
highScoreText.setText('Best: ' + storage.highScore + 'm');
}
// Show red flash effect
LK.effects.flashScreen(0xFF0000, 1000);
- LK.showGameOver();
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 800);
}
// Handle face tracking for truck steering
function updateTruckPosition() {
if (!gameStarted || isGameOver) {