User prompt
Please fix the bug: 'TypeError: LK.isPressed is not a function' in or related to this line: 'if (LK.isPressed('left') && playerCar.x > 512) {' Line Number: 74
User prompt
Player can move the car and the is need to be a road
User prompt
Şimdi 2 şeritli bir yol olucak bir taraftan araçlar gelicek bir taraftan gidicek bizde aralarında sürerek kimseye çarpmadan en yüksek skoru elde edeceğiz
User prompt
Yada vazgeçtim at bütün projeyi çöpe
User prompt
There will be enemy cars
User prompt
Its broken
Code edit (1 edits merged)
Please save this source code
User prompt
Speedway Sprint: Level Challenge
Initial prompt
We gonna make a racing game with levels
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { level: 1, bestTime: 0 }); /**** * Classes ****/ var Car = Container.expand(function () { var self = Container.call(this); var carGraphics = self.attachAsset('playerCar', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.update = function () { // Player car does not move forward automatically anymore // Only horizontal movement is allowed, so no change to self.y here if (self.x < 0) { self.x = 2048; } else if (self.x > 2048) { self.x = 0; } }; return self; }); var EnemyCar = Container.expand(function () { var self = Container.call(this); // List of possible enemy car asset ids for variety var enemyCarAssetIds = ['enemyCar', 'enemyCar2', 'enemyCar3', 'enemyCar4']; // Pick a random car asset for this enemy var chosenAssetId = enemyCarAssetIds[Math.floor(Math.random() * enemyCarAssetIds.length)]; var enemyCarGraphics = self.attachAsset(chosenAssetId, { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.update = function () { // Enemy cars move down the screen (already correct) self.y += self.speed; if (self.x < 0) { self.x = 2048; } else if (self.x > 2048) { self.x = 0; } }; return self; }); // Powerup: Speed Boost var Powerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerupSpeed', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); self.speed = 10; self.type = "speed"; self.update = function () { self.y += self.speed; // Remove if off screen if (self.y > 2900) { self.destroy(); return true; } return false; }; return self; }); // Powerup: Shield var PowerupShield = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerupShield', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); self.speed = 10; self.type = "shield"; self.update = function () { self.y += self.speed; // Remove if off screen if (self.y > 2900) { self.destroy(); return true; } return false; }; return self; }); var Smoke = Container.expand(function () { var self = Container.call(this); var smokeGraphics = self.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5 }); // Initialize with random properties for varied effect self.speedX = (Math.random() - 0.5) * 2; // Random horizontal drift self.speedY = 1 + Math.random() * 2; // Move backward speed self.initialDistance = 0; // Track distance traveled self.maxAlpha = 0.8 + Math.random() * 0.2; // Maximum density at start self.alpha = self.maxAlpha; // Start with maximum opacity self.fadingDistance = 40 + Math.random() * 40; // Distance at which smoke starts to fade self.growSpeed = 0.03 + Math.random() * 0.03; // Expansion rate // Update smoke particle behavior self.update = function () { self.x += self.speedX; self.y += self.speedY; // Move downward (backward from car perspective) // Update distance traveled self.initialDistance += self.speedY; // Start dense and become less dense as it moves backward self.alpha = Math.max(0, self.maxAlpha * (1 - self.initialDistance / (self.fadingDistance * 2))); self.scale.x += self.growSpeed; self.scale.y += self.growSpeed; // Remove smoke when it becomes too transparent if (self.alpha <= 0) { self.destroy(); return true; // Signal that this smoke has been destroyed } return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Shield powerup asset // Speed powerup asset // Create score text // Additional car images for variety var score = 0; var scoreTxt = new Text2('Score: 0', { size: 100, fill: 0xFFFFFF }); // Add smoke effects var smokeParticles = []; function createSmoke(x, y, amount) { for (var i = 0; i < amount; i++) { var smoke = new Smoke(); // Alternate between left and right sides of the car var side = i % 2 === 0 ? -1 : 1; // Position smoke on the left or right side of the car smoke.x = x + side * 100 + (Math.random() - 0.5) * 20; // Offset from car sides smoke.y = y + 200; // Position behind car (below car in screen coordinates) smokeParticles.push(smoke); game.addChild(smoke); } } scoreTxt.anchor.set(0.5, 0); scoreTxt.alpha = 0; LK.gui.top.addChild(scoreTxt); tween(scoreTxt, { alpha: 1 }, 800, { easing: "easeOutCubic" }); var road = LK.getAsset('road', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); road.alpha = 0; road.scale.set(1.05, 1.05); game.addChild(road); // Create a second road image for seamless looping var road2 = LK.getAsset('road', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 - 2732 // Place directly above the first road }); road2.alpha = 0; road2.scale.set(1.05, 1.05); game.addChild(road2); tween(road, { alpha: 1 }, 1000, { easing: "easeOutCubic" }); tween(road2, { alpha: 1 }, 1000, { easing: "easeOutCubic" }); tween(road.scale, { x: 1, y: 1 }, 900, { easing: "easeOutCubic" }); tween(road2.scale, { x: 1, y: 1 }, 900, { easing: "easeOutCubic" }); // Add road movement variables var roadScrollSpeed = 16; var roadInitialY = 2366; var roadImageHeight = 2732; // Play background music with fade in LK.playMusic('bgmusic', { fade: { start: 0, end: 0.8, duration: 1000 } }); // Display high score var highScore = storage.highScore || 0; var highScoreTxt = new Text2('High Score: ' + highScore, { size: 80, fill: 0x00a000, // Lighter green color fontWeight: 'bold' // Make the text bold }); highScoreTxt.anchor.set(0.5, 0); highScoreTxt.y = 120; highScoreTxt.alpha = 0; LK.gui.top.addChild(highScoreTxt); tween(highScoreTxt, { alpha: 1 }, 1000, { easing: "easeOutCubic" }); // Add shadow under player car var playerCarShadow = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 0.35, x: 0, y: 0, alpha: 0.25, tint: 0x000000 }); game.addChild(playerCarShadow); var playerCar = game.addChild(new Car()); // Place player in left, center, or right lane randomly var laneXs = [512, 1024, 1536]; // 512 = left, 1024 = center, 1536 = right playerCar.x = laneXs[Math.floor(Math.random() * laneXs.length)]; playerCar.y = 2300; // Start near the bottom, adjusted for bigger car // Fade in the player car for a polished entrance playerCar.alpha = 0; playerCar.scale.set(1.2, 1.2); tween(playerCar, { alpha: 1 }, 600, { easing: "easeOutCubic" }); tween(playerCar.scale, { x: 1, y: 1 }, 400, { easing: "easeOutBack" }); var enemyCars = []; function spawnEnemyCar() { // Only allow enemy cars to spawn in the same vertical lines as the player (left, center, or right lane) // Lane Xs: left, center, right var laneXs = [512, 1024, 1536]; // Car height for vertical gap - increased multiplier for more space var carHeight = 660; var verticalGapMultiplier = 3.5; // Find the highest Y of any existing enemy car, or use -330 if none var topY = -330; for (var i = 0; i < enemyCars.length; i++) { if (enemyCars[i].y < topY) { topY = enemyCars[i].y; } } // Patterns: only left, only center, only right - never more than one at a time // to ensure player always has a path to pass through var patterns = [ // Only left lane [{ x: laneXs[0] }], // Only center lane [{ x: laneXs[1] }], // Only right lane [{ x: laneXs[2] }]]; // Keep track of which pattern to use next if (typeof spawnEnemyCar.patternIndex === "undefined") { spawnEnemyCar.patternIndex = 0; } // Shuffle patterns order every cycle for variety if (typeof spawnEnemyCar.patternOrder === "undefined" || spawnEnemyCar.patternOrder.length === 0) { var order = []; for (var i = 0; i < patterns.length; i++) { order.push(i); } // Fisher-Yates shuffle for (var i = order.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = order[i]; order[i] = order[j]; order[j] = temp; } spawnEnemyCar.patternOrder = order; spawnEnemyCar.patternIndex = 0; } var patternIdx = spawnEnemyCar.patternOrder[spawnEnemyCar.patternIndex]; var pattern = patterns[patternIdx]; spawnEnemyCar.patternIndex++; if (spawnEnemyCar.patternIndex >= spawnEnemyCar.patternOrder.length) { spawnEnemyCar.patternOrder = []; } // Place new pattern below the last one, with the specified gap var spawnY = topY; for (var i = 0; i < pattern.length; i++) { var carDef = pattern[i]; var enemyCar = new EnemyCar(); // Apply global speed bonus if any if (typeof globalEnemySpeedBonus !== "undefined") { enemyCar.speed += globalEnemySpeedBonus; } enemyCar.x = carDef.x; enemyCar.y = spawnY; // --- Add shadow under enemy car for polish --- var enemyCarShadow = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 0.32, x: enemyCar.x, y: enemyCar.y + 180, alpha: 0.18, tint: 0x000000 }); enemyCar._shadow = enemyCarShadow; game.addChild(enemyCarShadow); enemyCars.push(enemyCar); game.addChild(enemyCar); spawnY -= carHeight * verticalGapMultiplier; } } game.update = function () { // Move both road images downward to simulate motion road.y += roadScrollSpeed; road2.y += roadScrollSpeed; // If a road image moves off the bottom, move it above the other for seamless looping if (road.y > roadInitialY + roadImageHeight / 2) { road.y = road2.y - roadImageHeight; } if (road2.y > roadInitialY + roadImageHeight / 2) { road2.y = road.y - roadImageHeight; } // No gradual movement needed; handled instantly in game.down // Only update playerCar for horizontal movement, not forward movement playerCar.update(); // Create smoke particles behind player car if (LK.ticks % 5 == 0) { createSmoke(playerCar.x, playerCar.y, 2); } // Update and manage smoke particles for (var i = smokeParticles.length - 1; i >= 0; i--) { var isDestroyed = smokeParticles[i].update(); if (isDestroyed) { smokeParticles.splice(i, 1); } } var _loop = function _loop() { enemyCar = enemyCars[i]; // Track previous position for scoring if (enemyCar.lastY === undefined) { enemyCar.lastY = enemyCar.y; enemyCar.scored = false; } enemyCar.update(); // No smoke for enemy cars // Update shadow position if exists if (enemyCar._shadow) { enemyCar._shadow.x = enemyCar.x; enemyCar._shadow.y = enemyCar.y + 180; enemyCar._shadow.alpha = 0.18 + 0.07 * Math.abs(Math.sin(LK.ticks * 0.08)); } // Score when car passes the player if (!enemyCar.scored && enemyCar.lastY < playerCar.y && enemyCar.y >= playerCar.y) { score += 10; scoreTxt.setText('Score: ' + score); // Increase speed every 50 points (much more) if (score % 50 === 0) { // Increase speed for player car playerCar.speed += 3; // Increase speed for all existing enemy cars for (var j = 0; j < enemyCars.length; j++) { enemyCars[j].speed += 3; } // Mark that all future enemy cars should also be faster if (typeof globalEnemySpeedBonus === "undefined") { globalEnemySpeedBonus = 0; } globalEnemySpeedBonus += 3; // Play gas sound effect LK.getSound('gas', { volume: 0.7 }).play(); } // Subtle pop animation for score text scoreTxt.scale.set(1.2, 1.2); tween(scoreTxt.scale, { x: 1, y: 1 }, 200, { easing: "easeOutBack" }); enemyCar.scored = true; } // Update last position enemyCar.lastY = enemyCar.y; if (enemyCar.y > 2832) { // If the enemy car goes off the screen if (enemyCar._shadow) { // Fade out shadow before destroying (function (shadow) { tween(shadow, { alpha: 0 }, 200, { easing: "easeOutCubic", complete: function complete() { shadow.destroy(); } }); })(enemyCar._shadow); } enemyCar.destroy(); enemyCars.splice(i, 1); } if (playerCar.intersects(enemyCar)) { var _doShake = function doShake() { if (shakeIndex < shakeTimes) { playerCar.x = originalX + (shakeIndex % 2 === 0 ? shakeMagnitude : -shakeMagnitude); LK.setTimeout(function () { playerCar.x = originalX; shakeIndex++; _doShake(); }, shakeStep); } else { playerCar.x = originalX; // Update high score if needed if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('High Score: ' + highScore); // Subtle fade-in and pop effect for new high score highScoreTxt.alpha = 0.2; highScoreTxt.scale.set(1.3, 1.3); tween(highScoreTxt, { alpha: 1 }, 400, { easing: "easeOutCubic" }); tween(highScoreTxt.scale, { x: 1, y: 1 }, 300, { easing: "easeOutBack" }); } // Set the final score before game over LK.setScore(score); LK.showGameOver(); } }; // Subtle shake effect for player car originalX = playerCar.x; shakeTimes = 6; shakeMagnitude = 30; shakeDuration = 180; shakeStep = shakeDuration / shakeTimes; shakeIndex = 0; _doShake(); return { v: void 0 }; // Prevent double game over } }, enemyCar, originalX, shakeTimes, shakeMagnitude, shakeDuration, shakeStep, shakeIndex, _ret; for (var i = enemyCars.length - 1; i >= 0; i--) { _ret = _loop(); if (_ret) { return _ret.v; } } if (LK.ticks % 120 == 0) { // Spawn new enemy cars every 2 seconds to keep more space between them spawnEnemyCar(); } }; game.down = function (x, y, obj) { // 3 lanes: left (0-853), center (853-1195), right (1195-2048) if (x < 853) { playerCar.x = 512; // Left lane } else if (x < 1195) { playerCar.x = 1024; // Center lane } else { playerCar.x = 1536; // Right lane } }; game.up = function (x, y, obj) { // No action needed }; game.update = function () { // Move both road images downward to simulate motion road.y += roadScrollSpeed; road2.y += roadScrollSpeed; // If a road image moves off the bottom, move it above the other for seamless looping if (road.y > roadInitialY + roadImageHeight / 2) { road.y = road2.y - roadImageHeight; } if (road2.y > roadInitialY + roadImageHeight / 2) { road2.y = road.y - roadImageHeight; } // No gradual movement needed; handled instantly in game.down // Only update playerCar for horizontal movement, not forward movement playerCar.update(); if (typeof playerCarShadow !== "undefined" && playerCarShadow) { playerCarShadow.x = playerCar.x; playerCarShadow.y = playerCar.y + 180; playerCarShadow.alpha = 0.18 + 0.07 * Math.abs(Math.sin(LK.ticks * 0.08)); } // Create smoke particles behind player car if (LK.ticks % 5 == 0) { createSmoke(playerCar.x, playerCar.y, 2); } // Update and manage smoke particles for (var i = smokeParticles.length - 1; i >= 0; i--) { var isDestroyed = smokeParticles[i].update(); if (isDestroyed) { smokeParticles.splice(i, 1); } } // --- Powerup logic --- if (typeof powerups === "undefined") { powerups = []; } if (typeof playerShieldActive === "undefined") { playerShieldActive = false; playerShieldTimer = 0; } // Spawn powerups at intervals if (LK.ticks % 600 === 0) { // Every 10 seconds var which = Math.random() < 0.5 ? "speed" : "shield"; var laneXs = [512, 1024, 1536]; var px = laneXs[Math.floor(Math.random() * laneXs.length)]; var py = -100; var powerup; if (which === "speed") { powerup = new Powerup(); } else { powerup = new PowerupShield(); } powerup.x = px; powerup.y = py; powerups.push(powerup); game.addChild(powerup); } // Update powerups and check for collection for (var i = powerups.length - 1; i >= 0; i--) { var p = powerups[i]; var destroyed = p.update(); if (!destroyed && playerCar.intersects(p)) { // Powerup collected! if (p.type === "speed") { // Temporary speed boost playerCar.speed += 8; LK.setTimeout(function () { playerCar.speed -= 8; }, 3000); // Optional: flash effect LK.effects.flashObject(playerCar, 0x00bfff, 500); } else if (p.type === "shield") { playerShieldActive = true; playerShieldTimer = LK.ticks + 360; // 6 seconds at 60fps // Optional: flash effect LK.effects.flashObject(playerCar, 0xffd700, 500); } // Powerup pop/fade effect var pop = LK.getAsset(p.type === "speed" ? "powerupSpeed" : "powerupShield", { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 2.2, x: p.x, y: p.y, alpha: 1 }); game.addChild(pop); tween(pop.scale, { x: 2.7, y: 2.7 }, 350, { easing: "easeOutCubic" }); tween(pop, { alpha: 0 }, 350, { easing: "easeOutCubic", complete: function complete() { pop.destroy(); } }); p.destroy(); powerups.splice(i, 1); } else if (destroyed) { powerups.splice(i, 1); } } // Handle shield timer if (playerShieldActive && LK.ticks > playerShieldTimer) { playerShieldActive = false; // Shield lost pop/fade effect if (typeof playerShieldSprite !== "undefined" && playerShieldSprite) { var pop = LK.getAsset('powerupShield', { anchorX: 0.5, anchorY: 0.5, scaleX: playerShieldSprite.scale.x, scaleY: playerShieldSprite.scale.y, x: playerShieldSprite.x, y: playerShieldSprite.y, alpha: 0.5 }); game.addChild(pop); tween(pop.scale, { x: pop.scale.x * 1.4, y: pop.scale.y * 1.4 }, 350, { easing: "easeOutCubic" }); tween(pop, { alpha: 0 }, 350, { easing: "easeOutCubic", complete: function complete() { pop.destroy(); } }); } } // Show shield visual effect if shield is active if (playerShieldActive) { if (typeof playerShieldSprite === "undefined" || !playerShieldSprite) { playerShieldSprite = LK.getAsset('powerupShield', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 2.2, alpha: 0.5 }); playerShieldSprite.y = playerCar.y; playerShieldSprite.x = playerCar.x; game.addChild(playerShieldSprite); } else { playerShieldSprite.x = playerCar.x; playerShieldSprite.y = playerCar.y; playerShieldSprite.alpha = 0.5 + 0.2 * Math.sin(LK.ticks * 0.2); playerShieldSprite.scale.x = 2.2 + 0.1 * Math.sin(LK.ticks * 0.15); playerShieldSprite.scale.y = 2.2 + 0.1 * Math.sin(LK.ticks * 0.15); } } else if (typeof playerShieldSprite !== "undefined" && playerShieldSprite) { playerShieldSprite.destroy(); playerShieldSprite = null; } var _loop = function _loop() { enemyCar = enemyCars[i]; // Track previous position for scoring if (enemyCar.lastY === undefined) { enemyCar.lastY = enemyCar.y; enemyCar.scored = false; } enemyCar.update(); // No smoke for enemy cars // Score when car passes the player if (!enemyCar.scored && enemyCar.lastY < playerCar.y && enemyCar.y >= playerCar.y) { score += 10; scoreTxt.setText('Score: ' + score); // Increase speed every 50 points (much more) if (score % 50 === 0) { // Increase speed for player car playerCar.speed += 3; // Increase speed for all existing enemy cars for (var j = 0; j < enemyCars.length; j++) { enemyCars[j].speed += 3; } // Mark that all future enemy cars should also be faster if (typeof globalEnemySpeedBonus === "undefined") { globalEnemySpeedBonus = 0; } globalEnemySpeedBonus += 3; // Increase road scroll speed as well roadScrollSpeed += 3; // Play gas sound effect LK.getSound('gas', { volume: 0.7 }).play(); } // Subtle pop animation for score text scoreTxt.scale.set(1.2, 1.2); tween(scoreTxt.scale, { x: 1, y: 1 }, 200, { easing: "easeOutBack" }); enemyCar.scored = true; } // Update last position enemyCar.lastY = enemyCar.y; if (enemyCar.y > 2832) { // If the enemy car goes off the screen // Subtle pop/fade effect for enemy car destroyed by going off screen var pop = LK.getAsset('enemyCar', { anchorX: 0.5, anchorY: 0.5, scaleX: enemyCar.scale ? enemyCar.scale.x : 1, scaleY: enemyCar.scale ? enemyCar.scale.y : 1, x: enemyCar.x, y: enemyCar.y, alpha: 1 }); game.addChild(pop); tween(pop.scale, { x: pop.scale.x * 1.2, y: pop.scale.y * 1.2 }, 250, { easing: "easeOutCubic" }); tween(pop, { alpha: 0 }, 250, { easing: "easeOutCubic", complete: function complete() { pop.destroy(); } }); if (enemyCar._shadow) { (function (shadow) { tween(shadow, { alpha: 0 }, 200, { easing: "easeOutCubic", complete: function complete() { shadow.destroy(); } }); })(enemyCar._shadow); } enemyCar.destroy(); enemyCars.splice(i, 1); } if (playerCar.intersects(enemyCar)) { if (playerShieldActive) { // Destroy enemy car and deactivate shield // Subtle pop/fade effect for enemy car destroyed by shield var pop = LK.getAsset('enemyCar', { anchorX: 0.5, anchorY: 0.5, scaleX: enemyCar.scale ? enemyCar.scale.x : 1, scaleY: enemyCar.scale ? enemyCar.scale.y : 1, x: enemyCar.x, y: enemyCar.y, alpha: 1 }); game.addChild(pop); tween(pop.scale, { x: pop.scale.x * 1.5, y: pop.scale.y * 1.5 }, 350, { easing: "easeOutCubic" }); tween(pop, { alpha: 0 }, 350, { easing: "easeOutCubic", complete: function complete() { pop.destroy(); } }); if (enemyCar._shadow) { (function (shadow) { tween(shadow, { alpha: 0 }, 200, { easing: "easeOutCubic", complete: function complete() { shadow.destroy(); } }); })(enemyCar._shadow); } enemyCar.destroy(); enemyCars.splice(i, 1); playerShieldActive = false; LK.effects.flashObject(playerCar, 0xffd700, 400); // Shield block pop/fade effect if (typeof playerShieldSprite !== "undefined" && playerShieldSprite) { var pop = LK.getAsset('powerupShield', { anchorX: 0.5, anchorY: 0.5, scaleX: playerShieldSprite.scale.x, scaleY: playerShieldSprite.scale.y, x: playerShieldSprite.x, y: playerShieldSprite.y, alpha: 0.5 }); game.addChild(pop); tween(pop.scale, { x: pop.scale.x * 1.4, y: pop.scale.y * 1.4 }, 350, { easing: "easeOutCubic" }); tween(pop, { alpha: 0 }, 350, { easing: "easeOutCubic", complete: function complete() { pop.destroy(); } }); } return; } var _doShake = function doShake() { if (shakeIndex < shakeTimes) { playerCar.x = originalX + (shakeIndex % 2 === 0 ? shakeMagnitude : -shakeMagnitude); LK.setTimeout(function () { playerCar.x = originalX; shakeIndex++; _doShake(); }, shakeStep); } else { playerCar.x = originalX; // Update high score if needed if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('High Score: ' + highScore); // Subtle fade-in and pop effect for new high score highScoreTxt.alpha = 0.2; highScoreTxt.scale.set(1.3, 1.3); tween(highScoreTxt, { alpha: 1 }, 400, { easing: "easeOutCubic" }); tween(highScoreTxt.scale, { x: 1, y: 1 }, 300, { easing: "easeOutBack" }); } // Set the final score before game over LK.setScore(score); // Reset all speed variables to initial values on game over playerCar.speed = 8; roadScrollSpeed = 16; globalEnemySpeedBonus = 0; for (var j = 0; j < enemyCars.length; j++) { enemyCars[j].speed = 8; } // Player car destroyed pop/fade effect var pop = LK.getAsset('playerCar', { anchorX: 0.5, anchorY: 0.5, scaleX: playerCar.scale.x, scaleY: playerCar.scale.y, x: playerCar.x, y: playerCar.y, alpha: 1 }); game.addChild(pop); tween(pop.scale, { x: pop.scale.x * 1.5, y: pop.scale.y * 1.5 }, 350, { easing: "easeOutCubic" }); tween(pop, { alpha: 0 }, 350, { easing: "easeOutCubic", complete: function complete() { pop.destroy(); } }); LK.showGameOver(); } }; // Subtle shake effect for player car originalX = playerCar.x; shakeTimes = 6; shakeMagnitude = 30; shakeDuration = 180; shakeStep = shakeDuration / shakeTimes; shakeIndex = 0; _doShake(); return { v: void 0 }; // Prevent double game over } }, enemyCar, originalX, shakeTimes, shakeMagnitude, shakeDuration, shakeStep, shakeIndex, _ret; for (var i = enemyCars.length - 1; i >= 0; i--) { _ret = _loop(); if (_ret) { return _ret.v; } } if (LK.ticks % 120 == 0) { // Spawn new enemy cars every 2 seconds to keep more space between them spawnEnemyCar(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
level: 1,
bestTime: 0
});
/****
* Classes
****/
var Car = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.update = function () {
// Player car does not move forward automatically anymore
// Only horizontal movement is allowed, so no change to self.y here
if (self.x < 0) {
self.x = 2048;
} else if (self.x > 2048) {
self.x = 0;
}
};
return self;
});
var EnemyCar = Container.expand(function () {
var self = Container.call(this);
// List of possible enemy car asset ids for variety
var enemyCarAssetIds = ['enemyCar', 'enemyCar2', 'enemyCar3', 'enemyCar4'];
// Pick a random car asset for this enemy
var chosenAssetId = enemyCarAssetIds[Math.floor(Math.random() * enemyCarAssetIds.length)];
var enemyCarGraphics = self.attachAsset(chosenAssetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.update = function () {
// Enemy cars move down the screen (already correct)
self.y += self.speed;
if (self.x < 0) {
self.x = 2048;
} else if (self.x > 2048) {
self.x = 0;
}
};
return self;
});
// Powerup: Speed Boost
var Powerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerupSpeed', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.speed = 10;
self.type = "speed";
self.update = function () {
self.y += self.speed;
// Remove if off screen
if (self.y > 2900) {
self.destroy();
return true;
}
return false;
};
return self;
});
// Powerup: Shield
var PowerupShield = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerupShield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.speed = 10;
self.type = "shield";
self.update = function () {
self.y += self.speed;
// Remove if off screen
if (self.y > 2900) {
self.destroy();
return true;
}
return false;
};
return self;
});
var Smoke = Container.expand(function () {
var self = Container.call(this);
var smokeGraphics = self.attachAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
// Initialize with random properties for varied effect
self.speedX = (Math.random() - 0.5) * 2; // Random horizontal drift
self.speedY = 1 + Math.random() * 2; // Move backward speed
self.initialDistance = 0; // Track distance traveled
self.maxAlpha = 0.8 + Math.random() * 0.2; // Maximum density at start
self.alpha = self.maxAlpha; // Start with maximum opacity
self.fadingDistance = 40 + Math.random() * 40; // Distance at which smoke starts to fade
self.growSpeed = 0.03 + Math.random() * 0.03; // Expansion rate
// Update smoke particle behavior
self.update = function () {
self.x += self.speedX;
self.y += self.speedY; // Move downward (backward from car perspective)
// Update distance traveled
self.initialDistance += self.speedY;
// Start dense and become less dense as it moves backward
self.alpha = Math.max(0, self.maxAlpha * (1 - self.initialDistance / (self.fadingDistance * 2)));
self.scale.x += self.growSpeed;
self.scale.y += self.growSpeed;
// Remove smoke when it becomes too transparent
if (self.alpha <= 0) {
self.destroy();
return true; // Signal that this smoke has been destroyed
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Shield powerup asset
// Speed powerup asset
// Create score text
// Additional car images for variety
var score = 0;
var scoreTxt = new Text2('Score: 0', {
size: 100,
fill: 0xFFFFFF
});
// Add smoke effects
var smokeParticles = [];
function createSmoke(x, y, amount) {
for (var i = 0; i < amount; i++) {
var smoke = new Smoke();
// Alternate between left and right sides of the car
var side = i % 2 === 0 ? -1 : 1;
// Position smoke on the left or right side of the car
smoke.x = x + side * 100 + (Math.random() - 0.5) * 20; // Offset from car sides
smoke.y = y + 200; // Position behind car (below car in screen coordinates)
smokeParticles.push(smoke);
game.addChild(smoke);
}
}
scoreTxt.anchor.set(0.5, 0);
scoreTxt.alpha = 0;
LK.gui.top.addChild(scoreTxt);
tween(scoreTxt, {
alpha: 1
}, 800, {
easing: "easeOutCubic"
});
var road = LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
road.alpha = 0;
road.scale.set(1.05, 1.05);
game.addChild(road);
// Create a second road image for seamless looping
var road2 = LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366 - 2732 // Place directly above the first road
});
road2.alpha = 0;
road2.scale.set(1.05, 1.05);
game.addChild(road2);
tween(road, {
alpha: 1
}, 1000, {
easing: "easeOutCubic"
});
tween(road2, {
alpha: 1
}, 1000, {
easing: "easeOutCubic"
});
tween(road.scale, {
x: 1,
y: 1
}, 900, {
easing: "easeOutCubic"
});
tween(road2.scale, {
x: 1,
y: 1
}, 900, {
easing: "easeOutCubic"
});
// Add road movement variables
var roadScrollSpeed = 16;
var roadInitialY = 2366;
var roadImageHeight = 2732;
// Play background music with fade in
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 0.8,
duration: 1000
}
});
// Display high score
var highScore = storage.highScore || 0;
var highScoreTxt = new Text2('High Score: ' + highScore, {
size: 80,
fill: 0x00a000,
// Lighter green color
fontWeight: 'bold' // Make the text bold
});
highScoreTxt.anchor.set(0.5, 0);
highScoreTxt.y = 120;
highScoreTxt.alpha = 0;
LK.gui.top.addChild(highScoreTxt);
tween(highScoreTxt, {
alpha: 1
}, 1000, {
easing: "easeOutCubic"
});
// Add shadow under player car
var playerCarShadow = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 0.35,
x: 0,
y: 0,
alpha: 0.25,
tint: 0x000000
});
game.addChild(playerCarShadow);
var playerCar = game.addChild(new Car());
// Place player in left, center, or right lane randomly
var laneXs = [512, 1024, 1536]; // 512 = left, 1024 = center, 1536 = right
playerCar.x = laneXs[Math.floor(Math.random() * laneXs.length)];
playerCar.y = 2300; // Start near the bottom, adjusted for bigger car
// Fade in the player car for a polished entrance
playerCar.alpha = 0;
playerCar.scale.set(1.2, 1.2);
tween(playerCar, {
alpha: 1
}, 600, {
easing: "easeOutCubic"
});
tween(playerCar.scale, {
x: 1,
y: 1
}, 400, {
easing: "easeOutBack"
});
var enemyCars = [];
function spawnEnemyCar() {
// Only allow enemy cars to spawn in the same vertical lines as the player (left, center, or right lane)
// Lane Xs: left, center, right
var laneXs = [512, 1024, 1536];
// Car height for vertical gap - increased multiplier for more space
var carHeight = 660;
var verticalGapMultiplier = 3.5;
// Find the highest Y of any existing enemy car, or use -330 if none
var topY = -330;
for (var i = 0; i < enemyCars.length; i++) {
if (enemyCars[i].y < topY) {
topY = enemyCars[i].y;
}
}
// Patterns: only left, only center, only right - never more than one at a time
// to ensure player always has a path to pass through
var patterns = [
// Only left lane
[{
x: laneXs[0]
}],
// Only center lane
[{
x: laneXs[1]
}],
// Only right lane
[{
x: laneXs[2]
}]];
// Keep track of which pattern to use next
if (typeof spawnEnemyCar.patternIndex === "undefined") {
spawnEnemyCar.patternIndex = 0;
}
// Shuffle patterns order every cycle for variety
if (typeof spawnEnemyCar.patternOrder === "undefined" || spawnEnemyCar.patternOrder.length === 0) {
var order = [];
for (var i = 0; i < patterns.length; i++) {
order.push(i);
}
// Fisher-Yates shuffle
for (var i = order.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = order[i];
order[i] = order[j];
order[j] = temp;
}
spawnEnemyCar.patternOrder = order;
spawnEnemyCar.patternIndex = 0;
}
var patternIdx = spawnEnemyCar.patternOrder[spawnEnemyCar.patternIndex];
var pattern = patterns[patternIdx];
spawnEnemyCar.patternIndex++;
if (spawnEnemyCar.patternIndex >= spawnEnemyCar.patternOrder.length) {
spawnEnemyCar.patternOrder = [];
}
// Place new pattern below the last one, with the specified gap
var spawnY = topY;
for (var i = 0; i < pattern.length; i++) {
var carDef = pattern[i];
var enemyCar = new EnemyCar();
// Apply global speed bonus if any
if (typeof globalEnemySpeedBonus !== "undefined") {
enemyCar.speed += globalEnemySpeedBonus;
}
enemyCar.x = carDef.x;
enemyCar.y = spawnY;
// --- Add shadow under enemy car for polish ---
var enemyCarShadow = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.1,
scaleY: 0.32,
x: enemyCar.x,
y: enemyCar.y + 180,
alpha: 0.18,
tint: 0x000000
});
enemyCar._shadow = enemyCarShadow;
game.addChild(enemyCarShadow);
enemyCars.push(enemyCar);
game.addChild(enemyCar);
spawnY -= carHeight * verticalGapMultiplier;
}
}
game.update = function () {
// Move both road images downward to simulate motion
road.y += roadScrollSpeed;
road2.y += roadScrollSpeed;
// If a road image moves off the bottom, move it above the other for seamless looping
if (road.y > roadInitialY + roadImageHeight / 2) {
road.y = road2.y - roadImageHeight;
}
if (road2.y > roadInitialY + roadImageHeight / 2) {
road2.y = road.y - roadImageHeight;
}
// No gradual movement needed; handled instantly in game.down
// Only update playerCar for horizontal movement, not forward movement
playerCar.update();
// Create smoke particles behind player car
if (LK.ticks % 5 == 0) {
createSmoke(playerCar.x, playerCar.y, 2);
}
// Update and manage smoke particles
for (var i = smokeParticles.length - 1; i >= 0; i--) {
var isDestroyed = smokeParticles[i].update();
if (isDestroyed) {
smokeParticles.splice(i, 1);
}
}
var _loop = function _loop() {
enemyCar = enemyCars[i]; // Track previous position for scoring
if (enemyCar.lastY === undefined) {
enemyCar.lastY = enemyCar.y;
enemyCar.scored = false;
}
enemyCar.update();
// No smoke for enemy cars
// Update shadow position if exists
if (enemyCar._shadow) {
enemyCar._shadow.x = enemyCar.x;
enemyCar._shadow.y = enemyCar.y + 180;
enemyCar._shadow.alpha = 0.18 + 0.07 * Math.abs(Math.sin(LK.ticks * 0.08));
}
// Score when car passes the player
if (!enemyCar.scored && enemyCar.lastY < playerCar.y && enemyCar.y >= playerCar.y) {
score += 10;
scoreTxt.setText('Score: ' + score);
// Increase speed every 50 points (much more)
if (score % 50 === 0) {
// Increase speed for player car
playerCar.speed += 3;
// Increase speed for all existing enemy cars
for (var j = 0; j < enemyCars.length; j++) {
enemyCars[j].speed += 3;
}
// Mark that all future enemy cars should also be faster
if (typeof globalEnemySpeedBonus === "undefined") {
globalEnemySpeedBonus = 0;
}
globalEnemySpeedBonus += 3;
// Play gas sound effect
LK.getSound('gas', {
volume: 0.7
}).play();
}
// Subtle pop animation for score text
scoreTxt.scale.set(1.2, 1.2);
tween(scoreTxt.scale, {
x: 1,
y: 1
}, 200, {
easing: "easeOutBack"
});
enemyCar.scored = true;
}
// Update last position
enemyCar.lastY = enemyCar.y;
if (enemyCar.y > 2832) {
// If the enemy car goes off the screen
if (enemyCar._shadow) {
// Fade out shadow before destroying
(function (shadow) {
tween(shadow, {
alpha: 0
}, 200, {
easing: "easeOutCubic",
complete: function complete() {
shadow.destroy();
}
});
})(enemyCar._shadow);
}
enemyCar.destroy();
enemyCars.splice(i, 1);
}
if (playerCar.intersects(enemyCar)) {
var _doShake = function doShake() {
if (shakeIndex < shakeTimes) {
playerCar.x = originalX + (shakeIndex % 2 === 0 ? shakeMagnitude : -shakeMagnitude);
LK.setTimeout(function () {
playerCar.x = originalX;
shakeIndex++;
_doShake();
}, shakeStep);
} else {
playerCar.x = originalX;
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('High Score: ' + highScore);
// Subtle fade-in and pop effect for new high score
highScoreTxt.alpha = 0.2;
highScoreTxt.scale.set(1.3, 1.3);
tween(highScoreTxt, {
alpha: 1
}, 400, {
easing: "easeOutCubic"
});
tween(highScoreTxt.scale, {
x: 1,
y: 1
}, 300, {
easing: "easeOutBack"
});
}
// Set the final score before game over
LK.setScore(score);
LK.showGameOver();
}
};
// Subtle shake effect for player car
originalX = playerCar.x;
shakeTimes = 6;
shakeMagnitude = 30;
shakeDuration = 180;
shakeStep = shakeDuration / shakeTimes;
shakeIndex = 0;
_doShake();
return {
v: void 0
}; // Prevent double game over
}
},
enemyCar,
originalX,
shakeTimes,
shakeMagnitude,
shakeDuration,
shakeStep,
shakeIndex,
_ret;
for (var i = enemyCars.length - 1; i >= 0; i--) {
_ret = _loop();
if (_ret) {
return _ret.v;
}
}
if (LK.ticks % 120 == 0) {
// Spawn new enemy cars every 2 seconds to keep more space between them
spawnEnemyCar();
}
};
game.down = function (x, y, obj) {
// 3 lanes: left (0-853), center (853-1195), right (1195-2048)
if (x < 853) {
playerCar.x = 512; // Left lane
} else if (x < 1195) {
playerCar.x = 1024; // Center lane
} else {
playerCar.x = 1536; // Right lane
}
};
game.up = function (x, y, obj) {
// No action needed
};
game.update = function () {
// Move both road images downward to simulate motion
road.y += roadScrollSpeed;
road2.y += roadScrollSpeed;
// If a road image moves off the bottom, move it above the other for seamless looping
if (road.y > roadInitialY + roadImageHeight / 2) {
road.y = road2.y - roadImageHeight;
}
if (road2.y > roadInitialY + roadImageHeight / 2) {
road2.y = road.y - roadImageHeight;
}
// No gradual movement needed; handled instantly in game.down
// Only update playerCar for horizontal movement, not forward movement
playerCar.update();
if (typeof playerCarShadow !== "undefined" && playerCarShadow) {
playerCarShadow.x = playerCar.x;
playerCarShadow.y = playerCar.y + 180;
playerCarShadow.alpha = 0.18 + 0.07 * Math.abs(Math.sin(LK.ticks * 0.08));
}
// Create smoke particles behind player car
if (LK.ticks % 5 == 0) {
createSmoke(playerCar.x, playerCar.y, 2);
}
// Update and manage smoke particles
for (var i = smokeParticles.length - 1; i >= 0; i--) {
var isDestroyed = smokeParticles[i].update();
if (isDestroyed) {
smokeParticles.splice(i, 1);
}
}
// --- Powerup logic ---
if (typeof powerups === "undefined") {
powerups = [];
}
if (typeof playerShieldActive === "undefined") {
playerShieldActive = false;
playerShieldTimer = 0;
}
// Spawn powerups at intervals
if (LK.ticks % 600 === 0) {
// Every 10 seconds
var which = Math.random() < 0.5 ? "speed" : "shield";
var laneXs = [512, 1024, 1536];
var px = laneXs[Math.floor(Math.random() * laneXs.length)];
var py = -100;
var powerup;
if (which === "speed") {
powerup = new Powerup();
} else {
powerup = new PowerupShield();
}
powerup.x = px;
powerup.y = py;
powerups.push(powerup);
game.addChild(powerup);
}
// Update powerups and check for collection
for (var i = powerups.length - 1; i >= 0; i--) {
var p = powerups[i];
var destroyed = p.update();
if (!destroyed && playerCar.intersects(p)) {
// Powerup collected!
if (p.type === "speed") {
// Temporary speed boost
playerCar.speed += 8;
LK.setTimeout(function () {
playerCar.speed -= 8;
}, 3000);
// Optional: flash effect
LK.effects.flashObject(playerCar, 0x00bfff, 500);
} else if (p.type === "shield") {
playerShieldActive = true;
playerShieldTimer = LK.ticks + 360; // 6 seconds at 60fps
// Optional: flash effect
LK.effects.flashObject(playerCar, 0xffd700, 500);
}
// Powerup pop/fade effect
var pop = LK.getAsset(p.type === "speed" ? "powerupSpeed" : "powerupShield", {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 2.2,
x: p.x,
y: p.y,
alpha: 1
});
game.addChild(pop);
tween(pop.scale, {
x: 2.7,
y: 2.7
}, 350, {
easing: "easeOutCubic"
});
tween(pop, {
alpha: 0
}, 350, {
easing: "easeOutCubic",
complete: function complete() {
pop.destroy();
}
});
p.destroy();
powerups.splice(i, 1);
} else if (destroyed) {
powerups.splice(i, 1);
}
}
// Handle shield timer
if (playerShieldActive && LK.ticks > playerShieldTimer) {
playerShieldActive = false;
// Shield lost pop/fade effect
if (typeof playerShieldSprite !== "undefined" && playerShieldSprite) {
var pop = LK.getAsset('powerupShield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: playerShieldSprite.scale.x,
scaleY: playerShieldSprite.scale.y,
x: playerShieldSprite.x,
y: playerShieldSprite.y,
alpha: 0.5
});
game.addChild(pop);
tween(pop.scale, {
x: pop.scale.x * 1.4,
y: pop.scale.y * 1.4
}, 350, {
easing: "easeOutCubic"
});
tween(pop, {
alpha: 0
}, 350, {
easing: "easeOutCubic",
complete: function complete() {
pop.destroy();
}
});
}
}
// Show shield visual effect if shield is active
if (playerShieldActive) {
if (typeof playerShieldSprite === "undefined" || !playerShieldSprite) {
playerShieldSprite = LK.getAsset('powerupShield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 2.2,
alpha: 0.5
});
playerShieldSprite.y = playerCar.y;
playerShieldSprite.x = playerCar.x;
game.addChild(playerShieldSprite);
} else {
playerShieldSprite.x = playerCar.x;
playerShieldSprite.y = playerCar.y;
playerShieldSprite.alpha = 0.5 + 0.2 * Math.sin(LK.ticks * 0.2);
playerShieldSprite.scale.x = 2.2 + 0.1 * Math.sin(LK.ticks * 0.15);
playerShieldSprite.scale.y = 2.2 + 0.1 * Math.sin(LK.ticks * 0.15);
}
} else if (typeof playerShieldSprite !== "undefined" && playerShieldSprite) {
playerShieldSprite.destroy();
playerShieldSprite = null;
}
var _loop = function _loop() {
enemyCar = enemyCars[i]; // Track previous position for scoring
if (enemyCar.lastY === undefined) {
enemyCar.lastY = enemyCar.y;
enemyCar.scored = false;
}
enemyCar.update();
// No smoke for enemy cars
// Score when car passes the player
if (!enemyCar.scored && enemyCar.lastY < playerCar.y && enemyCar.y >= playerCar.y) {
score += 10;
scoreTxt.setText('Score: ' + score);
// Increase speed every 50 points (much more)
if (score % 50 === 0) {
// Increase speed for player car
playerCar.speed += 3;
// Increase speed for all existing enemy cars
for (var j = 0; j < enemyCars.length; j++) {
enemyCars[j].speed += 3;
}
// Mark that all future enemy cars should also be faster
if (typeof globalEnemySpeedBonus === "undefined") {
globalEnemySpeedBonus = 0;
}
globalEnemySpeedBonus += 3;
// Increase road scroll speed as well
roadScrollSpeed += 3;
// Play gas sound effect
LK.getSound('gas', {
volume: 0.7
}).play();
}
// Subtle pop animation for score text
scoreTxt.scale.set(1.2, 1.2);
tween(scoreTxt.scale, {
x: 1,
y: 1
}, 200, {
easing: "easeOutBack"
});
enemyCar.scored = true;
}
// Update last position
enemyCar.lastY = enemyCar.y;
if (enemyCar.y > 2832) {
// If the enemy car goes off the screen
// Subtle pop/fade effect for enemy car destroyed by going off screen
var pop = LK.getAsset('enemyCar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: enemyCar.scale ? enemyCar.scale.x : 1,
scaleY: enemyCar.scale ? enemyCar.scale.y : 1,
x: enemyCar.x,
y: enemyCar.y,
alpha: 1
});
game.addChild(pop);
tween(pop.scale, {
x: pop.scale.x * 1.2,
y: pop.scale.y * 1.2
}, 250, {
easing: "easeOutCubic"
});
tween(pop, {
alpha: 0
}, 250, {
easing: "easeOutCubic",
complete: function complete() {
pop.destroy();
}
});
if (enemyCar._shadow) {
(function (shadow) {
tween(shadow, {
alpha: 0
}, 200, {
easing: "easeOutCubic",
complete: function complete() {
shadow.destroy();
}
});
})(enemyCar._shadow);
}
enemyCar.destroy();
enemyCars.splice(i, 1);
}
if (playerCar.intersects(enemyCar)) {
if (playerShieldActive) {
// Destroy enemy car and deactivate shield
// Subtle pop/fade effect for enemy car destroyed by shield
var pop = LK.getAsset('enemyCar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: enemyCar.scale ? enemyCar.scale.x : 1,
scaleY: enemyCar.scale ? enemyCar.scale.y : 1,
x: enemyCar.x,
y: enemyCar.y,
alpha: 1
});
game.addChild(pop);
tween(pop.scale, {
x: pop.scale.x * 1.5,
y: pop.scale.y * 1.5
}, 350, {
easing: "easeOutCubic"
});
tween(pop, {
alpha: 0
}, 350, {
easing: "easeOutCubic",
complete: function complete() {
pop.destroy();
}
});
if (enemyCar._shadow) {
(function (shadow) {
tween(shadow, {
alpha: 0
}, 200, {
easing: "easeOutCubic",
complete: function complete() {
shadow.destroy();
}
});
})(enemyCar._shadow);
}
enemyCar.destroy();
enemyCars.splice(i, 1);
playerShieldActive = false;
LK.effects.flashObject(playerCar, 0xffd700, 400);
// Shield block pop/fade effect
if (typeof playerShieldSprite !== "undefined" && playerShieldSprite) {
var pop = LK.getAsset('powerupShield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: playerShieldSprite.scale.x,
scaleY: playerShieldSprite.scale.y,
x: playerShieldSprite.x,
y: playerShieldSprite.y,
alpha: 0.5
});
game.addChild(pop);
tween(pop.scale, {
x: pop.scale.x * 1.4,
y: pop.scale.y * 1.4
}, 350, {
easing: "easeOutCubic"
});
tween(pop, {
alpha: 0
}, 350, {
easing: "easeOutCubic",
complete: function complete() {
pop.destroy();
}
});
}
return;
}
var _doShake = function doShake() {
if (shakeIndex < shakeTimes) {
playerCar.x = originalX + (shakeIndex % 2 === 0 ? shakeMagnitude : -shakeMagnitude);
LK.setTimeout(function () {
playerCar.x = originalX;
shakeIndex++;
_doShake();
}, shakeStep);
} else {
playerCar.x = originalX;
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('High Score: ' + highScore);
// Subtle fade-in and pop effect for new high score
highScoreTxt.alpha = 0.2;
highScoreTxt.scale.set(1.3, 1.3);
tween(highScoreTxt, {
alpha: 1
}, 400, {
easing: "easeOutCubic"
});
tween(highScoreTxt.scale, {
x: 1,
y: 1
}, 300, {
easing: "easeOutBack"
});
}
// Set the final score before game over
LK.setScore(score);
// Reset all speed variables to initial values on game over
playerCar.speed = 8;
roadScrollSpeed = 16;
globalEnemySpeedBonus = 0;
for (var j = 0; j < enemyCars.length; j++) {
enemyCars[j].speed = 8;
}
// Player car destroyed pop/fade effect
var pop = LK.getAsset('playerCar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: playerCar.scale.x,
scaleY: playerCar.scale.y,
x: playerCar.x,
y: playerCar.y,
alpha: 1
});
game.addChild(pop);
tween(pop.scale, {
x: pop.scale.x * 1.5,
y: pop.scale.y * 1.5
}, 350, {
easing: "easeOutCubic"
});
tween(pop, {
alpha: 0
}, 350, {
easing: "easeOutCubic",
complete: function complete() {
pop.destroy();
}
});
LK.showGameOver();
}
};
// Subtle shake effect for player car
originalX = playerCar.x;
shakeTimes = 6;
shakeMagnitude = 30;
shakeDuration = 180;
shakeStep = shakeDuration / shakeTimes;
shakeIndex = 0;
_doShake();
return {
v: void 0
}; // Prevent double game over
}
},
enemyCar,
originalX,
shakeTimes,
shakeMagnitude,
shakeDuration,
shakeStep,
shakeIndex,
_ret;
for (var i = enemyCars.length - 1; i >= 0; i--) {
_ret = _loop();
if (_ret) {
return _ret.v;
}
}
if (LK.ticks % 120 == 0) {
// Spawn new enemy cars every 2 seconds to keep more space between them
spawnEnemyCar();
}
};