/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var AttackingEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('attackingEnemy', { anchorX: 0.5, anchorY: 1.0 }); self.velocityX = 0; self.velocityY = 0; self.onGround = false; self.speed = 4; self.gravity = 0.8; self.direction = 1; self.attackRange = 300; self.update = function () { // Apply gravity self.velocityY += self.gravity; // Calculate direction to player var distanceToPlayer = player.x - self.x; var absoluteDistance = Math.abs(distanceToPlayer); // Always move towards player (no range limit for chasing) if (distanceToPlayer > 0) { self.velocityX = self.speed; // Move right towards player self.direction = 1; enemyGraphics.scaleX = -1; // Face right } else { self.velocityX = -self.speed; // Move left towards player self.direction = -1; enemyGraphics.scaleX = 1; // Face left } // Apply velocity var currentTimeMultiplier = slowMotionActive ? 0.3 : 1; self.x += self.velocityX * currentTimeMultiplier; self.y += self.velocityY * currentTimeMultiplier; // Check platform collisions self.onGround = false; for (var i = 0; i < platforms.length; i++) { var plat = platforms[i]; var platLeft = plat.obj.x - plat.width / 2; var platRight = plat.obj.x + plat.width / 2; // Check if enemy is within platform bounds horizontally if (self.x >= platLeft && self.x <= platRight) { // Check collision from above (landing on platform) if (self.y >= plat.y && self.y <= plat.y + 30 && self.velocityY >= 0) { self.y = plat.y; self.velocityY = 0; self.onGround = true; break; } } } // Keep enemy on platform if (self.x < 40) { self.x = 40; } if (self.x > 2008) { self.x = 2008; } }; return self; }); var BigEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('bigEnemy', { anchorX: 0.5, anchorY: 1.0 }); self.velocityX = 0; self.velocityY = 0; self.onGround = false; self.speed = 12; // Much faster than regular enemies self.gravity = 0.8; self.direction = 1; self.update = function () { // Apply gravity self.velocityY += self.gravity; // Move only from right to left self.velocityX = -self.speed; self.direction = -1; // Apply velocity var currentTimeMultiplier = slowMotionActive ? 0.3 : 1; self.x += self.velocityX * currentTimeMultiplier; self.y += self.velocityY * currentTimeMultiplier; // Check platform collisions self.onGround = false; for (var i = 0; i < platforms.length; i++) { var plat = platforms[i]; var platLeft = plat.obj.x - plat.width / 2; var platRight = plat.obj.x + plat.width / 2; // Check if enemy is within platform bounds horizontally if (self.x >= platLeft && self.x <= platRight) { // Check collision from above (landing on platform) if (self.y >= plat.y && self.y <= plat.y + 30 && self.velocityY >= 0) { self.y = plat.y; self.velocityY = 0; self.onGround = true; break; } } } // Mark for removal when far off screen if (self.x < -400 || self.x > 2448) { self.shouldRemove = true; } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.speed = 12; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; // Mark for removal when off screen if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) { self.shouldRemove = true; } }; return self; }); var Collectible = Container.expand(function () { var self = Container.call(this); var collectibleGraphics = self.attachAsset('collectible', { anchorX: 0.5, anchorY: 0.5 }); // Add a gentle floating animation self.floatOffset = 0; self.update = function () { self.floatOffset += 0.1; self.y += Math.sin(self.floatOffset) * 0.5; }; return self; }); var DPad = Container.expand(function () { var self = Container.call(this); var sharedBackground = self.attachAsset('dpadBackground', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, scaleX: 2.0, scaleY: 2.0, alpha: 0.5 }); var leftButton = self.attachAsset('dpadLeftButton', { anchorX: 0.5, anchorY: 0.5, x: -60, y: 0 }); var rightButton = self.attachAsset('dpadRightButton', { anchorX: 0.5, anchorY: 0.5, x: 60, y: 0 }); var upButton = self.attachAsset('dpadUpButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -60 }); self.leftPressed = false; self.rightPressed = false; self.upPressed = false; leftButton.down = function () { self.leftPressed = true; leftButton.alpha = 0.5; }; leftButton.up = function () { self.leftPressed = false; leftButton.alpha = 1.0; }; rightButton.down = function () { self.rightPressed = true; rightButton.alpha = 0.5; }; rightButton.up = function () { self.rightPressed = false; rightButton.alpha = 1.0; }; upButton.down = function () { self.upPressed = true; upButton.alpha = 0.5; player.jump(); }; upButton.up = function () { self.upPressed = false; upButton.alpha = 1.0; }; self.update = function () { if (self.leftPressed) { player.moveLeft(); } if (self.rightPressed) { player.moveRight(); } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 1.0 }); self.velocityX = 0; self.velocityY = 0; self.onGround = false; self.speed = 3; self.gravity = 0.8; self.direction = 1; self.update = function () { // Apply gravity self.velocityY += self.gravity; // Move only from right to left self.velocityX = -self.speed; self.direction = -1; // Apply velocity var currentTimeMultiplier = slowMotionActive ? 0.3 : 1; self.x += self.velocityX * currentTimeMultiplier; self.y += self.velocityY * currentTimeMultiplier; // Check platform collisions self.onGround = false; for (var i = 0; i < platforms.length; i++) { var plat = platforms[i]; var platLeft = plat.obj.x - plat.width / 2; var platRight = plat.obj.x + plat.width / 2; // Check if enemy is within platform bounds horizontally if (self.x >= platLeft && self.x <= platRight) { // Check collision from above (landing on platform) if (self.y >= plat.y && self.y <= plat.y + 30 && self.velocityY >= 0) { self.y = plat.y; self.velocityY = 0; self.onGround = true; break; } } } // Mark for removal when far off screen if (self.x < -200 || self.x > 2248) { self.shouldRemove = true; } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 1.0 }); self.velocityX = 0; self.velocityY = 0; self.onGround = false; self.speed = 8; self.jumpPower = -25; self.gravity = 0.8; self.direction = 1; // 1 for right, -1 for left self.update = function () { // Apply gravity self.velocityY += self.gravity; // Apply velocity // Player movement is not affected by slow motion self.x += self.velocityX; self.y += self.velocityY; // Check platform collisions self.onGround = false; for (var i = 0; i < platforms.length; i++) { var plat = platforms[i]; var platLeft = plat.obj.x - plat.width / 2; var platRight = plat.obj.x + plat.width / 2; // Check if player is within platform bounds horizontally if (self.x >= platLeft && self.x <= platRight) { // Check collision from above (landing on platform) if (self.y >= plat.y && self.y <= plat.y + 30 && self.velocityY >= 0) { self.y = plat.y; self.velocityY = 0; self.onGround = true; break; } } } // Keep player on screen if (self.x < 40) { self.x = 40; } if (self.x > 2008) { self.x = 2008; } // Apply friction self.velocityX *= 0.8; }; self.moveLeft = function () { self.velocityX = -self.speed; if (self.direction !== -1) { self.direction = -1; playerGraphics.scaleX = -1; // Flip sprite to face left } }; self.moveRight = function () { self.velocityX = self.speed; if (self.direction !== 1) { self.direction = 1; playerGraphics.scaleX = 1; // Flip sprite to face right } }; self.jump = function () { if (self.onGround) { self.velocityY = self.jumpPower; self.onGround = false; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var gameStarted = false; var mainMenuScreen = null; var startGameButton = null; var platformY = 2500; var enemies = []; var bigEnemies = []; var attackingEnemies = []; var enemySpawnTimer = 0; var enemySpawnRate = 180; var bigEnemySpawnTimer = 0; var bigEnemySpawnRate = 600; // Spawn every 10 seconds initially var gameSpeed = 1; var platforms = []; var slowMotionActive = false; var slowMotionDuration = 0; var slowMotionCooldown = 0; var slowMotionMaxDuration = 180; // 3 seconds at 60fps var slowMotionMaxCooldown = 600; // 10 seconds at 60fps var collectible = null; var collectibleSpawned = false; var gameWon = false; var victoryAsset = null; var victoryAssetSpawned = false; var teleportDestination = null; var bullets = []; var gameEndAsset = null; var gameEndAssetSpawned = false; var gameEnded = false; var gameEndScreen = null; var gameEndText = null; var playAgainButton = null; // Create main platform var platform = game.addChild(LK.getAsset('platform', { anchorX: 0.5, anchorY: 0.0, x: 1024, y: platformY })); platforms.push({ obj: platform, y: platformY, width: 2048 }); // Create first floating platform var floatingPlatform1 = game.addChild(LK.getAsset('smallPlatform', { anchorX: 0.5, anchorY: 0.0, x: 500, y: platformY - 400 })); platforms.push({ obj: floatingPlatform1, y: platformY - 400, width: 300 }); // Create second floating platform var floatingPlatform2 = game.addChild(LK.getAsset('smallPlatform', { anchorX: 0.5, anchorY: 0.0, x: 1024, y: platformY - 500 })); platforms.push({ obj: floatingPlatform2, y: platformY - 500, width: 300 }); // Create third floating platform var floatingPlatform3 = game.addChild(LK.getAsset('smallPlatform', { anchorX: 0.5, anchorY: 0.0, x: 1548, y: platformY - 400 })); platforms.push({ obj: floatingPlatform3, y: platformY - 400, width: 300 }); // Create player var player = game.addChild(new Player()); player.x = 1024; player.y = platformY; // Create D-pad var dpad = new DPad(); dpad.x = 150; dpad.y = -150; dpad.scaleX = 1.5; dpad.scaleY = 1.5; dpad.visible = false; // Hide initially LK.gui.bottomLeft.addChild(dpad); // Create slow motion button var slowMotionButton = LK.getAsset('slowMotionButton', { anchorX: 0.5, anchorY: 0.5 }); slowMotionButton.x = 150; slowMotionButton.y = -450; slowMotionButton.scaleX = 1.2; slowMotionButton.scaleY = 1.2; // Create countdown text for slow motion button var slowMotionCountdownText = new Text2('', { size: 30, fill: 0x000000 }); slowMotionCountdownText.anchor.set(0.5, 0.5); slowMotionCountdownText.x = 150; slowMotionCountdownText.y = -450; slowMotionCountdownText.visible = false; // Hide initially LK.gui.bottomLeft.addChild(slowMotionCountdownText); slowMotionButton.down = function () { if (!slowMotionActive && slowMotionCooldown <= 0) { slowMotionActive = true; slowMotionDuration = slowMotionMaxDuration; slowMotionButton.alpha = 0.5; } }; slowMotionButton.up = function () { // Button up logic if needed }; slowMotionButton.visible = false; // Hide initially LK.gui.bottomLeft.addChild(slowMotionButton); // Create shoot button var shootButton = LK.getAsset('fireButton', { anchorX: 0.5, anchorY: 0.5 }); shootButton.x = 150; shootButton.y = -600; shootButton.scaleX = 1.2; shootButton.scaleY = 1.2; shootButton.tint = 0xff4444; // Red tint to differentiate from slow motion button shootButton.visible = false; // Hide initially shootButton.down = function () { // Only allow shooting when in teleport destination if (teleportDestination) { var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y - 50; // Shoot in the direction player is facing bullet.velocityX = player.direction * bullet.speed; bullet.velocityY = -2; // Slight upward trajectory bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); shootButton.alpha = 0.5; } }; shootButton.up = function () { shootButton.alpha = 1.0; }; LK.gui.bottomLeft.addChild(shootButton); function spawnEnemy() { var enemy = new Enemy(); // Only spawn enemies from the right side enemy.x = 2024; enemy.y = platformY; enemy.lastIntersecting = false; enemies.push(enemy); game.addChild(enemy); } function spawnBigEnemy() { var bigEnemy = new BigEnemy(); // Only spawn from the right side bigEnemy.x = 2128; // From right bigEnemy.y = platformY; bigEnemy.lastIntersecting = false; bigEnemies.push(bigEnemy); game.addChild(bigEnemy); } function showMainMenu() { if (gameStarted) return; // Create black background that covers entire screen mainMenuScreen = game.addChild(LK.getAsset('gameEndBackground', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 })); // Create game title var titleText = new Text2('Time Loop', { size: 140, fill: 0xFFFFFF, font: "'Arial Black', Arial, sans-serif" }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 1000; game.addChild(titleText); // Create start game button startGameButton = game.addChild(LK.getAsset('startGameButton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1400 })); // Create start game button text var startGameText = new Text2('Start Game', { size: 70, fill: 0xFFFFFF, font: "'Arial Black', Arial, sans-serif" }); startGameText.anchor.set(0.5, 0.5); startGameText.x = 1024; startGameText.y = 1400; game.addChild(startGameText); // Set up start game button functionality startGameButton.down = function () { // Hide menu elements mainMenuScreen.destroy(); titleText.destroy(); startGameButton.destroy(); startGameText.destroy(); // Start the game gameStarted = true; mainMenuScreen = null; startGameButton = null; // Show game UI elements dpad.visible = true; slowMotionButton.visible = true; slowMotionCountdownText.visible = true; }; } function showGameEndScreen() { if (gameEnded) return; gameEnded = true; // Hide control buttons dpad.visible = false; slowMotionButton.visible = false; shootButton.visible = false; slowMotionCountdownText.visible = false; // Create black background that covers entire screen gameEndScreen = game.addChild(LK.getAsset('gameEndBackground', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 })); // Create "You escaped from time loop" text gameEndText = new Text2('You escaped from time loop', { size: 120, fill: 0xFFFFFF, font: "'Arial Black', Arial, sans-serif" }); gameEndText.anchor.set(0.5, 0.5); gameEndText.x = 1024; gameEndText.y = 1200; game.addChild(gameEndText); // Create left gameEnd asset var leftGameEndAsset = game.addChild(LK.getAsset('gameEndAsset', { anchorX: 0.5, anchorY: 0.5, x: 300, y: 1366 })); // Create right gameEnd asset var rightGameEndAsset = game.addChild(LK.getAsset('gameEndAsset', { anchorX: 0.5, anchorY: 0.5, x: 1748, y: 1366 })); // Create play again button playAgainButton = game.addChild(LK.getAsset('playAgainButton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1450 })); // Create play again button text var playAgainText = new Text2('Play Again', { size: 60, fill: 0xFFFFFF, font: "'Arial Black', Arial, sans-serif" }); playAgainText.anchor.set(0.5, 0.5); playAgainText.x = 1024; playAgainText.y = 1450; game.addChild(playAgainText); // Set up play again button functionality playAgainButton.down = function () { // Hide end screen elements gameEndScreen.destroy(); gameEndText.destroy(); leftGameEndAsset.destroy(); rightGameEndAsset.destroy(); playAgainButton.destroy(); playAgainText.destroy(); // Show control buttons again dpad.visible = true; slowMotionButton.visible = true; if (teleportDestination) { shootButton.visible = true; } slowMotionCountdownText.visible = true; // Reset game state gameEnded = false; gameStarted = false; gameEndScreen = null; gameEndText = null; playAgainButton = null; // Restart the game by calling LK.showGameOver which will reset everything LK.showGameOver(); }; } function checkCollisions() { // Check regular enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (player.intersects(enemy)) { // Check if player is above enemy (stomping) var playerBottom = player.y; var enemyTop = enemy.y - 140; var playerVelocityY = player.velocityY; if (playerBottom <= enemyTop + 20 && playerVelocityY >= 0) { // Player stomped enemy LK.getSound('stomp').play(); LK.setScore(LK.getScore() + 10); // Make player bounce player.velocityY = -8; // Remove enemy enemy.destroy(); enemies.splice(i, 1); // Increase game speed slightly gameSpeed += 0.01; if (enemySpawnRate > 60) { enemySpawnRate -= 1; } // Flash effect LK.effects.flashObject(enemy, 0xffff00, 200); } else { // Player touched enemy from side - game over LK.getSound('die').play(); LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } } } // Check big enemies for (var i = bigEnemies.length - 1; i >= 0; i--) { var bigEnemy = bigEnemies[i]; if (player.intersects(bigEnemy)) { // Big enemy kills player on any contact - cannot be stomped LK.getSound('die').play(); LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } } // Check collectible collision if (collectible && player.intersects(collectible)) { // Player collected the special item collectible.destroy(); collectible = null; // Create victory asset on main platform center if (!victoryAssetSpawned) { victoryAsset = game.addChild(LK.getAsset('starAsset', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: platformY - 60 })); victoryAssetSpawned = true; } } // Check attacking enemies for (var i = attackingEnemies.length - 1; i >= 0; i--) { var attackingEnemy = attackingEnemies[i]; if (player.intersects(attackingEnemy)) { // Check if player is above enemy (stomping) var playerBottom = player.y; var enemyTop = attackingEnemy.y - 140; var playerVelocityY = player.velocityY; if (playerBottom <= enemyTop + 20 && playerVelocityY >= 0) { // Player stomped attacking enemy LK.getSound('stomp').play(); LK.setScore(LK.getScore() + 20); // Make player bounce player.velocityY = -8; // Remove attacking enemy attackingEnemy.destroy(); attackingEnemies.splice(i, 1); // Flash effect LK.effects.flashObject(attackingEnemy, 0xffff00, 200); } else { // Player touched attacking enemy from side - game over LK.getSound('die').play(); LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } } } // Check bullet collisions with attacking enemies for (var b = bullets.length - 1; b >= 0; b--) { var bullet = bullets[b]; for (var i = attackingEnemies.length - 1; i >= 0; i--) { var attackingEnemy = attackingEnemies[i]; if (bullet.intersects(attackingEnemy)) { // Bullet hit attacking enemy LK.getSound('stomp').play(); LK.setScore(LK.getScore() + 30); // Remove bullet and enemy bullet.destroy(); bullets.splice(b, 1); attackingEnemy.destroy(); attackingEnemies.splice(i, 1); // Spawn game end asset if (!gameEndAssetSpawned) { gameEndAsset = game.addChild(LK.getAsset('gameEndAsset', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: platformY - 150 })); gameEndAssetSpawned = true; } break; } } } // Check game end asset collision if (gameEndAsset && player.intersects(gameEndAsset)) { showGameEndScreen(); } // Check star asset collision for teleportation if (victoryAsset && player.intersects(victoryAsset)) { // Create teleportation destination with only main platform if (!teleportDestination) { // Clear existing level elements for (var i = 0; i < platforms.length; i++) { if (platforms[i].obj !== platform) { platforms[i].obj.destroy(); } } // Destroy the original main platform platform.destroy(); // Create new teleport platform var teleportPlatform = game.addChild(LK.getAsset('teleportPlatform', { anchorX: 0.5, anchorY: 0.0, x: 1024, y: platformY })); // Reset platforms array to only contain teleport platform platforms = [{ obj: teleportPlatform, y: platformY, width: 2048 }]; // Clear all enemies for (var i = enemies.length - 1; i >= 0; i--) { enemies[i].destroy(); enemies.splice(i, 1); } for (var i = bigEnemies.length - 1; i >= 0; i--) { bigEnemies[i].destroy(); bigEnemies.splice(i, 1); } // Clear all attacking enemies for (var i = attackingEnemies.length - 1; i >= 0; i--) { attackingEnemies[i].destroy(); attackingEnemies.splice(i, 1); } // Set teleportation destination flag teleportDestination = true; // Show shoot button after teleportation shootButton.visible = true; // Teleport player to the destination player.x = 1024; player.y = platformY; // Destroy the original star asset victoryAsset.destroy(); victoryAsset = null; // Spawn attacking enemy var attackingEnemy = new AttackingEnemy(); attackingEnemy.x = 1500; // Spawn to the right of player attackingEnemy.y = platformY; attackingEnemy.lastIntersecting = false; attackingEnemies.push(attackingEnemy); game.addChild(attackingEnemy); } } } // Show main menu when game starts showMainMenu(); game.update = function () { // Only update game if it has started if (!gameStarted) return; // Handle slow motion state var timeMultiplier = 1; if (slowMotionActive) { timeMultiplier = 0.3; // Slow down time to 30% speed slowMotionDuration--; slowMotionCountdownText.setText(''); if (slowMotionDuration <= 0) { slowMotionActive = false; slowMotionCooldown = slowMotionMaxCooldown; slowMotionButton.alpha = 0.3; } } else if (slowMotionCooldown > 0) { slowMotionCooldown--; var secondsLeft = Math.ceil(slowMotionCooldown / 60); slowMotionCountdownText.setText(secondsLeft.toString()); if (slowMotionCooldown <= 0) { slowMotionButton.alpha = 1.0; slowMotionCountdownText.setText(''); } } else { slowMotionCountdownText.setText(''); } // Update D-pad input if (dpad && dpad.update) { dpad.update(); } // Check if collectible should spawn if (LK.getScore() >= 100 && !collectibleSpawned && !gameWon) { // Destroy all enemies when reaching 100 points for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; enemy.destroy(); enemies.splice(i, 1); } // Destroy all big enemies when reaching 100 points for (var i = bigEnemies.length - 1; i >= 0; i--) { var bigEnemy = bigEnemies[i]; bigEnemy.destroy(); bigEnemies.splice(i, 1); } collectible = new Collectible(); collectible.x = 1024; // Center of top platform collectible.y = platformY - 530; // On top of the highest platform game.addChild(collectible); collectibleSpawned = true; } // Only spawn enemies if collectible hasn't been spawned yet if (!collectibleSpawned && !gameWon) { // Update enemy spawn timer enemySpawnTimer += timeMultiplier; if (enemySpawnTimer >= enemySpawnRate) { spawnEnemy(); enemySpawnTimer = 0; } // Update big enemy spawn timer bigEnemySpawnTimer += timeMultiplier; if (bigEnemySpawnTimer >= bigEnemySpawnRate) { spawnBigEnemy(); bigEnemySpawnTimer = 0; // Randomize next spawn time (between 8-15 seconds) bigEnemySpawnRate = 480 + Math.random() * 420; } } // Check collisions checkCollisions(); // Remove enemies that fall off screen or go off sides for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (enemy.y > 2800 || enemy.shouldRemove) { enemy.destroy(); enemies.splice(i, 1); } } // Remove big enemies that fall off screen or go off sides for (var i = bigEnemies.length - 1; i >= 0; i--) { var bigEnemy = bigEnemies[i]; if (bigEnemy.y > 2800 || bigEnemy.shouldRemove) { bigEnemy.destroy(); bigEnemies.splice(i, 1); // When a big enemy is removed, schedule another one to spawn soon bigEnemySpawnTimer = bigEnemySpawnRate - 120; // Spawn another in 2 seconds } } // Update enemy speed based on game speed for (var i = 0; i < enemies.length; i++) { enemies[i].speed = 3 * gameSpeed; } // Update big enemy speed based on game speed for (var i = 0; i < bigEnemies.length; i++) { bigEnemies[i].speed = 12 * gameSpeed; } // Remove attacking enemies that fall off screen for (var i = attackingEnemies.length - 1; i >= 0; i--) { var attackingEnemy = attackingEnemies[i]; if (attackingEnemy.y > 2800) { attackingEnemy.destroy(); attackingEnemies.splice(i, 1); } } // Remove bullets that are off screen for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.shouldRemove) { bullet.destroy(); bullets.splice(i, 1); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AttackingEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('attackingEnemy', {
anchorX: 0.5,
anchorY: 1.0
});
self.velocityX = 0;
self.velocityY = 0;
self.onGround = false;
self.speed = 4;
self.gravity = 0.8;
self.direction = 1;
self.attackRange = 300;
self.update = function () {
// Apply gravity
self.velocityY += self.gravity;
// Calculate direction to player
var distanceToPlayer = player.x - self.x;
var absoluteDistance = Math.abs(distanceToPlayer);
// Always move towards player (no range limit for chasing)
if (distanceToPlayer > 0) {
self.velocityX = self.speed; // Move right towards player
self.direction = 1;
enemyGraphics.scaleX = -1; // Face right
} else {
self.velocityX = -self.speed; // Move left towards player
self.direction = -1;
enemyGraphics.scaleX = 1; // Face left
}
// Apply velocity
var currentTimeMultiplier = slowMotionActive ? 0.3 : 1;
self.x += self.velocityX * currentTimeMultiplier;
self.y += self.velocityY * currentTimeMultiplier;
// Check platform collisions
self.onGround = false;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
var platLeft = plat.obj.x - plat.width / 2;
var platRight = plat.obj.x + plat.width / 2;
// Check if enemy is within platform bounds horizontally
if (self.x >= platLeft && self.x <= platRight) {
// Check collision from above (landing on platform)
if (self.y >= plat.y && self.y <= plat.y + 30 && self.velocityY >= 0) {
self.y = plat.y;
self.velocityY = 0;
self.onGround = true;
break;
}
}
}
// Keep enemy on platform
if (self.x < 40) {
self.x = 40;
}
if (self.x > 2008) {
self.x = 2008;
}
};
return self;
});
var BigEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('bigEnemy', {
anchorX: 0.5,
anchorY: 1.0
});
self.velocityX = 0;
self.velocityY = 0;
self.onGround = false;
self.speed = 12; // Much faster than regular enemies
self.gravity = 0.8;
self.direction = 1;
self.update = function () {
// Apply gravity
self.velocityY += self.gravity;
// Move only from right to left
self.velocityX = -self.speed;
self.direction = -1;
// Apply velocity
var currentTimeMultiplier = slowMotionActive ? 0.3 : 1;
self.x += self.velocityX * currentTimeMultiplier;
self.y += self.velocityY * currentTimeMultiplier;
// Check platform collisions
self.onGround = false;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
var platLeft = plat.obj.x - plat.width / 2;
var platRight = plat.obj.x + plat.width / 2;
// Check if enemy is within platform bounds horizontally
if (self.x >= platLeft && self.x <= platRight) {
// Check collision from above (landing on platform)
if (self.y >= plat.y && self.y <= plat.y + 30 && self.velocityY >= 0) {
self.y = plat.y;
self.velocityY = 0;
self.onGround = true;
break;
}
}
}
// Mark for removal when far off screen
if (self.x < -400 || self.x > 2448) {
self.shouldRemove = true;
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.speed = 12;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
// Mark for removal when off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.shouldRemove = true;
}
};
return self;
});
var Collectible = Container.expand(function () {
var self = Container.call(this);
var collectibleGraphics = self.attachAsset('collectible', {
anchorX: 0.5,
anchorY: 0.5
});
// Add a gentle floating animation
self.floatOffset = 0;
self.update = function () {
self.floatOffset += 0.1;
self.y += Math.sin(self.floatOffset) * 0.5;
};
return self;
});
var DPad = Container.expand(function () {
var self = Container.call(this);
var sharedBackground = self.attachAsset('dpadBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0,
scaleX: 2.0,
scaleY: 2.0,
alpha: 0.5
});
var leftButton = self.attachAsset('dpadLeftButton', {
anchorX: 0.5,
anchorY: 0.5,
x: -60,
y: 0
});
var rightButton = self.attachAsset('dpadRightButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 60,
y: 0
});
var upButton = self.attachAsset('dpadUpButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -60
});
self.leftPressed = false;
self.rightPressed = false;
self.upPressed = false;
leftButton.down = function () {
self.leftPressed = true;
leftButton.alpha = 0.5;
};
leftButton.up = function () {
self.leftPressed = false;
leftButton.alpha = 1.0;
};
rightButton.down = function () {
self.rightPressed = true;
rightButton.alpha = 0.5;
};
rightButton.up = function () {
self.rightPressed = false;
rightButton.alpha = 1.0;
};
upButton.down = function () {
self.upPressed = true;
upButton.alpha = 0.5;
player.jump();
};
upButton.up = function () {
self.upPressed = false;
upButton.alpha = 1.0;
};
self.update = function () {
if (self.leftPressed) {
player.moveLeft();
}
if (self.rightPressed) {
player.moveRight();
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 1.0
});
self.velocityX = 0;
self.velocityY = 0;
self.onGround = false;
self.speed = 3;
self.gravity = 0.8;
self.direction = 1;
self.update = function () {
// Apply gravity
self.velocityY += self.gravity;
// Move only from right to left
self.velocityX = -self.speed;
self.direction = -1;
// Apply velocity
var currentTimeMultiplier = slowMotionActive ? 0.3 : 1;
self.x += self.velocityX * currentTimeMultiplier;
self.y += self.velocityY * currentTimeMultiplier;
// Check platform collisions
self.onGround = false;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
var platLeft = plat.obj.x - plat.width / 2;
var platRight = plat.obj.x + plat.width / 2;
// Check if enemy is within platform bounds horizontally
if (self.x >= platLeft && self.x <= platRight) {
// Check collision from above (landing on platform)
if (self.y >= plat.y && self.y <= plat.y + 30 && self.velocityY >= 0) {
self.y = plat.y;
self.velocityY = 0;
self.onGround = true;
break;
}
}
}
// Mark for removal when far off screen
if (self.x < -200 || self.x > 2248) {
self.shouldRemove = true;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1.0
});
self.velocityX = 0;
self.velocityY = 0;
self.onGround = false;
self.speed = 8;
self.jumpPower = -25;
self.gravity = 0.8;
self.direction = 1; // 1 for right, -1 for left
self.update = function () {
// Apply gravity
self.velocityY += self.gravity;
// Apply velocity
// Player movement is not affected by slow motion
self.x += self.velocityX;
self.y += self.velocityY;
// Check platform collisions
self.onGround = false;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
var platLeft = plat.obj.x - plat.width / 2;
var platRight = plat.obj.x + plat.width / 2;
// Check if player is within platform bounds horizontally
if (self.x >= platLeft && self.x <= platRight) {
// Check collision from above (landing on platform)
if (self.y >= plat.y && self.y <= plat.y + 30 && self.velocityY >= 0) {
self.y = plat.y;
self.velocityY = 0;
self.onGround = true;
break;
}
}
}
// Keep player on screen
if (self.x < 40) {
self.x = 40;
}
if (self.x > 2008) {
self.x = 2008;
}
// Apply friction
self.velocityX *= 0.8;
};
self.moveLeft = function () {
self.velocityX = -self.speed;
if (self.direction !== -1) {
self.direction = -1;
playerGraphics.scaleX = -1; // Flip sprite to face left
}
};
self.moveRight = function () {
self.velocityX = self.speed;
if (self.direction !== 1) {
self.direction = 1;
playerGraphics.scaleX = 1; // Flip sprite to face right
}
};
self.jump = function () {
if (self.onGround) {
self.velocityY = self.jumpPower;
self.onGround = false;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var gameStarted = false;
var mainMenuScreen = null;
var startGameButton = null;
var platformY = 2500;
var enemies = [];
var bigEnemies = [];
var attackingEnemies = [];
var enemySpawnTimer = 0;
var enemySpawnRate = 180;
var bigEnemySpawnTimer = 0;
var bigEnemySpawnRate = 600; // Spawn every 10 seconds initially
var gameSpeed = 1;
var platforms = [];
var slowMotionActive = false;
var slowMotionDuration = 0;
var slowMotionCooldown = 0;
var slowMotionMaxDuration = 180; // 3 seconds at 60fps
var slowMotionMaxCooldown = 600; // 10 seconds at 60fps
var collectible = null;
var collectibleSpawned = false;
var gameWon = false;
var victoryAsset = null;
var victoryAssetSpawned = false;
var teleportDestination = null;
var bullets = [];
var gameEndAsset = null;
var gameEndAssetSpawned = false;
var gameEnded = false;
var gameEndScreen = null;
var gameEndText = null;
var playAgainButton = null;
// Create main platform
var platform = game.addChild(LK.getAsset('platform', {
anchorX: 0.5,
anchorY: 0.0,
x: 1024,
y: platformY
}));
platforms.push({
obj: platform,
y: platformY,
width: 2048
});
// Create first floating platform
var floatingPlatform1 = game.addChild(LK.getAsset('smallPlatform', {
anchorX: 0.5,
anchorY: 0.0,
x: 500,
y: platformY - 400
}));
platforms.push({
obj: floatingPlatform1,
y: platformY - 400,
width: 300
});
// Create second floating platform
var floatingPlatform2 = game.addChild(LK.getAsset('smallPlatform', {
anchorX: 0.5,
anchorY: 0.0,
x: 1024,
y: platformY - 500
}));
platforms.push({
obj: floatingPlatform2,
y: platformY - 500,
width: 300
});
// Create third floating platform
var floatingPlatform3 = game.addChild(LK.getAsset('smallPlatform', {
anchorX: 0.5,
anchorY: 0.0,
x: 1548,
y: platformY - 400
}));
platforms.push({
obj: floatingPlatform3,
y: platformY - 400,
width: 300
});
// Create player
var player = game.addChild(new Player());
player.x = 1024;
player.y = platformY;
// Create D-pad
var dpad = new DPad();
dpad.x = 150;
dpad.y = -150;
dpad.scaleX = 1.5;
dpad.scaleY = 1.5;
dpad.visible = false; // Hide initially
LK.gui.bottomLeft.addChild(dpad);
// Create slow motion button
var slowMotionButton = LK.getAsset('slowMotionButton', {
anchorX: 0.5,
anchorY: 0.5
});
slowMotionButton.x = 150;
slowMotionButton.y = -450;
slowMotionButton.scaleX = 1.2;
slowMotionButton.scaleY = 1.2;
// Create countdown text for slow motion button
var slowMotionCountdownText = new Text2('', {
size: 30,
fill: 0x000000
});
slowMotionCountdownText.anchor.set(0.5, 0.5);
slowMotionCountdownText.x = 150;
slowMotionCountdownText.y = -450;
slowMotionCountdownText.visible = false; // Hide initially
LK.gui.bottomLeft.addChild(slowMotionCountdownText);
slowMotionButton.down = function () {
if (!slowMotionActive && slowMotionCooldown <= 0) {
slowMotionActive = true;
slowMotionDuration = slowMotionMaxDuration;
slowMotionButton.alpha = 0.5;
}
};
slowMotionButton.up = function () {
// Button up logic if needed
};
slowMotionButton.visible = false; // Hide initially
LK.gui.bottomLeft.addChild(slowMotionButton);
// Create shoot button
var shootButton = LK.getAsset('fireButton', {
anchorX: 0.5,
anchorY: 0.5
});
shootButton.x = 150;
shootButton.y = -600;
shootButton.scaleX = 1.2;
shootButton.scaleY = 1.2;
shootButton.tint = 0xff4444; // Red tint to differentiate from slow motion button
shootButton.visible = false; // Hide initially
shootButton.down = function () {
// Only allow shooting when in teleport destination
if (teleportDestination) {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - 50;
// Shoot in the direction player is facing
bullet.velocityX = player.direction * bullet.speed;
bullet.velocityY = -2; // Slight upward trajectory
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
shootButton.alpha = 0.5;
}
};
shootButton.up = function () {
shootButton.alpha = 1.0;
};
LK.gui.bottomLeft.addChild(shootButton);
function spawnEnemy() {
var enemy = new Enemy();
// Only spawn enemies from the right side
enemy.x = 2024;
enemy.y = platformY;
enemy.lastIntersecting = false;
enemies.push(enemy);
game.addChild(enemy);
}
function spawnBigEnemy() {
var bigEnemy = new BigEnemy();
// Only spawn from the right side
bigEnemy.x = 2128; // From right
bigEnemy.y = platformY;
bigEnemy.lastIntersecting = false;
bigEnemies.push(bigEnemy);
game.addChild(bigEnemy);
}
function showMainMenu() {
if (gameStarted) return;
// Create black background that covers entire screen
mainMenuScreen = game.addChild(LK.getAsset('gameEndBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// Create game title
var titleText = new Text2('Time Loop', {
size: 140,
fill: 0xFFFFFF,
font: "'Arial Black', Arial, sans-serif"
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 1000;
game.addChild(titleText);
// Create start game button
startGameButton = game.addChild(LK.getAsset('startGameButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1400
}));
// Create start game button text
var startGameText = new Text2('Start Game', {
size: 70,
fill: 0xFFFFFF,
font: "'Arial Black', Arial, sans-serif"
});
startGameText.anchor.set(0.5, 0.5);
startGameText.x = 1024;
startGameText.y = 1400;
game.addChild(startGameText);
// Set up start game button functionality
startGameButton.down = function () {
// Hide menu elements
mainMenuScreen.destroy();
titleText.destroy();
startGameButton.destroy();
startGameText.destroy();
// Start the game
gameStarted = true;
mainMenuScreen = null;
startGameButton = null;
// Show game UI elements
dpad.visible = true;
slowMotionButton.visible = true;
slowMotionCountdownText.visible = true;
};
}
function showGameEndScreen() {
if (gameEnded) return;
gameEnded = true;
// Hide control buttons
dpad.visible = false;
slowMotionButton.visible = false;
shootButton.visible = false;
slowMotionCountdownText.visible = false;
// Create black background that covers entire screen
gameEndScreen = game.addChild(LK.getAsset('gameEndBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// Create "You escaped from time loop" text
gameEndText = new Text2('You escaped from time loop', {
size: 120,
fill: 0xFFFFFF,
font: "'Arial Black', Arial, sans-serif"
});
gameEndText.anchor.set(0.5, 0.5);
gameEndText.x = 1024;
gameEndText.y = 1200;
game.addChild(gameEndText);
// Create left gameEnd asset
var leftGameEndAsset = game.addChild(LK.getAsset('gameEndAsset', {
anchorX: 0.5,
anchorY: 0.5,
x: 300,
y: 1366
}));
// Create right gameEnd asset
var rightGameEndAsset = game.addChild(LK.getAsset('gameEndAsset', {
anchorX: 0.5,
anchorY: 0.5,
x: 1748,
y: 1366
}));
// Create play again button
playAgainButton = game.addChild(LK.getAsset('playAgainButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1450
}));
// Create play again button text
var playAgainText = new Text2('Play Again', {
size: 60,
fill: 0xFFFFFF,
font: "'Arial Black', Arial, sans-serif"
});
playAgainText.anchor.set(0.5, 0.5);
playAgainText.x = 1024;
playAgainText.y = 1450;
game.addChild(playAgainText);
// Set up play again button functionality
playAgainButton.down = function () {
// Hide end screen elements
gameEndScreen.destroy();
gameEndText.destroy();
leftGameEndAsset.destroy();
rightGameEndAsset.destroy();
playAgainButton.destroy();
playAgainText.destroy();
// Show control buttons again
dpad.visible = true;
slowMotionButton.visible = true;
if (teleportDestination) {
shootButton.visible = true;
}
slowMotionCountdownText.visible = true;
// Reset game state
gameEnded = false;
gameStarted = false;
gameEndScreen = null;
gameEndText = null;
playAgainButton = null;
// Restart the game by calling LK.showGameOver which will reset everything
LK.showGameOver();
};
}
function checkCollisions() {
// Check regular enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (player.intersects(enemy)) {
// Check if player is above enemy (stomping)
var playerBottom = player.y;
var enemyTop = enemy.y - 140;
var playerVelocityY = player.velocityY;
if (playerBottom <= enemyTop + 20 && playerVelocityY >= 0) {
// Player stomped enemy
LK.getSound('stomp').play();
LK.setScore(LK.getScore() + 10);
// Make player bounce
player.velocityY = -8;
// Remove enemy
enemy.destroy();
enemies.splice(i, 1);
// Increase game speed slightly
gameSpeed += 0.01;
if (enemySpawnRate > 60) {
enemySpawnRate -= 1;
}
// Flash effect
LK.effects.flashObject(enemy, 0xffff00, 200);
} else {
// Player touched enemy from side - game over
LK.getSound('die').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}
}
// Check big enemies
for (var i = bigEnemies.length - 1; i >= 0; i--) {
var bigEnemy = bigEnemies[i];
if (player.intersects(bigEnemy)) {
// Big enemy kills player on any contact - cannot be stomped
LK.getSound('die').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}
// Check collectible collision
if (collectible && player.intersects(collectible)) {
// Player collected the special item
collectible.destroy();
collectible = null;
// Create victory asset on main platform center
if (!victoryAssetSpawned) {
victoryAsset = game.addChild(LK.getAsset('starAsset', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: platformY - 60
}));
victoryAssetSpawned = true;
}
}
// Check attacking enemies
for (var i = attackingEnemies.length - 1; i >= 0; i--) {
var attackingEnemy = attackingEnemies[i];
if (player.intersects(attackingEnemy)) {
// Check if player is above enemy (stomping)
var playerBottom = player.y;
var enemyTop = attackingEnemy.y - 140;
var playerVelocityY = player.velocityY;
if (playerBottom <= enemyTop + 20 && playerVelocityY >= 0) {
// Player stomped attacking enemy
LK.getSound('stomp').play();
LK.setScore(LK.getScore() + 20);
// Make player bounce
player.velocityY = -8;
// Remove attacking enemy
attackingEnemy.destroy();
attackingEnemies.splice(i, 1);
// Flash effect
LK.effects.flashObject(attackingEnemy, 0xffff00, 200);
} else {
// Player touched attacking enemy from side - game over
LK.getSound('die').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}
}
// Check bullet collisions with attacking enemies
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
for (var i = attackingEnemies.length - 1; i >= 0; i--) {
var attackingEnemy = attackingEnemies[i];
if (bullet.intersects(attackingEnemy)) {
// Bullet hit attacking enemy
LK.getSound('stomp').play();
LK.setScore(LK.getScore() + 30);
// Remove bullet and enemy
bullet.destroy();
bullets.splice(b, 1);
attackingEnemy.destroy();
attackingEnemies.splice(i, 1);
// Spawn game end asset
if (!gameEndAssetSpawned) {
gameEndAsset = game.addChild(LK.getAsset('gameEndAsset', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: platformY - 150
}));
gameEndAssetSpawned = true;
}
break;
}
}
}
// Check game end asset collision
if (gameEndAsset && player.intersects(gameEndAsset)) {
showGameEndScreen();
}
// Check star asset collision for teleportation
if (victoryAsset && player.intersects(victoryAsset)) {
// Create teleportation destination with only main platform
if (!teleportDestination) {
// Clear existing level elements
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].obj !== platform) {
platforms[i].obj.destroy();
}
}
// Destroy the original main platform
platform.destroy();
// Create new teleport platform
var teleportPlatform = game.addChild(LK.getAsset('teleportPlatform', {
anchorX: 0.5,
anchorY: 0.0,
x: 1024,
y: platformY
}));
// Reset platforms array to only contain teleport platform
platforms = [{
obj: teleportPlatform,
y: platformY,
width: 2048
}];
// Clear all enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
enemies.splice(i, 1);
}
for (var i = bigEnemies.length - 1; i >= 0; i--) {
bigEnemies[i].destroy();
bigEnemies.splice(i, 1);
}
// Clear all attacking enemies
for (var i = attackingEnemies.length - 1; i >= 0; i--) {
attackingEnemies[i].destroy();
attackingEnemies.splice(i, 1);
}
// Set teleportation destination flag
teleportDestination = true;
// Show shoot button after teleportation
shootButton.visible = true;
// Teleport player to the destination
player.x = 1024;
player.y = platformY;
// Destroy the original star asset
victoryAsset.destroy();
victoryAsset = null;
// Spawn attacking enemy
var attackingEnemy = new AttackingEnemy();
attackingEnemy.x = 1500; // Spawn to the right of player
attackingEnemy.y = platformY;
attackingEnemy.lastIntersecting = false;
attackingEnemies.push(attackingEnemy);
game.addChild(attackingEnemy);
}
}
}
// Show main menu when game starts
showMainMenu();
game.update = function () {
// Only update game if it has started
if (!gameStarted) return;
// Handle slow motion state
var timeMultiplier = 1;
if (slowMotionActive) {
timeMultiplier = 0.3; // Slow down time to 30% speed
slowMotionDuration--;
slowMotionCountdownText.setText('');
if (slowMotionDuration <= 0) {
slowMotionActive = false;
slowMotionCooldown = slowMotionMaxCooldown;
slowMotionButton.alpha = 0.3;
}
} else if (slowMotionCooldown > 0) {
slowMotionCooldown--;
var secondsLeft = Math.ceil(slowMotionCooldown / 60);
slowMotionCountdownText.setText(secondsLeft.toString());
if (slowMotionCooldown <= 0) {
slowMotionButton.alpha = 1.0;
slowMotionCountdownText.setText('');
}
} else {
slowMotionCountdownText.setText('');
}
// Update D-pad input
if (dpad && dpad.update) {
dpad.update();
}
// Check if collectible should spawn
if (LK.getScore() >= 100 && !collectibleSpawned && !gameWon) {
// Destroy all enemies when reaching 100 points
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.destroy();
enemies.splice(i, 1);
}
// Destroy all big enemies when reaching 100 points
for (var i = bigEnemies.length - 1; i >= 0; i--) {
var bigEnemy = bigEnemies[i];
bigEnemy.destroy();
bigEnemies.splice(i, 1);
}
collectible = new Collectible();
collectible.x = 1024; // Center of top platform
collectible.y = platformY - 530; // On top of the highest platform
game.addChild(collectible);
collectibleSpawned = true;
}
// Only spawn enemies if collectible hasn't been spawned yet
if (!collectibleSpawned && !gameWon) {
// Update enemy spawn timer
enemySpawnTimer += timeMultiplier;
if (enemySpawnTimer >= enemySpawnRate) {
spawnEnemy();
enemySpawnTimer = 0;
}
// Update big enemy spawn timer
bigEnemySpawnTimer += timeMultiplier;
if (bigEnemySpawnTimer >= bigEnemySpawnRate) {
spawnBigEnemy();
bigEnemySpawnTimer = 0;
// Randomize next spawn time (between 8-15 seconds)
bigEnemySpawnRate = 480 + Math.random() * 420;
}
}
// Check collisions
checkCollisions();
// Remove enemies that fall off screen or go off sides
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.y > 2800 || enemy.shouldRemove) {
enemy.destroy();
enemies.splice(i, 1);
}
}
// Remove big enemies that fall off screen or go off sides
for (var i = bigEnemies.length - 1; i >= 0; i--) {
var bigEnemy = bigEnemies[i];
if (bigEnemy.y > 2800 || bigEnemy.shouldRemove) {
bigEnemy.destroy();
bigEnemies.splice(i, 1);
// When a big enemy is removed, schedule another one to spawn soon
bigEnemySpawnTimer = bigEnemySpawnRate - 120; // Spawn another in 2 seconds
}
}
// Update enemy speed based on game speed
for (var i = 0; i < enemies.length; i++) {
enemies[i].speed = 3 * gameSpeed;
}
// Update big enemy speed based on game speed
for (var i = 0; i < bigEnemies.length; i++) {
bigEnemies[i].speed = 12 * gameSpeed;
}
// Remove attacking enemies that fall off screen
for (var i = attackingEnemies.length - 1; i >= 0; i--) {
var attackingEnemy = attackingEnemies[i];
if (attackingEnemy.y > 2800) {
attackingEnemy.destroy();
attackingEnemies.splice(i, 1);
}
}
// Remove bullets that are off screen
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.shouldRemove) {
bullet.destroy();
bullets.splice(i, 1);
}
}
};
yuvarlak içinde bir kum küresi. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
daire içinde sola bakan bir ok. In-Game asset. 2d. High contrast. No shadows
eski bir saat. In-Game asset. 2d. High contrast. No shadows
metal platform. In-Game asset. 2d. High contrast. No shadows
Çim zemin. In-Game asset. 2d. High contrast. No shadows
Dinozor. In-Game asset. 2d. High contrast. No shadows
Büyük kum saati. In-Game asset. 2d. High contrast. No shadows
Işın. In-Game asset. 2d. High contrast. No shadows
Daire içinde mavi ışın In-Game asset. 2d. High contrast. No shadows