/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { coins: 0, selectedCar: 0, ownedCars: [0] }); /**** * Classes ****/ var Coin = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.update = function () { self.y += self.speed; // Simple rotation animation coinGraphics.rotation += 0.1; }; return self; }); var EnemyCar = Container.expand(function () { var self = Container.call(this); // Array of enemy car assets var enemyCarAssets = ['enemyCar', 'enemyCar2', 'enemyCar3', 'enemyCar4']; // Randomly select a car type var randomCarType = enemyCarAssets[Math.floor(Math.random() * enemyCarAssets.length)]; var carGraphics = self.attachAsset(randomCarType, { anchorX: 0.5, anchorY: 0.5 }); // Set different random speeds for each enemy car self.speed = 4 + Math.floor(Math.random() * 8); // Random speed between 4 and 11 self.carType = randomCarType; // Store the car type for reference self.update = function () { // All enemy cars move in the same direction as player (downward) // Move at consistent speed in the same direction as player self.y += self.speed; }; return self; }); var GarageUI = Container.expand(function () { var self = Container.call(this); // Garage background var background = self.attachAsset('garageBackground', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); // Title var title = new Text2('GARAGE', { size: 120, fill: '#ffffff' }); title.anchor.set(0.5, 0); title.x = 2048 / 2; title.y = 200; self.addChild(title); // Car data var carData = [{ name: 'Basic Car', asset: 'playerCar', price: 0, color: 0x4287f5 }, { name: 'Sports Car', asset: 'sportsCar', price: 100, color: 0xff4500 }, { name: 'Luxury Car', asset: 'luxuryCar', price: 250, color: 0x9932cc }, { name: 'Super Car', asset: 'superCar', price: 500, color: 0xffd700 }]; var carDisplays = []; var carTexts = []; var buttons = []; // Create car displays for (var i = 0; i < carData.length; i++) { var car = carData[i]; var yPos = 500 + i * 400; // Car display var carDisplay = LK.getAsset(car.asset, { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 300, y: yPos, scaleX: 1.5, scaleY: 1.5 }); self.addChild(carDisplay); carDisplays.push(carDisplay); // Car name and price var carText = new Text2(car.name + (car.price > 0 ? ' - ' + car.price + ' coins' : ' - FREE'), { size: 60, fill: '#ffffff' }); carText.anchor.set(0, 0.5); carText.x = 2048 / 2 - 100; carText.y = yPos - 50; self.addChild(carText); carTexts.push(carText); // Status text var statusText = new Text2('', { size: 50, fill: '#00ff00' }); statusText.anchor.set(0, 0.5); statusText.x = 2048 / 2 - 100; statusText.y = yPos; self.addChild(statusText); // Buy/Select button var button = LK.getAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 200, y: yPos + 50 }); self.addChild(button); buttons.push(button); var buttonText = new Text2('', { size: 40, fill: '#ffffff' }); buttonText.anchor.set(0.5, 0.5); buttonText.x = 2048 / 2 + 200; buttonText.y = yPos + 50; self.addChild(buttonText); // Store references button.carIndex = i; button.statusText = statusText; button.buttonText = buttonText; button.carData = car; } // Coins display var coinsDisplay = new Text2('', { size: 80, fill: '#ffd700' }); coinsDisplay.anchor.set(0.5, 0); coinsDisplay.x = 2048 / 2; coinsDisplay.y = 100; self.addChild(coinsDisplay); // Back button var backButton = LK.getAsset('garageButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2500 }); self.addChild(backButton); var backText = new Text2('BACK TO GAME', { size: 50, fill: '#ffffff' }); backText.anchor.set(0.5, 0.5); backText.x = 2048 / 2; backText.y = 2500; self.addChild(backText); self.updateDisplay = function () { var playerCoins = storage.coins || 0; coinsDisplay.setText('Coins: ' + playerCoins); var ownedCars = storage.ownedCars || [0]; var selectedCar = storage.selectedCar || 0; for (var i = 0; i < buttons.length; i++) { var button = buttons[i]; var isOwned = ownedCars.indexOf(i) !== -1; var isSelected = selectedCar === i; if (isSelected) { button.statusText.setText('SELECTED'); button.buttonText.setText('SELECTED'); button.tint = 0x00ff00; } else if (isOwned) { button.statusText.setText('OWNED'); button.buttonText.setText('SELECT'); button.tint = 0x1e90ff; } else { button.statusText.setText(''); if (playerCoins >= button.carData.price) { button.buttonText.setText('BUY'); button.tint = 0x00ff00; } else { button.buttonText.setText('NEED ' + (button.carData.price - playerCoins) + ' MORE'); button.tint = 0xff0000; } } } }; self.down = function (x, y, obj) { // Use direct coordinates instead of toLocal conversion to avoid parent issues var localPos = { x: x, y: y }; // Check back button if (Math.abs(localPos.x - 2048 / 2) < 100 && Math.abs(localPos.y - 2500) < 40) { showGame(); return; } // Check car buttons for (var i = 0; i < buttons.length; i++) { var button = buttons[i]; var buttonPos = { x: 2048 / 2 + 200, y: 500 + i * 400 + 50 }; if (Math.abs(localPos.x - buttonPos.x) < 75 && Math.abs(localPos.y - buttonPos.y) < 30) { var ownedCars = storage.ownedCars || [0]; var isOwned = ownedCars.indexOf(i) !== -1; var playerCoins = storage.coins || 0; if (isOwned) { // Select car storage.selectedCar = i; self.updateDisplay(); } else if (playerCoins >= button.carData.price) { // Buy car storage.coins = playerCoins - button.carData.price; ownedCars.push(i); storage.ownedCars = ownedCars; storage.selectedCar = i; self.updateDisplay(); } break; } } }; return self; }); var Pedestrian = Container.expand(function () { var self = Container.call(this); var pedestrianGraphics = self.attachAsset('pedestrian', { anchorX: 0.5, anchorY: 0.5 }); self.speed = (2 + Math.random() * 3) * 0.1; // Reduced speed by 90% (multiply by 0.1) self.direction = Math.random() > 0.5 ? 1 : -1; // Random direction self.changeDirectionTimer = 0; self.changeDirectionInterval = 120 + Math.floor(Math.random() * 240); // Change direction every 2-6 seconds self.update = function () { // Move pedestrian self.y += self.speed * self.direction; // Random direction changes self.changeDirectionTimer++; if (self.changeDirectionTimer >= self.changeDirectionInterval) { self.direction *= -1; // Reverse direction self.changeDirectionTimer = 0; self.changeDirectionInterval = 120 + Math.floor(Math.random() * 240); // Add random horizontal movement with tween if (Math.random() < 0.3) { var newX = self.x + (Math.random() - 0.5) * 100; tween(self, { x: newX }, { duration: 1000 + Math.random() * 2000, easing: tween.easeInOut }); } } // Keep pedestrians within reasonable bounds if (self.y < -100) { self.y = -100; self.direction = 1; } else if (self.y > 2732 + 100) { self.y = 2732 + 100; self.direction = -1; } }; return self; }); var PlayerCar = Container.expand(function () { var self = Container.call(this); var carAssets = ['playerCar', 'sportsCar', 'luxuryCar', 'superCar']; var selectedCar = storage.selectedCar || 0; var carAsset = carAssets[selectedCar] || 'playerCar'; var carGraphics = self.attachAsset(carAsset, { anchorX: 0.5, anchorY: 0.5 }); self.lane = 1; // 0 = leftmost, 1 = left center, 2 = right center, 3 = rightmost self.targetX = 0; self.speed = 70; // Character speed set to 70 self.targetRotation = 0; self.update = function () { // Smooth movement to target position var diff = self.targetX - self.x; self.x += diff * 0.15; // Smooth rotation animation var rotDiff = self.targetRotation - carGraphics.rotation; carGraphics.rotation += rotDiff * 0.2; }; return self; }); var PowerSpring = Container.expand(function () { var self = Container.call(this); var springGraphics = self.attachAsset('powerSpring', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.bounceAmount = 0.5; self.update = function () { self.y += self.speed; // More intense bounce animation springGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.3) * self.bounceAmount; springGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.25) * 0.2; springGraphics.rotation += 0.08; }; return self; }); var RegularSpring = Container.expand(function () { var self = Container.call(this); var springGraphics = self.attachAsset('regularSpring', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.bounceAmount = 0.3; self.update = function () { self.y += self.speed; // Bounce animation springGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.2) * self.bounceAmount; springGraphics.rotation += 0.05; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2d5a2d }); /**** * Game Code ****/ // Game dimensions: 2048x2732 var gameSpeed = 8; var speedIncrement = 0; var maxSpeed = 8; // Garage system var garage; var garageButton; var inGarage = false; // Initialize persistent coins from storage if (storage.coins === undefined) { storage.coins = 0; } function showGarage() { inGarage = true; // Hide all game elements for (var i = 0; i < game.children.length; i++) { game.children[i].visible = false; } // Show garage garage.visible = true; garage.updateDisplay(); garageButton.visible = false; } function showGame() { inGarage = false; // Show all game elements for (var i = 0; i < game.children.length; i++) { game.children[i].visible = true; } // Hide garage garage.visible = false; garageButton.visible = true; // Recreate player with new car var oldX = player.x; var oldY = player.y; var oldLane = player.lane; var oldTargetX = player.targetX; game.removeChild(player); player = new PlayerCar(); player.x = oldX; player.y = oldY; player.lane = oldLane; player.targetX = oldTargetX; game.addChild(player); } // Lane positions var lanes = [2048 / 2 - 300, 2048 / 2 - 100, 2048 / 2 + 100, 2048 / 2 + 300]; // Game objects var player; var enemyCars = []; var coins = []; var regularSprings = []; var powerSprings = []; var roadSegments = []; var laneMarkers = []; var buildings = []; var trees = []; var sidewalks = []; var pedestrians = []; // Game state var gameDistance = 0; var coinsCollected = 0; var spawnTimer = 0; var coinSpawnTimer = 0; // Create road background function createRoadSegment(y) { var segment = LK.getAsset('road', { anchorX: 0.5, anchorY: 0, x: 2048 / 2, y: y }); return segment; } // Create lane markers function createLaneMarker(x, y) { var marker = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0, x: x, y: y }); return marker; } // Create city background elements function createBuilding(x, y, type) { var buildingAsset = type === 0 ? 'building1' : type === 1 ? 'building2' : 'building3'; var building = LK.getAsset(buildingAsset, { anchorX: 0.5, anchorY: 1, x: x, y: y }); return building; } function createTree(x, y) { var tree = LK.getAsset('tree', { anchorX: 0.5, anchorY: 1, x: x, y: y }); return tree; } function createSidewalk(x, y) { var sidewalk = LK.getAsset('sidewalk', { anchorX: 0.5, anchorY: 0, x: x, y: y }); return sidewalk; } // Initialize road for (var i = 0; i < 12; i++) { var segment = createRoadSegment(i * 300 - 300); roadSegments.push(segment); game.addChild(segment); } // Initialize lane markers for (var i = 0; i < 24; i++) { var marker1 = createLaneMarker((lanes[0] + lanes[1]) / 2, i * 150 - 300); var marker2 = createLaneMarker((lanes[1] + lanes[2]) / 2, i * 150 - 300); var marker3 = createLaneMarker((lanes[2] + lanes[3]) / 2, i * 150 - 300); laneMarkers.push(marker1); laneMarkers.push(marker2); laneMarkers.push(marker3); game.addChild(marker1); game.addChild(marker2); game.addChild(marker3); } // Initialize city background elements // Create sidewalks on both sides and between lanes and buildings for (var i = 0; i < 10; i++) { var yPos = i * 300 - 300; var leftSidewalk = createSidewalk(300, yPos); var rightSidewalk = createSidewalk(2048 - 300, yPos); // Create sidewalks between road and buildings var leftInnerSidewalk = createSidewalk(lanes[0] - 200, yPos); var rightInnerSidewalk = createSidewalk(lanes[3] + 200, yPos); sidewalks.push(leftSidewalk); sidewalks.push(rightSidewalk); sidewalks.push(leftInnerSidewalk); sidewalks.push(rightInnerSidewalk); game.addChild(leftSidewalk); game.addChild(rightSidewalk); game.addChild(leftInnerSidewalk); game.addChild(rightInnerSidewalk); } // Create buildings on both sides of the road for (var i = 0; i < 20; i++) { var yPos = i * 400 - 300; // Left side buildings var leftBuilding = createBuilding(200, yPos, Math.floor(Math.random() * 3)); buildings.push(leftBuilding); game.addChild(leftBuilding); // Right side buildings var rightBuilding = createBuilding(2048 - 200, yPos, Math.floor(Math.random() * 3)); buildings.push(rightBuilding); game.addChild(rightBuilding); } // Create trees scattered around for (var i = 0; i < 30; i++) { var yPos = i * 300 - 300; // Left side trees if (Math.random() < 0.6) { var leftTree = createTree(100 + Math.random() * 100, yPos); trees.push(leftTree); game.addChild(leftTree); } // Right side trees if (Math.random() < 0.6) { var rightTree = createTree(2048 - 100 - Math.random() * 100, yPos); trees.push(rightTree); game.addChild(rightTree); } } // Create pedestrians on sidewalks only for (var i = 0; i < 6; i++) { // Left side pedestrians (between road and buildings) var leftPedestrian = new Pedestrian(); leftPedestrian.x = 350 + Math.random() * 100; // Between sidewalk and buildings leftPedestrian.y = Math.random() * 2732; pedestrians.push(leftPedestrian); game.addChild(leftPedestrian); // Right side pedestrians (between road and buildings) var rightPedestrian = new Pedestrian(); rightPedestrian.x = 2048 - 450 + Math.random() * 100; // Between sidewalk and buildings rightPedestrian.y = Math.random() * 2732; pedestrians.push(rightPedestrian); game.addChild(rightPedestrian); } // Create player car player = new PlayerCar(); player.x = lanes[1]; player.y = 2732 - 300; player.targetX = lanes[1]; game.addChild(player); // Score display var scoreText = new Text2('Score: 0', { size: 60, fill: '#ffffff' }); scoreText.anchor.set(0, 0); scoreText.x = 150; scoreText.y = 50; LK.gui.topLeft.addChild(scoreText); // Coins display var coinsText = new Text2('Coins: 0', { size: 60, fill: '#ffd700' }); coinsText.anchor.set(1, 0); coinsText.x = -50; coinsText.y = 50; LK.gui.topRight.addChild(coinsText); // Speed display var speedText = new Text2('Speed: 0 KMH', { size: 60, fill: '#ffffff' }); speedText.anchor.set(1, 0); speedText.x = -50; speedText.y = 120; LK.gui.topRight.addChild(speedText); // Create garage UI garage = new GarageUI(); garage.visible = false; game.addChild(garage); // Create garage button garageButton = LK.getAsset('garageButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 150 }); game.addChild(garageButton); var garageButtonText = new Text2('GARAGE', { size: 50, fill: '#ffffff' }); garageButtonText.anchor.set(0.5, 0.5); garageButtonText.x = 2048 / 2; garageButtonText.y = 150; game.addChild(garageButtonText); // Load stored coins coinsCollected = storage.coins || 0; // Drag and drop variables var isDragging = false; // Mouse/Touch controls - drag and drop with right click support game.down = function (x, y, obj) { // Check if in garage if (inGarage) { return; // Let garage handle its own events } // Check garage button if (Math.abs(x - 2048 / 2) < 100 && Math.abs(y - 150) < 40) { showGarage(); return; } // Check if it's right mouse button (button 2) if (obj.event && obj.event.button === 2) { // Right mouse button - turn right if (player.lane < 3) { player.lane++; player.targetX = lanes[player.lane]; player.targetRotation = 0.2; // Rotate right } return; } // Left mouse button or touch - drag and drop isDragging = true; // Prevent car from going onto sidewalks - keep within road boundaries var roadLeftBoundary = lanes[0] - 100; // Left boundary of road var roadRightBoundary = lanes[3] + 100; // Right boundary of road if (x < roadLeftBoundary) { x = roadLeftBoundary; } else if (x > roadRightBoundary) { x = roadRightBoundary; } player.targetX = x; // Calculate which lane the player is closest to var closestLane = 0; var minDistance = Math.abs(x - lanes[0]); for (var i = 1; i < lanes.length; i++) { var distance = Math.abs(x - lanes[i]); if (distance < minDistance) { minDistance = distance; closestLane = i; } } player.lane = closestLane; // Set rotation based on movement direction if (x < player.x) { player.targetRotation = -0.2; // Rotate left } else if (x > player.x) { player.targetRotation = 0.2; // Rotate right } else { player.targetRotation = 0; // No rotation } }; game.move = function (x, y, obj) { if (inGarage) { return; // Don't handle movement in garage } if (isDragging) { // Prevent car from going onto sidewalks - keep within road boundaries var roadLeftBoundary = lanes[0] - 100; // Left boundary of road var roadRightBoundary = lanes[3] + 100; // Right boundary of road if (x < roadLeftBoundary) { x = roadLeftBoundary; } else if (x > roadRightBoundary) { x = roadRightBoundary; } player.targetX = x; // Calculate which lane the player is closest to var closestLane = 0; var minDistance = Math.abs(x - lanes[0]); for (var i = 1; i < lanes.length; i++) { var distance = Math.abs(x - lanes[i]); if (distance < minDistance) { minDistance = distance; closestLane = i; } } player.lane = closestLane; // Set rotation based on movement direction if (x < player.x) { player.targetRotation = -0.2; // Rotate left } else if (x > player.x) { player.targetRotation = 0.2; // Rotate right } else { player.targetRotation = 0; // No rotation } } }; game.up = function (x, y, obj) { if (inGarage) { return; // Don't handle up events in garage } isDragging = false; player.targetRotation = 0; // Reset rotation to straight }; // Prevent context menu on right click if (typeof document !== 'undefined') { document.addEventListener('contextmenu', function (e) { e.preventDefault(); return false; }); } // Spawn coin function spawnCoin() { var lane = Math.floor(Math.random() * 4); var coin = new Coin(); coin.x = lanes[lane] + (Math.random() - 0.5) * 100; coin.y = -100; coin.speed = gameSpeed; coins.push(coin); game.addChild(coin); } // Spawn regular spring function spawnRegularSpring() { var lane = Math.floor(Math.random() * 4); var spring = new RegularSpring(); spring.x = lanes[lane] + (Math.random() - 0.5) * 100; spring.y = -100; spring.speed = gameSpeed; regularSprings.push(spring); game.addChild(spring); } // Spawn power spring function spawnPowerSpring() { var lane = Math.floor(Math.random() * 4); var spring = new PowerSpring(); spring.x = lanes[lane] + (Math.random() - 0.5) * 100; spring.y = -100; spring.speed = gameSpeed; powerSprings.push(spring); game.addChild(spring); } // Check collisions function checkCollisions() { // Check coin collection for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; if (player.intersects(coin)) { LK.getSound('coinCollect').play(); coinsCollected += 50; storage.coins = coinsCollected; // Save to storage LK.setScore(LK.getScore() + 50); coin.destroy(); coins.splice(i, 1); } } // Check regular spring collection for (var i = regularSprings.length - 1; i >= 0; i--) { var spring = regularSprings[i]; if (player.intersects(spring)) { LK.getSound('coinCollect').play(); // Small speed boost gameSpeed = Math.min(gameSpeed + 1, 15); LK.setScore(LK.getScore() + 25); spring.destroy(); regularSprings.splice(i, 1); } } // Check power spring collection for (var i = powerSprings.length - 1; i >= 0; i--) { var spring = powerSprings[i]; if (player.intersects(spring)) { LK.getSound('coinCollect').play(); // Bigger speed boost and score gameSpeed = Math.min(gameSpeed + 3, 20); LK.setScore(LK.getScore() + 100); coinsCollected += 25; storage.coins = coinsCollected; spring.destroy(); powerSprings.splice(i, 1); } } // Check enemy car collisions for (var i = 0; i < enemyCars.length; i++) { var enemy = enemyCars[i]; if (player.intersects(enemy)) { LK.getSound('crash').play(); LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } } } // Update game game.update = function () { // Don't update game when in garage if (inGarage) { return; } // Maintain stable speed at 80 KMH (gameSpeed = 8) gameSpeed = 8; // Update distance gameDistance += gameSpeed; var distanceScore = Math.floor(gameDistance / 10); LK.setScore(distanceScore + coinsCollected * 10); // Update UI scoreText.setText('Score: ' + LK.getScore()); coinsText.setText('Coins: ' + coinsCollected); // Convert game speed to KMH (multiply by 10 for realistic speed values) var speedKMH = Math.round(gameSpeed * 10); speedText.setText('Speed: ' + speedKMH + ' KMH'); // Move road segments for (var i = 0; i < roadSegments.length; i++) { var segment = roadSegments[i]; segment.y += gameSpeed; if (segment.y > 2732 + 300) { segment.y -= roadSegments.length * 300; } } // Move lane markers for (var i = 0; i < laneMarkers.length; i++) { var marker = laneMarkers[i]; marker.y += gameSpeed; if (marker.y > 2732 + 150) { marker.y -= laneMarkers.length * 75; } } // Move sidewalks for (var i = 0; i < sidewalks.length; i++) { var sidewalk = sidewalks[i]; sidewalk.y += gameSpeed; if (sidewalk.y > 2732 + 500) { sidewalk.y -= 10 * 300; } } // Move buildings for (var i = 0; i < buildings.length; i++) { var building = buildings[i]; building.y += gameSpeed; if (building.y > 2732 + 500) { building.y -= 20 * 400; } } // Move trees for (var i = 0; i < trees.length; i++) { var tree = trees[i]; tree.y += gameSpeed; if (tree.y > 2732 + 200) { tree.y -= 30 * 300; } } // Spawn enemy cars - randomly in lanes spawnTimer++; if (spawnTimer >= 60) { // 1 second at 60 FPS var randomLane = Math.floor(Math.random() * 4); var enemy = new EnemyCar(); enemy.x = lanes[randomLane]; enemy.y = -200; // Start from top of screen to move downward // Enemy cars now have their own random speed, don't override it enemy.lane = randomLane; // Enemy cars move straight down in their assigned lane enemyCars.push(enemy); game.addChild(enemy); spawnTimer = 0; } // Spawn coins coinSpawnTimer++; if (coinSpawnTimer >= 120) { if (Math.random() < 0.7) { spawnCoin(); } // Spawn regular springs (less frequent) if (Math.random() < 0.3) { spawnRegularSpring(); } // Spawn power springs (rare) if (Math.random() < 0.1) { spawnPowerSpring(); } coinSpawnTimer = 0; } // Update player car speed based on distance player.speed = gameSpeed; // Update and clean up enemy cars for (var i = enemyCars.length - 1; i >= 0; i--) { var enemy = enemyCars[i]; // Enemy cars continue moving in their assigned lanes // Enemy cars move at stable speed if (enemy.y > 2732 + 200) { // Clean up when they go off the bottom of screen enemy.destroy(); enemyCars.splice(i, 1); } } // Enemy cars now avoid collisions with each other automatically // Update and clean up coins for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; coin.speed = gameSpeed; if (coin.y > 2732 + 100) { coin.destroy(); coins.splice(i, 1); } } // Update and clean up regular springs for (var i = regularSprings.length - 1; i >= 0; i--) { var spring = regularSprings[i]; spring.speed = gameSpeed; if (spring.y > 2732 + 100) { spring.destroy(); regularSprings.splice(i, 1); } } // Update and clean up power springs for (var i = powerSprings.length - 1; i >= 0; i--) { var spring = powerSprings[i]; spring.speed = gameSpeed; if (spring.y > 2732 + 100) { spring.destroy(); powerSprings.splice(i, 1); } } // Update pedestrians with random tween animations for (var i = 0; i < pedestrians.length; i++) { var pedestrian = pedestrians[i]; // Occasionally add random tween animations if (LK.ticks % 300 === 0 && Math.random() < 0.1) { // Random scale animation tween(pedestrian, { scaleX: 1.2, scaleY: 1.2 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(pedestrian, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeInOut }); } }); } // Occasionally add random rotation animation if (LK.ticks % 400 === 0 && Math.random() < 0.05) { tween(pedestrian, { rotation: Math.PI * 2 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { pedestrian.rotation = 0; } }); } } // Check collisions checkCollisions(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
coins: 0,
selectedCar: 0,
ownedCars: [0]
});
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.update = function () {
self.y += self.speed;
// Simple rotation animation
coinGraphics.rotation += 0.1;
};
return self;
});
var EnemyCar = Container.expand(function () {
var self = Container.call(this);
// Array of enemy car assets
var enemyCarAssets = ['enemyCar', 'enemyCar2', 'enemyCar3', 'enemyCar4'];
// Randomly select a car type
var randomCarType = enemyCarAssets[Math.floor(Math.random() * enemyCarAssets.length)];
var carGraphics = self.attachAsset(randomCarType, {
anchorX: 0.5,
anchorY: 0.5
});
// Set different random speeds for each enemy car
self.speed = 4 + Math.floor(Math.random() * 8); // Random speed between 4 and 11
self.carType = randomCarType; // Store the car type for reference
self.update = function () {
// All enemy cars move in the same direction as player (downward)
// Move at consistent speed in the same direction as player
self.y += self.speed;
};
return self;
});
var GarageUI = Container.expand(function () {
var self = Container.call(this);
// Garage background
var background = self.attachAsset('garageBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
// Title
var title = new Text2('GARAGE', {
size: 120,
fill: '#ffffff'
});
title.anchor.set(0.5, 0);
title.x = 2048 / 2;
title.y = 200;
self.addChild(title);
// Car data
var carData = [{
name: 'Basic Car',
asset: 'playerCar',
price: 0,
color: 0x4287f5
}, {
name: 'Sports Car',
asset: 'sportsCar',
price: 100,
color: 0xff4500
}, {
name: 'Luxury Car',
asset: 'luxuryCar',
price: 250,
color: 0x9932cc
}, {
name: 'Super Car',
asset: 'superCar',
price: 500,
color: 0xffd700
}];
var carDisplays = [];
var carTexts = [];
var buttons = [];
// Create car displays
for (var i = 0; i < carData.length; i++) {
var car = carData[i];
var yPos = 500 + i * 400;
// Car display
var carDisplay = LK.getAsset(car.asset, {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 300,
y: yPos,
scaleX: 1.5,
scaleY: 1.5
});
self.addChild(carDisplay);
carDisplays.push(carDisplay);
// Car name and price
var carText = new Text2(car.name + (car.price > 0 ? ' - ' + car.price + ' coins' : ' - FREE'), {
size: 60,
fill: '#ffffff'
});
carText.anchor.set(0, 0.5);
carText.x = 2048 / 2 - 100;
carText.y = yPos - 50;
self.addChild(carText);
carTexts.push(carText);
// Status text
var statusText = new Text2('', {
size: 50,
fill: '#00ff00'
});
statusText.anchor.set(0, 0.5);
statusText.x = 2048 / 2 - 100;
statusText.y = yPos;
self.addChild(statusText);
// Buy/Select button
var button = LK.getAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 200,
y: yPos + 50
});
self.addChild(button);
buttons.push(button);
var buttonText = new Text2('', {
size: 40,
fill: '#ffffff'
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = 2048 / 2 + 200;
buttonText.y = yPos + 50;
self.addChild(buttonText);
// Store references
button.carIndex = i;
button.statusText = statusText;
button.buttonText = buttonText;
button.carData = car;
}
// Coins display
var coinsDisplay = new Text2('', {
size: 80,
fill: '#ffd700'
});
coinsDisplay.anchor.set(0.5, 0);
coinsDisplay.x = 2048 / 2;
coinsDisplay.y = 100;
self.addChild(coinsDisplay);
// Back button
var backButton = LK.getAsset('garageButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2500
});
self.addChild(backButton);
var backText = new Text2('BACK TO GAME', {
size: 50,
fill: '#ffffff'
});
backText.anchor.set(0.5, 0.5);
backText.x = 2048 / 2;
backText.y = 2500;
self.addChild(backText);
self.updateDisplay = function () {
var playerCoins = storage.coins || 0;
coinsDisplay.setText('Coins: ' + playerCoins);
var ownedCars = storage.ownedCars || [0];
var selectedCar = storage.selectedCar || 0;
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
var isOwned = ownedCars.indexOf(i) !== -1;
var isSelected = selectedCar === i;
if (isSelected) {
button.statusText.setText('SELECTED');
button.buttonText.setText('SELECTED');
button.tint = 0x00ff00;
} else if (isOwned) {
button.statusText.setText('OWNED');
button.buttonText.setText('SELECT');
button.tint = 0x1e90ff;
} else {
button.statusText.setText('');
if (playerCoins >= button.carData.price) {
button.buttonText.setText('BUY');
button.tint = 0x00ff00;
} else {
button.buttonText.setText('NEED ' + (button.carData.price - playerCoins) + ' MORE');
button.tint = 0xff0000;
}
}
}
};
self.down = function (x, y, obj) {
// Use direct coordinates instead of toLocal conversion to avoid parent issues
var localPos = {
x: x,
y: y
};
// Check back button
if (Math.abs(localPos.x - 2048 / 2) < 100 && Math.abs(localPos.y - 2500) < 40) {
showGame();
return;
}
// Check car buttons
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
var buttonPos = {
x: 2048 / 2 + 200,
y: 500 + i * 400 + 50
};
if (Math.abs(localPos.x - buttonPos.x) < 75 && Math.abs(localPos.y - buttonPos.y) < 30) {
var ownedCars = storage.ownedCars || [0];
var isOwned = ownedCars.indexOf(i) !== -1;
var playerCoins = storage.coins || 0;
if (isOwned) {
// Select car
storage.selectedCar = i;
self.updateDisplay();
} else if (playerCoins >= button.carData.price) {
// Buy car
storage.coins = playerCoins - button.carData.price;
ownedCars.push(i);
storage.ownedCars = ownedCars;
storage.selectedCar = i;
self.updateDisplay();
}
break;
}
}
};
return self;
});
var Pedestrian = Container.expand(function () {
var self = Container.call(this);
var pedestrianGraphics = self.attachAsset('pedestrian', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = (2 + Math.random() * 3) * 0.1; // Reduced speed by 90% (multiply by 0.1)
self.direction = Math.random() > 0.5 ? 1 : -1; // Random direction
self.changeDirectionTimer = 0;
self.changeDirectionInterval = 120 + Math.floor(Math.random() * 240); // Change direction every 2-6 seconds
self.update = function () {
// Move pedestrian
self.y += self.speed * self.direction;
// Random direction changes
self.changeDirectionTimer++;
if (self.changeDirectionTimer >= self.changeDirectionInterval) {
self.direction *= -1; // Reverse direction
self.changeDirectionTimer = 0;
self.changeDirectionInterval = 120 + Math.floor(Math.random() * 240);
// Add random horizontal movement with tween
if (Math.random() < 0.3) {
var newX = self.x + (Math.random() - 0.5) * 100;
tween(self, {
x: newX
}, {
duration: 1000 + Math.random() * 2000,
easing: tween.easeInOut
});
}
}
// Keep pedestrians within reasonable bounds
if (self.y < -100) {
self.y = -100;
self.direction = 1;
} else if (self.y > 2732 + 100) {
self.y = 2732 + 100;
self.direction = -1;
}
};
return self;
});
var PlayerCar = Container.expand(function () {
var self = Container.call(this);
var carAssets = ['playerCar', 'sportsCar', 'luxuryCar', 'superCar'];
var selectedCar = storage.selectedCar || 0;
var carAsset = carAssets[selectedCar] || 'playerCar';
var carGraphics = self.attachAsset(carAsset, {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1; // 0 = leftmost, 1 = left center, 2 = right center, 3 = rightmost
self.targetX = 0;
self.speed = 70; // Character speed set to 70
self.targetRotation = 0;
self.update = function () {
// Smooth movement to target position
var diff = self.targetX - self.x;
self.x += diff * 0.15;
// Smooth rotation animation
var rotDiff = self.targetRotation - carGraphics.rotation;
carGraphics.rotation += rotDiff * 0.2;
};
return self;
});
var PowerSpring = Container.expand(function () {
var self = Container.call(this);
var springGraphics = self.attachAsset('powerSpring', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.bounceAmount = 0.5;
self.update = function () {
self.y += self.speed;
// More intense bounce animation
springGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.3) * self.bounceAmount;
springGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.25) * 0.2;
springGraphics.rotation += 0.08;
};
return self;
});
var RegularSpring = Container.expand(function () {
var self = Container.call(this);
var springGraphics = self.attachAsset('regularSpring', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.bounceAmount = 0.3;
self.update = function () {
self.y += self.speed;
// Bounce animation
springGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.2) * self.bounceAmount;
springGraphics.rotation += 0.05;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5a2d
});
/****
* Game Code
****/
// Game dimensions: 2048x2732
var gameSpeed = 8;
var speedIncrement = 0;
var maxSpeed = 8;
// Garage system
var garage;
var garageButton;
var inGarage = false;
// Initialize persistent coins from storage
if (storage.coins === undefined) {
storage.coins = 0;
}
function showGarage() {
inGarage = true;
// Hide all game elements
for (var i = 0; i < game.children.length; i++) {
game.children[i].visible = false;
}
// Show garage
garage.visible = true;
garage.updateDisplay();
garageButton.visible = false;
}
function showGame() {
inGarage = false;
// Show all game elements
for (var i = 0; i < game.children.length; i++) {
game.children[i].visible = true;
}
// Hide garage
garage.visible = false;
garageButton.visible = true;
// Recreate player with new car
var oldX = player.x;
var oldY = player.y;
var oldLane = player.lane;
var oldTargetX = player.targetX;
game.removeChild(player);
player = new PlayerCar();
player.x = oldX;
player.y = oldY;
player.lane = oldLane;
player.targetX = oldTargetX;
game.addChild(player);
}
// Lane positions
var lanes = [2048 / 2 - 300, 2048 / 2 - 100, 2048 / 2 + 100, 2048 / 2 + 300];
// Game objects
var player;
var enemyCars = [];
var coins = [];
var regularSprings = [];
var powerSprings = [];
var roadSegments = [];
var laneMarkers = [];
var buildings = [];
var trees = [];
var sidewalks = [];
var pedestrians = [];
// Game state
var gameDistance = 0;
var coinsCollected = 0;
var spawnTimer = 0;
var coinSpawnTimer = 0;
// Create road background
function createRoadSegment(y) {
var segment = LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0,
x: 2048 / 2,
y: y
});
return segment;
}
// Create lane markers
function createLaneMarker(x, y) {
var marker = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0,
x: x,
y: y
});
return marker;
}
// Create city background elements
function createBuilding(x, y, type) {
var buildingAsset = type === 0 ? 'building1' : type === 1 ? 'building2' : 'building3';
var building = LK.getAsset(buildingAsset, {
anchorX: 0.5,
anchorY: 1,
x: x,
y: y
});
return building;
}
function createTree(x, y) {
var tree = LK.getAsset('tree', {
anchorX: 0.5,
anchorY: 1,
x: x,
y: y
});
return tree;
}
function createSidewalk(x, y) {
var sidewalk = LK.getAsset('sidewalk', {
anchorX: 0.5,
anchorY: 0,
x: x,
y: y
});
return sidewalk;
}
// Initialize road
for (var i = 0; i < 12; i++) {
var segment = createRoadSegment(i * 300 - 300);
roadSegments.push(segment);
game.addChild(segment);
}
// Initialize lane markers
for (var i = 0; i < 24; i++) {
var marker1 = createLaneMarker((lanes[0] + lanes[1]) / 2, i * 150 - 300);
var marker2 = createLaneMarker((lanes[1] + lanes[2]) / 2, i * 150 - 300);
var marker3 = createLaneMarker((lanes[2] + lanes[3]) / 2, i * 150 - 300);
laneMarkers.push(marker1);
laneMarkers.push(marker2);
laneMarkers.push(marker3);
game.addChild(marker1);
game.addChild(marker2);
game.addChild(marker3);
}
// Initialize city background elements
// Create sidewalks on both sides and between lanes and buildings
for (var i = 0; i < 10; i++) {
var yPos = i * 300 - 300;
var leftSidewalk = createSidewalk(300, yPos);
var rightSidewalk = createSidewalk(2048 - 300, yPos);
// Create sidewalks between road and buildings
var leftInnerSidewalk = createSidewalk(lanes[0] - 200, yPos);
var rightInnerSidewalk = createSidewalk(lanes[3] + 200, yPos);
sidewalks.push(leftSidewalk);
sidewalks.push(rightSidewalk);
sidewalks.push(leftInnerSidewalk);
sidewalks.push(rightInnerSidewalk);
game.addChild(leftSidewalk);
game.addChild(rightSidewalk);
game.addChild(leftInnerSidewalk);
game.addChild(rightInnerSidewalk);
}
// Create buildings on both sides of the road
for (var i = 0; i < 20; i++) {
var yPos = i * 400 - 300;
// Left side buildings
var leftBuilding = createBuilding(200, yPos, Math.floor(Math.random() * 3));
buildings.push(leftBuilding);
game.addChild(leftBuilding);
// Right side buildings
var rightBuilding = createBuilding(2048 - 200, yPos, Math.floor(Math.random() * 3));
buildings.push(rightBuilding);
game.addChild(rightBuilding);
}
// Create trees scattered around
for (var i = 0; i < 30; i++) {
var yPos = i * 300 - 300;
// Left side trees
if (Math.random() < 0.6) {
var leftTree = createTree(100 + Math.random() * 100, yPos);
trees.push(leftTree);
game.addChild(leftTree);
}
// Right side trees
if (Math.random() < 0.6) {
var rightTree = createTree(2048 - 100 - Math.random() * 100, yPos);
trees.push(rightTree);
game.addChild(rightTree);
}
}
// Create pedestrians on sidewalks only
for (var i = 0; i < 6; i++) {
// Left side pedestrians (between road and buildings)
var leftPedestrian = new Pedestrian();
leftPedestrian.x = 350 + Math.random() * 100; // Between sidewalk and buildings
leftPedestrian.y = Math.random() * 2732;
pedestrians.push(leftPedestrian);
game.addChild(leftPedestrian);
// Right side pedestrians (between road and buildings)
var rightPedestrian = new Pedestrian();
rightPedestrian.x = 2048 - 450 + Math.random() * 100; // Between sidewalk and buildings
rightPedestrian.y = Math.random() * 2732;
pedestrians.push(rightPedestrian);
game.addChild(rightPedestrian);
}
// Create player car
player = new PlayerCar();
player.x = lanes[1];
player.y = 2732 - 300;
player.targetX = lanes[1];
game.addChild(player);
// Score display
var scoreText = new Text2('Score: 0', {
size: 60,
fill: '#ffffff'
});
scoreText.anchor.set(0, 0);
scoreText.x = 150;
scoreText.y = 50;
LK.gui.topLeft.addChild(scoreText);
// Coins display
var coinsText = new Text2('Coins: 0', {
size: 60,
fill: '#ffd700'
});
coinsText.anchor.set(1, 0);
coinsText.x = -50;
coinsText.y = 50;
LK.gui.topRight.addChild(coinsText);
// Speed display
var speedText = new Text2('Speed: 0 KMH', {
size: 60,
fill: '#ffffff'
});
speedText.anchor.set(1, 0);
speedText.x = -50;
speedText.y = 120;
LK.gui.topRight.addChild(speedText);
// Create garage UI
garage = new GarageUI();
garage.visible = false;
game.addChild(garage);
// Create garage button
garageButton = LK.getAsset('garageButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 150
});
game.addChild(garageButton);
var garageButtonText = new Text2('GARAGE', {
size: 50,
fill: '#ffffff'
});
garageButtonText.anchor.set(0.5, 0.5);
garageButtonText.x = 2048 / 2;
garageButtonText.y = 150;
game.addChild(garageButtonText);
// Load stored coins
coinsCollected = storage.coins || 0;
// Drag and drop variables
var isDragging = false;
// Mouse/Touch controls - drag and drop with right click support
game.down = function (x, y, obj) {
// Check if in garage
if (inGarage) {
return; // Let garage handle its own events
}
// Check garage button
if (Math.abs(x - 2048 / 2) < 100 && Math.abs(y - 150) < 40) {
showGarage();
return;
}
// Check if it's right mouse button (button 2)
if (obj.event && obj.event.button === 2) {
// Right mouse button - turn right
if (player.lane < 3) {
player.lane++;
player.targetX = lanes[player.lane];
player.targetRotation = 0.2; // Rotate right
}
return;
}
// Left mouse button or touch - drag and drop
isDragging = true;
// Prevent car from going onto sidewalks - keep within road boundaries
var roadLeftBoundary = lanes[0] - 100; // Left boundary of road
var roadRightBoundary = lanes[3] + 100; // Right boundary of road
if (x < roadLeftBoundary) {
x = roadLeftBoundary;
} else if (x > roadRightBoundary) {
x = roadRightBoundary;
}
player.targetX = x;
// Calculate which lane the player is closest to
var closestLane = 0;
var minDistance = Math.abs(x - lanes[0]);
for (var i = 1; i < lanes.length; i++) {
var distance = Math.abs(x - lanes[i]);
if (distance < minDistance) {
minDistance = distance;
closestLane = i;
}
}
player.lane = closestLane;
// Set rotation based on movement direction
if (x < player.x) {
player.targetRotation = -0.2; // Rotate left
} else if (x > player.x) {
player.targetRotation = 0.2; // Rotate right
} else {
player.targetRotation = 0; // No rotation
}
};
game.move = function (x, y, obj) {
if (inGarage) {
return; // Don't handle movement in garage
}
if (isDragging) {
// Prevent car from going onto sidewalks - keep within road boundaries
var roadLeftBoundary = lanes[0] - 100; // Left boundary of road
var roadRightBoundary = lanes[3] + 100; // Right boundary of road
if (x < roadLeftBoundary) {
x = roadLeftBoundary;
} else if (x > roadRightBoundary) {
x = roadRightBoundary;
}
player.targetX = x;
// Calculate which lane the player is closest to
var closestLane = 0;
var minDistance = Math.abs(x - lanes[0]);
for (var i = 1; i < lanes.length; i++) {
var distance = Math.abs(x - lanes[i]);
if (distance < minDistance) {
minDistance = distance;
closestLane = i;
}
}
player.lane = closestLane;
// Set rotation based on movement direction
if (x < player.x) {
player.targetRotation = -0.2; // Rotate left
} else if (x > player.x) {
player.targetRotation = 0.2; // Rotate right
} else {
player.targetRotation = 0; // No rotation
}
}
};
game.up = function (x, y, obj) {
if (inGarage) {
return; // Don't handle up events in garage
}
isDragging = false;
player.targetRotation = 0; // Reset rotation to straight
};
// Prevent context menu on right click
if (typeof document !== 'undefined') {
document.addEventListener('contextmenu', function (e) {
e.preventDefault();
return false;
});
}
// Spawn coin
function spawnCoin() {
var lane = Math.floor(Math.random() * 4);
var coin = new Coin();
coin.x = lanes[lane] + (Math.random() - 0.5) * 100;
coin.y = -100;
coin.speed = gameSpeed;
coins.push(coin);
game.addChild(coin);
}
// Spawn regular spring
function spawnRegularSpring() {
var lane = Math.floor(Math.random() * 4);
var spring = new RegularSpring();
spring.x = lanes[lane] + (Math.random() - 0.5) * 100;
spring.y = -100;
spring.speed = gameSpeed;
regularSprings.push(spring);
game.addChild(spring);
}
// Spawn power spring
function spawnPowerSpring() {
var lane = Math.floor(Math.random() * 4);
var spring = new PowerSpring();
spring.x = lanes[lane] + (Math.random() - 0.5) * 100;
spring.y = -100;
spring.speed = gameSpeed;
powerSprings.push(spring);
game.addChild(spring);
}
// Check collisions
function checkCollisions() {
// Check coin collection
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (player.intersects(coin)) {
LK.getSound('coinCollect').play();
coinsCollected += 50;
storage.coins = coinsCollected; // Save to storage
LK.setScore(LK.getScore() + 50);
coin.destroy();
coins.splice(i, 1);
}
}
// Check regular spring collection
for (var i = regularSprings.length - 1; i >= 0; i--) {
var spring = regularSprings[i];
if (player.intersects(spring)) {
LK.getSound('coinCollect').play();
// Small speed boost
gameSpeed = Math.min(gameSpeed + 1, 15);
LK.setScore(LK.getScore() + 25);
spring.destroy();
regularSprings.splice(i, 1);
}
}
// Check power spring collection
for (var i = powerSprings.length - 1; i >= 0; i--) {
var spring = powerSprings[i];
if (player.intersects(spring)) {
LK.getSound('coinCollect').play();
// Bigger speed boost and score
gameSpeed = Math.min(gameSpeed + 3, 20);
LK.setScore(LK.getScore() + 100);
coinsCollected += 25;
storage.coins = coinsCollected;
spring.destroy();
powerSprings.splice(i, 1);
}
}
// Check enemy car collisions
for (var i = 0; i < enemyCars.length; i++) {
var enemy = enemyCars[i];
if (player.intersects(enemy)) {
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
}
// Update game
game.update = function () {
// Don't update game when in garage
if (inGarage) {
return;
}
// Maintain stable speed at 80 KMH (gameSpeed = 8)
gameSpeed = 8;
// Update distance
gameDistance += gameSpeed;
var distanceScore = Math.floor(gameDistance / 10);
LK.setScore(distanceScore + coinsCollected * 10);
// Update UI
scoreText.setText('Score: ' + LK.getScore());
coinsText.setText('Coins: ' + coinsCollected);
// Convert game speed to KMH (multiply by 10 for realistic speed values)
var speedKMH = Math.round(gameSpeed * 10);
speedText.setText('Speed: ' + speedKMH + ' KMH');
// Move road segments
for (var i = 0; i < roadSegments.length; i++) {
var segment = roadSegments[i];
segment.y += gameSpeed;
if (segment.y > 2732 + 300) {
segment.y -= roadSegments.length * 300;
}
}
// Move lane markers
for (var i = 0; i < laneMarkers.length; i++) {
var marker = laneMarkers[i];
marker.y += gameSpeed;
if (marker.y > 2732 + 150) {
marker.y -= laneMarkers.length * 75;
}
}
// Move sidewalks
for (var i = 0; i < sidewalks.length; i++) {
var sidewalk = sidewalks[i];
sidewalk.y += gameSpeed;
if (sidewalk.y > 2732 + 500) {
sidewalk.y -= 10 * 300;
}
}
// Move buildings
for (var i = 0; i < buildings.length; i++) {
var building = buildings[i];
building.y += gameSpeed;
if (building.y > 2732 + 500) {
building.y -= 20 * 400;
}
}
// Move trees
for (var i = 0; i < trees.length; i++) {
var tree = trees[i];
tree.y += gameSpeed;
if (tree.y > 2732 + 200) {
tree.y -= 30 * 300;
}
}
// Spawn enemy cars - randomly in lanes
spawnTimer++;
if (spawnTimer >= 60) {
// 1 second at 60 FPS
var randomLane = Math.floor(Math.random() * 4);
var enemy = new EnemyCar();
enemy.x = lanes[randomLane];
enemy.y = -200; // Start from top of screen to move downward
// Enemy cars now have their own random speed, don't override it
enemy.lane = randomLane;
// Enemy cars move straight down in their assigned lane
enemyCars.push(enemy);
game.addChild(enemy);
spawnTimer = 0;
}
// Spawn coins
coinSpawnTimer++;
if (coinSpawnTimer >= 120) {
if (Math.random() < 0.7) {
spawnCoin();
}
// Spawn regular springs (less frequent)
if (Math.random() < 0.3) {
spawnRegularSpring();
}
// Spawn power springs (rare)
if (Math.random() < 0.1) {
spawnPowerSpring();
}
coinSpawnTimer = 0;
}
// Update player car speed based on distance
player.speed = gameSpeed;
// Update and clean up enemy cars
for (var i = enemyCars.length - 1; i >= 0; i--) {
var enemy = enemyCars[i];
// Enemy cars continue moving in their assigned lanes
// Enemy cars move at stable speed
if (enemy.y > 2732 + 200) {
// Clean up when they go off the bottom of screen
enemy.destroy();
enemyCars.splice(i, 1);
}
}
// Enemy cars now avoid collisions with each other automatically
// Update and clean up coins
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
coin.speed = gameSpeed;
if (coin.y > 2732 + 100) {
coin.destroy();
coins.splice(i, 1);
}
}
// Update and clean up regular springs
for (var i = regularSprings.length - 1; i >= 0; i--) {
var spring = regularSprings[i];
spring.speed = gameSpeed;
if (spring.y > 2732 + 100) {
spring.destroy();
regularSprings.splice(i, 1);
}
}
// Update and clean up power springs
for (var i = powerSprings.length - 1; i >= 0; i--) {
var spring = powerSprings[i];
spring.speed = gameSpeed;
if (spring.y > 2732 + 100) {
spring.destroy();
powerSprings.splice(i, 1);
}
}
// Update pedestrians with random tween animations
for (var i = 0; i < pedestrians.length; i++) {
var pedestrian = pedestrians[i];
// Occasionally add random tween animations
if (LK.ticks % 300 === 0 && Math.random() < 0.1) {
// Random scale animation
tween(pedestrian, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(pedestrian, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
}
// Occasionally add random rotation animation
if (LK.ticks % 400 === 0 && Math.random() < 0.05) {
tween(pedestrian, {
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
pedestrian.rotation = 0;
}
});
}
}
// Check collisions
checkCollisions();
};
asvalt. In-Game asset. 2d. High contrast. No shadows
üsten çekilmiş araba. In-Game asset. 2d. High contrast. No shadows
üstden çekilmiş bina. In-Game asset. 2d. High contrast. No shadows
içinde TE yazan coin. In-Game asset. 2d. High contrast. No shadows
üstden çekilen araç. In-Game asset. 2d. High contrast. No shadows
üstden çekilmiç araba. In-Game asset. 2d. High contrast. No shadows
üstden çekilmiş sport araba. In-Game asset. 2d. High contrast. No shadows
üstden çekilmiş lüks araba. In-Game asset. 2d. High contrast. No shadows
üstden çekilmiş super araba. In-Game asset. 2d. High contrast. No shadows
üstden çekilmiş kaldirim. In-Game asset. 2d. High contrast. No shadows
üstden çekilmiş yaya. In-Game asset. 2d. High contrast. No shadows