Code edit (8 edits merged)
Please save this source code
User prompt
can you determine why some times in level 2 only 1 asset is used for the obstacle instead of 3 different ?
Code edit (3 edits merged)
Please save this source code
User prompt
update CoinAnimation to use the same asset as Coin for currentLevel
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: level is not defined' in or related to this line: 'if (level === 1) {' Line Number: 446
User prompt
Make KillerManager.killerDelay 12000 for level 1; 10000 at level 2 and 8000 at level 3
Code edit (1 edits merged)
Please save this source code
User prompt
that's too much, reduce a bit
User prompt
spawn obstacles a bit more frequently
Code edit (2 edits merged)
Please save this source code
User prompt
don't update KillerManager if !isGameStarted
Code edit (1 edits merged)
Please save this source code
User prompt
when detecting a move above threshold, ignore next moves until current move ends
Code edit (1 edits merged)
Please save this source code
User prompt
Currently player move from one side of the road to the other : fix that by only move to the next postiion
User prompt
only move when mouse/finger is down
User prompt
add a treshold in game.move
Code edit (1 edits merged)
Please save this source code
User prompt
Add game.move() event handler
Code edit (11 edits merged)
Please save this source code
User prompt
make user swipe reaction time quicker without making player move faster
User prompt
make swipe react faster
Code edit (2 edits merged)
Please save this source code
User prompt
when killed, do LK.setScore(score); and call Gameover after 3 sec
/**** * Classes ****/ var Background = Container.expand(function () { var self = Container.call(this); var backgroundGraphics1 = self.attachAsset('background_1', { anchorX: 0.5, anchorY: 0.5, visible: true }); var backgroundGraphics2 = self.attachAsset('background_2', { anchorX: 0.5, anchorY: 0.5, visible: false }); var backgroundGraphics3 = self.attachAsset('background_3', { anchorX: 0.5, anchorY: 0.5, visible: false }); self.updateForLevel = function (level) { backgroundGraphics1.visible = level === 1; backgroundGraphics2.visible = level === 2; backgroundGraphics3.visible = level === 3; }; }); // Assets will be automatically created and loaded during gameplay // Coin class var Coin = Container.expand(function (index) { var self = Container.call(this); self.index = index; var coinGraphics = self.attachAsset('coin1', { anchorX: 0.5, anchorY: 0.5 }); var coinGraphics2 = self.attachAsset('coin2', { //'dollarsBundle' anchorX: 0.5, anchorY: 0.5, visible: false }); var coinGraphics3 = self.attachAsset('dollarsBundle', { //'dollarsBundle' anchorX: 0.5, anchorY: 0.5, visible: false }); var speed = 5; var startY = roadTop + 50; var endY = startY + roadHeight; var leftStartX = 1024 - 100; var leftEndX = 1024 - 650; var rightStartX = 1024 + 100; var rightEndX = 1024 + 650; var startSize = 2; var endSize = 140; coinGraphics.width = startSize; coinGraphics.height = startSize; coinGraphics2.width = startSize; coinGraphics2.height = startSize; coinGraphics3.width = startSize; coinGraphics3.height = startSize; self.pathIndex = 0; self.update = function () { // Road should animate even if the game hasn't started if (!isPlaying || isKilled) { return; } ; obstacleManager.updateObstacles(); self.progress = Math.max(0, self.y - startY) / (endY - startY); // Update progress property coinGraphics.width = startSize + (endSize - startSize) * self.progress; coinGraphics.height = startSize + (endSize - startSize) * self.progress; coinGraphics2.width = startSize + (endSize - startSize) * self.progress; coinGraphics2.height = startSize + (endSize - startSize) * self.progress; coinGraphics3.width = startSize + (endSize - startSize) * self.progress; coinGraphics3.height = startSize + (endSize - startSize) * self.progress; var newSpeed = currentSpeed; // + 10 * self.progress; var tempSpeed = currentSpeed * 0.05 + currentSpeed * (self.progress * 3); newSpeed = tempSpeed; self.y += newSpeed; // Move innerLineLeft x progressively to innerLeftLineEndX if (self.pathIndex == 0 && self.x != leftEndX) { self.x = leftStartX + (leftEndX - leftStartX) * self.progress; } if (self.pathIndex == 2 && self.x != rightEndX) { self.x = rightStartX + (rightEndX - rightStartX) * self.progress; } if (self.y > endY + endSize / 2) { self.reset(); } // Check for collision with player if (!player.isJumping && self.y > 2500 && self.y < 2732 && player.shadow.intersects(self)) { LK.getSound('coin_1').play(); updateScore(false); // coinsCollected increment moved to increaseScore function LK.effects.flashObject(player, 0x00ff00, 500); // Flash green for 0.5 seconds self.reset(); // Increase speed every 3 coins collected /* if (coinsCollected % nextCoinTypeThreshold === 0 && currentSpeed < maxSpeed) { currentSpeed += 3; // Increase speed by 3 } */ } }; self.reset = function () { self.y = startY; self.progress = 0; // Initialize progress property coinGraphics.width = startSize; coinGraphics.height = startSize; coinGraphics2.width = startSize; coinGraphics2.height = startSize; coinGraphics3.width = startSize; coinGraphics3.height = startSize; self.pathIndex = Math.floor(Math.random() * 3); if (self.pathIndex === 0) { self.x = leftStartX; } else if (self.pathIndex === 2) { self.x = rightStartX; } else { self.x = 1024; } }; self.updateForLevel = function (level) { coinGraphics.visible = level === 1; coinGraphics2.visible = level === 2; coinGraphics3.visible = level === 3; }; }); // CoinAnimation class var CoinAnimation = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('coin1', { anchorX: 0.5, anchorY: 0.5, visible: currentCoinType == 0 }); var coinGraphics2 = self.attachAsset('coin2', { anchorX: 0.5, anchorY: 0.5, visible: currentCoinType == 1 }); // Initialize velocity and gravity self.vx = (Math.random() < 0.5 ? -1 : 1) * 5; // Random horizontal velocity self.vy = -15; // Initial vertical velocity self.gravity = 0.5; // Gravity effect self.update = function () { self.vy += self.gravity; // Apply gravity to vertical velocity self.x += self.vx; // Update horizontal position self.y += self.vy; // Update vertical position self.alpha -= 0.0035; // Fade out the coin if (currentCoinType == 0) { coinGraphics.alpha = 1; coinGraphics2.alpha = 0; } else if (currentCoinType == 1) { coinGraphics.alpha = 0; coinGraphics2.alpha = 1; } if (self.alpha <= 0) { self.destroy(); // Remove the coin when it becomes invisible } }; }); // Decoration class var Decoration = Container.expand(function (decoIndex) { var self = Container.call(this); self.index = decoIndex; var assets = ['decoration_1_1', 'decoration_1_2', 'decoration_1_3', 'decoration_2_1', 'decoration_2_2', 'decoration_2_3', 'decoration_3_1', 'decoration_3_2', 'decoration_3_3']; self.assets = assets.map(function (assetId) { return self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, visible: false }); }); self.ready = false; var speed = 5; var startY = roadTop + 50; var endY = startY + roadHeight; var xOffset = 1024; var baseLeftStartX = 780; var rand = Math.random(); self.leftStartX = baseLeftStartX; // - rand * xOffset; self.leftEndX = self.leftStartX - xOffset * (1.5 + rand); var baseRightStartX = 1280; self.rightStartX = baseRightStartX; // + rand * xOffset / 2; self.rightEndX = self.rightStartX + xOffset * (1.5 + rand); self.assetWidthRatios = [100 / 300, 1, 1, 1, 1, 1, 1, 1]; self.endSizes = [600, 600, 600, 600, 600, 600, 600, 600, 600]; var startSize = 1; self.assetIndex = Math.floor(Math.random() * 3) + (currentLevel - 1) * 3; mainGraphics = self.assets[self.assetIndex]; mainGraphics.width = startSize; mainGraphics.height = startSize; self.pathIndex = 0; self.update = function () { if (isKilled) { return; } var newTint = intensityHalf << 16 | intensityHalf << 8 | intensityHalf; //mainGraphics.tint = newTint; var tempSpeed = currentSpeed * 0.055 + currentSpeed * (self.progress * 3); var newSpeed = currentSpeed; // + 10 * self.progress; newSpeed = tempSpeed * 1; // TEMP DEBUG !!! self.y += newSpeed; self.progress = Math.max(0, self.y - startY) / (endY - startY); // Update progress property // Move innerLineLeft x progressively to innerLeftLineEndX if (self.index == 7) { //log("Decoration " + self.index + " update - p=", self.progress, "x:", Math.round(self.x), "y:", Math.round(self.y)); //log(self.progress); } if (self.pathIndex == 0 && self.x > self.leftEndX) { self.x = self.leftStartX + (self.leftEndX - self.leftStartX) * self.progress * 3; } if (self.pathIndex == 1 && self.x < self.rightEndX) { self.x = self.rightStartX + (self.rightEndX - self.rightStartX) * self.progress * 3; } if (self.y > endY + self.endSizes[self.assetIndex] / 2) { //self.y = -startSize; // Move obstacle back to the top self.reset(); } //mainGraphics = self.assets[self.assetIndex]; mainGraphics.height = startSize + (self.endSizes[self.assetIndex] - startSize) * self.progress * 2; mainGraphics.width = mainGraphics.height * self.assetWidthRatios[self.assetIndex]; if (self.index == 8 && mainGraphics.width > 200) { //log("Decoration " + self.index + " update - assetIndex:", self.assetIndex, "width:", mainGraphics.width, "x:", Math.round(self.x), "y:", Math.round(self.y)); } if (self.index == 7 && mainGraphics.width > 200) { //log("Decoration " + self.index + " update - assetIndex:", self.assetIndex, "width:", mainGraphics.width, "x:", Math.round(self.x), "y:", Math.round(self.y)); } if (!self.ready) { //log("Decoration " + self.index + " ready =" + self.ready); } //log("Decoration " + self.index + " update width:", Math.round(mainGraphics.width), "x:", Math.round(self.x), "y:", Math.round(self.y)); }; self.reset = function () { self.ready = false; //log("Decoration reset" + self.index); self.y = startY; self.progress = 0; // Initialize progress property rand = Math.random(); self.assetIndex = Math.floor(Math.random() * 3) + (currentLevel - 1) * 3; self.assets.forEach(function (asset, index) { asset.visible = index === self.assetIndex; }); mainGraphics = self.assets[self.assetIndex]; mainGraphics.height = startSize; mainGraphics.width = mainGraphics.height * self.assetWidthRatios[self.assetIndex]; if (self.index == 1 && mainGraphics.width > 200) { //log("=== Decoration " + self.index + " reset - assetIndex:", self.assetIndex, "width:", mainGraphics.width, "y:", self.y, " ==="); } self.leftStartX = baseLeftStartX; // - rand * xOffset; self.leftEndX = self.leftStartX - xOffset * (1 + rand); self.rightStartX = baseRightStartX; // + rand * xOffset; self.rightEndX = self.rightStartX + xOffset * (1 + rand); if (self.index == 1) { //log("=== Decoration " + self.index); //log("Left StartX:", self.leftStartX, "Left EndX:", self.leftEndX); //log("Right StartX:", self.rightStartX, "Right EndX:", self.rightEndX); } self.pathIndex = Math.floor(rand * 2); if (self.pathIndex === 0) { self.x = self.leftStartX; } else { self.x = self.rightStartX; } self.ready = true; }; }); var Killer = Container.expand(function (index) { var self = Container.call(this); self.index = index; var assets = ['killer1', 'killer2', 'killer3']; self.assetIndex = index % assets.length; var randomAsset = assets[self.assetIndex]; var killerGraphics = self.attachAsset(randomAsset, { anchorX: 0.5, anchorY: 0.5 }); var speed = 5; var startY = roadTop - 20; var endY = startY + roadHeight; var leftStartX = 1024 - 100; var leftEndX = 1024 - 650; var rightStartX = 1024 + 100; var rightEndX = 1024 + 650; var startSize = 1; var endSize = 800; var assetHeightRatio = 500 / 400; killerGraphics.width = startSize; killerGraphics.height = startSize; self.pathIndex = 0; self.inactive = true; self.inactiveStartTime = Date.now(); self.update = function () { if (!isPlaying) { return; } if (self.inactive) { return; } if (!isKilled && player && self.y > 2500 && self.y < 2732 && player.shadow.intersects(self)) { isKilled = true; player.visible = false; LK.stopMusic(); LK.getSound('accident_1').play(); LK.setTimeout(function () { LK.getSound('killed_1').play(); }, 100); // Adjust the delay as needed LK.setTimeout(function () { LK.getSound('rip_1').play(); }, 1000); // Play rip_1 sound 1 second after killed LK.effects.flashScreen(0xff0000, 4000); // Spawn MurderShape at player's last position var murderShape = new MurderShape(); murderShape.x = player.x; murderShape.y = playerBaseY; murderShape.fixPosition(); game.addChildAt(murderShape, game.getChildIndex(road) + 1); // Store the score in LK score before game over LK.setScore(score); LK.setTimeout(function () { LK.showGameOver(); }, 5000); return; } self.progress = Math.max(0, self.y - startY) / (endY - startY); killerGraphics.width = startSize + (endSize - startSize) * self.progress; debugTxt.setText(self.progress.toFixed(2)); killerGraphics.height = assetHeightRatio * killerGraphics.width; var tempSpeed = currentSpeed * 0.5 + currentSpeed * (self.progress * 3); var newSpeed = currentSpeed * 3; newSpeed = tempSpeed * 1; self.y += newSpeed; if (self.pathIndex == 0 && self.x != leftEndX) { self.x = leftStartX + (leftEndX - leftStartX) * self.progress; } if (self.pathIndex == 2 && self.x != rightEndX) { self.x = rightStartX + (rightEndX - rightStartX) * self.progress; } if (self.y > endY + endSize / 2) { self.reset(); } }; self.reset = function () { self.y = startY; self.progress = 0; killerGraphics.width = startSize; killerGraphics.height = startSize; self.pathIndex = Math.floor(Math.random() * 3); if (self.pathIndex === 0) { self.x = leftStartX; } else if (self.pathIndex === 2) { self.x = rightStartX; } else { self.x = 1024; } self.inactive = true; self.inactiveStartTime = Date.now(); }; }); var KillerManager = Container.expand(function () { var self = Container.call(this); self.killers = []; self.currentKillerIndex = 0; self.lastKillerUpdate = 0; self.killerDelay = 10000; // Delay in milliseconds before updating killer self.addKiller = function (killer) { self.killers.push(killer); }; self.update = function () { var currentTime = Date.now(); var currentDelay = currentTime - self.lastKillerUpdate; if (currentDelay >= self.killerDelay) { self.killers[self.currentKillerIndex].inactive = false; if (self.currentKillerIndex === 0) { LK.getSound('car_1').play(); } else if (self.currentKillerIndex === 1) { LK.getSound('police_1').play(); } else if (self.currentKillerIndex === 2) { LK.getSound('ambulance_1').play(); } self.currentKillerIndex = (self.currentKillerIndex + 1) % self.killers.length; self.lastKillerUpdate = currentTime; } }; self.resetKillers = function () { self.killers.forEach(function (killer) { killer.reset(); }); self.currentKillerIndex = 0; self.lastKillerUpdate = Date.now(); }; }); var Landscape = Container.expand(function () { var self = Container.call(this); var landscapeGraphics = self.attachAsset('landscape_1', { anchorX: 0.5, anchorY: 0.0 }); var landscapeGraphics2 = self.attachAsset('landscape_2', { anchorX: 0.5, anchorY: 0.0, visible: false }); var landscapeGraphics3 = self.attachAsset('landscape_3', { anchorX: 0.5, anchorY: 0.0, visible: false }); var gradientGraphics = self.attachAsset('gradient', { anchorX: 0.5, anchorY: 0.0, scaleY: -1, y: 1024, blendMode: 2, alpha: 0.5, tint: 0xFEFEFE, height: 15 }); self.x = 2048 / 2; // Center horizontally self.y = 0; // Position at the top self.update = function () { var newTint = intensityHalf << 16 | intensityHalf << 8 | intensityHalf; landscapeGraphics.tint = newTint; // Apply reduced tint to the road based on the intensity }; self.updateForLevel = function (level) { landscapeGraphics.visible = level === 1; landscapeGraphics2.visible = level === 2; landscapeGraphics3.visible = level === 3; }; }); var MurderShape = Container.expand(function () { var self = Container.call(this); var murderShapeGraphics = self.attachAsset('murderShape', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // MurderShape does not need to update its position or behavior }; self.fixPosition = function () { if (self.x < 600) { self.x += 150; } else if (self.x > 1400) { self.x -= 150; } }; }); // Obstacle class var Obstacle = Container.expand(function (index) { var self = Container.call(this); self.active = true; self.index = index; var assets = []; if (currentLevel === 1) { assets = ['obstacle_1_1', 'obstacle_1_2', 'obstacle_1_3']; } else if (currentLevel === 2) { assets = ['obstacle_2_1', 'obstacle_2_2', 'obstacle_2_3']; } else if (currentLevel === 3) { assets = ['obstacle_3_1', 'obstacle_3_2', 'obstacle_3_3']; } self.assetIndex = Math.floor(Math.random() * assets.length); var randomAsset = assets[self.assetIndex]; var obstacleGraphics = self.attachAsset(randomAsset, { anchorX: 0.5, anchorY: 0.5 }); var speed = 5; var startY = roadTop + 50; var endY = startY + roadHeight; var leftStartX = 1024 - 100; var leftEndX = 1024 - 650; var rightStartX = 1024 + 100; var rightEndX = 1024 + 650; var innerLeftLineStartX = -150; var innerLeftLineEndX = -390; var startSize, endSize; if (self.assetIndex == 0) { startSize = 3; endSize = 350; } else if (self.assetIndex == 1) { startSize = 1; endSize = 350; } else if (self.assetIndex == 2) { startSize = 2; endSize = 350; } obstacleGraphics.width = startSize; obstacleGraphics.height = startSize; self.pathIndex = 0; self.update = function () { if (!isPlaying || isKilled) { return; } // coinsCollected increment moved to updateScore function var currentTime = Date.now(); if (currentTime - lastObstacleHitTime > immunityDelay && player && !player.isJumping && self.y > 2500 && self.y < 2732 && player.shadow.intersects(self)) { playHit(); lastObstacleHitTime = currentTime; // Update the last hit time // Make player flash red for 1 second LK.effects.flashObject(player, 0xff0000, 1000); // Add coin animation only if score is greater than 0 if (score > 0) { var coinAnimation = new CoinAnimation(); coinAnimation.x = player.x; coinAnimation.y = player.y; game.addChild(coinAnimation); } // Reduce score by 1 updateScore(true); //log("Obstacle y:", self.y); // Reduce currentSpeed by a factor (e.g., 0.8) //log("Old speed :", currentSpeed); //currentSpeed = Math.max(10, Math.min(20, Math.round(currentSpeed * 0.8))); //log("New speed :", currentSpeed); } self.progress = Math.max(0, self.y - startY) / (endY - startY); // Update progress property obstacleGraphics.width = startSize + (endSize - startSize) * self.progress; obstacleGraphics.height = startSize + (endSize - startSize) * self.progress; var tempSpeed = currentSpeed * 0.05 + currentSpeed * (self.progress * 3); var newSpeed = currentSpeed; // + 10 * self.progress; newSpeed = tempSpeed * 1; // TEMP DEBUG !!! self.y += newSpeed; // Move innerLineLeft x progressively to innerLeftLineEndX if (self.pathIndex == 0 && self.x != leftEndX) { self.x = leftStartX + (leftEndX - leftStartX) * self.progress; } if (self.pathIndex == 2 && self.x != rightEndX) { self.x = rightStartX + (rightEndX - rightStartX) * self.progress; } if (self.y > endY + endSize / 2) { self.reset(); } }; self.reset = function () { obstacleManager.freePath(self.pathIndex); // Mark the path as unoccupied self.active = false; self.y = startY; self.progress = 0; // Initialize progress property obstacleGraphics.width = startSize; obstacleGraphics.height = startSize; }; self.setPath = function (newPathIndex) { self.pathIndex = newPathIndex; //Math.floor(Math.random() * 3); if (self.pathIndex === 0) { self.x = leftStartX; } else if (self.pathIndex === 2) { self.x = rightStartX; } else { self.x = 1024; } }; self.updateForLevel = function (level) { log("Obstacle updateForLevel", level); var assets = []; if (level === 1) { assets = ['obstacle_1_1', 'obstacle_1_2', 'obstacle_1_3']; } else if (level === 2) { assets = ['obstacle_2_1', 'obstacle_2_2', 'obstacle_2_3']; } else if (level === 3) { assets = ['obstacle_3_1', 'obstacle_3_2', 'obstacle_3_3']; } self.assetIndex = Math.floor(Math.random() * assets.length); var randomAsset = assets[self.assetIndex]; log("Obstacle asset =>", randomAsset); obstacleGraphics.destroy(); obstacleGraphics = self.attachAsset(randomAsset, { anchorX: 0.5, anchorY: 0.5 }); self.reset(); }; }); var ObstacleManager = Container.expand(function () { var self = Container.call(this); self.obstacles = []; self.occupiedPaths = [false, false, false]; self.addObstacle = function (obstacle) { self.obstacles.push(obstacle); }; self.resetObstacles = function () { self.occupiedPaths = [false, false, false]; self.obstacles.forEach(function (obstacle) { obstacle.reset(); }); }; self.updateObstacles = function () { self.obstacles.forEach(function (obstacle) { if (!obstacle.active) { obstacle.reset(); } }); }; self.update = function () { if (!isPlaying || isKilled) { return; } // Activate obstacles regularly in random path var currentTime = Date.now(); log("ObstacleManager update..."); if (currentTime - lastObstacleSpawnTime > baseObstacleSpawnDelay) { log("Attempting to spawn obstacle. Current time:", currentTime, "Last spawn time:", lastObstacleSpawnTime); var availablePaths = self.occupiedPaths.map(function (occupied, index) { return occupied ? null : index; }).filter(function (index) { return index !== null; }); log("Available paths for obstacle activation:", availablePaths); if (availablePaths.length > 0) { var randomPathIndex = availablePaths[Math.floor(Math.random() * availablePaths.length)]; var inactiveObstacles = self.obstacles.filter(function (obstacle) { return !obstacle.active; }); log("Inactive obstacles available for activation:", inactiveObstacles.length); if (inactiveObstacles.length > 0) { var obstacleToActivate = inactiveObstacles[Math.floor(Math.random() * inactiveObstacles.length)]; log("Activating obstacle in path:", randomPathIndex); obstacleToActivate.setPath(randomPathIndex); log("Obstacle activated:", obstacleToActivate); obstacleToActivate.active = true; self.setPathOccupied(randomPathIndex, true); log("Path occupied status updated. Path:", randomPathIndex, "Occupied:", self.isPathOccupied(randomPathIndex)); lastObstacleSpawnTime = currentTime; // Update the last spawn time } } } }; self.isPathOccupied = function (pathIndex) { return self.occupiedPaths[pathIndex]; }; self.setPathOccupied = function (pathIndex, occupied) { self.occupiedPaths[pathIndex] = occupied; }; self.freePath = function (pathIndex) { self.setPathOccupied(pathIndex, false); }; self.updateForLevel = function (level) { self.obstacles.forEach(function (obstacle) { obstacle.updateForLevel(level); }); }; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); self.shadow = self.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5 }); self.isJumping = false; // Initialize isJumping to false self.shadow.alpha = 0.5; // Make the shadow semi-transparent self.shadow.y = 270; // Offset the shadow slightly below the player var playerGraphics1_1 = self.attachAsset('player_1_1', { anchorX: 0.5, anchorY: 0.5, x: -5 }); var playerGraphics1_2 = self.attachAsset('player_1_2', { anchorX: 0.5, anchorY: 0.5, x: 5 }); var playerGraphics2_1 = self.attachAsset('player_2_1', { anchorX: 0.5, anchorY: 0.5, x: -5, visible: false // Initially hide player2_1 asset }); var playerGraphics2_2 = self.attachAsset('player_2_2', { anchorX: 0.5, anchorY: 0.5, x: 5, visible: false // Initially hide player2_2 asset }); var playerGraphics3_1 = self.attachAsset('player_3_1', { anchorX: 0.5, anchorY: 0.5, x: -5, visible: false // Initially hide player3_1 asset }); var playerGraphics3_2 = self.attachAsset('player_3_2', { anchorX: 0.5, anchorY: 0.5, x: 5, visible: false // Initially hide player3_2 asset }); var frame = 0; self.update = function () { if (!self.isJumping) { frame += Math.min(currentSpeed, 20); // Add a max limit to avoid optical effects if (frame >= 100) { frame = 0; // Swap frames every 10 game ticks if (currentLevel <= 1) { var visible = playerGraphics1_1.visible; playerGraphics1_1.visible = !visible; playerGraphics1_2.visible = visible; } if (currentLevel === 2) { var visible = playerGraphics2_1.visible; playerGraphics2_1.visible = !visible; playerGraphics2_2.visible = visible; } if (currentLevel === 3) { var visible = playerGraphics3_1.visible; playerGraphics3_1.visible = !visible; playerGraphics3_2.visible = visible; } } } }; self.updateForLevel = function (level) { playerGraphics1_1.visible = level === 1; playerGraphics1_2.visible = level === 1; playerGraphics2_1.visible = level === 2; playerGraphics2_2.visible = level === 2; playerGraphics3_1.visible = level === 3; playerGraphics3_2.visible = level === 3; }; self.jump = function () { if (!self.isJumping) { self.isJumping = true; LK.getSound('jump_1').play(); var initialY = self.y; var initialShadowY = self.shadow.y; var jumpHeight = 300; var jumpDuration = 30; var jumpStep = jumpHeight / jumpDuration; var fallStep = jumpHeight / jumpDuration; var jumpStartTime = Date.now(); var jumpInterval = LK.setInterval(function () { var elapsed = Date.now() - jumpStartTime; var progress = elapsed / (jumpDuration * 1000 / 60); if (progress < 1) { var easeProgress = Math.sin(progress * Math.PI / 2); self.y = initialY - jumpHeight * easeProgress; self.shadow.y = initialShadowY + jumpHeight * easeProgress; // Move shadow inversely self.shadow.width = 240 * (1 - 0.5 * easeProgress); // Reduce shadow width self.shadow.height = 100 * (1 - 0.5 * easeProgress); // Reduce shadow height } else { LK.clearInterval(jumpInterval); var fallStartTime = Date.now(); var fallInterval = LK.setInterval(function () { var elapsed = Date.now() - fallStartTime; var progress = elapsed / (jumpDuration * 1000 / 60); if (progress < 1) { var easeProgress = Math.sin(progress * Math.PI / 2); self.y = initialY - jumpHeight + jumpHeight * easeProgress; self.shadow.y = initialShadowY + jumpHeight - jumpHeight * easeProgress; // Move shadow inversely self.shadow.width = 120 + 120 * easeProgress; // Reset shadow width self.shadow.height = 50 + 50 * easeProgress; // Reset shadow height } else { self.y = initialY; self.shadow.y = initialShadowY; // Reset shadow position self.isJumping = false; LK.clearInterval(fallInterval); } }, 1000 / 60); } }, 1000 / 60); } }; }); // Road class var Road = Container.expand(function () { var self = Container.call(this); var baseY = 750; var roadGraphics = self.attachAsset('triangle', { tint: 0x555555, // Initialize tint to white anchorX: 0.5, anchorY: 0, width: 2048, height: roadHeight, y: baseY }); var speed = 5; var lineOffset = -150; // Inner lines var innerLineStartY = roadTop; var innerLineEndY = roadTop + roadHeight + 200; // Left var innerLeftLineStartX = -50; var innerLeftLineEndX = -412; var innerLeftLineStartW = 3; var innerLeftLineEndW = 80; var innerLeftLineStartH = 3; var innerLeftLineEndH = 500; var innerLeftLineStartR = 0.22; //0.075; var innerLeftLineEndR = 0.275; // Right var innerRightLineStartX = 50; var innerRightLineEndX = 412; var innerRightLineStartW = 3; var innerRightLineEndW = 80; var innerRightLineStartH = 3; var innerRightLineEndH = 500; var innerRightLineStartR = -0.22; var innerRightLineEndR = -0.275; // Lamp posts // Left Lamp var leftLampStartX = -130; var leftLampEndX = -1600; var leftLampStartY = roadTop; var leftLampEndY = roadTop + roadHeight + 0; // Define leftLampEndY variable var leftLampStartH = 2; var leftLampEndH = 900; var leftLampWRatio = 1 / 3; // Right Lamp var rightLampStartX = 130; var rightLampEndX = 1600; var rightLampStartY = roadTop; var rightLampEndY = roadTop + roadHeight + 0; // Define leftLampEndY variable var rightLampStartH = 2; var rightLampEndH = 900; var rightLampWRatio = 1 / 3; var nbInnerLines = 6; var leftLine = self.attachAsset('triangle', { anchorX: 0.5, anchorY: 0, width: 100, height: 1950, rotation: 0.45 }); leftLine.x = lineOffset; // Position the left line on the left side of the road leftLine.y = roadTop + 45; // Center the left line vertically var rightLine = self.attachAsset('triangle', { anchorX: 0.5, anchorY: 0, width: 100, height: 1950, rotation: -0.45 }); rightLine.x = -lineOffset; // Position the right line on the right side of the road rightLine.y = roadTop + 45; // Center the right line vertically self.innerLeftLines = []; self.innerRightLines = []; self.leftLampPosts = []; self.rightLampPosts = []; // Define arrays to store assets for each level var leftLampPostAssets = ['lampPost_1', // Level 1 asset 'lampPost_2', // Level 2 asset 'lampPost_3' // Level 3 asset ]; var rightLampPostAssets = ['lampPost_1', // Level 1 asset 'lampPost_2', // Level 2 asset 'lampPost_3' // Level 3 asset ]; for (var i = 0; i < nbInnerLines; i++) { var innerLineLeft = self.attachAsset('line', { anchorX: 0.5, anchorY: 0.5, width: innerLeftLineStartW, height: innerLeftLineStartH, rotation: innerLeftLineStartR, alpha: 1 }); innerLineLeft.x = innerLeftLineStartX; innerLineLeft.y = innerLineStartY - 0.1 * i * roadHeight / nbInnerLines; //log(i + " : " + innerLineStartY + " + " + i * roadHeight / nbInnerLines + " => " + innerLineLeft.y); innerLineLeft.progress = 0; // Initialize progress property self.innerLeftLines.push(innerLineLeft); var innerLineRight = self.attachAsset('line', { anchorX: 0.5, anchorY: 0.5, width: innerRightLineStartW, height: innerRightLineStartH, rotation: innerRightLineStartR, alpha: 1 }); innerLineRight.x = innerRightLineStartX; innerLineRight.y = innerLineStartY - 0.1 * i * roadHeight / nbInnerLines; innerLineRight.progress = 0; // Initialize progress property self.innerRightLines.push(innerLineRight); if (i % 2 == 0) { continue; } var leftLampPost = self.attachAsset(leftLampPostAssets[currentLevel - 1], { anchorX: 0.5, anchorY: 0.5, height: leftLampStartH, width: leftLampStartH * leftLampWRatio }); var leftLampShadow = self.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5, width: leftLampPost.width * 0.8, height: leftLampPost.height * 0.1, y: leftLampPost.height * 0.5 + 10 // Offset shadow slightly below the lamp post }); leftLampPost.addChild(leftLampShadow); leftLampPost.x = leftLampStartX; leftLampPost.y = leftLampStartY - (i - 1) * 40; self.addChild(leftLampPost); self.leftLampPosts.push(leftLampPost); var rightLampPost = self.attachAsset(rightLampPostAssets[currentLevel - 1], { anchorX: 0.5, anchorY: 0.5, scaleX: -1, height: rightLampStartH, width: rightLampStartH * rightLampWRatio }); var rightLampShadow = self.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5, width: rightLampPost.width * 0.8, height: rightLampPost.height * 0.1, y: rightLampPost.height * 0.5 + 10 // Offset shadow slightly below the lamp post }); rightLampPost.addChild(rightLampShadow); rightLampPost.x = rightLampStartX; rightLampPost.y = rightLampStartY - (i - 1) * 40; self.addChild(rightLampPost); self.rightLampPosts.push(rightLampPost); } self.update = function () { if (isKilled) { return; } var newTint = intensityHalf << 16 | intensityHalf << 8 | intensityHalf; //roadGraphics.tint = newTint; // Apply reduced tint to the road based on the intensity leftLine.tint = newTint; rightLine.tint = newTint; // Add any update logic for the road if needed for (var i = 0; i < self.innerLeftLines.length; i++) { innerLineLeft = self.innerLeftLines[i]; innerLineLeft.tint = newTint; if (innerLineLeft.y > innerLineEndY) { self.resetInnerLine(innerLineLeft, true); } else { innerLineLeft.progress = Math.max(0, innerLineLeft.y - innerLineStartY) / (innerLineEndY - innerLineStartY); // Update progress property } var tempSpeed = currentSpeed * 0.05 + currentSpeed * (innerLineLeft.progress * 3); var newSpeed = currentSpeed; // + 10 * self.progress; newSpeed = tempSpeed * 1; // TEMP DEBUG !!! innerLineLeft.y += newSpeed; // Move innerLineLeft x progressively to innerLeftLineEndX if (innerLineLeft.x != innerLeftLineEndX) { innerLineLeft.x = innerLeftLineStartX + (innerLeftLineEndX - innerLeftLineStartX) * innerLineLeft.progress; } // Move innerLineLeft x progressively if (innerLineLeft.rotation != innerLeftLineEndR) { //innerLineLeft.rotation = innerLeftLineStartR + (innerLeftLineEndR - innerLeftLineStartR) * innerLineLeft.progress; } // Move innerLineLeft x progressively if (innerLineLeft.width != innerLeftLineEndW) { innerLineLeft.width = innerLeftLineStartW + (innerLeftLineEndW - innerLeftLineStartW) * innerLineLeft.progress; } // Move innerLineLeft x progressively if (innerLineLeft.height != innerLeftLineEndH) { innerLineLeft.height = innerLeftLineStartH + (innerLeftLineEndH - innerLeftLineStartH) * innerLineLeft.progress; } } for (var i = 0; i < self.innerRightLines.length; i++) { innerLineRight = self.innerRightLines[i]; innerLineRight.tint = newTint; if (innerLineRight.y > innerLineEndY) { self.resetInnerLine(innerLineRight, false); } else { innerLineRight.progress = Math.max(0, innerLineRight.y - innerLineStartY) / (innerLineEndY - innerLineStartY); } var tempSpeed = currentSpeed * 0.05 + currentSpeed * (innerLineRight.progress * 3); var newSpeed = currentSpeed; // + 10 * self.progress; newSpeed = tempSpeed * 1; // TEMP DEBUG !!! innerLineRight.y += newSpeed; // Move innerLineRight x progressively to innerRightLineEndX if (innerLineRight.x != innerRightLineEndX) { innerLineRight.x = innerRightLineStartX + (innerRightLineEndX - innerRightLineStartX) * innerLineRight.progress; } // Move innerLineRight x progressively if (innerLineRight.rotation != innerRightLineEndR) { //innerLineRight.rotation = innerRightLineStartR + (innerRightLineEndR - innerRightLineStartR) * innerLineRight.progress; } // Move innerLineRight x progressively if (innerLineRight.width != innerRightLineEndW) { innerLineRight.width = innerRightLineStartW + (innerRightLineEndW - innerRightLineStartW) * innerLineRight.progress; } // Move innerLineRight x progressively if (innerLineRight.height != innerRightLineEndH) { innerLineRight.height = innerRightLineStartH + (innerRightLineEndH - innerRightLineStartH) * innerLineRight.progress; } } // Lamp posts for (var i = 0; i < self.leftLampPosts.length; i++) { var leftLampPost = self.leftLampPosts[i]; //leftLampPost.tint = newTint; var tempProgress = Math.max(0, leftLampPost.y - leftLampStartY) / (leftLampEndY - leftLampStartY); var tempSpeed = currentSpeed * 0.05 + currentSpeed * (tempProgress * 3); leftLampPost.y += tempSpeed; //leftLampPost.visible = currentLevel !== 1; // Make lampPost not visible when level is 1 if (leftLampPost.y > leftLampEndY) { leftLampPost.y = leftLampStartY; leftLampPost.x = leftLampStartX; leftLampPost.height = leftLampStartH; } leftLampPost.progress = Math.max(0, leftLampPost.y - leftLampStartY) / (leftLampEndY - leftLampStartY); // Update progress property leftLampPost.alpha = 0.75 + Math.min(0.25, leftLampPost.progress); if (i == 0) { //debugTxt.setText(leftLampPost.progress.toFixed(2)); } if (leftLampPost.x != leftLampEndX) { leftLampPost.x = leftLampStartX + (leftLampEndX - leftLampStartX) * Math.min(1, leftLampPost.progress * 1); } if (leftLampPost.height != leftLampEndH) { leftLampPost.height = Math.min(1, leftLampPost.progress * 2) * leftLampEndH; // leftLampStartH + (leftLampEndH - leftLampStartH) * Math.min(1, leftLampPost.progress * 1); leftLampPost.width = leftLampPost.height * leftLampWRatio; } } for (var i = 0; i < self.rightLampPosts.length; i++) { var rightLampPost = self.rightLampPosts[i]; var tempProgress = Math.max(0, rightLampPost.y - rightLampStartY) / (rightLampEndY - rightLampStartY); var tempSpeed = currentSpeed * 0.05 + currentSpeed * (tempProgress * 3); rightLampPost.y += tempSpeed; //rightLampPost.visible = currentLevel !== 1; // Make right lampPost not visible when level is 1 if (rightLampPost.y > rightLampEndY) { rightLampPost.y = rightLampStartY; rightLampPost.x = rightLampStartX; rightLampPost.height = rightLampStartH; } rightLampPost.progress = Math.max(0, rightLampPost.y - rightLampStartY) / (rightLampEndY - rightLampStartY); rightLampPost.alpha = 0.75 + Math.min(0.25, rightLampPost.progress); if (rightLampPost.x != rightLampEndX) { rightLampPost.x = rightLampStartX + (rightLampEndX - rightLampStartX) * rightLampPost.progress; } if (rightLampPost.height != leftLampEndH) { rightLampPost.height = rightLampStartH + (rightLampEndH - rightLampStartH) * Math.min(1, rightLampPost.progress * 2); rightLampPost.width = rightLampPost.height * rightLampWRatio; } } }; self.updateForLevel = function (level) { // Iterate through left lamp posts for (var i = 0; i < self.leftLampPosts.length; i++) { var leftLampPost = self.leftLampPosts[i]; var newLeftLampPost = self.attachAsset(leftLampPostAssets[level - 1], { anchorX: 0.5, anchorY: 0.5, height: leftLampPost.height, width: leftLampPost.width }); newLeftLampPost.visible = leftLampPost.visible; newLeftLampPost.x = leftLampPost.x; newLeftLampPost.y = leftLampPost.y; self.leftLampPosts[i] = newLeftLampPost; leftLampPost.destroy(); } for (var i = 0; i < self.rightLampPosts.length; i++) { var rightLampPost = self.rightLampPosts[i]; rightLampPost.children.forEach(function (child) { child.visible = false; }); var newRightLampPost = self.attachAsset(rightLampPostAssets[level - 1], { anchorX: 0.5, anchorY: 0.5, scaleX: -1, height: rightLampPost.height, width: rightLampPost.width }); newRightLampPost.visible = rightLampPost.visible; newRightLampPost.x = rightLampPost.x; newRightLampPost.y = rightLampPost.y; self.rightLampPosts[i] = newRightLampPost; rightLampPost.destroy(); } }; self.resetInnerLine = function (innerLine, isLeft) { if (isLeft) { innerLine.x = innerLeftLineStartX; innerLine.rotation = innerLeftLineStartR; innerLine.width = innerLeftLineStartW; innerLine.height = innerLeftLineStartH; } else { innerLine.x = innerRightLineStartX; innerLine.rotation = innerRightLineStartR; innerLine.width = innerRightLineStartW; innerLine.height = innerRightLineStartH; } innerLine.y = innerLineStartY - 0.2 * roadHeight / nbInnerLines; innerLine.progress = 0; // Reset progress property }; }); var StartButton = Container.expand(function () { var self = Container.call(this); var buttonGraphics = self.attachAsset('startButton', { anchorX: 0.5, anchorY: 0.5 }); self.interactive = true; self.buttonMode = true; self.on('down', function () { LK.playMusic('bgMusic', { loop: true }); self.visible = false; updateGoalForLevel(1); // Call updateGoalForLevel(1) when start button is pressed LK.setTimeout(function () { goalText.visible = false; scoreTxt.visible = true; isPlaying = true; }, goalAnnounceDelay); }); }); var Stripe = Container.expand(function () { var self = Container.call(this); self.stripeGraphics = self.attachAsset('stripe_1', { anchorX: 0, anchorY: 1, height: 1 }); self.stripeGraphics2 = self.attachAsset('stripe_2', { anchorX: 0, anchorY: 1, height: 1, visible: false }); self.stripeGraphics3 = self.attachAsset('stripe_3', { anchorX: 0, anchorY: 1, height: 1, visible: false }); self.progress = 0; // Initialize progress property self.update = function () { if (isKilled) { return; } self.progress = Math.max(0, self.y - roadTop) / roadHeight; // Update progress property var newTint = intensityHalf << 16 | intensityHalf << 8 | intensityHalf; self.stripeGraphics.tint = newTint; self.stripeGraphics2.tint = newTint; self.stripeGraphics3.tint = newTint; var tempSpeed = currentSpeed * 0.05 + currentSpeed * (self.progress * 3); self.y += tempSpeed; self.stripeGraphics.height = 400 * self.progress; // Adjust height based on progress self.stripeGraphics2.height = 400 * self.progress; // Adjust height based on progress self.stripeGraphics3.height = 400 * self.progress; // Adjust height based on progress if (self.y > roadTop + roadHeight) { self.y = roadTop; self.stripeGraphics.height = 0; // Reset height to initial value self.stripeGraphics.tint = 0xFFFFFF; // Reset tint to initial value self.stripeGraphics2.height = 0; self.stripeGraphics2.tint = 0xFFFFFF; self.stripeGraphics3.height = 0; self.stripeGraphics3.tint = 0xFFFFFF; } }; self.updateForLevel = function (level) { self.stripeGraphics.visible = level === 1; self.stripeGraphics2.visible = level === 2; self.stripeGraphics3.visible = level === 3; }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Init game with black background }); /**** * Game Code ****/ function updateGoalForLevel(level) { if (level === 1) { goalText.setText('COLLECT\r\n$10'); } else if (level === 2) { goalText.setText('COLLECT\r\n$100'); } else if (level === 3) { goalText.setText('COLLECT\r\n$1 000 000+'); } goalText.visible = true; LK.setTimeout(function () { goalText.visible = false; }, goalAnnounceDelay); } var moneyLost = 0; // Initialize global moneyLost variable var isDebug = true; // Define global isDebug variable var occupiedPaths = [false, false, false]; // Initialize an array to track occupied paths var baseObstacleSpawnDelay = 2000; // Define global baseObstacleSpawnDelay var obstacleManager; // Define obstacleManager in the global scope var killerManager = new KillerManager(); // Initialize killerManager in the global scope var lastObstacleSpawnTime = 0; // Track the last time an obstacle was spawned var levelConfigs = [{}, { name: "Level 1", backgroundTint: 0xeda716, coinValue: 0.10, baseSpeed: 10, nextLevelScore: 1 // 10 TEMP DEBUG !!! }, { name: "Level 2", backgroundTint: 0x2faf1d, coinValue: 1, baseSpeed: 15, nextLevelScore: 100 }, { name: "Level 3", backgroundTint: 0x6c6060, coinValue: 100, baseSpeed: 20, nextLevelScore: Infinity // Endless Runner ;) }]; var stripes = []; var nbDecorations = 10; var decorations = []; // Initialize arrays and variables var currentLevel = 1; var road = new Road(); var isPlaying = false; var isKilled = false; var killerDelay = 10000; // Delay in milliseconds before updating killer var lastKillerUpdate = 0; // Timestamp of the last killer update var currentCoinType = 0; var nextCoinTypeThreshold = 1000; var isNight = false; var roadHeight = 2000; var roadTop = 1000; // ~= road.height/2 - baseY var background; var landscape; var nbStripes = 33; var baseNbCoins = 10; var baseNbObstacles = 10; var coins = []; var obstacles = []; var killers = []; var road; var score = 0; var scoreTxt; var goalText; var goalAnnounceDelay = 3000; var startX = 0; var startY = 0; var endX = 0; var endY = 0; var intensity = 0; var intensityHalf = 0; var leftLampPosts = []; var rightLampPosts = []; var leftDecorations = []; var rightDecorationss = []; var maxSpeed = 70; // Define a maximum speed limit var currentSpeed = 15; //20; // Initialize currentSpeed var coinsCollected = 0; // Initialize coins collected counter var isIntersectingObstacle = false; // Flag to track if the player is currently intersecting an obstacle var lastObstacleHitTime = 0; // Timestamp of the last obstacle hit var immunityDelay = 500; // Immunity delay in milliseconds var playerPositionIndex = 1; // Initialize player position index var playerBaseY = 2732 - 300; // Define the three fixed x positions for the player var playerPositions = [2048 / 5, 2048 / 2, 4 * 2048 / 5]; // Create player var player; var debugMarker; var debugText; var debugTxt; /****************************************************************************************** */ /************************************** GAME FUNCTIONS ************************************ */ /****************************************************************************************** */ function updateScore() { var negative = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; if (negative) { if (score > 0) { moneyLost += Math.min(levelConfigs[currentLevel].coinValue || 1, score); } score -= levelConfigs[currentLevel].coinValue || 1; score = parseFloat(score.toFixed(1)); score = Math.max(0, score); // Ensure score doesn't go below 0 } else { score += levelConfigs[currentLevel].coinValue || 1; score = parseFloat(score.toFixed(1)); coinsCollected += 1; // Increment coins collected counter } if (score >= levelConfigs[currentLevel].nextLevelScore) { changeLevel(currentLevel + 1); } // Format score log("score=", score, " => ", (score * 100).toFixed(0) + "¢"); if (score < 1) { scoreTxt.setText((score * 100).toFixed(0) + "¢"); } else if (score < 10) { scoreTxt.setText("$" + score.toFixed(2)); } else { scoreTxt.setText("$" + Math.floor(score)); } } // Function to change the level function changeLevel(newLevel) { obstacleManager.updateForLevel(currentLevel); log("changeLevel:", newLevel); newLevel = Math.max(1, Math.min(levelConfigs.length, newLevel)); currentLevel = newLevel; currentSpeed = levelConfigs[currentLevel].baseSpeed; console.log("Level changed to:", currentLevel); // Add a big white flash effect LK.effects.flashScreen(0xFFFFFF, 1000); // Flash white for 1 second // Change background tint using levelConfig background.updateForLevel(currentLevel); // Update stripe graphics visibility based on the level stripes.forEach(function (stripe) { stripe.updateForLevel(currentLevel); }); // Update landscape based on the level landscape.updateForLevel(currentLevel); // Update player graphics based on the level player.updateForLevel(currentLevel); if (road) { road.updateForLevel(currentLevel); } coins.forEach(function (coin) { coin.updateForLevel(currentLevel); }); LK.getSound('levelWin_1').play(); updateGoalForLevel(currentLevel); } function easeInOutQuad(t) { return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; } function playHit() { var hitSounds = ['hit_1', 'hit_2', 'hit_3']; var randomIndex = Math.floor(Math.random() * hitSounds.length); LK.getSound(hitSounds[randomIndex]).play(); } function updateBackgroundColor() { var time = 1000 + new Date().getTime() * 0.0002; intensity = Math.sin(time) * 127 + 128; var baseColor = levelConfigs[currentLevel].backgroundTint; var r = (baseColor >> 16 & 0xFF) + intensity; var g = (baseColor >> 8 & 0xFF) + intensity; var b = (baseColor & 0xFF) + intensity; r = Math.min(255, Math.max(0, r)); g = Math.min(255, Math.max(0, g)); b = Math.min(255, Math.max(0, b)); var color = r << 16 | g << 8 | b; background.tint = color; isNight = intensity < 128; intensityHalf = 128 + Math.floor(intensity * 0.5); } function log() { if (isDebug) { var _console; (_console = console).log.apply(_console, arguments); } } /****************************************************************************************** */ /************************************** INPUT HANDLERS ************************************ */ /****************************************************************************************** */ // Handle move events game.down = function (x, y, obj) { if (!isPlaying) { return; } startX = x; startY = y; }; game.up = function (x, y, obj) { if (isKilled) { LK.setScore(score); // Store the score in LK score before game over LK.setTimeout(function () { LK.stopMusic(); LK.showGameOver(); }, 500); return; } if (!isPlaying) { return; } endX = x; endY = y; var deltaX = endX - startX; var deltaY = endY - startY; if (Math.abs(deltaX) > Math.abs(deltaY)) { if (deltaX > 0) { // Swipe right if (playerPositionIndex < 2) { playerPositionIndex++; } } else { // Swipe left if (playerPositionIndex > 0) { playerPositionIndex--; } } } else { if (deltaY < 0) { // Swipe up player.jump(); } } // Make the player move progressively to the next path var targetX = playerPositions[playerPositionIndex]; var initialX = player.x; var moveDuration = 30; var moveStartTime = Date.now(); var moveInterval = LK.setInterval(function () { var elapsed = Date.now() - moveStartTime; var progress = elapsed / (moveDuration * 1000 / 60); if (progress < 1) { var easeProgress = easeInOutQuad(progress); player.x = initialX + (targetX - initialX) * easeProgress; } else { player.x = targetX; LK.clearInterval(moveInterval); } }, 1000 / 60); }; // Update game every tick game.update = function () { updateBackgroundColor(); if (!isPlaying || isKilled) { return; } }; // Initialize game function gameInitialize() { killerManager.resetKillers(); // Initialize arrays and variables // Attach the background asset to the game background = game.addChild(new Background()); background.updateForLevel(currentLevel); // Add a series of Stripe instances to cover the bottom half of the screen for (var i = 0; i < nbStripes; i++) { var stripe = new Stripe(); stripe.y = i === 0 ? roadTop : stripes[i - 1].y + stripes[i - 1].stripeGraphics.height; // Position stripe under the previous one using previous stripe y and height stripe.progress = Math.max(0, stripe.y - roadTop) / roadHeight; // Calculate progress stripes.push(stripe); game.addChild(stripe); stripe.stripeGraphics.height = 1 + 400 * stripe.progress; // Adjust height based on progress //log("Stripe ", i, " y=", stripe.y, " h=", stripe.stripeGraphics.height, " p=", stripe.progress); } for (var i = 0; i < stripes.length; i++) { stripes[i].update(); } // Create and attach decoration instances to the game for (var i = 0; i < nbDecorations; i++) { var newDecoration = new Decoration(i); newDecoration.reset(); decorations.push(newDecoration); game.addChild(newDecoration); } // Create and attach the road instance to the game road = game.addChild(new Road()); road.x = 2048 / 2; road.y = 0; if (road) { //road.updateForLevel(currentLevel); } score = 0; scoreTxt = new Text2('0¢', { size: 150, fill: "#ffffff", dropShadow: true, dropShadowColor: "#000000", dropShadowBlur: 5, dropShadowDistance: 5 }); scoreTxt.anchor.set(0.5, 0); scoreTxt.visible = false; goalText = new Text2('', { size: 150, fill: "#ffffff", dropShadow: true, dropShadowColor: "#111111", dropShadowBlur: 10, dropShadowDistance: 10, align: 'center', weight: 1000 }); goalText.anchor.set(0.5, 1); LK.gui.center.addChild(goalText); //goalText.x = 2048 / 2; //goalText.y = 100; //goalText.visible = true; LK.gui.top.addChild(scoreTxt); coins = []; for (var i = 0; i < baseNbCoins; i++) { var newCoin = new Coin(i); newCoin.reset(); newCoin.y = roadTop - i * 50; coins.push(newCoin); game.addChild(newCoin); } // Create a variable to store the current player position index playerPositionIndex = 1; // Create and attach obstacle instances to the game obstacleManager = new ObstacleManager(); var numObstacles = Math.floor(Math.random() * baseNbObstacles) + 1; // Randomize number of obstacles (1 to baseNbObstacles) for (var i = 0; i < numObstacles; i++) { var newObstacle = new Obstacle(i); obstacleManager.addObstacle(newObstacle); game.addChild(newObstacle); } obstacleManager.resetObstacles(); game.addChild(obstacleManager); // Create and attach the killer instance to the game // killerManager is already initialized in the global scope for (var i = 0; i < 3; i++) { var newKiller = new Killer(i); // Pass index for each killer killerManager.addKiller(newKiller); game.addChild(newKiller); } killerManager.resetKillers(); game.addChild(killerManager); // Create player player = game.addChild(new Player()); player.frame = 0; player.x = playerPositions[playerPositionIndex]; // Start at the center position player.y = playerBaseY; // Create and attach the landscape instance to the game landscape = game.addChild(new Landscape()); var startButton = game.addChild(new StartButton()); startButton.x = 2048 / 2; startButton.y = 2732 / 4; // TEMP DEBUG !!! startButton.width = 100; startButton.height = 100; // Attach a debugMarker asset to the game at position (1000, 0) debugMarker = game.attachAsset('debugMarker', { anchorX: 0.5, anchorY: 0.5 }); debugMarker.x = 1280; debugMarker.y = roadTop; debugTxt = new Text2('Debug Info', { size: 50, fill: "#ff0000" }); debugTxt.anchor.set(1, 1); // Set anchor to the bottom right corner LK.gui.bottomRight.addChild(debugTxt); isPlaying = false; } gameInitialize(); // DEVLOG: // Add sound for important events in the game
===================================================================
--- original.js
+++ change.js
@@ -321,9 +321,9 @@
// Store the score in LK score before game over
LK.setScore(score);
LK.setTimeout(function () {
LK.showGameOver();
- }, 3000);
+ }, 5000);
return;
}
self.progress = Math.max(0, self.y - startY) / (endY - startY);
killerGraphics.width = startSize + (endSize - startSize) * self.progress;
Directly overhead, plumb view of a beggar heading top (we see his back).. Zenith view, directly overhead, plumb view. NOT PERSPECTIVE! Fantasy theme. Pixel art
a traffic cone. video game sprite
face view of a big start button in the shape of a dollar bill. video game style
a tree. video game style
a black garbage bag. video game style
Dollar bill. Perspective. video game sprite
perspective of a simple snake rolled up on itself.. video game sprite
Ball of dry desert bushes. video game sprite
tractor. high definition video game sprite
street ad billboard with 1 or 2 posts with "Get rich!" on it. high definition video game sprite
a dog sleeping on a street. video game sprite
desert bush. video game sprite
profile view of an empty motorcycle helmet. black with a white vertical central band and another thiner orange band on the center. NOT PERSPECTIVE!. Pixel art high definition
simple red and white magnet. video game style
gold sign with a "X" and a "2". video game style
bgMusic
Music
coin_1
Sound effect
hit_1
Sound effect
hit_2
Sound effect
hit_3
Sound effect
levelWin_1
Sound effect
car_1
Sound effect
police_1
Sound effect
ambulance_1
Sound effect
accident_1
Sound effect
killed_1
Sound effect
jump_1
Sound effect
rip_1
Sound effect
bonus_take
Sound effect
bonus_approaching
Sound effect