/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Coin = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; // Gentle floating animation self.floatOffset = 0; self.originalY = 0; self.update = function () { if (!self.collected) { self.floatOffset += 0.1; self.y = self.originalY + Math.sin(self.floatOffset) * 5; } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); // Default to Skeleton, will be updated based on level var assetName = 'Skeleton'; var enemyGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 1 }); // Method to change enemy asset based on level self.setAssetForLevel = function (level) { if (enemyGraphics) { self.removeChild(enemyGraphics); } var assetName = level === 1 ? 'Skeleton' : level === 2 ? 'Slime' : 'Eye'; enemyGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 1 }); }; self.speed = 1.5; self.direction = 1; self.verticalSpeed = 1; self.verticalDirection = 1; // Physics properties for ground positioning self.velocityY = 0; self.gravity = 0.5; self.isGrounded = false; self.platformBounds = { left: 0, right: 500, top: 0, bottom: 0 }; self.assignedPlatform = 0; self.maxHealth = 50; self.health = 50; // Jumping properties for slimes self.jumpHeight = 150; // Height of jump self.jumpDuration = 800; // Duration of jump animation self.jumpCooldown = 180; // Ticks between jumps (3 seconds at 60fps) self.lastJump = 0; // Track last jump time self.isJumping = false; // Track if currently jumping self.originalY = 0; // Store original Y position // Create health bar background self.healthBarBg = self.attachAsset('enemyHealthBarBg', { anchorX: 0.5, anchorY: 1 }); self.healthBarBg.x = 0; self.healthBarBg.y = -120; // Create health bar self.healthBar = self.attachAsset('enemyHealthBar', { anchorX: 0.5, anchorY: 1 }); self.healthBar.x = 0; self.healthBar.y = -120; self.updateHealthBar = function () { var healthPercent = self.health / self.maxHealth; self.healthBar.width = 60 * healthPercent; if (healthPercent > 0.6) { self.healthBar.tint = 0x00ff00; } else if (healthPercent > 0.3) { self.healthBar.tint = 0xffff00; } else { self.healthBar.tint = 0xff0000; } }; // Platform collision detection for enemies self.checkPlatformCollision = function () { self.isGrounded = false; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; var platformTop = platform.y - 200; // Platform surface (adjusted for platform height) // Adjust platform boundaries based on scale var platformScale = platform.scaleX || 1; var platformWidth = 450 * platformScale; var platformLeft = platform.x - platformWidth; var platformRight = platform.x + platformWidth; // Check if enemy is above platform surface and within horizontal bounds if (self.x >= platformLeft && self.x <= platformRight && self.y >= platformTop - 20 && self.y <= platformTop + 20 && self.velocityY >= 0) { // Land on platform self.y = platformTop; self.velocityY = 0; self.isGrounded = true; break; } } }; // Initialize movement properties self.isMoving = false; self.movementDuration = 3000; // Time to move across platform // Start initial movement self.startMovement = function () { if (self.assignedPlatform !== undefined && platforms[self.assignedPlatform] && !self.isMoving) { self.isMoving = true; // Calculate full platform width based on platform scale var platform = platforms[self.assignedPlatform]; var platformScale = platform.scaleX || 1; var fullPlatformWidth = 450 * platformScale; // Base platform width * scale // Set platform bounds to full edges reduced by 50px from each side var platformLeft = platform.x - fullPlatformWidth + 50; var platformRight = platform.x + fullPlatformWidth - 50; // Update platform bounds for this enemy self.platformBounds.left = platformLeft; self.platformBounds.right = platformRight; var targetX = self.direction > 0 ? platformRight : platformLeft; var distance = Math.abs(targetX - self.x); var duration = self.movementDuration; // Use consistent movement duration tween(self, { x: targetX }, { duration: duration, easing: tween.linear, onFinish: function onFinish() { // Reverse direction and start moving to opposite end self.direction *= -1; self.isMoving = false; // Flip enemy based on new direction if (self.direction > 0) { enemyGraphics.scaleX = 1; } else { enemyGraphics.scaleX = -1; } // Start next movement after brief pause LK.setTimeout(function () { self.startMovement(); }, 200); // Slightly longer pause between movements } }); } }; self.update = function () { // For all levels, enemies stay constrained to their platform positions if (self.assignedPlatform !== undefined) { // Store original Y position for jumping if (self.originalY === 0) { self.originalY = platforms[self.assignedPlatform].y - 200; } // Level 2 slimes have jumping behavior if (currentLevel === 2 && !self.isJumping) { // Check if it's time to jump if (LK.ticks - self.lastJump > self.jumpCooldown) { self.isJumping = true; self.lastJump = LK.ticks; // Jump up and then down using tween tween(self, { y: self.originalY - self.jumpHeight }, { duration: self.jumpDuration / 2, easing: tween.easeOut, onFinish: function onFinish() { // Jump back down tween(self, { y: self.originalY }, { duration: self.jumpDuration / 2, easing: tween.easeIn, onFinish: function onFinish() { self.isJumping = false; } }); } }); } } else if (currentLevel !== 2) { // Non-jumping enemies stay on platform top edge consistently if (currentLevel === 2 && self.assignedPlatform === 2) { // Special case for large platform right side enemy in Level 2 self.y = platforms[self.assignedPlatform].y - 200; // Keep on platform top edge } else { // All other enemies stay on platform top edge self.y = platforms[self.assignedPlatform].y - 200; // Always stay on platform top edge } } } }; return self; }); var Ladder = Container.expand(function () { var self = Container.call(this); var ladderGraphics = self.attachAsset('ladder', { anchorX: 0.5, anchorY: 0.4 }); return self; }); var Platform = Container.expand(function () { var self = Container.call(this); var platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 1 }); self.speed = 7; self.currentPlatform = null; self.maxHealth = 100; self.health = 100; self.lastShot = 0; self.shootCooldown = 30; // 30 ticks = 0.5 seconds // Physics properties self.velocityY = 0; self.gravity = 0.8; self.terminalVelocity = 15; self.isGrounded = false; // Animation properties self.animationFrame = 0; self.animationSpeed = 8; // Change frame every 8 ticks self.isMoving = false; self.isShooting = false; self.facingLeft = false; self.isClimbing = false; self.onLadder = null; self.lastX = self.x; // Animation frames for different states self.walkFrames = ['Ninja1', 'Ninja2', 'Ninja3', 'Ninja4']; self.shootFrame = 'Ninjashooting'; self.climbFrames = ['Ninja01', 'Ninja02']; // Track animation state changes self.lastAsset = null; self.lastFlip = null; // Platform collision detection self.checkPlatformCollision = function () { self.isGrounded = false; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; var platformTop = platform.y - 200; // Platform surface // Adjust platform boundaries based on scale for Level 2 var platformScale = platform.scaleX || 1; var platformWidth = 450 * platformScale; var platformLeft = platform.x - platformWidth; // Half platform width var platformRight = platform.x + platformWidth; // Half platform width // Check if player is above platform surface and within horizontal bounds if (self.x >= platformLeft && self.x <= platformRight && self.y >= platformTop - 20 && self.y <= platformTop + 20 && self.velocityY >= 0) { // Land on platform self.y = platformTop; self.velocityY = 0; self.isGrounded = true; self.currentPlatform = i; break; } } }; self.updateAnimation = function () { var currentAsset = ''; if (self.isShooting) { currentAsset = self.shootFrame; } else if (self.isClimbing) { // Climbing animation when on ladder var climbFrameIndex = Math.floor(self.animationFrame / self.animationSpeed) % self.climbFrames.length; currentAsset = self.climbFrames[climbFrameIndex]; } else if (self.isMoving) { // Walking animation when moving var walkFrameIndex = Math.floor(self.animationFrame / self.animationSpeed) % self.walkFrames.length; currentAsset = self.walkFrames[walkFrameIndex]; } else { // Default standing pose - show player asset when not moving currentAsset = 'player'; } // Only update graphics if asset changed if (!self.lastAsset || self.lastAsset !== currentAsset) { // Remove old graphics if exists if (playerGraphics) { self.removeChild(playerGraphics); } // Create new graphics playerGraphics = self.attachAsset(currentAsset, { anchorX: 0.5, anchorY: 1 }); // Store current state self.lastAsset = currentAsset; } // Flip player based on facing direction for all animation frames if (self.facingLeft) { // Facing left, flip horizontally playerGraphics.scaleX = -1; } else { // Facing right, normal orientation playerGraphics.scaleX = 1; } }; self.update = function () { // Apply gravity when not climbing if (!self.isClimbing) { // Apply gravity self.velocityY += self.gravity; // Cap at terminal velocity if (self.velocityY > self.terminalVelocity) { self.velocityY = self.terminalVelocity; } // Apply vertical velocity self.y += self.velocityY; // Check platform collisions self.checkPlatformCollision(); } else { // Reset velocity when climbing self.velocityY = 0; self.isGrounded = true; } // Check for ladder intersection or standing on top edge var currentLadder = null; for (var i = 0; i < ladders.length; i++) { var ladder = ladders[i]; // Check direct intersection (already on ladder) if (self.intersects(ladder)) { currentLadder = ladder; break; } // Check if standing on top edge of ladder (within 40px horizontally and 50px above) var horizontalDistance = Math.abs(self.x - ladder.x); var verticalDistance = ladder.y - self.y; if (horizontalDistance <= 40 && verticalDistance >= -50 && verticalDistance <= 50 && self.isGrounded) { currentLadder = ladder; break; } } // Check for rope intersection for climbing if (!currentLadder) { for (var i = 0; i < ropes.length; i++) { var rope = ropes[i]; if (self.intersects(rope)) { currentLadder = rope; break; } } } // Update climbing state if (currentLadder && !self.isClimbing) { // Just reached a ladder - enter climbing mode self.isClimbing = true; self.onLadder = currentLadder; self.isMoving = false; // Stop any horizontal movement when reaching ladder tween.stop(self, { x: true, y: true }); // Snap to ladder center self.x = currentLadder.x; } else if (!currentLadder && self.isClimbing) { // Left ladder area - exit climbing mode self.isClimbing = false; self.onLadder = null; // Start falling when leaving ladder self.velocityY = 0; self.isGrounded = false; } // Check if player is moving (only when not climbing) if (!self.isClimbing) { var horizontalMovement = Math.abs(self.x - self.lastX) > 0.1; var verticalMovement = Math.abs(self.y - (self.lastY || self.y)) > 0.1; if (horizontalMovement || verticalMovement) { self.isMoving = true; // Determine facing direction for any horizontal movement if (horizontalMovement) { if (self.x < self.lastX) { if (!self.facingLeft) { self.facingLeft = true; self.updateAnimation(); } } else if (self.x > self.lastX) { if (self.facingLeft) { self.facingLeft = false; self.updateAnimation(); } } } } else { self.isMoving = false; } } // Update last positions self.lastX = self.x; self.lastY = self.y; // Check if player is shooting (cooldown active) self.isShooting = LK.ticks - self.lastShot < 15; // Show shooting animation for 15 ticks // Update animation frame counter only when moving, shooting, or climbing if (self.isMoving || self.isShooting || self.isClimbing) { self.animationFrame++; } // Check if player has fallen off the world or gone out of bounds if (self.y > 2732 + 100 || self.x < -100 || self.x > 2148) { // Player is out of bounds - trigger death if (typeof handlePlayerDeath === 'function') { handlePlayerDeath(); } } // Update animation self.updateAnimation(); }; return self; }); var Rope = Container.expand(function () { var self = Container.call(this); // Create rope using a brown rectangle var ropeGraphics = self.attachAsset('enemyHealthBarBg', { anchorX: 0.5, anchorY: 0.5 }); ropeGraphics.tint = 0x8B4513; // Brown color for rope self.canClimb = true; return self; }); var Star = Container.expand(function () { var self = Container.call(this); var starGraphics = self.attachAsset('star', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 30; self.targetX = 0; self.targetY = 0; self.active = true; self.shootAt = function (targetX, targetY) { self.targetX = targetX; self.targetY = targetY; // Calculate distance for animation duration var distance = Math.sqrt(Math.pow(targetX - self.x, 2) + Math.pow(targetY - self.y, 2)); var duration = distance * 3; // Adjust speed by changing multiplier // Use tween to animate star to target tween(self, { x: targetX, y: targetY, rotation: Math.PI * 4 }, { duration: duration, easing: tween.linear, onFinish: function onFinish() { self.active = false; } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Level game state variables var currentLevel = 1; var coinsCollected = 0; var totalCoins = 5; var enemiesDefeated = 0; var totalEnemies = 4; var levelComplete = false; var platforms = []; var ladders = []; var ropes = []; var coins = []; var enemies = []; var stars = []; var player; var playerLives = 5; var livesDisplay = []; var levelStartTime = 0; // Level 1 Platform positions (central hub + 4 outer platforms in 2x2 grid) var level1PlatformPositions = [{ x: 1024, y: 1366 }, // Center platform { x: 524, y: 850 }, // Top-left { x: 1524, y: 850 }, // Top-right { x: 524, y: 2000 }, // Bottom-left { x: 1524, y: 2000 } // Bottom-right ]; // Level 2 Platform positions (vertical tower layout with varying sizes) var level2PlatformPositions = [{ x: 1024, y: 2500 // Bottom platform (500px from bottom: 2732 - 500 = 2232, plus platform height) }, { x: 400, y: 2200 // Small platform left side }, { x: 1500, y: 1950 // Large platform right side }, { x: 400, y: 1400 // Medium platform left-center }, { x: 1400, y: 1350 // Small platform right-center }, { x: 1200, y: 900 // Large center platform }, { x: 400, y: 600 // Small platform far left }, { x: 1750, y: 500 // Small platform far right }]; // Level 3 Platform positions (4x4 grid with 500px horizontal and 600px vertical spacing) var level3PlatformPositions = [ // Bottom row (y = 2432 - moved up by 200px) { x: 274, y: 2432 }, { x: 774, y: 2432 }, { x: 1274, y: 2432 }, { x: 1774, y: 2432 }, // Third row (y = 1832 - moved up by 200px) { x: 274, y: 1832 }, { x: 774, y: 1832 }, { x: 1274, y: 1832 }, { x: 1774, y: 1832 }, // Second row (y = 1232 - moved up by 200px) { x: 274, y: 1232 }, { x: 774, y: 1232 }, { x: 1274, y: 1232 }, { x: 1774, y: 1232 }, // Top row (y = 632 - moved up by 200px) { x: 274, y: 632 }, { x: 774, y: 632 }, { x: 1274, y: 632 }, { x: 1774, y: 632 }]; // Level 4 Platform positions (scattered platforms with varying heights) var level4PlatformPositions = [{ x: 400, y: 2600 }, // Bottom left { x: 400, y: 2100 }, // Mid-left { x: 1500, y: 2100 }, // Mid-right { x: 600, y: 1600 }, // Upper-left { x: 1700, y: 1600 }, // Upper-right { x: 400, y: 1100 }, // High-left { x: 1500, y: 1100 }, // High-right { x: 1024, y: 600 } // Top center ]; // Level 5 Platform positions (spiral layout) var level5PlatformPositions = [{ x: 1024, y: 2500 }, // Center bottom { x: 1524, y: 1900 }, // Right moved up by 300px { x: 1724, y: 1500 }, // Far right moved up by 300px { x: 624, y: 1800 }, // Far left moved right by 300px { x: 400, y: 2200 }, // Left { x: 1024, y: 1000 }, // Center-high { x: 400, y: 600 } // Top center ]; // Level 6 Platform positions (double tower layout) var level6PlatformPositions = [ // Left tower { x: 500, y: 2500 }, { x: 500, y: 2100 }, { x: 500, y: 1700 }, { x: 500, y: 1300 }, { x: 500, y: 900 }, { x: 500, y: 500 }, // Right tower { x: 1548, y: 2500 }, { x: 1548, y: 2100 }, { x: 1548, y: 1700 }, { x: 1548, y: 1300 }, { x: 1548, y: 900 }, { x: 1548, y: 500 }, // Bridge platforms { x: 800, y: 1500 }, { x: 1248, y: 1500 }, { x: 1024, y: 1000 }]; // Level 7 Platform positions (maze-like layout) var level7PlatformPositions = [{ x: 200, y: 2500 }, { x: 600, y: 2500 }, { x: 1000, y: 2500 }, { x: 1400, y: 2500 }, { x: 1800, y: 2500 }, { x: 200, y: 2000 }, { x: 1000, y: 2000 }, { x: 1800, y: 2000 }, { x: 400, y: 1600 }, { x: 800, y: 1600 }, { x: 1200, y: 1600 }, { x: 1600, y: 1600 }, { x: 200, y: 1200 }, { x: 1000, y: 1200 }, { x: 1800, y: 1200 }, { x: 400, y: 800 }, { x: 1200, y: 800 }, { x: 600, y: 500 }, { x: 1400, y: 500 }]; // Level 8 Platform positions (pyramid layout) var level8PlatformPositions = [ // Base row (7 platforms) { x: 200, y: 2500 }, { x: 500, y: 2500 }, { x: 800, y: 2500 }, { x: 1024, y: 2500 }, { x: 1248, y: 2500 }, { x: 1548, y: 2500 }, { x: 1848, y: 2500 }, // Second row (5 platforms) { x: 350, y: 2100 }, { x: 700, y: 2100 }, { x: 1024, y: 2100 }, { x: 1348, y: 2100 }, { x: 1698, y: 2100 }, // Third row (3 platforms) { x: 524, y: 1700 }, { x: 1024, y: 1700 }, { x: 1524, y: 1700 }, // Fourth row (2 platforms) { x: 774, y: 1300 }, { x: 1274, y: 1300 }, // Top platform { x: 1024, y: 900 }]; // Level 9 Platform positions (circular arrangement with center) var level9PlatformPositions = [{ x: 1024, y: 1500 }, // Center platform // Inner circle { x: 1024, y: 1000 }, { x: 1324, y: 1200 }, { x: 1324, y: 1800 }, { x: 1024, y: 2000 }, { x: 724, y: 1800 }, { x: 724, y: 1200 }, // Outer circle { x: 1024, y: 600 }, { x: 1524, y: 800 }, { x: 1724, y: 1200 }, { x: 1724, y: 1800 }, { x: 1524, y: 2200 }, { x: 1024, y: 2400 }, { x: 524, y: 2200 }, { x: 324, y: 1800 }, { x: 324, y: 1200 }, { x: 524, y: 800 }]; // Level 10 Platform positions (final challenge - complex multi-level) var level10PlatformPositions = [ // Bottom foundation { x: 200, y: 2600 }, { x: 600, y: 2600 }, { x: 1000, y: 2600 }, { x: 1400, y: 2600 }, { x: 1800, y: 2600 }, // Second level { x: 400, y: 2200 }, { x: 1024, y: 2200 }, { x: 1600, y: 2200 }, // Third level branches { x: 200, y: 1800 }, { x: 500, y: 1800 }, { x: 800, y: 1800 }, { x: 1248, y: 1800 }, { x: 1548, y: 1800 }, { x: 1848, y: 1800 }, // Fourth level connections { x: 350, y: 1400 }, { x: 700, y: 1400 }, { x: 1350, y: 1400 }, { x: 1700, y: 1400 }, // Upper platforms { x: 400, y: 1000 }, { x: 1024, y: 1000 }, { x: 1600, y: 1000 }, // Near top { x: 600, y: 700 }, { x: 1400, y: 700 }, // Final platform { x: 1024, y: 400 }]; var platformPositions = currentLevel === 1 ? level1PlatformPositions : currentLevel === 2 ? level2PlatformPositions : currentLevel === 3 ? level3PlatformPositions : currentLevel === 4 ? level4PlatformPositions : currentLevel === 5 ? level5PlatformPositions : currentLevel === 6 ? level6PlatformPositions : currentLevel === 7 ? level7PlatformPositions : currentLevel === 8 ? level8PlatformPositions : currentLevel === 9 ? level9PlatformPositions : level10PlatformPositions; // Add background based on current level var backgroundAsset = currentLevel === 1 ? 'background1' : currentLevel === 2 ? 'background2' : 'background3'; var background = game.attachAsset(backgroundAsset, { anchorX: 0, anchorY: 0, x: 0, y: 0 }); // Create platforms with different sizes for Level 2 for (var i = 0; i < platformPositions.length; i++) { var platform = new Platform(); platform.x = platformPositions[i].x; platform.y = platformPositions[i].y; // Scale platforms differently for Level 2 to create variety if (currentLevel === 2) { if (i === 1 || i === 4 || i === 6 || i === 7) { // Small platforms platform.scaleX = 0.6; platform.scaleY = 1.6; } else if (i === 2 || i === 5) { // Large platforms platform.scaleX = 1.2; platform.scaleY = 1.0; } else { // Medium platforms platform.scaleX = 0.9; platform.scaleY = 1.0; } } else if (currentLevel === 3) { // Level 3: All platforms are 400x450px (scale to achieve this from 900x450 base) platform.scaleX = 0.44; // 900 * 0.44 ≈ 400px platform.scaleY = 1.0; // 450 * 1.0 = 450px } platforms.push(platform); game.addChild(platform); } // Create comprehensive ladder system with multiple segments function createLadderPath(fromPlatform, toPlatform, segments) { var startX = fromPlatform.x; var startY = fromPlatform.y - 200; // Start from platform top edge var endX = toPlatform.x; var endY = toPlatform.y - 200; // End at platform top edge var stepX = (endX - startX) / segments; var stepY = (endY - startY) / segments; for (var i = 0; i < segments; i++) { var ladder = new Ladder(); ladder.x = startX + stepX * i + stepX / 2; ladder.y = startY + stepY * i + stepY / 2; ladders.push(ladder); game.addChild(ladder); } } // Create rope connections between platforms function createRope(fromPlatform, toPlatform) { var rope = new Rope(); rope.x = (fromPlatform.x + toPlatform.x) / 2; rope.y = (fromPlatform.y + toPlatform.y) / 2; // Scale rope to connect platforms var distance = Math.sqrt(Math.pow(toPlatform.x - fromPlatform.x, 2) + Math.pow(toPlatform.y - fromPlatform.y, 2)); rope.scaleX = distance / 60; // Scale to fit distance rope.scaleY = 0.5; // Thin rope // Rotate rope to align with platforms var angle = Math.atan2(toPlatform.y - fromPlatform.y, toPlatform.x - fromPlatform.x); rope.rotation = angle; ropes.push(rope); game.addChild(rope); } if (currentLevel === 1) { // Level 1: Create only the two side lines of 5 ladders each // Left side connection (platform 1 to 3) - 5 ladder segments createLadderPath(platforms[1], platforms[3], 5); // Right side connection (platform 2 to 4) - 5 ladder segments createLadderPath(platforms[2], platforms[4], 5); } else if (currentLevel === 2) { // Level 2: Create ladders from small left platform to medium platform left-center and from bottom platform left to large platform right // Small left platform to medium platform left-center - 4 ladder segments createLadderPath(platforms[1], platforms[3], 4); // Bottom platform left side to large platform right side - 3 ladder segments moved up to platform top edge createLadderPath({ x: platforms[0].x, y: platforms[0].y - 200 // Start from platform top edge }, platforms[2], 3); // Add new ladder on left side of bottom platform var leftBottomLadder = new Ladder(); leftBottomLadder.x = platforms[0].x / 2 - 300; // Left side of bottom platform moved left by 100px leftBottomLadder.y = platforms[0].y / 2 - 850; // Top edge of platform moved up by 200px ladders.push(leftBottomLadder); game.addChild(leftBottomLadder); // Add 2 ladders from small platform right-center (platform 4) to large center platform (platform 5) // From right top edge of platform 4 to middle top edge of platform 5 createLadderPath({ x: platforms[4].x + 150, y: platforms[4].y }, { x: platforms[5].x, y: platforms[5].y }, 2); // Add 2 ladders from large center platform (platform 5) right side before 200px to small platform far right (platform 7) // From right side of platform 5 (before 200px) to platform 7, moved up by 50px createLadderPath({ x: platforms[5].x + 350, y: platforms[5].y - 50 }, { x: platforms[7].x - 200, y: platforms[7].y - 50 }, 2); // Add 2 ladders from large center platform (platform 5) top left edge to small platform far left (platform 6) createLadderPath({ x: platforms[5].x - 350, y: platforms[5].y - 50 }, platforms[6], 2); // Add 2 ladders above each other on right side of large platform before 240px from right edge var rightLadder1 = new Ladder(); rightLadder1.x = 2048 - 250; // 240px from right edge of screen moved left by 100px rightLadder1.y = platforms[2].y - 200; // Top edge of large platform right side moved up by 150px ladders.push(rightLadder1); game.addChild(rightLadder1); var rightLadder2 = new Ladder(); rightLadder2.x = 2048 - 250; // Same x position as first ladder moved left by 100px rightLadder2.y = platforms[2].y - 500; // 290px above first ladder (height of one ladder segment) moved up by 150px ladders.push(rightLadder2); game.addChild(rightLadder2); } else if (currentLevel === 3) { // Level 3: Create 4 continuous vertical ladder lines from bottom to top // Each ladder line connects all 4 platforms vertically (4 rows with 600px spacing) for (var col = 0; col < 4; col++) { // Create continuous ladders from bottom platform to top platform var bottomPlatformIndex = col; // Bottom row platforms (0-3) var topPlatformIndex = col + 12; // Top row platforms (12-15) // Create 16 ladder segments to span from bottom to top (removed 2 bottom segments) for (var segment = 2; segment < 18; segment++) { var ladder = new Ladder(); ladder.x = platforms[bottomPlatformIndex].x; // Start from bottom platform top edge, go up with ladder segments ladder.y = platforms[bottomPlatformIndex].y - 200 - segment * 100; ladders.push(ladder); game.addChild(ladder); } } } else if (currentLevel === 4) { // Level 4: Only new ladders - remove old ones // Add 2 ladders in line above each other from left side of bottom platform at its top edge for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[0].x - 350; // Left side of bottom platform ladder.y = platforms[0].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders in line above each other at mid left platform top edge for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[1].x + 200; // Before 200px from left side of mid left platform ladder.y = platforms[1].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders from top edge of upper left platform before 200px from its right for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[3].x + 200; // Before 200px from right side of upper left platform ladder.y = platforms[3].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders above each other on high left platform moved left by 50px at its top edge for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[5].x + 150; // Before 200px from right side moved left by 50px ladder.y = platforms[5].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders above each other in middle of top edge of high right platform for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[6].x; // Middle of high right platform ladder.y = platforms[6].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders diagonal going left from middle upper right platform above its top edge by 200px for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[4].x - i * 100; // Diagonal going left ladder.y = platforms[4].y - 400 - i * 100; // Above top edge by 200px and diagonal up ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders diagonal going up and right from mid right platform above its top edge by 200px for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[2].x - 200 + i * 100; // Before 200px from left but 2nd ladder goes right ladder.y = platforms[2].y - 500 - i * 100; // Above top edge by 200px and diagonal up, moved up by 100px ladders.push(ladder); game.addChild(ladder); } } else if (currentLevel === 5) { // Level 5: Add 2 ladders above each other from top edge of bottom platform at its max right side for (var i = 0; i < 2; i++) { var ladder = new Ladder(); // Position at max right side of bottom platform (platform 0) ladder.x = platforms[0].x + 400; // Right edge of bottom platform ladder.y = platforms[0].y - 300 - i * 290; // Stack above each other from top edge ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders from top mid edge of right platform by 50px going right diagonally for (var i = 0; i < 2; i++) { var ladder = new Ladder(); // Position above right platform (platform 1) going diagonally right ladder.x = platforms[1].x + 100 + i * 60; // Start 100px right of center and space by 60px horizontally ladder.y = platforms[1].y - 450 - i * 150; // Above top edge by 150px and diagonal up (moved up by 100px) ladders.push(ladder); game.addChild(ladder); } // Move all ladders to front after background to ensure visibility for (var i = 0; i < ladders.length; i++) { game.setChildIndex(ladders[i], game.children.length - 1); } } else if (currentLevel === 6) { // Level 6: Connect the towers with ropes and ladders for (var i = 0; i < 5; i++) { createLadderPath(platforms[i], platforms[i + 1], 2); createLadderPath(platforms[i + 6], platforms[i + 7], 2); } createRope(platforms[12], platforms[13]); createRope(platforms[5], platforms[14]); createRope(platforms[11], platforms[14]); } else if (currentLevel === 7) { // Level 7: Maze connections createLadderPath(platforms[0], platforms[5], 3); createRope(platforms[1], platforms[6]); createLadderPath(platforms[7], platforms[12], 2); createRope(platforms[8], platforms[13]); createLadderPath(platforms[14], platforms[16], 2); createRope(platforms[15], platforms[17]); } else if (currentLevel === 8) { // Level 8: Pyramid climbing for (var row = 0; row < 4; row++) { var startIdx = row === 0 ? 0 : row === 1 ? 7 : row === 2 ? 12 : 15; var count = row === 0 ? 7 : row === 1 ? 5 : row === 2 ? 3 : 2; for (var i = 0; i < count - 1; i++) { if (row < 3) { var nextRowStart = row === 0 ? 7 : row === 1 ? 12 : 15; var nextIdx = nextRowStart + Math.floor(i / 2); if (nextIdx < platforms.length) { createLadderPath(platforms[startIdx + i], platforms[nextIdx], 2); } } } } createLadderPath(platforms[15], platforms[17], 2); } else if (currentLevel === 9) { // Level 9: Circular connections createLadderPath(platforms[0], platforms[1], 3); for (var i = 1; i < 6; i++) { createRope(platforms[i], platforms[i % 6 + 1]); } for (var i = 7; i < 15; i++) { createRope(platforms[i], platforms[(i - 7) % 8 + 7]); } createLadderPath(platforms[1], platforms[7], 2); createLadderPath(platforms[3], platforms[9], 2); } else if (currentLevel === 10) { // Level 10: Complex final level connections createLadderPath(platforms[0], platforms[5], 3); createRope(platforms[5], platforms[6]); createLadderPath(platforms[6], platforms[11], 3); createRope(platforms[11], platforms[19]); createLadderPath(platforms[19], platforms[21], 2); createRope(platforms[21], platforms[22]); createLadderPath(platforms[22], platforms[24], 2); // Additional connections createRope(platforms[1], platforms[7]); createRope(platforms[8], platforms[15]); createLadderPath(platforms[20], platforms[23], 2); } // Create coins above platforms for (var i = 0; i < platforms.length; i++) { var coin = new Coin(); coin.x = platforms[i].x; coin.y = platforms[i].y - 280; // Position coins closer to platforms coin.originalY = coin.y; coins.push(coin); game.addChild(coin); } // Create player player = new Player(); if (currentLevel === 3) { // Position player beside the first ladder line from the right, not touching player.x = platforms[0].x + 100; // 100px to the right of first ladder line } else { player.x = platforms[0].x; // Start on center platform } player.y = platforms[0].y - 200; // Position above the top edge of middle platform player.currentPlatform = 0; game.addChild(player); // Move player to front (above background) game.setChildIndex(player, game.children.length - 1); // Create enemies based on level function spawnEnemies() { // Clear existing enemies for (var i = 0; i < enemies.length; i++) { enemies[i].destroy(); } enemies = []; if (currentLevel === 1) { // Level 1: Spawn exactly 4 enemies, one on each outer platform (excluding center platform at index 0) for (var i = 1; i < platforms.length; i++) { var enemy = new Enemy(); enemy.setAssetForLevel(1); // Set Skeleton asset for level 1 enemy.x = platforms[i].x; enemy.y = platforms[i].y - 200; // Position on top edge of platform surface (same as Level 2) enemy.assignedPlatform = i; // Set platform boundaries to keep enemy confined to its platform horizontally only var platformScale = platforms[i].scaleX || 1; var fullPlatformWidth = 450 * platformScale; enemy.platformBounds.left = platforms[i].x - fullPlatformWidth + 50; enemy.platformBounds.right = platforms[i].x + fullPlatformWidth - 50; // Set platform bounds for vertical constraint (keep enemies close to top edge like Level 2) enemy.platformBounds.top = platforms[i].y - 220; // 20px above surface enemy.platformBounds.bottom = platforms[i].y - 180; // 20px below surface enemies.push(enemy); game.addChild(enemy); } } else if (currentLevel === 2) { // Level 2: Spawn enemies on selected platforms with adjusted boundaries based on platform scale var enemyPlatforms = [1, 2, 3, 4, 5, 6, 7]; // Skip bottom platform, include large center platform 5 and medium platform 3 for (var i = 0; i < enemyPlatforms.length; i++) { var platformIndex = enemyPlatforms[i]; var enemy = new Enemy(); enemy.setAssetForLevel(2); // Set Slime asset for level 2 enemy.x = platforms[platformIndex].x; // Check if this is a small platform (platforms 1, 4, 6, 7) and position at top edge if (platformIndex === 1 || platformIndex === 4 || platformIndex === 6 || platformIndex === 7) { // Small platforms - position at top edge with no space enemy.y = platforms[platformIndex].y - 200; // Position on top edge of platform } else if (platformIndex === 2) { enemy.y = platforms[platformIndex].y - 50; // Position above platform to let gravity take effect - moved down 150px } else { enemy.y = platforms[platformIndex].y - 160; // Position on top edge of platform } enemy.assignedPlatform = platformIndex; // Adjust boundaries based on platform scale var platformScale = platforms[platformIndex].scaleX || 1; var fullPlatformWidth = 450 * platformScale; // Use full platform width enemy.platformBounds.left = platforms[platformIndex].x - fullPlatformWidth + 50; enemy.platformBounds.right = platforms[platformIndex].x + fullPlatformWidth - 50; // Set platform bounds for vertical constraint (keep enemies close to top edge) if (platformIndex === 2) { enemy.platformBounds.top = platforms[platformIndex].y - 220; // 20px above moved surface (adjusted for new position) enemy.platformBounds.bottom = platforms[platformIndex].y - 180; // 20px below moved surface (adjusted for new position) } else if (platformIndex === 5) { enemy.platformBounds.top = platforms[platformIndex].y - 170; // 20px above surface for large center platform enemy.platformBounds.bottom = platforms[platformIndex].y - 130; // 20px below surface for large center platform } else { enemy.platformBounds.top = platforms[platformIndex].y - 170; // 20px above surface enemy.platformBounds.bottom = platforms[platformIndex].y - 130; // 20px below surface } // Add slight velocity to keep enemies moving and visible enemy.speed = 2.0; // Slightly faster movement enemies.push(enemy); game.addChild(enemy); } } else if (currentLevel === 3) { // Level 3: Spawn enemies on 12 platforms (exclude 4 corner platforms for player safety) var enemyPlatforms = [1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14]; // Skip corners (0, 3, 12, 15) for (var i = 0; i < enemyPlatforms.length; i++) { var platformIndex = enemyPlatforms[i]; var enemy = new Enemy(); enemy.setAssetForLevel(3); // Use Eye asset for level 3 enemy.x = platforms[platformIndex].x; enemy.y = platforms[platformIndex].y - 225; // Position directly on platform surface enemy.assignedPlatform = platformIndex; // Set platform boundaries to keep enemy confined to its platform horizontally only var platformScale = platforms[platformIndex].scaleX || 1; var fullPlatformWidth = 450 * platformScale; // Full platform width for Level 3 enemy.platformBounds.left = platforms[platformIndex].x - fullPlatformWidth + 50; enemy.platformBounds.right = platforms[platformIndex].x + fullPlatformWidth - 50; // Set platform bounds for vertical constraint (keep enemies close to top edge like Level 1) enemy.platformBounds.top = platforms[platformIndex].y - 245; // 20px above surface enemy.platformBounds.bottom = platforms[platformIndex].y - 205; // 20px below surface enemy.speed = 1.5; // Standard movement speed enemies.push(enemy); game.addChild(enemy); } } else if (currentLevel >= 4 && currentLevel <= 10) { // Levels 4-10: Spawn enemies on most platforms with cycling enemy types var enemyAssetLevel = (currentLevel - 1) % 3 + 1; // Cycle through asset types 1, 2, 3 if (currentLevel === 4) { // Level 4: Specific enemy placement including top center platform and all empty platforms var level4EnemyPlatforms = [1, 2, 3, 4, 5, 6, 7]; // Include all platforms except bottom (index 0) for (var i = 0; i < level4EnemyPlatforms.length; i++) { var platformIndex = level4EnemyPlatforms[i]; var enemy = new Enemy(); enemy.setAssetForLevel(enemyAssetLevel); enemy.x = platforms[platformIndex].x; enemy.y = platforms[platformIndex].y - 225; enemy.assignedPlatform = platformIndex; var platformScale = platforms[platformIndex].scaleX || 1; var fullPlatformWidth = 450 * platformScale; // Full platform width for Level 4 enemy.platformBounds.left = platforms[platformIndex].x - fullPlatformWidth + 50; enemy.platformBounds.right = platforms[platformIndex].x + fullPlatformWidth - 50; enemy.platformBounds.top = platforms[platformIndex].y - 245; enemy.platformBounds.bottom = platforms[platformIndex].y - 205; enemy.speed = 1.0 + currentLevel * 0.2; // Increase speed with level enemies.push(enemy); game.addChild(enemy); } } else { // Other levels 5-10: Standard enemy spawning var enemyCount = Math.min(platforms.length - 2, 8 + (currentLevel - 4) * 2); // Increase enemies per level var skipPlatforms = currentLevel <= 6 ? 1 : 2; // Skip first platform(s) for player safety for (var i = skipPlatforms; i < skipPlatforms + enemyCount && i < platforms.length; i++) { var enemy = new Enemy(); enemy.setAssetForLevel(enemyAssetLevel); enemy.x = platforms[i].x; enemy.y = platforms[i].y - 225; enemy.assignedPlatform = i; var platformScale = platforms[i].scaleX || 1; var fullPlatformWidth = 450 * platformScale; // Full platform width for levels 5-10 enemy.platformBounds.left = platforms[i].x - fullPlatformWidth + 50; enemy.platformBounds.right = platforms[i].x + fullPlatformWidth - 50; enemy.platformBounds.top = platforms[i].y - 245; enemy.platformBounds.bottom = platforms[i].y - 205; enemy.speed = 1.0 + currentLevel * 0.2; // Increase speed with level enemies.push(enemy); game.addChild(enemy); } } } // Move enemies to front after spawning to ensure they are visible and not behind background for (var i = 0; i < enemies.length; i++) { game.setChildIndex(enemies[i], game.children.length - 1); // Start movement for each enemy LK.setTimeout(function (enemy) { return function () { enemy.startMovement(); }; }(enemies[i]), i * 500 + 1000); // Stagger enemy movement starts } // Move player to front after spawning enemies to ensure visibility game.setChildIndex(player, game.children.length - 1); } // Player health bar var playerHealthBarBg = LK.getAsset('healthBarBg', { anchorX: 0, anchorY: 0 }); playerHealthBarBg.x = 120; playerHealthBarBg.y = 20; LK.gui.topLeft.addChild(playerHealthBarBg); var playerHealthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0 }); playerHealthBar.x = 120; playerHealthBar.y = 20; LK.gui.topLeft.addChild(playerHealthBar); var healthText = new Text2('Health: 100/100', { size: 40, fill: 0xFFFFFF }); healthText.anchor.set(0, 0); healthText.x = 120; healthText.y = 50; LK.gui.topLeft.addChild(healthText); // Lives display (5 skull icons beside health bar) for (var i = 0; i < 5; i++) { var skull = LK.getAsset('skull', { anchorX: 0.5, anchorY: 0.5 }); skull.x = 350 + i * 50; // Position beside health bar with spacing skull.y = 35; // Align with health bar center skull.alpha = 1; // All skulls start visible livesDisplay.push(skull); LK.gui.topLeft.addChild(skull); } // Score display var scoreText = new Text2('Coins: 0/' + totalCoins, { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Level 1 title display var levelText = new Text2('LEVEL 1', { size: 60, fill: 0xFFD700 }); levelText.anchor.set(-2.3, 0.5); levelText.x = 0; levelText.y = 20; LK.gui.top.addChild(levelText); // Function to initialize specific level function initializeLevel(levelNumber) { currentLevel = levelNumber; // Clear existing game objects for (var i = 0; i < platforms.length; i++) { platforms[i].destroy(); } for (var i = 0; i < ladders.length; i++) { ladders[i].destroy(); } for (var i = 0; i < ropes.length; i++) { ropes[i].destroy(); } for (var i = 0; i < coins.length; i++) { coins[i].destroy(); } for (var i = 0; i < enemies.length; i++) { enemies[i].destroy(); } for (var i = 0; i < stars.length; i++) { stars[i].destroy(); } // Clear arrays platforms = []; ladders = []; ropes = []; coins = []; enemies = []; stars = []; // Reset game state coinsCollected = 0; enemiesDefeated = 0; levelComplete = false; // Update platform positions and totals based on level if (levelNumber === 1) { platformPositions = level1PlatformPositions; totalCoins = 5; totalEnemies = 4; } else if (levelNumber === 2) { platformPositions = level2PlatformPositions; totalCoins = 8; totalEnemies = 7; } else if (levelNumber === 3) { platformPositions = level3PlatformPositions; totalCoins = 16; totalEnemies = 12; } else if (levelNumber === 4) { platformPositions = level4PlatformPositions; totalCoins = 8; totalEnemies = 7; } else if (levelNumber === 5) { platformPositions = level5PlatformPositions; totalCoins = 6; totalEnemies = 4; } else if (levelNumber === 6) { platformPositions = level6PlatformPositions; totalCoins = 15; totalEnemies = 12; } else if (levelNumber === 7) { platformPositions = level7PlatformPositions; totalCoins = 18; totalEnemies = 15; } else if (levelNumber === 8) { platformPositions = level8PlatformPositions; totalCoins = 18; totalEnemies = 14; } else if (levelNumber === 9) { platformPositions = level9PlatformPositions; totalCoins = 16; totalEnemies = 13; } else if (levelNumber === 10) { platformPositions = level10PlatformPositions; totalCoins = 25; totalEnemies = 20; } // Update background background.destroy(); var backgroundAsset = currentLevel === 1 ? 'background1' : currentLevel === 2 ? 'background2' : 'background3'; background = game.attachAsset(backgroundAsset, { anchorX: 0, anchorY: 0, x: 0, y: 0 }); // Recreate platforms with scaling for Level 2 for (var i = 0; i < platformPositions.length; i++) { var platform = new Platform(); platform.x = platformPositions[i].x; platform.y = platformPositions[i].y; // Scale platforms differently for Level 2 to create variety if (currentLevel === 2) { if (i === 1 || i === 4 || i === 6 || i === 7) { // Small platforms platform.scaleX = 0.6; platform.scaleY = 1.0; } else if (i === 2 || i === 5) { // Large platforms platform.scaleX = 1.2; platform.scaleY = 1.0; } else { // Medium platforms platform.scaleX = 0.9; platform.scaleY = 1.0; } } else if (currentLevel === 3) { // Level 3: All platforms are 400x450px (scale to achieve this from 900x450 base) platform.scaleX = 0.44; // 900 * 0.44 ≈ 400px platform.scaleY = 1.0; // 450 * 1.0 = 450px } platforms.push(platform); game.addChild(platform); } // Recreate ladders based on level if (currentLevel === 1) { createLadderPath(platforms[1], platforms[3], 5); createLadderPath(platforms[2], platforms[4], 5); } else if (currentLevel === 2) { // Keep existing ladders createLadderPath(platforms[1], platforms[3], 4); // Bottom platform left side to large platform right side - 3 ladder segments moved up to platform top edge createLadderPath({ x: platforms[0].x, y: platforms[0].y - 200 // Start from platform top edge }, platforms[2], 3); // Add new ladder on left side of bottom platform var leftBottomLadder = new Ladder(); leftBottomLadder.x = platforms[0].x - 300; // Left side of bottom platform moved left by 100px leftBottomLadder.y = platforms[0].y - 350; // Top edge of platform moved up by 150px ladders.push(leftBottomLadder); game.addChild(leftBottomLadder); // Add 2 ladders from small platform right-center (platform 4) to large center platform (platform 5) // From right top edge of platform 4 to middle top edge of platform 5 createLadderPath({ x: platforms[4].x + 150, y: platforms[4].y }, { x: platforms[5].x, y: platforms[5].y }, 2); // Add 2 ladders from large center platform (platform 5) right side before 200px to small platform far right (platform 7) // From right side of platform 5 (before 200px) to platform 7, moved up by 50px createLadderPath({ x: platforms[5].x + 350, y: platforms[5].y - 50 }, { x: platforms[7].x - 200, y: platforms[7].y - 50 }, 2); // Add 2 ladders from large center platform (platform 5) top left edge to small platform far left (platform 6) createLadderPath({ x: platforms[5].x - 350, y: platforms[5].y - 50 }, platforms[6], 2); // Add 2 ladders above each other on right side of large platform before 240px from right edge var rightLadder1 = new Ladder(); rightLadder1.x = 2048 - 340; // 240px from right edge of screen moved left by 100px rightLadder1.y = platforms[2].y - 350; // Top edge of large platform right side moved up by 150px ladders.push(rightLadder1); game.addChild(rightLadder1); var rightLadder2 = new Ladder(); rightLadder2.x = 2048 - 340; // Same x position as first ladder moved left by 100px rightLadder2.y = platforms[2].y - 640; // 290px above first ladder (height of one ladder segment) moved up by 150px ladders.push(rightLadder2); game.addChild(rightLadder2); } else if (currentLevel === 3) { // Level 3: Recreate 4 continuous vertical ladder lines for (var col = 0; col < 4; col++) { var bottomPlatformIndex = col; // Bottom row platforms (0-3) // Create 16 ladder segments to span from bottom to top (removed 2 bottom segments) for (var segment = 2; segment < 18; segment++) { var ladder = new Ladder(); ladder.x = platforms[bottomPlatformIndex].x; ladder.y = platforms[bottomPlatformIndex].y - 200 - segment * 100; ladders.push(ladder); game.addChild(ladder); } } } else if (currentLevel === 4) { // Level 4: Only new ladders - remove old ones // Add 2 ladders in line above each other from left side of bottom platform at its top edge for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[0].x - 350; // Left side of bottom platform ladder.y = platforms[0].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders in line above each other at mid left platform top edge for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[1].x + 200; // Before 200px from left side of mid left platform ladder.y = platforms[1].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders from top edge of upper left platform before 200px from its right for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[3].x + 200; // Before 200px from right side of upper left platform ladder.y = platforms[3].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders above each other on high left platform moved left by 50px at its top edge for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[5].x + 150; // Before 200px from right side moved left by 50px ladder.y = platforms[5].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders above each other in middle of top edge of high right platform for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[6].x; // Middle of high right platform ladder.y = platforms[6].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders diagonal going left from middle upper right platform above its top edge by 200px for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[4].x - 100 - i * 100; // Diagonal going left ladder.y = platforms[4].y - 400 - i * 200; // Above top edge by 200px and diagonal up ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders diagonal going up and right from mid right platform above its top edge by 200px for (var i = 0; i < 2; i++) { var ladder = new Ladder(); ladder.x = platforms[2].x - 300 + i * 100; // Before 200px from left but 2nd ladder goes right ladder.y = platforms[2].y - 400 - i * 200; // Above top edge by 200px and diagonal up, moved up by 100px ladders.push(ladder); game.addChild(ladder); } } else if (currentLevel === 5) { // Level 5: Add 2 ladders above each other from top edge of bottom platform at its max right side for (var i = 0; i < 2; i++) { var ladder = new Ladder(); // Position at max right side of bottom platform (platform 0) ladder.x = platforms[0].x + 450; // Right edge of bottom platform ladder.y = platforms[0].y - 300 - i * 290; // Stack above each other from top edge ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders from top mid edge of right platform by 50px going right diagonally for (var i = 0; i < 2; i++) { var ladder = new Ladder(); // Position above right platform (platform 1) going diagonally right ladder.x = platforms[1].x + 50 + i * 100; // Start 50px right of center and space by 100px horizontally ladder.y = platforms[1].y - 450 - i * 150; // Above top edge by 150px and diagonal up (moved up by 100px) ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders going diagonally from far right platform top edge in the max left from its inside space between ladders horizontally 200px for (var i = 0; i < 2; i++) { var ladder = new Ladder(); // Position from far right platform (platform 2) at max left from its inside going diagonally if (i === 0) { // First ladder goes right ladder.x = platforms[2].x - 350 + i * 200; // Start from max left inside and space by 200px horizontally } else { // Second ladder goes left ladder.x = platforms[2].x - 350 - i * 200; // Start from max left inside and go left by 200px horizontally } ladder.y = platforms[2].y - 450 - i * 150; // Above top edge by 150px and diagonal up (moved up by 100px) ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders going diagonally from far right platform top edge in the max left from its inside space between ladders horizontally 200px for (var i = 0; i < 2; i++) { var ladder = new Ladder(); // Position from far right platform (platform 2) at max left from its inside going diagonally if (i === 0) { // First ladder goes right ladder.x = platforms[2].x - 350 + i * 200; // Start from max left inside and space by 200px horizontally } else { // Second ladder goes left ladder.x = platforms[2].x - 350 - i * 200; // Start from max left inside and go left by 200px horizontally } ladder.y = platforms[2].y - 450 - i * 150; // Above top edge by 150px and diagonal up (moved up by 100px) ladders.push(ladder); game.addChild(ladder); } // Add 2 ladders going diagonally from center high platform top edge going left for (var i = 0; i < 2; i++) { var ladder = new Ladder(); // Position from center high platform (platform 5) at mid top edge going diagonally left ladder.x = platforms[5].x - i * 200; // Start from center and go left by 200px horizontally ladder.y = platforms[5].y - 450 - i * 150; // Above top edge by 150px and diagonal up (moved up by 100px) ladders.push(ladder); game.addChild(ladder); } } // Move all ladders to front after background to ensure visibility for (var i = 0; i < ladders.length; i++) { game.setChildIndex(ladders[i], game.children.length - 1); } // Recreate coins for (var i = 0; i < platforms.length; i++) { var coin = new Coin(); coin.x = platforms[i].x; coin.y = platforms[i].y - 280; coin.originalY = coin.y; coins.push(coin); game.addChild(coin); } // Reset player position - for Level 2, place on bottom platform (index 0) if (levelNumber === 2) { player.x = platforms[0].x - 30; player.y = platforms[0].y - 200; player.currentPlatform = 0; } else { // Level 1 and 3 - place on center platform if (levelNumber === 3) { // Position player beside the first ladder line from the right, not touching player.x = platforms[0].x + 100; // 100px to the right of first ladder line } else { player.x = platforms[0].x; } player.y = platforms[0].y - 200; player.currentPlatform = 0; } player.health = player.maxHealth; player.velocityY = 0; player.isGrounded = true; // Update UI scoreText.setText('Coins: 0/' + totalCoins); levelText.setText('LEVEL ' + levelNumber); updatePlayerHealthBar(); // Spawn enemies spawnEnemies(); // Level intro effect // Move enemies to front after spawning to ensure they are visible and not behind background for (var i = 0; i < enemies.length; i++) { game.setChildIndex(enemies[i], game.children.length - 1); // Start movement for each enemy LK.setTimeout(function (enemy) { return function () { enemy.startMovement(); }; }(enemies[i]), i * 500 + 1000); // Stagger enemy movement starts } levelStartTime = LK.ticks; var levelColor = levelNumber === 1 ? 0x4169E1 : 0xFF6347; LK.effects.flashScreen(levelColor, 1000); } // Initialize Level 1 initializeLevel(1); // Move player to front (above background) after level initialization game.setChildIndex(player, game.children.length - 1); // Level 1 initialization levelStartTime = LK.ticks; // Level 1 intro effect - flash screen blue LK.effects.flashScreen(0x4169E1, 1000); // Level objective display var objectiveText = new Text2('Collect all coins and defeat all enemies!', { size: 40, fill: 0xFFFFFF }); objectiveText.anchor.set(0.5, 0); objectiveText.x = 0; objectiveText.y = 90; LK.gui.top.addChild(objectiveText); // Function to update lives display function updateLivesDisplay() { for (var i = 0; i < livesDisplay.length; i++) { if (i < playerLives) { livesDisplay[i].alpha = 1; // Show skull for remaining lives } else { livesDisplay[i].alpha = 0.3; // Dim skull for lost lives } } } // Function to handle player death function handlePlayerDeath() { playerLives--; updateLivesDisplay(); if (playerLives <= 0) { LK.showGameOver(); } else { // Reset player position to center platform if (currentLevel === 3) { // Position player beside the first ladder line from the right, not touching player.x = platforms[0].x + 100; // 100px to the right of first ladder line } else { player.x = platforms[0].x; } player.y = platforms[0].y - 200; player.health = player.maxHealth; player.velocityY = 0; player.isGrounded = true; player.currentPlatform = 0; updatePlayerHealthBar(); LK.effects.flashScreen(0xff0000, 1000); } } // Add climbing movement function function movePlayerVertically(direction) { if (player.isClimbing && player.onLadder) { var moveDistance = 200; // Distance to move up/down var targetY = player.y + direction * moveDistance; // Calculate duration based on distance var duration = 800; // Fixed duration for climbing movement // Animate vertical movement tween(player, { y: targetY }, { duration: duration, easing: tween.easeOut }); } } // Click-to-move controls game.down = function (x, y, obj) { // Use the x, y parameters directly as they are already in game coordinates var gamePos = { x: x, y: y }; // Check for climbing controls when player is on ladder or can start climbing if (player.isClimbing && player.onLadder) { // Determine if click is above or below player for climbing direction if (gamePos.y < player.y - 50) { // Click above player - climb up movePlayerVertically(-1); return; } else if (gamePos.y > player.y + 50) { // Click below player - climb down movePlayerVertically(1); return; } } else { // Check if player can start climbing down from platform edge var climbables = ladders.concat(ropes); for (var climbableIndex = 0; climbableIndex < climbables.length; climbableIndex++) { var climbable = climbables[climbableIndex]; var horizontalDistance = Math.abs(player.x - climbable.x); var verticalDistance = climbable.y - player.y; // If player is standing on top edge of climbable and clicks below if (horizontalDistance <= 40 && verticalDistance >= -50 && verticalDistance <= 50 && player.isGrounded && gamePos.y > player.y + 50) { // Start climbing down player.isClimbing = true; player.onLadder = climbable; player.isMoving = false; // Stop any horizontal movement tween.stop(player, { x: true, y: true }); // Snap to climbable center player.x = climbable.x; // Start climbing down movePlayerVertically(1); return; } } } // Check if tap is on an enemy for shooting var enemyClicked = false; for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var enemyDistance = Math.sqrt(Math.pow(gamePos.x - enemy.x, 2) + Math.pow(gamePos.y - enemy.y, 2)); if (enemyDistance < 80) { // Enemy click radius // Shoot at the clicked enemy if cooldown allows if (LK.ticks - player.lastShot > player.shootCooldown) { // Set facing direction based on enemy position var shouldFaceLeft = enemy.x < player.x; if (player.facingLeft !== shouldFaceLeft) { player.facingLeft = shouldFaceLeft; player.updateAnimation(); } var star = new Star(); star.x = player.x; star.y = player.y - 50; // Shoot from slightly above player // Shoot horizontally based on player facing direction var horizontalDistance = 1000; // Fixed horizontal shooting distance var targetX = player.facingLeft ? player.x - horizontalDistance : player.x + horizontalDistance; star.shootAt(targetX, star.y); // Keep same Y position for horizontal shot stars.push(star); game.addChild(star); player.lastShot = LK.ticks; LK.getSound('shoot').play(); } enemyClicked = true; break; } } // If no enemy was clicked, move player to clicked position if (!enemyClicked) { // Set facing direction based on click position if (gamePos.x < player.x) { // Clicked left of player - face left and move left player.facingLeft = true; player.updateAnimation(); } else if (gamePos.x > player.x) { // Clicked right of player - face right and move right player.facingLeft = false; player.updateAnimation(); } // Only allow horizontal movement when player is grounded or climbing if (player.isGrounded || player.isClimbing) { // Allow unlimited horizontal movement - no platform boundary constraints var targetX = gamePos.x; // Calculate movement distance for duration var moveDistance = Math.abs(targetX - player.x); var duration = moveDistance * 3; // Adjust speed by changing multiplier // Stop any existing movement tween tween.stop(player, { x: true }); // Smooth horizontal movement to target position tween(player, { x: targetX }, { duration: duration, easing: tween.easeOut }); } } }; // Update player health bar function function updatePlayerHealthBar() { var healthPercent = player.health / player.maxHealth; playerHealthBar.width = 200 * healthPercent; if (healthPercent > 0.6) { playerHealthBar.tint = 0x00ff00; } else if (healthPercent > 0.3) { playerHealthBar.tint = 0xffff00; } else { playerHealthBar.tint = 0xff0000; } healthText.setText('Health: ' + player.health + '/' + player.maxHealth); } // Game update loop game.update = function () { // Check coin collection for (var i = 0; i < coins.length; i++) { var coin = coins[i]; if (!coin.collected && player.intersects(coin)) { coin.collected = true; coin.alpha = 0; coinsCollected++; LK.setScore(coinsCollected); scoreText.setText('Coins: ' + coinsCollected + '/' + totalCoins); LK.getSound('coinCollect').play(); } } // Update and check star collisions for (var i = stars.length - 1; i >= 0; i--) { var star = stars[i]; // Check star-enemy collisions var hitEnemy = false; for (var j = 0; j < enemies.length; j++) { var enemy = enemies[j]; if (star.active && star.intersects(enemy)) { // Damage enemy enemy.health -= 25; enemy.updateHealthBar(); // Flash enemy red tween(enemy, { tint: 0xFF0000 }, { duration: 200, onFinish: function onFinish() { tween(enemy, { tint: 0xFFFFFF }, { duration: 200 }); } }); LK.getSound('enemyHit').play(); hitEnemy = true; // Remove enemy if health <= 0 if (enemy.health <= 0) { enemy.destroy(); enemies.splice(j, 1); enemiesDefeated++; j--; // Adjust index after removal } break; } } // Remove star if hit enemy or inactive if (hitEnemy || !star.active) { tween.stop(star); // Stop any ongoing tween star.destroy(); stars.splice(i, 1); } } // Check enemy collisions for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (player.intersects(enemy)) { // Initialize lastHit if not exists if (enemy.lastHit === undefined) { enemy.lastHit = 0; } // Only damage if enough time has passed (1 second = 60 ticks) if (LK.ticks - enemy.lastHit > 60) { player.health -= 10; enemy.lastHit = LK.ticks; updatePlayerHealthBar(); LK.getSound('enemyHit').play(); LK.effects.flashScreen(0xff0000, 500); if (player.health <= 0) { handlePlayerDeath(); } } } // Update enemy health bars enemy.updateHealthBar(); } // Level completion check - ensure both conditions are met before advancing // Only advance when enemies array is completely empty AND all coins are collected if (!levelComplete && coinsCollected >= totalCoins && enemies.length === 0) { levelComplete = true; // Flash screen green to indicate level completion LK.effects.flashScreen(0x00ff00, 1500); if (currentLevel < 10) { // Advance to next level after a brief delay LK.setTimeout(function () { initializeLevel(currentLevel + 1); }, 2000); } else if (currentLevel === 10) { // Show victory after completing level 10 LK.setTimeout(function () { LK.showYouWin(); }, 2000); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
// Gentle floating animation
self.floatOffset = 0;
self.originalY = 0;
self.update = function () {
if (!self.collected) {
self.floatOffset += 0.1;
self.y = self.originalY + Math.sin(self.floatOffset) * 5;
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Default to Skeleton, will be updated based on level
var assetName = 'Skeleton';
var enemyGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 1
});
// Method to change enemy asset based on level
self.setAssetForLevel = function (level) {
if (enemyGraphics) {
self.removeChild(enemyGraphics);
}
var assetName = level === 1 ? 'Skeleton' : level === 2 ? 'Slime' : 'Eye';
enemyGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 1
});
};
self.speed = 1.5;
self.direction = 1;
self.verticalSpeed = 1;
self.verticalDirection = 1;
// Physics properties for ground positioning
self.velocityY = 0;
self.gravity = 0.5;
self.isGrounded = false;
self.platformBounds = {
left: 0,
right: 500,
top: 0,
bottom: 0
};
self.assignedPlatform = 0;
self.maxHealth = 50;
self.health = 50;
// Jumping properties for slimes
self.jumpHeight = 150; // Height of jump
self.jumpDuration = 800; // Duration of jump animation
self.jumpCooldown = 180; // Ticks between jumps (3 seconds at 60fps)
self.lastJump = 0; // Track last jump time
self.isJumping = false; // Track if currently jumping
self.originalY = 0; // Store original Y position
// Create health bar background
self.healthBarBg = self.attachAsset('enemyHealthBarBg', {
anchorX: 0.5,
anchorY: 1
});
self.healthBarBg.x = 0;
self.healthBarBg.y = -120;
// Create health bar
self.healthBar = self.attachAsset('enemyHealthBar', {
anchorX: 0.5,
anchorY: 1
});
self.healthBar.x = 0;
self.healthBar.y = -120;
self.updateHealthBar = function () {
var healthPercent = self.health / self.maxHealth;
self.healthBar.width = 60 * healthPercent;
if (healthPercent > 0.6) {
self.healthBar.tint = 0x00ff00;
} else if (healthPercent > 0.3) {
self.healthBar.tint = 0xffff00;
} else {
self.healthBar.tint = 0xff0000;
}
};
// Platform collision detection for enemies
self.checkPlatformCollision = function () {
self.isGrounded = false;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
var platformTop = platform.y - 200; // Platform surface (adjusted for platform height)
// Adjust platform boundaries based on scale
var platformScale = platform.scaleX || 1;
var platformWidth = 450 * platformScale;
var platformLeft = platform.x - platformWidth;
var platformRight = platform.x + platformWidth;
// Check if enemy is above platform surface and within horizontal bounds
if (self.x >= platformLeft && self.x <= platformRight && self.y >= platformTop - 20 && self.y <= platformTop + 20 && self.velocityY >= 0) {
// Land on platform
self.y = platformTop;
self.velocityY = 0;
self.isGrounded = true;
break;
}
}
};
// Initialize movement properties
self.isMoving = false;
self.movementDuration = 3000; // Time to move across platform
// Start initial movement
self.startMovement = function () {
if (self.assignedPlatform !== undefined && platforms[self.assignedPlatform] && !self.isMoving) {
self.isMoving = true;
// Calculate full platform width based on platform scale
var platform = platforms[self.assignedPlatform];
var platformScale = platform.scaleX || 1;
var fullPlatformWidth = 450 * platformScale; // Base platform width * scale
// Set platform bounds to full edges reduced by 50px from each side
var platformLeft = platform.x - fullPlatformWidth + 50;
var platformRight = platform.x + fullPlatformWidth - 50;
// Update platform bounds for this enemy
self.platformBounds.left = platformLeft;
self.platformBounds.right = platformRight;
var targetX = self.direction > 0 ? platformRight : platformLeft;
var distance = Math.abs(targetX - self.x);
var duration = self.movementDuration; // Use consistent movement duration
tween(self, {
x: targetX
}, {
duration: duration,
easing: tween.linear,
onFinish: function onFinish() {
// Reverse direction and start moving to opposite end
self.direction *= -1;
self.isMoving = false;
// Flip enemy based on new direction
if (self.direction > 0) {
enemyGraphics.scaleX = 1;
} else {
enemyGraphics.scaleX = -1;
}
// Start next movement after brief pause
LK.setTimeout(function () {
self.startMovement();
}, 200); // Slightly longer pause between movements
}
});
}
};
self.update = function () {
// For all levels, enemies stay constrained to their platform positions
if (self.assignedPlatform !== undefined) {
// Store original Y position for jumping
if (self.originalY === 0) {
self.originalY = platforms[self.assignedPlatform].y - 200;
}
// Level 2 slimes have jumping behavior
if (currentLevel === 2 && !self.isJumping) {
// Check if it's time to jump
if (LK.ticks - self.lastJump > self.jumpCooldown) {
self.isJumping = true;
self.lastJump = LK.ticks;
// Jump up and then down using tween
tween(self, {
y: self.originalY - self.jumpHeight
}, {
duration: self.jumpDuration / 2,
easing: tween.easeOut,
onFinish: function onFinish() {
// Jump back down
tween(self, {
y: self.originalY
}, {
duration: self.jumpDuration / 2,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isJumping = false;
}
});
}
});
}
} else if (currentLevel !== 2) {
// Non-jumping enemies stay on platform top edge consistently
if (currentLevel === 2 && self.assignedPlatform === 2) {
// Special case for large platform right side enemy in Level 2
self.y = platforms[self.assignedPlatform].y - 200; // Keep on platform top edge
} else {
// All other enemies stay on platform top edge
self.y = platforms[self.assignedPlatform].y - 200; // Always stay on platform top edge
}
}
}
};
return self;
});
var Ladder = Container.expand(function () {
var self = Container.call(this);
var ladderGraphics = self.attachAsset('ladder', {
anchorX: 0.5,
anchorY: 0.4
});
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1
});
self.speed = 7;
self.currentPlatform = null;
self.maxHealth = 100;
self.health = 100;
self.lastShot = 0;
self.shootCooldown = 30; // 30 ticks = 0.5 seconds
// Physics properties
self.velocityY = 0;
self.gravity = 0.8;
self.terminalVelocity = 15;
self.isGrounded = false;
// Animation properties
self.animationFrame = 0;
self.animationSpeed = 8; // Change frame every 8 ticks
self.isMoving = false;
self.isShooting = false;
self.facingLeft = false;
self.isClimbing = false;
self.onLadder = null;
self.lastX = self.x;
// Animation frames for different states
self.walkFrames = ['Ninja1', 'Ninja2', 'Ninja3', 'Ninja4'];
self.shootFrame = 'Ninjashooting';
self.climbFrames = ['Ninja01', 'Ninja02'];
// Track animation state changes
self.lastAsset = null;
self.lastFlip = null;
// Platform collision detection
self.checkPlatformCollision = function () {
self.isGrounded = false;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
var platformTop = platform.y - 200; // Platform surface
// Adjust platform boundaries based on scale for Level 2
var platformScale = platform.scaleX || 1;
var platformWidth = 450 * platformScale;
var platformLeft = platform.x - platformWidth; // Half platform width
var platformRight = platform.x + platformWidth; // Half platform width
// Check if player is above platform surface and within horizontal bounds
if (self.x >= platformLeft && self.x <= platformRight && self.y >= platformTop - 20 && self.y <= platformTop + 20 && self.velocityY >= 0) {
// Land on platform
self.y = platformTop;
self.velocityY = 0;
self.isGrounded = true;
self.currentPlatform = i;
break;
}
}
};
self.updateAnimation = function () {
var currentAsset = '';
if (self.isShooting) {
currentAsset = self.shootFrame;
} else if (self.isClimbing) {
// Climbing animation when on ladder
var climbFrameIndex = Math.floor(self.animationFrame / self.animationSpeed) % self.climbFrames.length;
currentAsset = self.climbFrames[climbFrameIndex];
} else if (self.isMoving) {
// Walking animation when moving
var walkFrameIndex = Math.floor(self.animationFrame / self.animationSpeed) % self.walkFrames.length;
currentAsset = self.walkFrames[walkFrameIndex];
} else {
// Default standing pose - show player asset when not moving
currentAsset = 'player';
}
// Only update graphics if asset changed
if (!self.lastAsset || self.lastAsset !== currentAsset) {
// Remove old graphics if exists
if (playerGraphics) {
self.removeChild(playerGraphics);
}
// Create new graphics
playerGraphics = self.attachAsset(currentAsset, {
anchorX: 0.5,
anchorY: 1
});
// Store current state
self.lastAsset = currentAsset;
}
// Flip player based on facing direction for all animation frames
if (self.facingLeft) {
// Facing left, flip horizontally
playerGraphics.scaleX = -1;
} else {
// Facing right, normal orientation
playerGraphics.scaleX = 1;
}
};
self.update = function () {
// Apply gravity when not climbing
if (!self.isClimbing) {
// Apply gravity
self.velocityY += self.gravity;
// Cap at terminal velocity
if (self.velocityY > self.terminalVelocity) {
self.velocityY = self.terminalVelocity;
}
// Apply vertical velocity
self.y += self.velocityY;
// Check platform collisions
self.checkPlatformCollision();
} else {
// Reset velocity when climbing
self.velocityY = 0;
self.isGrounded = true;
}
// Check for ladder intersection or standing on top edge
var currentLadder = null;
for (var i = 0; i < ladders.length; i++) {
var ladder = ladders[i];
// Check direct intersection (already on ladder)
if (self.intersects(ladder)) {
currentLadder = ladder;
break;
}
// Check if standing on top edge of ladder (within 40px horizontally and 50px above)
var horizontalDistance = Math.abs(self.x - ladder.x);
var verticalDistance = ladder.y - self.y;
if (horizontalDistance <= 40 && verticalDistance >= -50 && verticalDistance <= 50 && self.isGrounded) {
currentLadder = ladder;
break;
}
}
// Check for rope intersection for climbing
if (!currentLadder) {
for (var i = 0; i < ropes.length; i++) {
var rope = ropes[i];
if (self.intersects(rope)) {
currentLadder = rope;
break;
}
}
}
// Update climbing state
if (currentLadder && !self.isClimbing) {
// Just reached a ladder - enter climbing mode
self.isClimbing = true;
self.onLadder = currentLadder;
self.isMoving = false;
// Stop any horizontal movement when reaching ladder
tween.stop(self, {
x: true,
y: true
});
// Snap to ladder center
self.x = currentLadder.x;
} else if (!currentLadder && self.isClimbing) {
// Left ladder area - exit climbing mode
self.isClimbing = false;
self.onLadder = null;
// Start falling when leaving ladder
self.velocityY = 0;
self.isGrounded = false;
}
// Check if player is moving (only when not climbing)
if (!self.isClimbing) {
var horizontalMovement = Math.abs(self.x - self.lastX) > 0.1;
var verticalMovement = Math.abs(self.y - (self.lastY || self.y)) > 0.1;
if (horizontalMovement || verticalMovement) {
self.isMoving = true;
// Determine facing direction for any horizontal movement
if (horizontalMovement) {
if (self.x < self.lastX) {
if (!self.facingLeft) {
self.facingLeft = true;
self.updateAnimation();
}
} else if (self.x > self.lastX) {
if (self.facingLeft) {
self.facingLeft = false;
self.updateAnimation();
}
}
}
} else {
self.isMoving = false;
}
}
// Update last positions
self.lastX = self.x;
self.lastY = self.y;
// Check if player is shooting (cooldown active)
self.isShooting = LK.ticks - self.lastShot < 15; // Show shooting animation for 15 ticks
// Update animation frame counter only when moving, shooting, or climbing
if (self.isMoving || self.isShooting || self.isClimbing) {
self.animationFrame++;
}
// Check if player has fallen off the world or gone out of bounds
if (self.y > 2732 + 100 || self.x < -100 || self.x > 2148) {
// Player is out of bounds - trigger death
if (typeof handlePlayerDeath === 'function') {
handlePlayerDeath();
}
}
// Update animation
self.updateAnimation();
};
return self;
});
var Rope = Container.expand(function () {
var self = Container.call(this);
// Create rope using a brown rectangle
var ropeGraphics = self.attachAsset('enemyHealthBarBg', {
anchorX: 0.5,
anchorY: 0.5
});
ropeGraphics.tint = 0x8B4513; // Brown color for rope
self.canClimb = true;
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 30;
self.targetX = 0;
self.targetY = 0;
self.active = true;
self.shootAt = function (targetX, targetY) {
self.targetX = targetX;
self.targetY = targetY;
// Calculate distance for animation duration
var distance = Math.sqrt(Math.pow(targetX - self.x, 2) + Math.pow(targetY - self.y, 2));
var duration = distance * 3; // Adjust speed by changing multiplier
// Use tween to animate star to target
tween(self, {
x: targetX,
y: targetY,
rotation: Math.PI * 4
}, {
duration: duration,
easing: tween.linear,
onFinish: function onFinish() {
self.active = false;
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Level game state variables
var currentLevel = 1;
var coinsCollected = 0;
var totalCoins = 5;
var enemiesDefeated = 0;
var totalEnemies = 4;
var levelComplete = false;
var platforms = [];
var ladders = [];
var ropes = [];
var coins = [];
var enemies = [];
var stars = [];
var player;
var playerLives = 5;
var livesDisplay = [];
var levelStartTime = 0;
// Level 1 Platform positions (central hub + 4 outer platforms in 2x2 grid)
var level1PlatformPositions = [{
x: 1024,
y: 1366
},
// Center platform
{
x: 524,
y: 850
},
// Top-left
{
x: 1524,
y: 850
},
// Top-right
{
x: 524,
y: 2000
},
// Bottom-left
{
x: 1524,
y: 2000
} // Bottom-right
];
// Level 2 Platform positions (vertical tower layout with varying sizes)
var level2PlatformPositions = [{
x: 1024,
y: 2500 // Bottom platform (500px from bottom: 2732 - 500 = 2232, plus platform height)
}, {
x: 400,
y: 2200 // Small platform left side
}, {
x: 1500,
y: 1950 // Large platform right side
}, {
x: 400,
y: 1400 // Medium platform left-center
}, {
x: 1400,
y: 1350 // Small platform right-center
}, {
x: 1200,
y: 900 // Large center platform
}, {
x: 400,
y: 600 // Small platform far left
}, {
x: 1750,
y: 500 // Small platform far right
}];
// Level 3 Platform positions (4x4 grid with 500px horizontal and 600px vertical spacing)
var level3PlatformPositions = [
// Bottom row (y = 2432 - moved up by 200px)
{
x: 274,
y: 2432
}, {
x: 774,
y: 2432
}, {
x: 1274,
y: 2432
}, {
x: 1774,
y: 2432
},
// Third row (y = 1832 - moved up by 200px)
{
x: 274,
y: 1832
}, {
x: 774,
y: 1832
}, {
x: 1274,
y: 1832
}, {
x: 1774,
y: 1832
},
// Second row (y = 1232 - moved up by 200px)
{
x: 274,
y: 1232
}, {
x: 774,
y: 1232
}, {
x: 1274,
y: 1232
}, {
x: 1774,
y: 1232
},
// Top row (y = 632 - moved up by 200px)
{
x: 274,
y: 632
}, {
x: 774,
y: 632
}, {
x: 1274,
y: 632
}, {
x: 1774,
y: 632
}];
// Level 4 Platform positions (scattered platforms with varying heights)
var level4PlatformPositions = [{
x: 400,
y: 2600
},
// Bottom left
{
x: 400,
y: 2100
},
// Mid-left
{
x: 1500,
y: 2100
},
// Mid-right
{
x: 600,
y: 1600
},
// Upper-left
{
x: 1700,
y: 1600
},
// Upper-right
{
x: 400,
y: 1100
},
// High-left
{
x: 1500,
y: 1100
},
// High-right
{
x: 1024,
y: 600
} // Top center
];
// Level 5 Platform positions (spiral layout)
var level5PlatformPositions = [{
x: 1024,
y: 2500
},
// Center bottom
{
x: 1524,
y: 1900
},
// Right moved up by 300px
{
x: 1724,
y: 1500
},
// Far right moved up by 300px
{
x: 624,
y: 1800
},
// Far left moved right by 300px
{
x: 400,
y: 2200
},
// Left
{
x: 1024,
y: 1000
},
// Center-high
{
x: 400,
y: 600
} // Top center
];
// Level 6 Platform positions (double tower layout)
var level6PlatformPositions = [
// Left tower
{
x: 500,
y: 2500
}, {
x: 500,
y: 2100
}, {
x: 500,
y: 1700
}, {
x: 500,
y: 1300
}, {
x: 500,
y: 900
}, {
x: 500,
y: 500
},
// Right tower
{
x: 1548,
y: 2500
}, {
x: 1548,
y: 2100
}, {
x: 1548,
y: 1700
}, {
x: 1548,
y: 1300
}, {
x: 1548,
y: 900
}, {
x: 1548,
y: 500
},
// Bridge platforms
{
x: 800,
y: 1500
}, {
x: 1248,
y: 1500
}, {
x: 1024,
y: 1000
}];
// Level 7 Platform positions (maze-like layout)
var level7PlatformPositions = [{
x: 200,
y: 2500
}, {
x: 600,
y: 2500
}, {
x: 1000,
y: 2500
}, {
x: 1400,
y: 2500
}, {
x: 1800,
y: 2500
}, {
x: 200,
y: 2000
}, {
x: 1000,
y: 2000
}, {
x: 1800,
y: 2000
}, {
x: 400,
y: 1600
}, {
x: 800,
y: 1600
}, {
x: 1200,
y: 1600
}, {
x: 1600,
y: 1600
}, {
x: 200,
y: 1200
}, {
x: 1000,
y: 1200
}, {
x: 1800,
y: 1200
}, {
x: 400,
y: 800
}, {
x: 1200,
y: 800
}, {
x: 600,
y: 500
}, {
x: 1400,
y: 500
}];
// Level 8 Platform positions (pyramid layout)
var level8PlatformPositions = [
// Base row (7 platforms)
{
x: 200,
y: 2500
}, {
x: 500,
y: 2500
}, {
x: 800,
y: 2500
}, {
x: 1024,
y: 2500
}, {
x: 1248,
y: 2500
}, {
x: 1548,
y: 2500
}, {
x: 1848,
y: 2500
},
// Second row (5 platforms)
{
x: 350,
y: 2100
}, {
x: 700,
y: 2100
}, {
x: 1024,
y: 2100
}, {
x: 1348,
y: 2100
}, {
x: 1698,
y: 2100
},
// Third row (3 platforms)
{
x: 524,
y: 1700
}, {
x: 1024,
y: 1700
}, {
x: 1524,
y: 1700
},
// Fourth row (2 platforms)
{
x: 774,
y: 1300
}, {
x: 1274,
y: 1300
},
// Top platform
{
x: 1024,
y: 900
}];
// Level 9 Platform positions (circular arrangement with center)
var level9PlatformPositions = [{
x: 1024,
y: 1500
},
// Center platform
// Inner circle
{
x: 1024,
y: 1000
}, {
x: 1324,
y: 1200
}, {
x: 1324,
y: 1800
}, {
x: 1024,
y: 2000
}, {
x: 724,
y: 1800
}, {
x: 724,
y: 1200
},
// Outer circle
{
x: 1024,
y: 600
}, {
x: 1524,
y: 800
}, {
x: 1724,
y: 1200
}, {
x: 1724,
y: 1800
}, {
x: 1524,
y: 2200
}, {
x: 1024,
y: 2400
}, {
x: 524,
y: 2200
}, {
x: 324,
y: 1800
}, {
x: 324,
y: 1200
}, {
x: 524,
y: 800
}];
// Level 10 Platform positions (final challenge - complex multi-level)
var level10PlatformPositions = [
// Bottom foundation
{
x: 200,
y: 2600
}, {
x: 600,
y: 2600
}, {
x: 1000,
y: 2600
}, {
x: 1400,
y: 2600
}, {
x: 1800,
y: 2600
},
// Second level
{
x: 400,
y: 2200
}, {
x: 1024,
y: 2200
}, {
x: 1600,
y: 2200
},
// Third level branches
{
x: 200,
y: 1800
}, {
x: 500,
y: 1800
}, {
x: 800,
y: 1800
}, {
x: 1248,
y: 1800
}, {
x: 1548,
y: 1800
}, {
x: 1848,
y: 1800
},
// Fourth level connections
{
x: 350,
y: 1400
}, {
x: 700,
y: 1400
}, {
x: 1350,
y: 1400
}, {
x: 1700,
y: 1400
},
// Upper platforms
{
x: 400,
y: 1000
}, {
x: 1024,
y: 1000
}, {
x: 1600,
y: 1000
},
// Near top
{
x: 600,
y: 700
}, {
x: 1400,
y: 700
},
// Final platform
{
x: 1024,
y: 400
}];
var platformPositions = currentLevel === 1 ? level1PlatformPositions : currentLevel === 2 ? level2PlatformPositions : currentLevel === 3 ? level3PlatformPositions : currentLevel === 4 ? level4PlatformPositions : currentLevel === 5 ? level5PlatformPositions : currentLevel === 6 ? level6PlatformPositions : currentLevel === 7 ? level7PlatformPositions : currentLevel === 8 ? level8PlatformPositions : currentLevel === 9 ? level9PlatformPositions : level10PlatformPositions;
// Add background based on current level
var backgroundAsset = currentLevel === 1 ? 'background1' : currentLevel === 2 ? 'background2' : 'background3';
var background = game.attachAsset(backgroundAsset, {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
// Create platforms with different sizes for Level 2
for (var i = 0; i < platformPositions.length; i++) {
var platform = new Platform();
platform.x = platformPositions[i].x;
platform.y = platformPositions[i].y;
// Scale platforms differently for Level 2 to create variety
if (currentLevel === 2) {
if (i === 1 || i === 4 || i === 6 || i === 7) {
// Small platforms
platform.scaleX = 0.6;
platform.scaleY = 1.6;
} else if (i === 2 || i === 5) {
// Large platforms
platform.scaleX = 1.2;
platform.scaleY = 1.0;
} else {
// Medium platforms
platform.scaleX = 0.9;
platform.scaleY = 1.0;
}
} else if (currentLevel === 3) {
// Level 3: All platforms are 400x450px (scale to achieve this from 900x450 base)
platform.scaleX = 0.44; // 900 * 0.44 ≈ 400px
platform.scaleY = 1.0; // 450 * 1.0 = 450px
}
platforms.push(platform);
game.addChild(platform);
}
// Create comprehensive ladder system with multiple segments
function createLadderPath(fromPlatform, toPlatform, segments) {
var startX = fromPlatform.x;
var startY = fromPlatform.y - 200; // Start from platform top edge
var endX = toPlatform.x;
var endY = toPlatform.y - 200; // End at platform top edge
var stepX = (endX - startX) / segments;
var stepY = (endY - startY) / segments;
for (var i = 0; i < segments; i++) {
var ladder = new Ladder();
ladder.x = startX + stepX * i + stepX / 2;
ladder.y = startY + stepY * i + stepY / 2;
ladders.push(ladder);
game.addChild(ladder);
}
}
// Create rope connections between platforms
function createRope(fromPlatform, toPlatform) {
var rope = new Rope();
rope.x = (fromPlatform.x + toPlatform.x) / 2;
rope.y = (fromPlatform.y + toPlatform.y) / 2;
// Scale rope to connect platforms
var distance = Math.sqrt(Math.pow(toPlatform.x - fromPlatform.x, 2) + Math.pow(toPlatform.y - fromPlatform.y, 2));
rope.scaleX = distance / 60; // Scale to fit distance
rope.scaleY = 0.5; // Thin rope
// Rotate rope to align with platforms
var angle = Math.atan2(toPlatform.y - fromPlatform.y, toPlatform.x - fromPlatform.x);
rope.rotation = angle;
ropes.push(rope);
game.addChild(rope);
}
if (currentLevel === 1) {
// Level 1: Create only the two side lines of 5 ladders each
// Left side connection (platform 1 to 3) - 5 ladder segments
createLadderPath(platforms[1], platforms[3], 5);
// Right side connection (platform 2 to 4) - 5 ladder segments
createLadderPath(platforms[2], platforms[4], 5);
} else if (currentLevel === 2) {
// Level 2: Create ladders from small left platform to medium platform left-center and from bottom platform left to large platform right
// Small left platform to medium platform left-center - 4 ladder segments
createLadderPath(platforms[1], platforms[3], 4);
// Bottom platform left side to large platform right side - 3 ladder segments moved up to platform top edge
createLadderPath({
x: platforms[0].x,
y: platforms[0].y - 200 // Start from platform top edge
}, platforms[2], 3);
// Add new ladder on left side of bottom platform
var leftBottomLadder = new Ladder();
leftBottomLadder.x = platforms[0].x / 2 - 300; // Left side of bottom platform moved left by 100px
leftBottomLadder.y = platforms[0].y / 2 - 850; // Top edge of platform moved up by 200px
ladders.push(leftBottomLadder);
game.addChild(leftBottomLadder);
// Add 2 ladders from small platform right-center (platform 4) to large center platform (platform 5)
// From right top edge of platform 4 to middle top edge of platform 5
createLadderPath({
x: platforms[4].x + 150,
y: platforms[4].y
}, {
x: platforms[5].x,
y: platforms[5].y
}, 2);
// Add 2 ladders from large center platform (platform 5) right side before 200px to small platform far right (platform 7)
// From right side of platform 5 (before 200px) to platform 7, moved up by 50px
createLadderPath({
x: platforms[5].x + 350,
y: platforms[5].y - 50
}, {
x: platforms[7].x - 200,
y: platforms[7].y - 50
}, 2);
// Add 2 ladders from large center platform (platform 5) top left edge to small platform far left (platform 6)
createLadderPath({
x: platforms[5].x - 350,
y: platforms[5].y - 50
}, platforms[6], 2);
// Add 2 ladders above each other on right side of large platform before 240px from right edge
var rightLadder1 = new Ladder();
rightLadder1.x = 2048 - 250; // 240px from right edge of screen moved left by 100px
rightLadder1.y = platforms[2].y - 200; // Top edge of large platform right side moved up by 150px
ladders.push(rightLadder1);
game.addChild(rightLadder1);
var rightLadder2 = new Ladder();
rightLadder2.x = 2048 - 250; // Same x position as first ladder moved left by 100px
rightLadder2.y = platforms[2].y - 500; // 290px above first ladder (height of one ladder segment) moved up by 150px
ladders.push(rightLadder2);
game.addChild(rightLadder2);
} else if (currentLevel === 3) {
// Level 3: Create 4 continuous vertical ladder lines from bottom to top
// Each ladder line connects all 4 platforms vertically (4 rows with 600px spacing)
for (var col = 0; col < 4; col++) {
// Create continuous ladders from bottom platform to top platform
var bottomPlatformIndex = col; // Bottom row platforms (0-3)
var topPlatformIndex = col + 12; // Top row platforms (12-15)
// Create 16 ladder segments to span from bottom to top (removed 2 bottom segments)
for (var segment = 2; segment < 18; segment++) {
var ladder = new Ladder();
ladder.x = platforms[bottomPlatformIndex].x;
// Start from bottom platform top edge, go up with ladder segments
ladder.y = platforms[bottomPlatformIndex].y - 200 - segment * 100;
ladders.push(ladder);
game.addChild(ladder);
}
}
} else if (currentLevel === 4) {
// Level 4: Only new ladders - remove old ones
// Add 2 ladders in line above each other from left side of bottom platform at its top edge
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[0].x - 350; // Left side of bottom platform
ladder.y = platforms[0].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders in line above each other at mid left platform top edge
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[1].x + 200; // Before 200px from left side of mid left platform
ladder.y = platforms[1].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders from top edge of upper left platform before 200px from its right
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[3].x + 200; // Before 200px from right side of upper left platform
ladder.y = platforms[3].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders above each other on high left platform moved left by 50px at its top edge
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[5].x + 150; // Before 200px from right side moved left by 50px
ladder.y = platforms[5].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders above each other in middle of top edge of high right platform
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[6].x; // Middle of high right platform
ladder.y = platforms[6].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders diagonal going left from middle upper right platform above its top edge by 200px
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[4].x - i * 100; // Diagonal going left
ladder.y = platforms[4].y - 400 - i * 100; // Above top edge by 200px and diagonal up
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders diagonal going up and right from mid right platform above its top edge by 200px
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[2].x - 200 + i * 100; // Before 200px from left but 2nd ladder goes right
ladder.y = platforms[2].y - 500 - i * 100; // Above top edge by 200px and diagonal up, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
} else if (currentLevel === 5) {
// Level 5: Add 2 ladders above each other from top edge of bottom platform at its max right side
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
// Position at max right side of bottom platform (platform 0)
ladder.x = platforms[0].x + 400; // Right edge of bottom platform
ladder.y = platforms[0].y - 300 - i * 290; // Stack above each other from top edge
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders from top mid edge of right platform by 50px going right diagonally
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
// Position above right platform (platform 1) going diagonally right
ladder.x = platforms[1].x + 100 + i * 60; // Start 100px right of center and space by 60px horizontally
ladder.y = platforms[1].y - 450 - i * 150; // Above top edge by 150px and diagonal up (moved up by 100px)
ladders.push(ladder);
game.addChild(ladder);
}
// Move all ladders to front after background to ensure visibility
for (var i = 0; i < ladders.length; i++) {
game.setChildIndex(ladders[i], game.children.length - 1);
}
} else if (currentLevel === 6) {
// Level 6: Connect the towers with ropes and ladders
for (var i = 0; i < 5; i++) {
createLadderPath(platforms[i], platforms[i + 1], 2);
createLadderPath(platforms[i + 6], platforms[i + 7], 2);
}
createRope(platforms[12], platforms[13]);
createRope(platforms[5], platforms[14]);
createRope(platforms[11], platforms[14]);
} else if (currentLevel === 7) {
// Level 7: Maze connections
createLadderPath(platforms[0], platforms[5], 3);
createRope(platforms[1], platforms[6]);
createLadderPath(platforms[7], platforms[12], 2);
createRope(platforms[8], platforms[13]);
createLadderPath(platforms[14], platforms[16], 2);
createRope(platforms[15], platforms[17]);
} else if (currentLevel === 8) {
// Level 8: Pyramid climbing
for (var row = 0; row < 4; row++) {
var startIdx = row === 0 ? 0 : row === 1 ? 7 : row === 2 ? 12 : 15;
var count = row === 0 ? 7 : row === 1 ? 5 : row === 2 ? 3 : 2;
for (var i = 0; i < count - 1; i++) {
if (row < 3) {
var nextRowStart = row === 0 ? 7 : row === 1 ? 12 : 15;
var nextIdx = nextRowStart + Math.floor(i / 2);
if (nextIdx < platforms.length) {
createLadderPath(platforms[startIdx + i], platforms[nextIdx], 2);
}
}
}
}
createLadderPath(platforms[15], platforms[17], 2);
} else if (currentLevel === 9) {
// Level 9: Circular connections
createLadderPath(platforms[0], platforms[1], 3);
for (var i = 1; i < 6; i++) {
createRope(platforms[i], platforms[i % 6 + 1]);
}
for (var i = 7; i < 15; i++) {
createRope(platforms[i], platforms[(i - 7) % 8 + 7]);
}
createLadderPath(platforms[1], platforms[7], 2);
createLadderPath(platforms[3], platforms[9], 2);
} else if (currentLevel === 10) {
// Level 10: Complex final level connections
createLadderPath(platforms[0], platforms[5], 3);
createRope(platforms[5], platforms[6]);
createLadderPath(platforms[6], platforms[11], 3);
createRope(platforms[11], platforms[19]);
createLadderPath(platforms[19], platforms[21], 2);
createRope(platforms[21], platforms[22]);
createLadderPath(platforms[22], platforms[24], 2);
// Additional connections
createRope(platforms[1], platforms[7]);
createRope(platforms[8], platforms[15]);
createLadderPath(platforms[20], platforms[23], 2);
}
// Create coins above platforms
for (var i = 0; i < platforms.length; i++) {
var coin = new Coin();
coin.x = platforms[i].x;
coin.y = platforms[i].y - 280; // Position coins closer to platforms
coin.originalY = coin.y;
coins.push(coin);
game.addChild(coin);
}
// Create player
player = new Player();
if (currentLevel === 3) {
// Position player beside the first ladder line from the right, not touching
player.x = platforms[0].x + 100; // 100px to the right of first ladder line
} else {
player.x = platforms[0].x; // Start on center platform
}
player.y = platforms[0].y - 200; // Position above the top edge of middle platform
player.currentPlatform = 0;
game.addChild(player);
// Move player to front (above background)
game.setChildIndex(player, game.children.length - 1);
// Create enemies based on level
function spawnEnemies() {
// Clear existing enemies
for (var i = 0; i < enemies.length; i++) {
enemies[i].destroy();
}
enemies = [];
if (currentLevel === 1) {
// Level 1: Spawn exactly 4 enemies, one on each outer platform (excluding center platform at index 0)
for (var i = 1; i < platforms.length; i++) {
var enemy = new Enemy();
enemy.setAssetForLevel(1); // Set Skeleton asset for level 1
enemy.x = platforms[i].x;
enemy.y = platforms[i].y - 200; // Position on top edge of platform surface (same as Level 2)
enemy.assignedPlatform = i;
// Set platform boundaries to keep enemy confined to its platform horizontally only
var platformScale = platforms[i].scaleX || 1;
var fullPlatformWidth = 450 * platformScale;
enemy.platformBounds.left = platforms[i].x - fullPlatformWidth + 50;
enemy.platformBounds.right = platforms[i].x + fullPlatformWidth - 50;
// Set platform bounds for vertical constraint (keep enemies close to top edge like Level 2)
enemy.platformBounds.top = platforms[i].y - 220; // 20px above surface
enemy.platformBounds.bottom = platforms[i].y - 180; // 20px below surface
enemies.push(enemy);
game.addChild(enemy);
}
} else if (currentLevel === 2) {
// Level 2: Spawn enemies on selected platforms with adjusted boundaries based on platform scale
var enemyPlatforms = [1, 2, 3, 4, 5, 6, 7]; // Skip bottom platform, include large center platform 5 and medium platform 3
for (var i = 0; i < enemyPlatforms.length; i++) {
var platformIndex = enemyPlatforms[i];
var enemy = new Enemy();
enemy.setAssetForLevel(2); // Set Slime asset for level 2
enemy.x = platforms[platformIndex].x;
// Check if this is a small platform (platforms 1, 4, 6, 7) and position at top edge
if (platformIndex === 1 || platformIndex === 4 || platformIndex === 6 || platformIndex === 7) {
// Small platforms - position at top edge with no space
enemy.y = platforms[platformIndex].y - 200; // Position on top edge of platform
} else if (platformIndex === 2) {
enemy.y = platforms[platformIndex].y - 50; // Position above platform to let gravity take effect - moved down 150px
} else {
enemy.y = platforms[platformIndex].y - 160; // Position on top edge of platform
}
enemy.assignedPlatform = platformIndex;
// Adjust boundaries based on platform scale
var platformScale = platforms[platformIndex].scaleX || 1;
var fullPlatformWidth = 450 * platformScale; // Use full platform width
enemy.platformBounds.left = platforms[platformIndex].x - fullPlatformWidth + 50;
enemy.platformBounds.right = platforms[platformIndex].x + fullPlatformWidth - 50;
// Set platform bounds for vertical constraint (keep enemies close to top edge)
if (platformIndex === 2) {
enemy.platformBounds.top = platforms[platformIndex].y - 220; // 20px above moved surface (adjusted for new position)
enemy.platformBounds.bottom = platforms[platformIndex].y - 180; // 20px below moved surface (adjusted for new position)
} else if (platformIndex === 5) {
enemy.platformBounds.top = platforms[platformIndex].y - 170; // 20px above surface for large center platform
enemy.platformBounds.bottom = platforms[platformIndex].y - 130; // 20px below surface for large center platform
} else {
enemy.platformBounds.top = platforms[platformIndex].y - 170; // 20px above surface
enemy.platformBounds.bottom = platforms[platformIndex].y - 130; // 20px below surface
}
// Add slight velocity to keep enemies moving and visible
enemy.speed = 2.0; // Slightly faster movement
enemies.push(enemy);
game.addChild(enemy);
}
} else if (currentLevel === 3) {
// Level 3: Spawn enemies on 12 platforms (exclude 4 corner platforms for player safety)
var enemyPlatforms = [1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14]; // Skip corners (0, 3, 12, 15)
for (var i = 0; i < enemyPlatforms.length; i++) {
var platformIndex = enemyPlatforms[i];
var enemy = new Enemy();
enemy.setAssetForLevel(3); // Use Eye asset for level 3
enemy.x = platforms[platformIndex].x;
enemy.y = platforms[platformIndex].y - 225; // Position directly on platform surface
enemy.assignedPlatform = platformIndex;
// Set platform boundaries to keep enemy confined to its platform horizontally only
var platformScale = platforms[platformIndex].scaleX || 1;
var fullPlatformWidth = 450 * platformScale; // Full platform width for Level 3
enemy.platformBounds.left = platforms[platformIndex].x - fullPlatformWidth + 50;
enemy.platformBounds.right = platforms[platformIndex].x + fullPlatformWidth - 50;
// Set platform bounds for vertical constraint (keep enemies close to top edge like Level 1)
enemy.platformBounds.top = platforms[platformIndex].y - 245; // 20px above surface
enemy.platformBounds.bottom = platforms[platformIndex].y - 205; // 20px below surface
enemy.speed = 1.5; // Standard movement speed
enemies.push(enemy);
game.addChild(enemy);
}
} else if (currentLevel >= 4 && currentLevel <= 10) {
// Levels 4-10: Spawn enemies on most platforms with cycling enemy types
var enemyAssetLevel = (currentLevel - 1) % 3 + 1; // Cycle through asset types 1, 2, 3
if (currentLevel === 4) {
// Level 4: Specific enemy placement including top center platform and all empty platforms
var level4EnemyPlatforms = [1, 2, 3, 4, 5, 6, 7]; // Include all platforms except bottom (index 0)
for (var i = 0; i < level4EnemyPlatforms.length; i++) {
var platformIndex = level4EnemyPlatforms[i];
var enemy = new Enemy();
enemy.setAssetForLevel(enemyAssetLevel);
enemy.x = platforms[platformIndex].x;
enemy.y = platforms[platformIndex].y - 225;
enemy.assignedPlatform = platformIndex;
var platformScale = platforms[platformIndex].scaleX || 1;
var fullPlatformWidth = 450 * platformScale; // Full platform width for Level 4
enemy.platformBounds.left = platforms[platformIndex].x - fullPlatformWidth + 50;
enemy.platformBounds.right = platforms[platformIndex].x + fullPlatformWidth - 50;
enemy.platformBounds.top = platforms[platformIndex].y - 245;
enemy.platformBounds.bottom = platforms[platformIndex].y - 205;
enemy.speed = 1.0 + currentLevel * 0.2; // Increase speed with level
enemies.push(enemy);
game.addChild(enemy);
}
} else {
// Other levels 5-10: Standard enemy spawning
var enemyCount = Math.min(platforms.length - 2, 8 + (currentLevel - 4) * 2); // Increase enemies per level
var skipPlatforms = currentLevel <= 6 ? 1 : 2; // Skip first platform(s) for player safety
for (var i = skipPlatforms; i < skipPlatforms + enemyCount && i < platforms.length; i++) {
var enemy = new Enemy();
enemy.setAssetForLevel(enemyAssetLevel);
enemy.x = platforms[i].x;
enemy.y = platforms[i].y - 225;
enemy.assignedPlatform = i;
var platformScale = platforms[i].scaleX || 1;
var fullPlatformWidth = 450 * platformScale; // Full platform width for levels 5-10
enemy.platformBounds.left = platforms[i].x - fullPlatformWidth + 50;
enemy.platformBounds.right = platforms[i].x + fullPlatformWidth - 50;
enemy.platformBounds.top = platforms[i].y - 245;
enemy.platformBounds.bottom = platforms[i].y - 205;
enemy.speed = 1.0 + currentLevel * 0.2; // Increase speed with level
enemies.push(enemy);
game.addChild(enemy);
}
}
}
// Move enemies to front after spawning to ensure they are visible and not behind background
for (var i = 0; i < enemies.length; i++) {
game.setChildIndex(enemies[i], game.children.length - 1);
// Start movement for each enemy
LK.setTimeout(function (enemy) {
return function () {
enemy.startMovement();
};
}(enemies[i]), i * 500 + 1000); // Stagger enemy movement starts
}
// Move player to front after spawning enemies to ensure visibility
game.setChildIndex(player, game.children.length - 1);
}
// Player health bar
var playerHealthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0,
anchorY: 0
});
playerHealthBarBg.x = 120;
playerHealthBarBg.y = 20;
LK.gui.topLeft.addChild(playerHealthBarBg);
var playerHealthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0
});
playerHealthBar.x = 120;
playerHealthBar.y = 20;
LK.gui.topLeft.addChild(playerHealthBar);
var healthText = new Text2('Health: 100/100', {
size: 40,
fill: 0xFFFFFF
});
healthText.anchor.set(0, 0);
healthText.x = 120;
healthText.y = 50;
LK.gui.topLeft.addChild(healthText);
// Lives display (5 skull icons beside health bar)
for (var i = 0; i < 5; i++) {
var skull = LK.getAsset('skull', {
anchorX: 0.5,
anchorY: 0.5
});
skull.x = 350 + i * 50; // Position beside health bar with spacing
skull.y = 35; // Align with health bar center
skull.alpha = 1; // All skulls start visible
livesDisplay.push(skull);
LK.gui.topLeft.addChild(skull);
}
// Score display
var scoreText = new Text2('Coins: 0/' + totalCoins, {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Level 1 title display
var levelText = new Text2('LEVEL 1', {
size: 60,
fill: 0xFFD700
});
levelText.anchor.set(-2.3, 0.5);
levelText.x = 0;
levelText.y = 20;
LK.gui.top.addChild(levelText);
// Function to initialize specific level
function initializeLevel(levelNumber) {
currentLevel = levelNumber;
// Clear existing game objects
for (var i = 0; i < platforms.length; i++) {
platforms[i].destroy();
}
for (var i = 0; i < ladders.length; i++) {
ladders[i].destroy();
}
for (var i = 0; i < ropes.length; i++) {
ropes[i].destroy();
}
for (var i = 0; i < coins.length; i++) {
coins[i].destroy();
}
for (var i = 0; i < enemies.length; i++) {
enemies[i].destroy();
}
for (var i = 0; i < stars.length; i++) {
stars[i].destroy();
}
// Clear arrays
platforms = [];
ladders = [];
ropes = [];
coins = [];
enemies = [];
stars = [];
// Reset game state
coinsCollected = 0;
enemiesDefeated = 0;
levelComplete = false;
// Update platform positions and totals based on level
if (levelNumber === 1) {
platformPositions = level1PlatformPositions;
totalCoins = 5;
totalEnemies = 4;
} else if (levelNumber === 2) {
platformPositions = level2PlatformPositions;
totalCoins = 8;
totalEnemies = 7;
} else if (levelNumber === 3) {
platformPositions = level3PlatformPositions;
totalCoins = 16;
totalEnemies = 12;
} else if (levelNumber === 4) {
platformPositions = level4PlatformPositions;
totalCoins = 8;
totalEnemies = 7;
} else if (levelNumber === 5) {
platformPositions = level5PlatformPositions;
totalCoins = 6;
totalEnemies = 4;
} else if (levelNumber === 6) {
platformPositions = level6PlatformPositions;
totalCoins = 15;
totalEnemies = 12;
} else if (levelNumber === 7) {
platformPositions = level7PlatformPositions;
totalCoins = 18;
totalEnemies = 15;
} else if (levelNumber === 8) {
platformPositions = level8PlatformPositions;
totalCoins = 18;
totalEnemies = 14;
} else if (levelNumber === 9) {
platformPositions = level9PlatformPositions;
totalCoins = 16;
totalEnemies = 13;
} else if (levelNumber === 10) {
platformPositions = level10PlatformPositions;
totalCoins = 25;
totalEnemies = 20;
}
// Update background
background.destroy();
var backgroundAsset = currentLevel === 1 ? 'background1' : currentLevel === 2 ? 'background2' : 'background3';
background = game.attachAsset(backgroundAsset, {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
// Recreate platforms with scaling for Level 2
for (var i = 0; i < platformPositions.length; i++) {
var platform = new Platform();
platform.x = platformPositions[i].x;
platform.y = platformPositions[i].y;
// Scale platforms differently for Level 2 to create variety
if (currentLevel === 2) {
if (i === 1 || i === 4 || i === 6 || i === 7) {
// Small platforms
platform.scaleX = 0.6;
platform.scaleY = 1.0;
} else if (i === 2 || i === 5) {
// Large platforms
platform.scaleX = 1.2;
platform.scaleY = 1.0;
} else {
// Medium platforms
platform.scaleX = 0.9;
platform.scaleY = 1.0;
}
} else if (currentLevel === 3) {
// Level 3: All platforms are 400x450px (scale to achieve this from 900x450 base)
platform.scaleX = 0.44; // 900 * 0.44 ≈ 400px
platform.scaleY = 1.0; // 450 * 1.0 = 450px
}
platforms.push(platform);
game.addChild(platform);
}
// Recreate ladders based on level
if (currentLevel === 1) {
createLadderPath(platforms[1], platforms[3], 5);
createLadderPath(platforms[2], platforms[4], 5);
} else if (currentLevel === 2) {
// Keep existing ladders
createLadderPath(platforms[1], platforms[3], 4);
// Bottom platform left side to large platform right side - 3 ladder segments moved up to platform top edge
createLadderPath({
x: platforms[0].x,
y: platforms[0].y - 200 // Start from platform top edge
}, platforms[2], 3);
// Add new ladder on left side of bottom platform
var leftBottomLadder = new Ladder();
leftBottomLadder.x = platforms[0].x - 300; // Left side of bottom platform moved left by 100px
leftBottomLadder.y = platforms[0].y - 350; // Top edge of platform moved up by 150px
ladders.push(leftBottomLadder);
game.addChild(leftBottomLadder);
// Add 2 ladders from small platform right-center (platform 4) to large center platform (platform 5)
// From right top edge of platform 4 to middle top edge of platform 5
createLadderPath({
x: platforms[4].x + 150,
y: platforms[4].y
}, {
x: platforms[5].x,
y: platforms[5].y
}, 2);
// Add 2 ladders from large center platform (platform 5) right side before 200px to small platform far right (platform 7)
// From right side of platform 5 (before 200px) to platform 7, moved up by 50px
createLadderPath({
x: platforms[5].x + 350,
y: platforms[5].y - 50
}, {
x: platforms[7].x - 200,
y: platforms[7].y - 50
}, 2);
// Add 2 ladders from large center platform (platform 5) top left edge to small platform far left (platform 6)
createLadderPath({
x: platforms[5].x - 350,
y: platforms[5].y - 50
}, platforms[6], 2);
// Add 2 ladders above each other on right side of large platform before 240px from right edge
var rightLadder1 = new Ladder();
rightLadder1.x = 2048 - 340; // 240px from right edge of screen moved left by 100px
rightLadder1.y = platforms[2].y - 350; // Top edge of large platform right side moved up by 150px
ladders.push(rightLadder1);
game.addChild(rightLadder1);
var rightLadder2 = new Ladder();
rightLadder2.x = 2048 - 340; // Same x position as first ladder moved left by 100px
rightLadder2.y = platforms[2].y - 640; // 290px above first ladder (height of one ladder segment) moved up by 150px
ladders.push(rightLadder2);
game.addChild(rightLadder2);
} else if (currentLevel === 3) {
// Level 3: Recreate 4 continuous vertical ladder lines
for (var col = 0; col < 4; col++) {
var bottomPlatformIndex = col; // Bottom row platforms (0-3)
// Create 16 ladder segments to span from bottom to top (removed 2 bottom segments)
for (var segment = 2; segment < 18; segment++) {
var ladder = new Ladder();
ladder.x = platforms[bottomPlatformIndex].x;
ladder.y = platforms[bottomPlatformIndex].y - 200 - segment * 100;
ladders.push(ladder);
game.addChild(ladder);
}
}
} else if (currentLevel === 4) {
// Level 4: Only new ladders - remove old ones
// Add 2 ladders in line above each other from left side of bottom platform at its top edge
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[0].x - 350; // Left side of bottom platform
ladder.y = platforms[0].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders in line above each other at mid left platform top edge
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[1].x + 200; // Before 200px from left side of mid left platform
ladder.y = platforms[1].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders from top edge of upper left platform before 200px from its right
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[3].x + 200; // Before 200px from right side of upper left platform
ladder.y = platforms[3].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders above each other on high left platform moved left by 50px at its top edge
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[5].x + 150; // Before 200px from right side moved left by 50px
ladder.y = platforms[5].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders above each other in middle of top edge of high right platform
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[6].x; // Middle of high right platform
ladder.y = platforms[6].y - 300 - i * 290; // Start from top edge and stack above, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders diagonal going left from middle upper right platform above its top edge by 200px
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[4].x - 100 - i * 100; // Diagonal going left
ladder.y = platforms[4].y - 400 - i * 200; // Above top edge by 200px and diagonal up
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders diagonal going up and right from mid right platform above its top edge by 200px
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
ladder.x = platforms[2].x - 300 + i * 100; // Before 200px from left but 2nd ladder goes right
ladder.y = platforms[2].y - 400 - i * 200; // Above top edge by 200px and diagonal up, moved up by 100px
ladders.push(ladder);
game.addChild(ladder);
}
} else if (currentLevel === 5) {
// Level 5: Add 2 ladders above each other from top edge of bottom platform at its max right side
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
// Position at max right side of bottom platform (platform 0)
ladder.x = platforms[0].x + 450; // Right edge of bottom platform
ladder.y = platforms[0].y - 300 - i * 290; // Stack above each other from top edge
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders from top mid edge of right platform by 50px going right diagonally
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
// Position above right platform (platform 1) going diagonally right
ladder.x = platforms[1].x + 50 + i * 100; // Start 50px right of center and space by 100px horizontally
ladder.y = platforms[1].y - 450 - i * 150; // Above top edge by 150px and diagonal up (moved up by 100px)
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders going diagonally from far right platform top edge in the max left from its inside space between ladders horizontally 200px
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
// Position from far right platform (platform 2) at max left from its inside going diagonally
if (i === 0) {
// First ladder goes right
ladder.x = platforms[2].x - 350 + i * 200; // Start from max left inside and space by 200px horizontally
} else {
// Second ladder goes left
ladder.x = platforms[2].x - 350 - i * 200; // Start from max left inside and go left by 200px horizontally
}
ladder.y = platforms[2].y - 450 - i * 150; // Above top edge by 150px and diagonal up (moved up by 100px)
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders going diagonally from far right platform top edge in the max left from its inside space between ladders horizontally 200px
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
// Position from far right platform (platform 2) at max left from its inside going diagonally
if (i === 0) {
// First ladder goes right
ladder.x = platforms[2].x - 350 + i * 200; // Start from max left inside and space by 200px horizontally
} else {
// Second ladder goes left
ladder.x = platforms[2].x - 350 - i * 200; // Start from max left inside and go left by 200px horizontally
}
ladder.y = platforms[2].y - 450 - i * 150; // Above top edge by 150px and diagonal up (moved up by 100px)
ladders.push(ladder);
game.addChild(ladder);
}
// Add 2 ladders going diagonally from center high platform top edge going left
for (var i = 0; i < 2; i++) {
var ladder = new Ladder();
// Position from center high platform (platform 5) at mid top edge going diagonally left
ladder.x = platforms[5].x - i * 200; // Start from center and go left by 200px horizontally
ladder.y = platforms[5].y - 450 - i * 150; // Above top edge by 150px and diagonal up (moved up by 100px)
ladders.push(ladder);
game.addChild(ladder);
}
}
// Move all ladders to front after background to ensure visibility
for (var i = 0; i < ladders.length; i++) {
game.setChildIndex(ladders[i], game.children.length - 1);
}
// Recreate coins
for (var i = 0; i < platforms.length; i++) {
var coin = new Coin();
coin.x = platforms[i].x;
coin.y = platforms[i].y - 280;
coin.originalY = coin.y;
coins.push(coin);
game.addChild(coin);
}
// Reset player position - for Level 2, place on bottom platform (index 0)
if (levelNumber === 2) {
player.x = platforms[0].x - 30;
player.y = platforms[0].y - 200;
player.currentPlatform = 0;
} else {
// Level 1 and 3 - place on center platform
if (levelNumber === 3) {
// Position player beside the first ladder line from the right, not touching
player.x = platforms[0].x + 100; // 100px to the right of first ladder line
} else {
player.x = platforms[0].x;
}
player.y = platforms[0].y - 200;
player.currentPlatform = 0;
}
player.health = player.maxHealth;
player.velocityY = 0;
player.isGrounded = true;
// Update UI
scoreText.setText('Coins: 0/' + totalCoins);
levelText.setText('LEVEL ' + levelNumber);
updatePlayerHealthBar();
// Spawn enemies
spawnEnemies();
// Level intro effect
// Move enemies to front after spawning to ensure they are visible and not behind background
for (var i = 0; i < enemies.length; i++) {
game.setChildIndex(enemies[i], game.children.length - 1);
// Start movement for each enemy
LK.setTimeout(function (enemy) {
return function () {
enemy.startMovement();
};
}(enemies[i]), i * 500 + 1000); // Stagger enemy movement starts
}
levelStartTime = LK.ticks;
var levelColor = levelNumber === 1 ? 0x4169E1 : 0xFF6347;
LK.effects.flashScreen(levelColor, 1000);
}
// Initialize Level 1
initializeLevel(1);
// Move player to front (above background) after level initialization
game.setChildIndex(player, game.children.length - 1);
// Level 1 initialization
levelStartTime = LK.ticks;
// Level 1 intro effect - flash screen blue
LK.effects.flashScreen(0x4169E1, 1000);
// Level objective display
var objectiveText = new Text2('Collect all coins and defeat all enemies!', {
size: 40,
fill: 0xFFFFFF
});
objectiveText.anchor.set(0.5, 0);
objectiveText.x = 0;
objectiveText.y = 90;
LK.gui.top.addChild(objectiveText);
// Function to update lives display
function updateLivesDisplay() {
for (var i = 0; i < livesDisplay.length; i++) {
if (i < playerLives) {
livesDisplay[i].alpha = 1; // Show skull for remaining lives
} else {
livesDisplay[i].alpha = 0.3; // Dim skull for lost lives
}
}
}
// Function to handle player death
function handlePlayerDeath() {
playerLives--;
updateLivesDisplay();
if (playerLives <= 0) {
LK.showGameOver();
} else {
// Reset player position to center platform
if (currentLevel === 3) {
// Position player beside the first ladder line from the right, not touching
player.x = platforms[0].x + 100; // 100px to the right of first ladder line
} else {
player.x = platforms[0].x;
}
player.y = platforms[0].y - 200;
player.health = player.maxHealth;
player.velocityY = 0;
player.isGrounded = true;
player.currentPlatform = 0;
updatePlayerHealthBar();
LK.effects.flashScreen(0xff0000, 1000);
}
}
// Add climbing movement function
function movePlayerVertically(direction) {
if (player.isClimbing && player.onLadder) {
var moveDistance = 200; // Distance to move up/down
var targetY = player.y + direction * moveDistance;
// Calculate duration based on distance
var duration = 800; // Fixed duration for climbing movement
// Animate vertical movement
tween(player, {
y: targetY
}, {
duration: duration,
easing: tween.easeOut
});
}
}
// Click-to-move controls
game.down = function (x, y, obj) {
// Use the x, y parameters directly as they are already in game coordinates
var gamePos = {
x: x,
y: y
};
// Check for climbing controls when player is on ladder or can start climbing
if (player.isClimbing && player.onLadder) {
// Determine if click is above or below player for climbing direction
if (gamePos.y < player.y - 50) {
// Click above player - climb up
movePlayerVertically(-1);
return;
} else if (gamePos.y > player.y + 50) {
// Click below player - climb down
movePlayerVertically(1);
return;
}
} else {
// Check if player can start climbing down from platform edge
var climbables = ladders.concat(ropes);
for (var climbableIndex = 0; climbableIndex < climbables.length; climbableIndex++) {
var climbable = climbables[climbableIndex];
var horizontalDistance = Math.abs(player.x - climbable.x);
var verticalDistance = climbable.y - player.y;
// If player is standing on top edge of climbable and clicks below
if (horizontalDistance <= 40 && verticalDistance >= -50 && verticalDistance <= 50 && player.isGrounded && gamePos.y > player.y + 50) {
// Start climbing down
player.isClimbing = true;
player.onLadder = climbable;
player.isMoving = false;
// Stop any horizontal movement
tween.stop(player, {
x: true,
y: true
});
// Snap to climbable center
player.x = climbable.x;
// Start climbing down
movePlayerVertically(1);
return;
}
}
}
// Check if tap is on an enemy for shooting
var enemyClicked = false;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var enemyDistance = Math.sqrt(Math.pow(gamePos.x - enemy.x, 2) + Math.pow(gamePos.y - enemy.y, 2));
if (enemyDistance < 80) {
// Enemy click radius
// Shoot at the clicked enemy if cooldown allows
if (LK.ticks - player.lastShot > player.shootCooldown) {
// Set facing direction based on enemy position
var shouldFaceLeft = enemy.x < player.x;
if (player.facingLeft !== shouldFaceLeft) {
player.facingLeft = shouldFaceLeft;
player.updateAnimation();
}
var star = new Star();
star.x = player.x;
star.y = player.y - 50; // Shoot from slightly above player
// Shoot horizontally based on player facing direction
var horizontalDistance = 1000; // Fixed horizontal shooting distance
var targetX = player.facingLeft ? player.x - horizontalDistance : player.x + horizontalDistance;
star.shootAt(targetX, star.y); // Keep same Y position for horizontal shot
stars.push(star);
game.addChild(star);
player.lastShot = LK.ticks;
LK.getSound('shoot').play();
}
enemyClicked = true;
break;
}
}
// If no enemy was clicked, move player to clicked position
if (!enemyClicked) {
// Set facing direction based on click position
if (gamePos.x < player.x) {
// Clicked left of player - face left and move left
player.facingLeft = true;
player.updateAnimation();
} else if (gamePos.x > player.x) {
// Clicked right of player - face right and move right
player.facingLeft = false;
player.updateAnimation();
}
// Only allow horizontal movement when player is grounded or climbing
if (player.isGrounded || player.isClimbing) {
// Allow unlimited horizontal movement - no platform boundary constraints
var targetX = gamePos.x;
// Calculate movement distance for duration
var moveDistance = Math.abs(targetX - player.x);
var duration = moveDistance * 3; // Adjust speed by changing multiplier
// Stop any existing movement tween
tween.stop(player, {
x: true
});
// Smooth horizontal movement to target position
tween(player, {
x: targetX
}, {
duration: duration,
easing: tween.easeOut
});
}
}
};
// Update player health bar function
function updatePlayerHealthBar() {
var healthPercent = player.health / player.maxHealth;
playerHealthBar.width = 200 * healthPercent;
if (healthPercent > 0.6) {
playerHealthBar.tint = 0x00ff00;
} else if (healthPercent > 0.3) {
playerHealthBar.tint = 0xffff00;
} else {
playerHealthBar.tint = 0xff0000;
}
healthText.setText('Health: ' + player.health + '/' + player.maxHealth);
}
// Game update loop
game.update = function () {
// Check coin collection
for (var i = 0; i < coins.length; i++) {
var coin = coins[i];
if (!coin.collected && player.intersects(coin)) {
coin.collected = true;
coin.alpha = 0;
coinsCollected++;
LK.setScore(coinsCollected);
scoreText.setText('Coins: ' + coinsCollected + '/' + totalCoins);
LK.getSound('coinCollect').play();
}
}
// Update and check star collisions
for (var i = stars.length - 1; i >= 0; i--) {
var star = stars[i];
// Check star-enemy collisions
var hitEnemy = false;
for (var j = 0; j < enemies.length; j++) {
var enemy = enemies[j];
if (star.active && star.intersects(enemy)) {
// Damage enemy
enemy.health -= 25;
enemy.updateHealthBar();
// Flash enemy red
tween(enemy, {
tint: 0xFF0000
}, {
duration: 200,
onFinish: function onFinish() {
tween(enemy, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
});
LK.getSound('enemyHit').play();
hitEnemy = true;
// Remove enemy if health <= 0
if (enemy.health <= 0) {
enemy.destroy();
enemies.splice(j, 1);
enemiesDefeated++;
j--; // Adjust index after removal
}
break;
}
}
// Remove star if hit enemy or inactive
if (hitEnemy || !star.active) {
tween.stop(star); // Stop any ongoing tween
star.destroy();
stars.splice(i, 1);
}
}
// Check enemy collisions
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (player.intersects(enemy)) {
// Initialize lastHit if not exists
if (enemy.lastHit === undefined) {
enemy.lastHit = 0;
}
// Only damage if enough time has passed (1 second = 60 ticks)
if (LK.ticks - enemy.lastHit > 60) {
player.health -= 10;
enemy.lastHit = LK.ticks;
updatePlayerHealthBar();
LK.getSound('enemyHit').play();
LK.effects.flashScreen(0xff0000, 500);
if (player.health <= 0) {
handlePlayerDeath();
}
}
}
// Update enemy health bars
enemy.updateHealthBar();
}
// Level completion check - ensure both conditions are met before advancing
// Only advance when enemies array is completely empty AND all coins are collected
if (!levelComplete && coinsCollected >= totalCoins && enemies.length === 0) {
levelComplete = true;
// Flash screen green to indicate level completion
LK.effects.flashScreen(0x00ff00, 1500);
if (currentLevel < 10) {
// Advance to next level after a brief delay
LK.setTimeout(function () {
initializeLevel(currentLevel + 1);
}, 2000);
} else if (currentLevel === 10) {
// Show victory after completing level 10
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
}
}
};
coin, hd colors. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Scary blue background of forest, moon, small owl on tree, HD colors. In-Game asset. 2d. High contrast. No shadows
Scary graveyard with different things around it scary things spiders, web spider, skulls, swords, grass, trees.. In-Game asset. 2d. High contrast. No shadows
Scary wallpaper without characters, with all colors, HD colors. In-Game asset. 3d. High contrast. No shadows