/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var Alien = Container.expand(function () { var self = Container.call(this); var alienGraphics = self.attachAsset('alien', { anchorX: 0.5, anchorY: 0.5 }); self.health = 2; self.speed = 1; self.direction = 1; self.moveRange = 200; self.startX = 0; self.active = true; self.lastWasHit = false; self.takeDamage = function () { self.health--; if (self.health <= 0) { self.active = false; LK.getSound('alienDestroy').play(); // Flash effect before destruction tween(alienGraphics, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, onFinish: function onFinish() { self.destroy(); } }); } else { LK.getSound('alienHit').play(); // Flash red when hit LK.effects.flashObject(self, 0xff0000, 200); } }; self.update = function () { if (!self.active) return; // Move alien horizontally self.x += self.direction * self.speed; // Reverse direction when reaching movement limits if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) { self.direction *= -1; } // Keep alien within screen bounds if (self.x < 40) { self.x = 40; self.direction = 1; } if (self.x > 2008) { self.x = 2008; self.direction = -1; } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.direction = { x: 0, y: -1 }; // Default upward direction self.active = true; self.update = function () { self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; // Remove bullet if it goes off screen if (self.y < cameraY - 200 || self.y > cameraY + 2732 + 200 || self.x < -100 || self.x > 2148) { self.active = false; } }; return self; }); var Coin = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; self.rotationSpeed = 0.1; self.update = function () { // Rotate coin for visual appeal coinGraphics.rotation += self.rotationSpeed; // Float up and down slightly self.y += Math.sin(LK.ticks * 0.05) * 0.5; }; return self; }); var Dude = Container.expand(function () { var self = Container.call(this); var dudeGraphics = self.attachAsset('dude', { anchorX: 0.5, anchorY: 0.5 }); self.velocityY = 0; self.velocityX = 0; self.isJumping = false; self.isOnPlatform = false; self.jumpPower = 35; self.gravity = 0.8; self.maxFallSpeed = 15; self.horizontalSpeed = 12; self.airResistance = 0.85; self.invincible = false; self.invincibleTimer = 0; self.health = 4; self.maxHealth = 4; self.jump = function () { if (self.isOnPlatform) { self.velocityY = -self.jumpPower; self.isJumping = true; self.isOnPlatform = false; LK.getSound('jump').play(); } }; self.update = function () { // Auto jump when on platform (only if not flying) if (self.isOnPlatform && !self.canFly) { self.jump(); } // Apply gravity (reduced if flying) if (self.canFly) { self.velocityY += self.gravity * 0.5; // Reduced gravity for flying } else { self.velocityY += self.gravity; } if (self.velocityY > self.maxFallSpeed) { self.velocityY = self.maxFallSpeed; } // Update position self.y += self.velocityY; self.x += self.velocityX; // Apply continuous horizontal movement while pressed if (isPressed && pressedSide !== 0) { self.velocityX += pressedSide * self.horizontalSpeed * 0.3; } // Apply air resistance to horizontal movement self.velocityX *= self.airResistance; // Handle invincibility timer if (self.invincible) { self.invincibleTimer--; if (self.invincibleTimer <= 0) { self.invincible = false; dudeGraphics.alpha = 1; } else { dudeGraphics.alpha = Math.sin(self.invincibleTimer * 0.3) * 0.5 + 0.5; } } // Allow infinite horizontal movement - no bounds restriction // Character can now move infinitely left and right // Check if fallen off screen if (self.y > cameraY + 2732 + 200) { // Reset gold to zero when player falls off screen gold = 0; storage.gold = 0; goldTxt.setText('Gold: ' + gold); // Reset total height when player dies totalHeight = 0; storage.totalHeight = 0; LK.showGameOver(); } }; self.takeDamage = function () { if (self.invincible) return; self.health--; self.invincible = true; self.invincibleTimer = 180; // 3 seconds of invincibility LK.effects.flashObject(self, 0xff0000, 500); updateHealthDisplay(); if (self.health <= 0) { // Reset gold to zero when player dies gold = 0; storage.gold = 0; goldTxt.setText('Gold: ' + gold); // Reset total height when player dies totalHeight = 0; storage.totalHeight = 0; LK.showGameOver(); } }; self.shoot = function (direction) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; // Set bullet direction based on parameter if (direction === 'up') { bullet.direction = { x: 0, y: -1 }; bullet.y = self.y - 30; } else if (direction === 'down') { bullet.direction = { x: 0, y: 1 }; bullet.y = self.y + 30; } else if (direction === 'left') { bullet.direction = { x: -1, y: 0 }; bullet.x = self.x - 30; } else if (direction === 'right') { bullet.direction = { x: 1, y: 0 }; bullet.x = self.x + 30; } bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); }; return self; }); var Platform = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'normal'; self.landed = false; self.disappearing = false; self.moveDirection = 1; self.moveRange = 300; self.startX = 0; var platformGraphics; if (self.type === 'moving') { platformGraphics = self.attachAsset('movingPlatform', { anchorX: 0.5, anchorY: 0.5 }); } else if (self.type === 'disappearing') { platformGraphics = self.attachAsset('disappearingPlatform', { anchorX: 0.5, anchorY: 0.5 }); } else if (self.type === 'powerup') { platformGraphics = self.attachAsset('powerUpPlatform', { anchorX: 0.5, anchorY: 0.5 }); } else { platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); } self.update = function () { // Moving platform behavior if (self.type === 'moving') { self.x += self.moveDirection * 2; if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) { self.moveDirection *= -1; } } // Disappearing platform behavior if (self.type === 'disappearing' && self.landed && !self.disappearing) { self.disappearing = true; tween(platformGraphics, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { self.active = false; } }); } }; return self; }); var Saw = Container.expand(function () { var self = Container.call(this); var sawGraphics = self.attachAsset('saw', { anchorX: 0.5, anchorY: 0.5 }); self.active = true; self.rotationSpeed = 0.3; self.lastWasIntersecting = false; self.moveDirection = Math.random() < 0.5 ? -1 : 1; // Random initial direction self.moveSpeed = 2; self.moveRange = 150; self.startX = 0; self.update = function () { // Move saw horizontally self.x += self.moveDirection * self.moveSpeed; // Reverse direction when reaching movement limits if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) { self.moveDirection *= -1; } // Keep saw within screen bounds if (self.x < 60) { self.x = 60; self.moveDirection = 1; } if (self.x > 1988) { self.x = 1988; self.moveDirection = -1; } }; return self; }); var SpecialItem = Container.expand(function (itemType) { var self = Container.call(this); self.itemType = itemType || 1; var assetId = 'specialItem' + self.itemType; var itemGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Make special items larger itemGraphics.scaleX = 2; itemGraphics.scaleY = 2; self.collected = false; self.active = true; self.rotationSpeed = 0.15; self.floatOffset = Math.random() * Math.PI * 2; self.update = function () { // Float up and down with more pronounced animation self.y += Math.sin(LK.ticks * 0.06 + self.floatOffset) * 1.2; // Pulsing scale effect var pulseScale = 2 + Math.sin(LK.ticks * 0.08) * 0.3; itemGraphics.scaleX = pulseScale; itemGraphics.scaleY = pulseScale; }; return self; }); var Trampoline = Container.expand(function () { var self = Container.call(this); var trampolineGraphics = self.attachAsset('trampoline', { anchorX: 0.5, anchorY: 0.5 }); self.bounced = false; self.active = true; self.bounce = function () { // Animate trampoline compression and expansion tween(trampolineGraphics, { scaleY: 0.5 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(trampolineGraphics, { scaleY: 1.2 }, { duration: 200, easing: tween.bounceOut, onFinish: function onFinish() { tween(trampolineGraphics, { scaleY: 1 }, { duration: 100, easing: tween.easeOut }); } }); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb }); /**** * Game Code ****/ var dude = game.addChild(new Dude()); var platforms = []; var coins = []; var bullets = []; var trampolines = []; var cameraY = 0; var highestY = 2400; var lastPlatformY = 2400; var platformSpacing = 200; var coinsCollected = 0; var gold = storage.gold || 0; var totalHeight = storage.totalHeight || 0; var lastShootTime = 0; var shootCooldown = 20; // 20 ticks between shots var aliens = []; var aliensKilled = 0; var saws = []; var specialItems = []; var specialItemsCollected = 0; var totalSpecialItems = 4; var zombiesKilled = 0; // Create score display var scoreTxt = new Text2('0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create height display var heightTxt = new Text2('Height: 0m', { size: 40, fill: 0xFFFFFF }); heightTxt.anchor.set(1, 0); heightTxt.x = -20; heightTxt.y = 20; LK.gui.topRight.addChild(heightTxt); // Create coin counter display var coinTxt = new Text2('Coins: 0', { size: 40, fill: 0xffd700 }); coinTxt.anchor.set(0, 0); coinTxt.x = 20; coinTxt.y = 20; LK.gui.topLeft.addChild(coinTxt); // Create gold display var goldTxt = new Text2('Gold: ' + gold, { size: 40, fill: 0xffd700 }); goldTxt.anchor.set(0, 0); goldTxt.x = 20; goldTxt.y = 120; LK.gui.topLeft.addChild(goldTxt); // Create special items display var specialItemsTxt = new Text2('Special Items: 0/' + totalSpecialItems, { size: 40, fill: 0xff0000 }); specialItemsTxt.anchor.set(0, 0); specialItemsTxt.x = 20; specialItemsTxt.y = 170; LK.gui.topLeft.addChild(specialItemsTxt); // Create health display var hearts = []; function createHealthDisplay() { for (var i = 0; i < dude.maxHealth; i++) { var heart = LK.getAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); heart.x = 20 + i * 50; heart.y = 80; hearts.push(heart); LK.gui.topLeft.addChild(heart); } } function updateHealthDisplay() { for (var i = 0; i < hearts.length; i++) { hearts[i].alpha = i < dude.health ? 1 : 0.3; } } // Initialize dude position dude.x = 1024; dude.y = 2400; // Initialize health display createHealthDisplay(); updateHealthDisplay(); // Create fire buttons for 4 directions var fireButtonUp = LK.getAsset('fireButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); fireButtonUp.x = -120; fireButtonUp.y = -300; LK.gui.bottomRight.addChild(fireButtonUp); var fireButtonDown = LK.getAsset('fireButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); fireButtonDown.x = -120; fireButtonDown.y = -100; fireButtonDown.rotation = Math.PI; // Rotate 180 degrees LK.gui.bottomRight.addChild(fireButtonDown); var fireButtonLeft = LK.getAsset('fireButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); fireButtonLeft.x = -220; fireButtonLeft.y = -200; fireButtonLeft.rotation = Math.PI * 1.5; // Rotate 270 degrees LK.gui.bottomRight.addChild(fireButtonLeft); var fireButtonRight = LK.getAsset('fireButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); fireButtonRight.x = -20; fireButtonRight.y = -200; fireButtonRight.rotation = Math.PI * 0.5; // Rotate 90 degrees LK.gui.bottomRight.addChild(fireButtonRight); // Create initial platforms function createPlatform(x, y, type) { var platform = new Platform(type); platform.x = x; platform.y = y; platform.startX = x; platform.active = true; platforms.push(platform); game.addChild(platform); return platform; } // Create starting platform createPlatform(1024, 2450, 'normal'); // Generate initial platforms for (var i = 0; i < 20; i++) { generateNextPlatform(); } function generateNextPlatform() { lastPlatformY -= platformSpacing + Math.random() * 100; var x = 200 + Math.random() * 1648; // Determine platform type based on height var type = 'normal'; var height = Math.abs(lastPlatformY - 2400); if (height > 1000) { var rand = Math.random(); var powerupChance = spaceThemeActivated ? 0.8 : 0.6; // Increased from 0.6 to 0.8 in space theme if (rand < 0.3) { type = 'moving'; } else if (rand < 0.5) { type = 'disappearing'; } else if (rand < powerupChance) { type = 'powerup'; } } createPlatform(x, lastPlatformY, type); // Generate coins near platforms (70% chance) if (Math.random() < 0.7) { generateCoin(x + (Math.random() - 0.5) * 200, lastPlatformY - 80); } // Generate trampolines occasionally (5% chance, 15% in space theme) var trampolineChance = spaceThemeActivated ? 0.15 : 0.05; if (Math.random() < trampolineChance) { createTrampoline(x, lastPlatformY - 100); } // Generate aliens occasionally (5% chance, 20% in space theme) var alienChance = spaceThemeActivated ? 0.20 : 0.05; if (Math.random() < alienChance) { createAlien(x + (Math.random() - 0.5) * 300, lastPlatformY - 150); } // Kittens removed from game // Generate saws occasionally (5% chance, 15% in space theme) var sawChance = spaceThemeActivated ? 0.15 : 0.05; if (Math.random() < sawChance) { createSaw(x + (Math.random() - 0.5) * 300, lastPlatformY - 100); } // Generate special items frequently (10% chance) and only if we haven't collected all yet if (Math.random() < 0.10 && specialItemsCollected < totalSpecialItems) { var nextItemType = specialItemsCollected + 1; createSpecialItem(x + (Math.random() - 0.5) * 200, lastPlatformY - 150, nextItemType); } } function generateCoin(x, y) { var coin = new Coin(); coin.x = x; coin.y = y; coin.active = true; coins.push(coin); game.addChild(coin); } function createTrampoline(x, y) { var trampoline = new Trampoline(); trampoline.x = x; trampoline.y = y; trampoline.active = true; trampolines.push(trampoline); game.addChild(trampoline); return trampoline; } function createAlien(x, y) { var alien = new Alien(); alien.x = x; alien.y = y; alien.startX = x; alien.active = true; aliens.push(alien); game.addChild(alien); return alien; } function createSaw(x, y) { var saw = new Saw(); saw.x = x; saw.y = y; saw.startX = x; saw.active = true; saw.lastWasIntersecting = false; saws.push(saw); game.addChild(saw); return saw; } function createSpecialItem(x, y, itemType) { var item = new SpecialItem(itemType); item.x = x; item.y = y; item.active = true; specialItems.push(item); game.addChild(item); return item; } function updateCamera() { var targetY = dude.y - 1800; if (targetY < cameraY) { cameraY = targetY; game.y = -cameraY; // Update highest position if (dude.y < highestY) { highestY = dude.y; var currentHeight = Math.floor((2400 - highestY) / 10); var displayHeight = totalHeight + currentHeight; LK.setScore(displayHeight); scoreTxt.setText(LK.getScore()); heightTxt.setText('Height: ' + displayHeight + 'm'); } } } function checkPlatformCollisions() { for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; if (!platform.active) continue; // Define dude and platform boundaries var dudeLeft = dude.x - 40; var dudeRight = dude.x + 40; var dudeTop = dude.y - 40; var dudeBottom = dude.y + 40; var platformLeft = platform.x - 150; var platformRight = platform.x + 150; var platformTop = platform.y - 15; var platformBottom = platform.y + 15; // Check if dude and platform are overlapping horizontally and vertically var horizontalOverlap = dudeRight > platformLeft && dudeLeft < platformRight; var verticalOverlap = dudeBottom > platformTop && dudeTop < platformBottom; if (horizontalOverlap && verticalOverlap) { // Calculate overlap distances for each direction var overlapLeft = dudeRight - platformLeft; var overlapRight = platformRight - dudeLeft; var overlapTop = dudeBottom - platformTop; var overlapBottom = platformBottom - dudeTop; // Find the smallest overlap to determine collision direction var minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom); // Handle collision based on the direction with smallest overlap if (minOverlap === overlapTop && dude.velocityY > 0) { // Landing on top of platform (falling down) dude.y = platformTop - 40; dude.velocityY = 0; dude.isOnPlatform = true; dude.isJumping = false; if (!platform.landed) { platform.landed = true; LK.getSound('land').play(); // Handle special platform effects if (platform.type === 'powerup') { dude.invincible = true; dude.invincibleTimer = 300; dude.jumpPower = 105; // Triple the normal jump power (35 * 3) LK.getSound('powerup').play(); // Reset jump power after 1 second using tween for precise timing LK.setTimeout(function () { dude.jumpPower = 35; // Reset to normal jump power }, 1000); // Changed from 3000ms to 1000ms (1 second) } } } else if (minOverlap === overlapLeft && dude.velocityX > 0) { // Hitting platform from the left (moving right) dude.x = platformLeft - 40; dude.velocityX = 0; } else if (minOverlap === overlapRight && dude.velocityX < 0) { // Hitting platform from the right (moving left) dude.x = platformRight + 40; dude.velocityX = 0; } break; } } } function checkCoinCollisions() { for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; if (!coin.active || coin.collected) continue; // Check if dude is close enough to collect coin var distance = Math.sqrt(Math.pow(dude.x - coin.x, 2) + Math.pow(dude.y - coin.y, 2)); if (distance < 50) { // Collect coin coin.collected = true; coin.active = false; coinsCollected++; coinTxt.setText('Coins: ' + coinsCollected); LK.getSound('coinCollect').play(); // Check if player reached 20 coins if (coinsCollected >= 20) { // Show bravo message LK.showYouWin(); } // Remove coin with fade effect tween(coin, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 200, onFinish: function onFinish() { coin.destroy(); coins.splice(i, 1); } }); } } } function checkTrampolineCollisions() { if (dude.velocityY <= 0) return; // Only check when falling for (var i = 0; i < trampolines.length; i++) { var trampoline = trampolines[i]; if (!trampoline.active) continue; var dudeBottom = dude.y + 40; var trampolineTop = trampoline.y - 30; var trampolineBottom = trampoline.y + 30; if (dudeBottom >= trampolineTop && dudeBottom <= trampolineBottom + 20) { if (dude.x >= trampoline.x - 150 && dude.x <= trampoline.x + 150) { // Bounce off trampoline with super jump dude.velocityY = -60; // Much higher than normal jump dude.isJumping = true; dude.isOnPlatform = false; trampoline.bounce(); LK.getSound('jump').play(); break; } } } } function checkBulletAlienCollisions() { for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (!bullet.active) continue; for (var j = aliens.length - 1; j >= 0; j--) { var alien = aliens[j]; if (!alien.active) continue; // Check collision between bullet and alien var distance = Math.sqrt(Math.pow(bullet.x - alien.x, 2) + Math.pow(bullet.y - alien.y, 2)); if (distance < 50) { // Hit detected bullet.active = false; bullet.destroy(); bullets.splice(i, 1); alien.takeDamage(); if (!alien.active) { aliensKilled++; aliens.splice(j, 1); // Increase score for killing alien LK.setScore(LK.getScore() + 10); scoreTxt.setText(LK.getScore()); // Give gold reward with 50% chance (100/2 = 50%) if (Math.random() < 0.5) { gold += 1; storage.gold = gold; goldTxt.setText('Gold: ' + gold); } // Check if player killed 3 UFOs if (aliensKilled >= 3) { // Show bravo message LK.showYouWin(); } } break; } } } } function cleanupPlatforms() { for (var i = platforms.length - 1; i >= 0; i--) { var platform = platforms[i]; if (platform.y > cameraY + 3000 || !platform.active) { platform.destroy(); platforms.splice(i, 1); } } } function cleanupCoins() { for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; if (coin.y > cameraY + 3000 || !coin.active) { coin.destroy(); coins.splice(i, 1); } } } function cleanupBullets() { for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.y < cameraY - 200 || !bullet.active) { bullet.destroy(); bullets.splice(i, 1); } } } function cleanupTrampolines() { for (var i = trampolines.length - 1; i >= 0; i--) { var trampoline = trampolines[i]; if (trampoline.y > cameraY + 3000 || !trampoline.active) { trampoline.destroy(); trampolines.splice(i, 1); } } } function checkSpecialItemCollisions() { for (var i = specialItems.length - 1; i >= 0; i--) { var item = specialItems[i]; if (!item.active || item.collected) continue; // Check if dude is close enough to collect special item var distance = Math.sqrt(Math.pow(dude.x - item.x, 2) + Math.pow(dude.y - item.y, 2)); if (distance < 60) { // Collect special item item.collected = true; item.active = false; specialItemsCollected++; specialItemsTxt.setText('Special Items: ' + specialItemsCollected + '/' + totalSpecialItems); // Visual feedback - dramatic collection effect LK.effects.flashScreen(0xff0000, 500); tween(item, { alpha: 0, scaleX: 4, scaleY: 4 }, { duration: 500, onFinish: function onFinish() { item.destroy(); specialItems.splice(i, 1); } }); // Check if all special items collected if (specialItemsCollected >= totalSpecialItems) { // Show you win message LK.showYouWin(); } break; } } } function checkAlienPlayerCollisions() { if (dude.invincible) return; for (var i = 0; i < aliens.length; i++) { var alien = aliens[i]; if (!alien.active) continue; var distance = Math.sqrt(Math.pow(dude.x - alien.x, 2) + Math.pow(dude.y - alien.y, 2)); if (distance < 60) { dude.takeDamage(); break; } } } function checkSawPlayerCollisions() { if (dude.invincible) return; for (var i = 0; i < saws.length; i++) { var saw = saws[i]; if (!saw.active) continue; var distance = Math.sqrt(Math.pow(dude.x - saw.x, 2) + Math.pow(dude.y - saw.y, 2)); var currentIntersecting = distance < 70; // Check for transition from not intersecting to intersecting if (!saw.lastWasIntersecting && currentIntersecting) { dude.takeDamage(); } // Update last intersecting state saw.lastWasIntersecting = currentIntersecting; } } function cleanupAliens() { for (var i = aliens.length - 1; i >= 0; i--) { var alien = aliens[i]; if (alien.y > cameraY + 3000 || !alien.active) { if (alien.active) { alien.destroy(); } aliens.splice(i, 1); } } } function cleanupSaws() { for (var i = saws.length - 1; i >= 0; i--) { var saw = saws[i]; if (saw.y > cameraY + 3000 || !saw.active) { if (saw.active) { saw.destroy(); } saws.splice(i, 1); } } } function cleanupSpecialItems() { for (var i = specialItems.length - 1; i >= 0; i--) { var item = specialItems[i]; if (item.y > cameraY + 3000 || !item.active) { if (item.active) { item.destroy(); } specialItems.splice(i, 1); } } } function generateMorePlatforms() { while (lastPlatformY > cameraY - 1000) { generateNextPlatform(); } } // Touch controls var isPressed = false; var pressedSide = 0; // -1 for left, 1 for right, 0 for center game.down = function (x, y, obj) { dude.jump(); isPressed = true; // Determine which side was pressed var screenCenter = 1024; // Half of 2048 var touchOffset = x - screenCenter; if (touchOffset > 50) { pressedSide = 1; // Right side } else if (touchOffset < -50) { pressedSide = -1; // Left side } else { pressedSide = 0; // Center } // Shoot when touching center area if (Math.abs(touchOffset) <= 50 && LK.ticks - lastShootTime >= shootCooldown) { dude.shoot('up'); lastShootTime = LK.ticks; } }; game.up = function (x, y, obj) { isPressed = false; pressedSide = 0; }; // Fire button touch handlers for 4 directions function createFireButtonHandler(button, direction) { button.down = function (x, y, obj) { if (LK.ticks - lastShootTime >= shootCooldown) { dude.shoot(direction); lastShootTime = LK.ticks; // Visual feedback - scale animation tween(button, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, onFinish: function onFinish() { tween(button, { scaleX: 1.5, scaleY: 1.5 }, { duration: 100 }); } }); } }; } createFireButtonHandler(fireButtonUp, 'up'); createFireButtonHandler(fireButtonDown, 'down'); createFireButtonHandler(fireButtonLeft, 'left'); createFireButtonHandler(fireButtonRight, 'right'); // Track if space theme has been activated var spaceThemeActivated = false; // Track if 1500m jump boost has been applied var jumpBoostApplied = false; // Track if 1200m horizontal speed boost has been applied var speedBoostApplied = false; // Track if 4000m jumpscare has been triggered var jumpscareTriggered = false; // Main game loop game.update = function () { updateCamera(); checkPlatformCollisions(); checkTrampolineCollisions(); checkCoinCollisions(); checkSpecialItemCollisions(); checkBulletAlienCollisions(); checkAlienPlayerCollisions(); checkSawPlayerCollisions(); generateMorePlatforms(); // Calculate current and total height var currentHeight = Math.floor((2400 - dude.y) / 10); var displayHeight = totalHeight + currentHeight; // Check if player reached 4000m height for jumpscare if (displayHeight >= 4000 && !jumpscareTriggered) { jumpscareTriggered = true; // Create scary alien jumpscare that covers the entire screen var jumpscareAlien = LK.getAsset('alien', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 20, alpha: 0 }); jumpscareAlien.x = 1024; // Center of screen jumpscareAlien.y = 1366; // Center of screen LK.gui.center.addChild(jumpscareAlien); // Play loud scary scream sound using microphone volume detection if (facekit.volume > 0.1) { // If player is making noise, make the sound even louder LK.getSound('jumpscare').play(); } else { LK.getSound('jumpscare').play(); } // Jumpscare animation with red flash and massive scaling LK.effects.flashScreen(0xff0000, 3000); // Red flash for 3 seconds tween(jumpscareAlien, { alpha: 1, scaleX: 25, scaleY: 25 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Hold for a longer moment with terrifying effect LK.setTimeout(function () { tween(jumpscareAlien, { alpha: 0, scaleX: 30, scaleY: 30 }, { duration: 1500, onFinish: function onFinish() { jumpscareAlien.destroy(); } }); }, 2000); } }); } // Check if player reached height 1200 and reset to starting position if (currentHeight >= 1200 && !speedBoostApplied) { speedBoostApplied = true; // Add current height to total height before reset totalHeight += 1200; storage.totalHeight = totalHeight; // Activate space theme when resetting after 1200m if (!spaceThemeActivated) { spaceThemeActivated = true; // Change background to dark space color game.setBackgroundColor(0x0a0a2e); // Dark blue-purple space color // Flash screen to indicate theme change LK.effects.flashScreen(0x8a2be2, 1000); // Purple flash for 1 second } // Reset character to starting position dude.x = 1024; dude.y = 2400; dude.velocityY = 0; dude.velocityX = 0; dude.isJumping = false; dude.isOnPlatform = false; // Reset camera cameraY = 0; game.y = -cameraY; highestY = 2400; // Reset current height tracking but keep total var newDisplayHeight = totalHeight; LK.setScore(newDisplayHeight); scoreTxt.setText(newDisplayHeight.toString()); heightTxt.setText('Height: ' + newDisplayHeight + 'm'); // Reset boost flags for next cycle jumpBoostApplied = false; speedBoostApplied = false; // Visual feedback for reset LK.effects.flashScreen(0x00ff00, 500); // Green flash } // Check if player reached height 1500 and boost jump power if (displayHeight >= 1500 && !jumpBoostApplied) { jumpBoostApplied = true; // Boost jump power by 1.5x (0.5x more than normal) dude.jumpPower = 52.5; // 35 * 1.5 = 52.5 // Visual feedback for power boost LK.effects.flashObject(dude, 0x00ff00, 500); // Green flash } // Remove platforms that are too far down if (LK.ticks % 60 === 0) { cleanupCoins(); cleanupBullets(); cleanupTrampolines(); cleanupAliens(); cleanupSaws(); cleanupSpecialItems(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
var Alien = Container.expand(function () {
var self = Container.call(this);
var alienGraphics = self.attachAsset('alien', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 2;
self.speed = 1;
self.direction = 1;
self.moveRange = 200;
self.startX = 0;
self.active = true;
self.lastWasHit = false;
self.takeDamage = function () {
self.health--;
if (self.health <= 0) {
self.active = false;
LK.getSound('alienDestroy').play();
// Flash effect before destruction
tween(alienGraphics, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
}
});
} else {
LK.getSound('alienHit').play();
// Flash red when hit
LK.effects.flashObject(self, 0xff0000, 200);
}
};
self.update = function () {
if (!self.active) return;
// Move alien horizontally
self.x += self.direction * self.speed;
// Reverse direction when reaching movement limits
if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) {
self.direction *= -1;
}
// Keep alien within screen bounds
if (self.x < 40) {
self.x = 40;
self.direction = 1;
}
if (self.x > 2008) {
self.x = 2008;
self.direction = -1;
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.direction = {
x: 0,
y: -1
}; // Default upward direction
self.active = true;
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
// Remove bullet if it goes off screen
if (self.y < cameraY - 200 || self.y > cameraY + 2732 + 200 || self.x < -100 || self.x > 2148) {
self.active = false;
}
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.rotationSpeed = 0.1;
self.update = function () {
// Rotate coin for visual appeal
coinGraphics.rotation += self.rotationSpeed;
// Float up and down slightly
self.y += Math.sin(LK.ticks * 0.05) * 0.5;
};
return self;
});
var Dude = Container.expand(function () {
var self = Container.call(this);
var dudeGraphics = self.attachAsset('dude', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityY = 0;
self.velocityX = 0;
self.isJumping = false;
self.isOnPlatform = false;
self.jumpPower = 35;
self.gravity = 0.8;
self.maxFallSpeed = 15;
self.horizontalSpeed = 12;
self.airResistance = 0.85;
self.invincible = false;
self.invincibleTimer = 0;
self.health = 4;
self.maxHealth = 4;
self.jump = function () {
if (self.isOnPlatform) {
self.velocityY = -self.jumpPower;
self.isJumping = true;
self.isOnPlatform = false;
LK.getSound('jump').play();
}
};
self.update = function () {
// Auto jump when on platform (only if not flying)
if (self.isOnPlatform && !self.canFly) {
self.jump();
}
// Apply gravity (reduced if flying)
if (self.canFly) {
self.velocityY += self.gravity * 0.5; // Reduced gravity for flying
} else {
self.velocityY += self.gravity;
}
if (self.velocityY > self.maxFallSpeed) {
self.velocityY = self.maxFallSpeed;
}
// Update position
self.y += self.velocityY;
self.x += self.velocityX;
// Apply continuous horizontal movement while pressed
if (isPressed && pressedSide !== 0) {
self.velocityX += pressedSide * self.horizontalSpeed * 0.3;
}
// Apply air resistance to horizontal movement
self.velocityX *= self.airResistance;
// Handle invincibility timer
if (self.invincible) {
self.invincibleTimer--;
if (self.invincibleTimer <= 0) {
self.invincible = false;
dudeGraphics.alpha = 1;
} else {
dudeGraphics.alpha = Math.sin(self.invincibleTimer * 0.3) * 0.5 + 0.5;
}
}
// Allow infinite horizontal movement - no bounds restriction
// Character can now move infinitely left and right
// Check if fallen off screen
if (self.y > cameraY + 2732 + 200) {
// Reset gold to zero when player falls off screen
gold = 0;
storage.gold = 0;
goldTxt.setText('Gold: ' + gold);
// Reset total height when player dies
totalHeight = 0;
storage.totalHeight = 0;
LK.showGameOver();
}
};
self.takeDamage = function () {
if (self.invincible) return;
self.health--;
self.invincible = true;
self.invincibleTimer = 180; // 3 seconds of invincibility
LK.effects.flashObject(self, 0xff0000, 500);
updateHealthDisplay();
if (self.health <= 0) {
// Reset gold to zero when player dies
gold = 0;
storage.gold = 0;
goldTxt.setText('Gold: ' + gold);
// Reset total height when player dies
totalHeight = 0;
storage.totalHeight = 0;
LK.showGameOver();
}
};
self.shoot = function (direction) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
// Set bullet direction based on parameter
if (direction === 'up') {
bullet.direction = {
x: 0,
y: -1
};
bullet.y = self.y - 30;
} else if (direction === 'down') {
bullet.direction = {
x: 0,
y: 1
};
bullet.y = self.y + 30;
} else if (direction === 'left') {
bullet.direction = {
x: -1,
y: 0
};
bullet.x = self.x - 30;
} else if (direction === 'right') {
bullet.direction = {
x: 1,
y: 0
};
bullet.x = self.x + 30;
}
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
};
return self;
});
var Platform = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'normal';
self.landed = false;
self.disappearing = false;
self.moveDirection = 1;
self.moveRange = 300;
self.startX = 0;
var platformGraphics;
if (self.type === 'moving') {
platformGraphics = self.attachAsset('movingPlatform', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.type === 'disappearing') {
platformGraphics = self.attachAsset('disappearingPlatform', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.type === 'powerup') {
platformGraphics = self.attachAsset('powerUpPlatform', {
anchorX: 0.5,
anchorY: 0.5
});
} else {
platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
}
self.update = function () {
// Moving platform behavior
if (self.type === 'moving') {
self.x += self.moveDirection * 2;
if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) {
self.moveDirection *= -1;
}
}
// Disappearing platform behavior
if (self.type === 'disappearing' && self.landed && !self.disappearing) {
self.disappearing = true;
tween(platformGraphics, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.active = false;
}
});
}
};
return self;
});
var Saw = Container.expand(function () {
var self = Container.call(this);
var sawGraphics = self.attachAsset('saw', {
anchorX: 0.5,
anchorY: 0.5
});
self.active = true;
self.rotationSpeed = 0.3;
self.lastWasIntersecting = false;
self.moveDirection = Math.random() < 0.5 ? -1 : 1; // Random initial direction
self.moveSpeed = 2;
self.moveRange = 150;
self.startX = 0;
self.update = function () {
// Move saw horizontally
self.x += self.moveDirection * self.moveSpeed;
// Reverse direction when reaching movement limits
if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) {
self.moveDirection *= -1;
}
// Keep saw within screen bounds
if (self.x < 60) {
self.x = 60;
self.moveDirection = 1;
}
if (self.x > 1988) {
self.x = 1988;
self.moveDirection = -1;
}
};
return self;
});
var SpecialItem = Container.expand(function (itemType) {
var self = Container.call(this);
self.itemType = itemType || 1;
var assetId = 'specialItem' + self.itemType;
var itemGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
// Make special items larger
itemGraphics.scaleX = 2;
itemGraphics.scaleY = 2;
self.collected = false;
self.active = true;
self.rotationSpeed = 0.15;
self.floatOffset = Math.random() * Math.PI * 2;
self.update = function () {
// Float up and down with more pronounced animation
self.y += Math.sin(LK.ticks * 0.06 + self.floatOffset) * 1.2;
// Pulsing scale effect
var pulseScale = 2 + Math.sin(LK.ticks * 0.08) * 0.3;
itemGraphics.scaleX = pulseScale;
itemGraphics.scaleY = pulseScale;
};
return self;
});
var Trampoline = Container.expand(function () {
var self = Container.call(this);
var trampolineGraphics = self.attachAsset('trampoline', {
anchorX: 0.5,
anchorY: 0.5
});
self.bounced = false;
self.active = true;
self.bounce = function () {
// Animate trampoline compression and expansion
tween(trampolineGraphics, {
scaleY: 0.5
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(trampolineGraphics, {
scaleY: 1.2
}, {
duration: 200,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(trampolineGraphics, {
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var dude = game.addChild(new Dude());
var platforms = [];
var coins = [];
var bullets = [];
var trampolines = [];
var cameraY = 0;
var highestY = 2400;
var lastPlatformY = 2400;
var platformSpacing = 200;
var coinsCollected = 0;
var gold = storage.gold || 0;
var totalHeight = storage.totalHeight || 0;
var lastShootTime = 0;
var shootCooldown = 20; // 20 ticks between shots
var aliens = [];
var aliensKilled = 0;
var saws = [];
var specialItems = [];
var specialItemsCollected = 0;
var totalSpecialItems = 4;
var zombiesKilled = 0;
// Create score display
var scoreTxt = new Text2('0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create height display
var heightTxt = new Text2('Height: 0m', {
size: 40,
fill: 0xFFFFFF
});
heightTxt.anchor.set(1, 0);
heightTxt.x = -20;
heightTxt.y = 20;
LK.gui.topRight.addChild(heightTxt);
// Create coin counter display
var coinTxt = new Text2('Coins: 0', {
size: 40,
fill: 0xffd700
});
coinTxt.anchor.set(0, 0);
coinTxt.x = 20;
coinTxt.y = 20;
LK.gui.topLeft.addChild(coinTxt);
// Create gold display
var goldTxt = new Text2('Gold: ' + gold, {
size: 40,
fill: 0xffd700
});
goldTxt.anchor.set(0, 0);
goldTxt.x = 20;
goldTxt.y = 120;
LK.gui.topLeft.addChild(goldTxt);
// Create special items display
var specialItemsTxt = new Text2('Special Items: 0/' + totalSpecialItems, {
size: 40,
fill: 0xff0000
});
specialItemsTxt.anchor.set(0, 0);
specialItemsTxt.x = 20;
specialItemsTxt.y = 170;
LK.gui.topLeft.addChild(specialItemsTxt);
// Create health display
var hearts = [];
function createHealthDisplay() {
for (var i = 0; i < dude.maxHealth; i++) {
var heart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
heart.x = 20 + i * 50;
heart.y = 80;
hearts.push(heart);
LK.gui.topLeft.addChild(heart);
}
}
function updateHealthDisplay() {
for (var i = 0; i < hearts.length; i++) {
hearts[i].alpha = i < dude.health ? 1 : 0.3;
}
}
// Initialize dude position
dude.x = 1024;
dude.y = 2400;
// Initialize health display
createHealthDisplay();
updateHealthDisplay();
// Create fire buttons for 4 directions
var fireButtonUp = LK.getAsset('fireButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
fireButtonUp.x = -120;
fireButtonUp.y = -300;
LK.gui.bottomRight.addChild(fireButtonUp);
var fireButtonDown = LK.getAsset('fireButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
fireButtonDown.x = -120;
fireButtonDown.y = -100;
fireButtonDown.rotation = Math.PI; // Rotate 180 degrees
LK.gui.bottomRight.addChild(fireButtonDown);
var fireButtonLeft = LK.getAsset('fireButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
fireButtonLeft.x = -220;
fireButtonLeft.y = -200;
fireButtonLeft.rotation = Math.PI * 1.5; // Rotate 270 degrees
LK.gui.bottomRight.addChild(fireButtonLeft);
var fireButtonRight = LK.getAsset('fireButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
fireButtonRight.x = -20;
fireButtonRight.y = -200;
fireButtonRight.rotation = Math.PI * 0.5; // Rotate 90 degrees
LK.gui.bottomRight.addChild(fireButtonRight);
// Create initial platforms
function createPlatform(x, y, type) {
var platform = new Platform(type);
platform.x = x;
platform.y = y;
platform.startX = x;
platform.active = true;
platforms.push(platform);
game.addChild(platform);
return platform;
}
// Create starting platform
createPlatform(1024, 2450, 'normal');
// Generate initial platforms
for (var i = 0; i < 20; i++) {
generateNextPlatform();
}
function generateNextPlatform() {
lastPlatformY -= platformSpacing + Math.random() * 100;
var x = 200 + Math.random() * 1648;
// Determine platform type based on height
var type = 'normal';
var height = Math.abs(lastPlatformY - 2400);
if (height > 1000) {
var rand = Math.random();
var powerupChance = spaceThemeActivated ? 0.8 : 0.6; // Increased from 0.6 to 0.8 in space theme
if (rand < 0.3) {
type = 'moving';
} else if (rand < 0.5) {
type = 'disappearing';
} else if (rand < powerupChance) {
type = 'powerup';
}
}
createPlatform(x, lastPlatformY, type);
// Generate coins near platforms (70% chance)
if (Math.random() < 0.7) {
generateCoin(x + (Math.random() - 0.5) * 200, lastPlatformY - 80);
}
// Generate trampolines occasionally (5% chance, 15% in space theme)
var trampolineChance = spaceThemeActivated ? 0.15 : 0.05;
if (Math.random() < trampolineChance) {
createTrampoline(x, lastPlatformY - 100);
}
// Generate aliens occasionally (5% chance, 20% in space theme)
var alienChance = spaceThemeActivated ? 0.20 : 0.05;
if (Math.random() < alienChance) {
createAlien(x + (Math.random() - 0.5) * 300, lastPlatformY - 150);
}
// Kittens removed from game
// Generate saws occasionally (5% chance, 15% in space theme)
var sawChance = spaceThemeActivated ? 0.15 : 0.05;
if (Math.random() < sawChance) {
createSaw(x + (Math.random() - 0.5) * 300, lastPlatformY - 100);
}
// Generate special items frequently (10% chance) and only if we haven't collected all yet
if (Math.random() < 0.10 && specialItemsCollected < totalSpecialItems) {
var nextItemType = specialItemsCollected + 1;
createSpecialItem(x + (Math.random() - 0.5) * 200, lastPlatformY - 150, nextItemType);
}
}
function generateCoin(x, y) {
var coin = new Coin();
coin.x = x;
coin.y = y;
coin.active = true;
coins.push(coin);
game.addChild(coin);
}
function createTrampoline(x, y) {
var trampoline = new Trampoline();
trampoline.x = x;
trampoline.y = y;
trampoline.active = true;
trampolines.push(trampoline);
game.addChild(trampoline);
return trampoline;
}
function createAlien(x, y) {
var alien = new Alien();
alien.x = x;
alien.y = y;
alien.startX = x;
alien.active = true;
aliens.push(alien);
game.addChild(alien);
return alien;
}
function createSaw(x, y) {
var saw = new Saw();
saw.x = x;
saw.y = y;
saw.startX = x;
saw.active = true;
saw.lastWasIntersecting = false;
saws.push(saw);
game.addChild(saw);
return saw;
}
function createSpecialItem(x, y, itemType) {
var item = new SpecialItem(itemType);
item.x = x;
item.y = y;
item.active = true;
specialItems.push(item);
game.addChild(item);
return item;
}
function updateCamera() {
var targetY = dude.y - 1800;
if (targetY < cameraY) {
cameraY = targetY;
game.y = -cameraY;
// Update highest position
if (dude.y < highestY) {
highestY = dude.y;
var currentHeight = Math.floor((2400 - highestY) / 10);
var displayHeight = totalHeight + currentHeight;
LK.setScore(displayHeight);
scoreTxt.setText(LK.getScore());
heightTxt.setText('Height: ' + displayHeight + 'm');
}
}
}
function checkPlatformCollisions() {
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
if (!platform.active) continue;
// Define dude and platform boundaries
var dudeLeft = dude.x - 40;
var dudeRight = dude.x + 40;
var dudeTop = dude.y - 40;
var dudeBottom = dude.y + 40;
var platformLeft = platform.x - 150;
var platformRight = platform.x + 150;
var platformTop = platform.y - 15;
var platformBottom = platform.y + 15;
// Check if dude and platform are overlapping horizontally and vertically
var horizontalOverlap = dudeRight > platformLeft && dudeLeft < platformRight;
var verticalOverlap = dudeBottom > platformTop && dudeTop < platformBottom;
if (horizontalOverlap && verticalOverlap) {
// Calculate overlap distances for each direction
var overlapLeft = dudeRight - platformLeft;
var overlapRight = platformRight - dudeLeft;
var overlapTop = dudeBottom - platformTop;
var overlapBottom = platformBottom - dudeTop;
// Find the smallest overlap to determine collision direction
var minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom);
// Handle collision based on the direction with smallest overlap
if (minOverlap === overlapTop && dude.velocityY > 0) {
// Landing on top of platform (falling down)
dude.y = platformTop - 40;
dude.velocityY = 0;
dude.isOnPlatform = true;
dude.isJumping = false;
if (!platform.landed) {
platform.landed = true;
LK.getSound('land').play();
// Handle special platform effects
if (platform.type === 'powerup') {
dude.invincible = true;
dude.invincibleTimer = 300;
dude.jumpPower = 105; // Triple the normal jump power (35 * 3)
LK.getSound('powerup').play();
// Reset jump power after 1 second using tween for precise timing
LK.setTimeout(function () {
dude.jumpPower = 35; // Reset to normal jump power
}, 1000); // Changed from 3000ms to 1000ms (1 second)
}
}
} else if (minOverlap === overlapLeft && dude.velocityX > 0) {
// Hitting platform from the left (moving right)
dude.x = platformLeft - 40;
dude.velocityX = 0;
} else if (minOverlap === overlapRight && dude.velocityX < 0) {
// Hitting platform from the right (moving left)
dude.x = platformRight + 40;
dude.velocityX = 0;
}
break;
}
}
}
function checkCoinCollisions() {
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (!coin.active || coin.collected) continue;
// Check if dude is close enough to collect coin
var distance = Math.sqrt(Math.pow(dude.x - coin.x, 2) + Math.pow(dude.y - coin.y, 2));
if (distance < 50) {
// Collect coin
coin.collected = true;
coin.active = false;
coinsCollected++;
coinTxt.setText('Coins: ' + coinsCollected);
LK.getSound('coinCollect').play();
// Check if player reached 20 coins
if (coinsCollected >= 20) {
// Show bravo message
LK.showYouWin();
}
// Remove coin with fade effect
tween(coin, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
onFinish: function onFinish() {
coin.destroy();
coins.splice(i, 1);
}
});
}
}
}
function checkTrampolineCollisions() {
if (dude.velocityY <= 0) return; // Only check when falling
for (var i = 0; i < trampolines.length; i++) {
var trampoline = trampolines[i];
if (!trampoline.active) continue;
var dudeBottom = dude.y + 40;
var trampolineTop = trampoline.y - 30;
var trampolineBottom = trampoline.y + 30;
if (dudeBottom >= trampolineTop && dudeBottom <= trampolineBottom + 20) {
if (dude.x >= trampoline.x - 150 && dude.x <= trampoline.x + 150) {
// Bounce off trampoline with super jump
dude.velocityY = -60; // Much higher than normal jump
dude.isJumping = true;
dude.isOnPlatform = false;
trampoline.bounce();
LK.getSound('jump').play();
break;
}
}
}
}
function checkBulletAlienCollisions() {
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (!bullet.active) continue;
for (var j = aliens.length - 1; j >= 0; j--) {
var alien = aliens[j];
if (!alien.active) continue;
// Check collision between bullet and alien
var distance = Math.sqrt(Math.pow(bullet.x - alien.x, 2) + Math.pow(bullet.y - alien.y, 2));
if (distance < 50) {
// Hit detected
bullet.active = false;
bullet.destroy();
bullets.splice(i, 1);
alien.takeDamage();
if (!alien.active) {
aliensKilled++;
aliens.splice(j, 1);
// Increase score for killing alien
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
// Give gold reward with 50% chance (100/2 = 50%)
if (Math.random() < 0.5) {
gold += 1;
storage.gold = gold;
goldTxt.setText('Gold: ' + gold);
}
// Check if player killed 3 UFOs
if (aliensKilled >= 3) {
// Show bravo message
LK.showYouWin();
}
}
break;
}
}
}
}
function cleanupPlatforms() {
for (var i = platforms.length - 1; i >= 0; i--) {
var platform = platforms[i];
if (platform.y > cameraY + 3000 || !platform.active) {
platform.destroy();
platforms.splice(i, 1);
}
}
}
function cleanupCoins() {
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (coin.y > cameraY + 3000 || !coin.active) {
coin.destroy();
coins.splice(i, 1);
}
}
}
function cleanupBullets() {
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.y < cameraY - 200 || !bullet.active) {
bullet.destroy();
bullets.splice(i, 1);
}
}
}
function cleanupTrampolines() {
for (var i = trampolines.length - 1; i >= 0; i--) {
var trampoline = trampolines[i];
if (trampoline.y > cameraY + 3000 || !trampoline.active) {
trampoline.destroy();
trampolines.splice(i, 1);
}
}
}
function checkSpecialItemCollisions() {
for (var i = specialItems.length - 1; i >= 0; i--) {
var item = specialItems[i];
if (!item.active || item.collected) continue;
// Check if dude is close enough to collect special item
var distance = Math.sqrt(Math.pow(dude.x - item.x, 2) + Math.pow(dude.y - item.y, 2));
if (distance < 60) {
// Collect special item
item.collected = true;
item.active = false;
specialItemsCollected++;
specialItemsTxt.setText('Special Items: ' + specialItemsCollected + '/' + totalSpecialItems);
// Visual feedback - dramatic collection effect
LK.effects.flashScreen(0xff0000, 500);
tween(item, {
alpha: 0,
scaleX: 4,
scaleY: 4
}, {
duration: 500,
onFinish: function onFinish() {
item.destroy();
specialItems.splice(i, 1);
}
});
// Check if all special items collected
if (specialItemsCollected >= totalSpecialItems) {
// Show you win message
LK.showYouWin();
}
break;
}
}
}
function checkAlienPlayerCollisions() {
if (dude.invincible) return;
for (var i = 0; i < aliens.length; i++) {
var alien = aliens[i];
if (!alien.active) continue;
var distance = Math.sqrt(Math.pow(dude.x - alien.x, 2) + Math.pow(dude.y - alien.y, 2));
if (distance < 60) {
dude.takeDamage();
break;
}
}
}
function checkSawPlayerCollisions() {
if (dude.invincible) return;
for (var i = 0; i < saws.length; i++) {
var saw = saws[i];
if (!saw.active) continue;
var distance = Math.sqrt(Math.pow(dude.x - saw.x, 2) + Math.pow(dude.y - saw.y, 2));
var currentIntersecting = distance < 70;
// Check for transition from not intersecting to intersecting
if (!saw.lastWasIntersecting && currentIntersecting) {
dude.takeDamage();
}
// Update last intersecting state
saw.lastWasIntersecting = currentIntersecting;
}
}
function cleanupAliens() {
for (var i = aliens.length - 1; i >= 0; i--) {
var alien = aliens[i];
if (alien.y > cameraY + 3000 || !alien.active) {
if (alien.active) {
alien.destroy();
}
aliens.splice(i, 1);
}
}
}
function cleanupSaws() {
for (var i = saws.length - 1; i >= 0; i--) {
var saw = saws[i];
if (saw.y > cameraY + 3000 || !saw.active) {
if (saw.active) {
saw.destroy();
}
saws.splice(i, 1);
}
}
}
function cleanupSpecialItems() {
for (var i = specialItems.length - 1; i >= 0; i--) {
var item = specialItems[i];
if (item.y > cameraY + 3000 || !item.active) {
if (item.active) {
item.destroy();
}
specialItems.splice(i, 1);
}
}
}
function generateMorePlatforms() {
while (lastPlatformY > cameraY - 1000) {
generateNextPlatform();
}
}
// Touch controls
var isPressed = false;
var pressedSide = 0; // -1 for left, 1 for right, 0 for center
game.down = function (x, y, obj) {
dude.jump();
isPressed = true;
// Determine which side was pressed
var screenCenter = 1024; // Half of 2048
var touchOffset = x - screenCenter;
if (touchOffset > 50) {
pressedSide = 1; // Right side
} else if (touchOffset < -50) {
pressedSide = -1; // Left side
} else {
pressedSide = 0; // Center
}
// Shoot when touching center area
if (Math.abs(touchOffset) <= 50 && LK.ticks - lastShootTime >= shootCooldown) {
dude.shoot('up');
lastShootTime = LK.ticks;
}
};
game.up = function (x, y, obj) {
isPressed = false;
pressedSide = 0;
};
// Fire button touch handlers for 4 directions
function createFireButtonHandler(button, direction) {
button.down = function (x, y, obj) {
if (LK.ticks - lastShootTime >= shootCooldown) {
dude.shoot(direction);
lastShootTime = LK.ticks;
// Visual feedback - scale animation
tween(button, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(button, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 100
});
}
});
}
};
}
createFireButtonHandler(fireButtonUp, 'up');
createFireButtonHandler(fireButtonDown, 'down');
createFireButtonHandler(fireButtonLeft, 'left');
createFireButtonHandler(fireButtonRight, 'right');
// Track if space theme has been activated
var spaceThemeActivated = false;
// Track if 1500m jump boost has been applied
var jumpBoostApplied = false;
// Track if 1200m horizontal speed boost has been applied
var speedBoostApplied = false;
// Track if 4000m jumpscare has been triggered
var jumpscareTriggered = false;
// Main game loop
game.update = function () {
updateCamera();
checkPlatformCollisions();
checkTrampolineCollisions();
checkCoinCollisions();
checkSpecialItemCollisions();
checkBulletAlienCollisions();
checkAlienPlayerCollisions();
checkSawPlayerCollisions();
generateMorePlatforms();
// Calculate current and total height
var currentHeight = Math.floor((2400 - dude.y) / 10);
var displayHeight = totalHeight + currentHeight;
// Check if player reached 4000m height for jumpscare
if (displayHeight >= 4000 && !jumpscareTriggered) {
jumpscareTriggered = true;
// Create scary alien jumpscare that covers the entire screen
var jumpscareAlien = LK.getAsset('alien', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 20,
alpha: 0
});
jumpscareAlien.x = 1024; // Center of screen
jumpscareAlien.y = 1366; // Center of screen
LK.gui.center.addChild(jumpscareAlien);
// Play loud scary scream sound using microphone volume detection
if (facekit.volume > 0.1) {
// If player is making noise, make the sound even louder
LK.getSound('jumpscare').play();
} else {
LK.getSound('jumpscare').play();
}
// Jumpscare animation with red flash and massive scaling
LK.effects.flashScreen(0xff0000, 3000); // Red flash for 3 seconds
tween(jumpscareAlien, {
alpha: 1,
scaleX: 25,
scaleY: 25
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Hold for a longer moment with terrifying effect
LK.setTimeout(function () {
tween(jumpscareAlien, {
alpha: 0,
scaleX: 30,
scaleY: 30
}, {
duration: 1500,
onFinish: function onFinish() {
jumpscareAlien.destroy();
}
});
}, 2000);
}
});
}
// Check if player reached height 1200 and reset to starting position
if (currentHeight >= 1200 && !speedBoostApplied) {
speedBoostApplied = true;
// Add current height to total height before reset
totalHeight += 1200;
storage.totalHeight = totalHeight;
// Activate space theme when resetting after 1200m
if (!spaceThemeActivated) {
spaceThemeActivated = true;
// Change background to dark space color
game.setBackgroundColor(0x0a0a2e); // Dark blue-purple space color
// Flash screen to indicate theme change
LK.effects.flashScreen(0x8a2be2, 1000); // Purple flash for 1 second
}
// Reset character to starting position
dude.x = 1024;
dude.y = 2400;
dude.velocityY = 0;
dude.velocityX = 0;
dude.isJumping = false;
dude.isOnPlatform = false;
// Reset camera
cameraY = 0;
game.y = -cameraY;
highestY = 2400;
// Reset current height tracking but keep total
var newDisplayHeight = totalHeight;
LK.setScore(newDisplayHeight);
scoreTxt.setText(newDisplayHeight.toString());
heightTxt.setText('Height: ' + newDisplayHeight + 'm');
// Reset boost flags for next cycle
jumpBoostApplied = false;
speedBoostApplied = false;
// Visual feedback for reset
LK.effects.flashScreen(0x00ff00, 500); // Green flash
}
// Check if player reached height 1500 and boost jump power
if (displayHeight >= 1500 && !jumpBoostApplied) {
jumpBoostApplied = true;
// Boost jump power by 1.5x (0.5x more than normal)
dude.jumpPower = 52.5; // 35 * 1.5 = 52.5
// Visual feedback for power boost
LK.effects.flashObject(dude, 0x00ff00, 500); // Green flash
}
// Remove platforms that are too far down
if (LK.ticks % 60 === 0) {
cleanupCoins();
cleanupBullets();
cleanupTrampolines();
cleanupAliens();
cleanupSaws();
cleanupSpecialItems();
}
};
bir sevimli gülen yüzlü uzaylı. In-Game asset. 2d. High contrast. No shadows
coin. In-Game asset. 2d. High contrast. No shadows
trambolin. In-Game asset. 2d. High contrast. No shadows
çirkin korkutucu uzaylı. In-Game asset. 2d. High contrast. No shadows
kalp. In-Game asset. 2d. High contrast. No shadows
bir düğme ama içinde kurukafa .işareti olsun şeffaf. In-Game asset. 2d. High contrast. No shadows
platform. In-Game asset. 2d. High contrast. No shadows
güç platformu. In-Game asset. 2d. High contrast. No shadows
yuvarlak yeşil top. In-Game asset. 2d. High contrast. No shadows
sevimli bana yardım edin diyen bir uzaylı. In-Game asset. 2d. High contrast. No shadows
ufo. In-Game asset. 2d. High contrast. No shadows