Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: torches is not defined' in or related to this line: 'fg2.x = fg1.x + GAME_WIDTH;' Line Number: 1414
User prompt
Please fix the bug: 'ReferenceError: torches is not defined' in or related to this line: 'for (var i = 0; i < torches.length; i++) {' Line Number: 1416
Code edit (8 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: player is not defined' in or related to this line: 'player.update();' Line Number: 1418
User prompt
Please fix the bug: 'ReferenceError: player is not defined' in or related to this line: 'player.update();' Line Number: 1417
Code edit (1 edits merged)
Please save this source code
User prompt
Update as needed with: function startGame() { if (!gameStarted) { gameStarted = true; titleScreen = false; // Fade out title and button tween(title, { alpha: 0 }, { duration: 500 }); tween(playButton, { alpha: 0 }, { duration: 500 }); // Run player in to the same position used for platform alignment tween(player, { x: PLAYER_START_X }, { duration: 2000, onFinish: function onFinish() { title.destroy(); playButton.destroy(); } }); } } ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Update with: function initializeGame() { // Create initial platforms at the low level for (var i = 0; i < 5; i++) { var platform = new Platform(); if (i === 0) { platform.x = PLAYER_START_X; // Use constant instead of player.x } else { platform.x = lastPlatformX + platformWidth - platformOverlap; } platform.y = lowPlatformHeight; platforms.push(platform); game.addChild(platform); lastPlatformX = platform.x; } lastPlatformHeight = lowPlatformHeight; // Initialize player off screen player = game.addChild(new Player()); player.x = -200; // Start off screen player.y = 2732 / 1.5; player.isOnGround = true; player.currentPlatform = platforms[0]; // Create title screen elements title = game.addChild(LK.getAsset('title', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_WIDTH / 3, alpha: 0, tint: 0x000000 })); playButton = game.addChild(LK.getAsset('playbutton', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_WIDTH / 3 + 300, alpha: 0 })); // Start title sequence startTitleSequence(); }
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'player.x')' in or related to this line: 'platform.x = player.x;' Line Number: 1407
User prompt
Please fix the bug: 'Can't find variable: player' in or related to this line: 'platform.x = player.x;' Line Number: 1409
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'LK.tween is not a function. (In 'LK.tween(title)', 'LK.tween' is undefined)' in or related to this line: 'LK.tween(title).to({' Line Number: 1335 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Update with: // Modify game.up to handle title screen var originalGameUp = game.up; game.up = function(x, y, obj) { if (titleScreen) { // Check if click/tap is on play button var buttonBounds = { left: playButton.x - 50, right: playButton.x + 50, top: playButton.y - 14, bottom: playButton.y + 14 }; if (x >= buttonBounds.left && x <= buttonBounds.right && y >= buttonBounds.top && y <= buttonBounds.bottom) { startGame(); } } else { originalGameUp(x, y, obj); } };
Code edit (1 edits merged)
Please save this source code
User prompt
Update with: function initializeGame() { // Create initial platforms at the low level for (var i = 0; i < 5; i++) { var platform = new Platform(); if (i === 0) { platform.x = player.x; } else { platform.x = lastPlatformX + platformWidth - platformOverlap; } platform.y = lowPlatformHeight; platforms.push(platform); game.addChild(platform); lastPlatformX = platform.x; } lastPlatformHeight = lowPlatformHeight; // Create title screen elements title = game.addChild(LK.getAsset('title', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_WIDTH / 3, alpha: 0, tint: 0x000000 })); playButton = game.addChild(LK.getAsset('playbutton', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_WIDTH / 3 + 300, alpha: 0 })); // Start title sequence startTitleSequence(); // Initialize player off screen player = game.addChild(new Player()); player.x = -200; // Off screen left player.y = 2732 / 1.5; player.isOnGround = true; player.currentPlatform = platforms[0]; }
Code edit (2 edits merged)
Please save this source code
User prompt
Import tween ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (12 edits merged)
Please save this source code
User prompt
Update with: var particleOffset = self.type === 'eyeball' ? 100 : 300; // smaller offset for eyeballs particleSystem.emitFromHit(self.x + particleOffset, self.y, player.x);
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Play coin bounce sound effect when a coin bounces.
User prompt
Use woodbreak sound effect instead of jarbreak when a treasure chest gets broken.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Coin = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'coin'; // Create sprite based on type self.sprite = self.attachAsset(self.type, { anchorX: 0.5, anchorY: 0.5, tint: 0xFFFFFF // No tint for gems }); self.velocityX = 0; self.velocityY = 0; self.collected = false; self.bounceCount = 0; self.maxBounces = 2; // Get value based on type self.getValue = function () { switch (self.type) { case 'diamond': return 10; case 'emerald': return 5; case 'ruby': return 3; default: return 1; } }; // Rest of the existing Coin code... // Make sure to use self.getValue() in the collect function self.collect = function () { if (!self.collected) { self.collected = true; var value = self.getValue(); scoreManager.addScore(value, self.x, self.y); LK.getSound('coincollect').play(); self.destroy(); } }; self.update = function () { if (self.collected) { return; } // Apply physics self.velocityY += 0.5; // gravity self.x += self.velocityX; self.y += self.velocityY; // Check for platform collision with bounce // Only bounce if we're moving downward and hit a platform if (self.velocityY > 0 && self.checkPlatformCollision()) { if (self.bounceCount < self.maxBounces) { LK.getSound('coinbounce').play(); var impactSpeed = Math.abs(self.velocityY); self.velocityY = -(impactSpeed * 0.5); // Use half of impact speed self.velocityX *= 0.8; self.bounceCount++; } else { self.velocityY = 0; self.velocityX = -5; // Match platform speed } } // Check if off screen if (self.x < -50 || self.x > 2048 + 50 || self.y > 2732) { self.destroy(); } // Player collection detection var playerBounds = player.getBounds(); var coinBounds = { left: self.x - 25, right: self.x + 25, top: self.y - 25, bottom: self.y + 25 }; if (playerBounds.left < coinBounds.right && playerBounds.right > coinBounds.left && playerBounds.top < coinBounds.bottom && playerBounds.bottom > coinBounds.top) { self.collect(); } }; self.checkPlatformCollision = function () { for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; if (Math.abs(self.y - (platform.y - 80)) < 10 && self.x > platform.x - 500 && self.x < platform.x + 500) { self.y = platform.y - 80; return true; } } return false; }; return self; }); var Enemy = Container.expand(function (type) { var self = Container.call(this); // Enemy properties self.type = type || 'basic'; self.speed = 7; self.isOnGround = true; self.velocityY = 0; self.currentPlatform = null; self.groundY = 2732 / 1.5; // Same as player ground Y self.hitAnimation = ['goblinhit1']; self.dieAnimation = ['goblindie1', 'goblindie2', 'goblindie3', 'goblindie4']; self.isHit = false; self.isDying = false; self.deathTimer = 0; self.throwBackSpeed = 15; // Initial backwards throw speed self.throwBackDistance = 0; // Track distance thrown self.maxThrowBack = 200; // Maximum throw back distance // Add bounding box properties self.hitboxWidth = 200; // Smaller than the 150px sprite width self.hitboxHeight = 260; // Adjusted for goblin height // Animation properties for goblin self.runAnimation = []; self.runFrame = 0; self.animationSpeed = 0.08; self.animationCounter = 0; self.sprites = []; // Add eyeball-specific properties self.isFlying = type === 'eyeball'; self.flyingHeight = 0; self.verticalSpeed = 2; // Speed of vertical adjustment self.maxVerticalSpeed = 4; // Maximum vertical speed self.homingDelay = 80; // Wait 60 frames before homing self.homingTimer = 0; // Track how long the eyeball has been alive // Add eyeball animations self.flyAnimation = ['eyefly1', 'eyefly2', 'eyefly3', 'eyefly4', 'eyefly5', 'eyefly6', 'eyefly7', 'eyefly8']; self.flyFrame = 0; // Initialize based on enemy type if (self.type === 'eyeball') { // Eyeball animations self.flyAnimation = ['eyefly1', 'eyefly2', 'eyefly3', 'eyefly4', 'eyefly5', 'eyefly6', 'eyefly7', 'eyefly8']; self.hitAnimation = ['eyedie1', 'eyedie2']; self.dieAnimation = ['eyedie3', 'eyedie4', 'eyedie5']; } else if (self.type === 'goblin') { // Goblin animations self.runAnimation = ['goblinrun1', 'goblinrun2', 'goblinrun3', 'goblinrun4', 'goblinrun5', 'goblinrun6', 'goblinrun7', 'goblinrun8']; self.hitAnimation = ['goblinhit1']; self.dieAnimation = ['goblindie1', 'goblindie2', 'goblindie3', 'goblindie4']; } // Initialize based on enemy type if (self.type === 'goblin') { // Setup all animations self.runAnimation = ['goblinrun1', 'goblinrun2', 'goblinrun3', 'goblinrun4', 'goblinrun5', 'goblinrun6', 'goblinrun7', 'goblinrun8']; // Pre-attach all animation frames // Run animation for (var i = 0; i < self.runAnimation.length; i++) { var sprite = self.attachAsset(self.runAnimation[i], { anchorX: 0.5, anchorY: 0.5 }); sprite.alpha = i === 0 ? 1 : 0; self.sprites.push(sprite); } // Hit animation for (var i = 0; i < self.hitAnimation.length; i++) { var sprite = self.attachAsset(self.hitAnimation[i], { anchorX: 0.5, anchorY: 0.5 }); sprite.alpha = 0; self.sprites.push(sprite); } // Die animation for (var i = 0; i < self.dieAnimation.length; i++) { var sprite = self.attachAsset(self.dieAnimation[i], { anchorX: 0.5, anchorY: 0.5 }); sprite.alpha = 0; self.sprites.push(sprite); } } else if (self.type === 'eyeball') { // First add fly animations (8 frames) for (var i = 0; i < self.flyAnimation.length; i++) { var sprite = self.attachAsset(self.flyAnimation[i], { anchorX: 0.5, anchorY: 0.5 }); sprite.alpha = i === 0 ? 1 : 0; self.sprites.push(sprite); } // Then hit animations (2 frames) for (var i = 0; i < self.hitAnimation.length; i++) { var sprite = self.attachAsset(self.hitAnimation[i], { anchorX: 0.5, anchorY: 0.5 }); sprite.alpha = 0; self.sprites.push(sprite); } // Then die animations (3 frames) for (var i = 0; i < self.dieAnimation.length; i++) { var sprite = self.attachAsset(self.dieAnimation[i], { anchorX: 0.5, anchorY: 0.5 }); sprite.alpha = 0; self.sprites.push(sprite); } // Adjust hitbox for eyeball self.hitboxWidth = 200; self.hitboxHeight = 90; // Flying enemies don't use ground physics self.isOnGround = false; } else { // Basic enemy (original version) var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); } self.checkPlatformCollision = function () { var onAnyPlatform = false; var platformHalfWidth = 500; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; var leftEdge = platform.x - platformHalfWidth; var rightEdge = platform.x + platformHalfWidth; // First check if we're on a platform (exact position check) if (self.x >= leftEdge && self.x <= rightEdge) { if (Math.abs(self.y - (platform.y - ENEMY_PLATFORM_OFFSET)) < 5) { onAnyPlatform = true; self.currentPlatform = platform; self.y = platform.y - ENEMY_PLATFORM_OFFSET; self.isOnGround = true; self.velocityY = 0; return true; } // NEW CODE: Check for passing through platform during fall // This detects if the enemy will cross the platform in the next frame if (self.velocityY > 0 && // Must be falling down self.y < platform.y - ENEMY_PLATFORM_OFFSET && self.y + self.velocityY >= platform.y - ENEMY_PLATFORM_OFFSET) { self.y = platform.y - ENEMY_PLATFORM_OFFSET; self.velocityY = 0; self.isOnGround = true; self.currentPlatform = platform; return true; } } } if (!onAnyPlatform) { self.isOnGround = false; self.currentPlatform = null; } return false; }; // Update collision check method self.getBounds = function () { return { left: self.x - self.hitboxWidth / 2, right: self.x + self.hitboxWidth / 2, top: self.y - self.hitboxHeight / 2, bottom: self.y + self.hitboxHeight / 2 }; }; self.hit = function () { if (!self.isHit && !self.isDying) { self.isHit = true; self.throwBackSpeed = 25; // Increased from 25 for more distance self.throwBackDistance = 0; self.hitTimer = 35; // Added hit timer for longer hit frame // Add particle effect here var particleOffset = self.type === 'eyeball' ? 175 : 250; // smaller offset for eyeballs particleSystem.emitFromHit(self.x + particleOffset, self.y, player.x); } }; self.update = function () { // Hide all sprites first for (var i = 0; i < self.sprites.length; i++) { self.sprites[i].alpha = 0; } if (self.type === 'eyeball' && (self.isHit || self.isDying)) { // First handle the hit state if (self.isHit) { var hitOffset = self.flyAnimation.length; self.throwBackDistance += Math.abs(self.throwBackSpeed); self.x += self.throwBackSpeed; self.throwBackSpeed *= 0.95; // Show hit animation (eyedie1, eyedie2) var hitFrame = Math.floor(self.hitTimer / 100) % 2; self.sprites[hitOffset + hitFrame].alpha = 1; self.hitTimer--; if (self.hitTimer <= 0) { self.isHit = false; self.isDying = true; self.deathTimer = 180; // 3 seconds for death sequence self.deathFrame = 0; // Start at first death frame } } // Then handle the dying state else if (self.isDying) { var dieOffset = self.flyAnimation.length + self.hitAnimation.length; // Always check for ground collision during fall if (!self.isOnGround) { self.velocityY += 0.5; self.y += self.velocityY; } //self.x -= 5; // Match platform speed // Progress through death frames if (self.deathTimer > 120) { self.sprites[dieOffset].alpha = 1; // eyedie3 } else if (self.deathTimer > 60) { self.sprites[dieOffset + 1].alpha = 1; // eyedie4 } else { self.sprites[dieOffset + 2].alpha = 1; // eyedie5 } self.deathTimer--; if (self.deathTimer <= 0) { self.alpha -= 0.05; if (self.alpha <= 0) { self.destroy(); } } } return; // Skip regular animation updates } else if (self.type === 'eyeball') { self.x -= self.speed; // Only start homing after delay if (self.homingTimer >= self.homingDelay) { // Home toward player var deltaY = player.y - self.y; self.velocityY += deltaY > 0 ? 0.2 : -0.2; self.velocityY = Math.max(-self.maxVerticalSpeed, Math.min(self.maxVerticalSpeed, self.velocityY)); } else { // Before homing, just maintain height with slight wave motion self.velocityY = Math.sin(self.homingTimer * 0.05) * 2; self.homingTimer++; } self.y += self.velocityY; // Animate self.animationCounter += self.animationSpeed; if (self.animationCounter >= 1) { self.animationCounter = 0; self.flyFrame = (self.flyFrame + 1) % self.flyAnimation.length; } self.sprites[self.flyFrame].alpha = 1; // Check if off screen if (self.x < -50 || self.y > 2732) { self.destroy(); } } else { if (self.isHit) { // Handle throw back motion self.x += self.throwBackSpeed; self.throwBackDistance += Math.abs(self.throwBackSpeed); self.throwBackSpeed *= 0.95; // Slower decay than 0.9 // Show hit animation var hitOffset = self.runAnimation.length; self.sprites[hitOffset].alpha = 1; // Decrease hit timer self.hitTimer--; // Once hit timer expires, start death animation if (self.hitTimer <= 0) { self.isHit = false; self.isDying = true; self.deathTimer = 60; // Increased to 60 frames self.deathFrame = 0; // Explicitly track which frame we're on } } else if (self.isDying) { // Continue throw back during death self.x += self.throwBackSpeed; // After halfway through death animation, match platform speed if (self.deathFrame >= 2) { // Since we have 4 frames, 2 is halfway self.x -= 5; // Platform speed is defined as 5 } self.throwBackSpeed *= 0.95; // Removed vertical movement code // Handle death animation var dieOffset = self.runAnimation.length + self.hitAnimation.length; // Progress frame every 15 frames (60/4 frames = 15) if (self.deathTimer % 15 === 0 && self.deathFrame < self.dieAnimation.length - 1) { self.deathFrame++; } var dieOffset = self.runAnimation.length + self.hitAnimation.length; self.sprites[dieOffset + self.deathFrame].alpha = 1; // Count down death timer self.deathTimer--; // After timer expires, fade out if (self.deathTimer <= 0) { self.alpha -= 0.1; if (self.alpha <= 0) { self.destroy(); } } } else { // Original movement and animation code // Move left self.x -= self.speed; // Original platform and gravity code if (!self.isOnGround) { self.velocityY += 0.7; self.y += self.velocityY; if (!self.checkPlatformCollision()) { // Let them fall if not on platform } } if (self.currentPlatform) { var platformHalfWidth = 500; // Match the existing platform width constant var stillOnPlatform = self.x >= self.currentPlatform.x - platformHalfWidth && self.x <= self.currentPlatform.x + platformHalfWidth; if (!stillOnPlatform) { var foundAnotherPlatform = false; // Check if there's another platform we might have moved to for (var i = 0; i < platforms.length; i++) { var otherPlatform = platforms[i]; if (otherPlatform === self.currentPlatform) { continue; } if (self.x >= otherPlatform.x - platformHalfWidth && self.x <= otherPlatform.x + platformHalfWidth && Math.abs(self.y - (otherPlatform.y - ENEMY_PLATFORM_OFFSET)) < 5) { // Found another platform at the same height self.currentPlatform = otherPlatform; foundAnotherPlatform = true; break; } } // If no other platform found, start falling if (!foundAnotherPlatform) { self.isOnGround = false; self.currentPlatform = null; // Start falling with initial velocity if (self.velocityY === 0) { self.velocityY = 0.1; } } } } // Handle run animation if (self.type === 'goblin') { self.animationCounter += self.animationSpeed; if (self.animationCounter >= 1) { self.animationCounter = 0; self.runFrame = (self.runFrame + 1) % self.runAnimation.length; } self.sprites[self.runFrame].alpha = 1; } } // Destroy if off screen if (self.x < -50 || self.y > 2732) { self.destroy(); } } }; }); var Jar = Container.expand(function () { var self = Container.call(this); // Attach jar sprite self.sprite = self.attachAsset('jar', { anchorX: 0.5, anchorY: 0.5, tint: 0xC0C0C0 // Change tint to an even lighter grey }); self.isBreaking = false; self.currentPlatform = null; self["break"] = function () { if (self.isBreaking) { return; } self.isBreaking = true; // Spawn jar pieces (keep existing piece code) for (var i = 1; i <= 4; i++) { var piece = new JarPiece(i); piece.x = self.x; piece.y = self.y; piece.velocityX = Math.random() * 10 - 5; piece.velocityY = -(Math.random() * 10 + 5); piece.rotationSpeed = Math.random() * 0.2 - 0.1; game.addChild(piece); } // Modified coin spawning with more forward motion var coinCount = Math.floor(Math.random() * 8) + 1; for (var i = 0; i < coinCount; i++) { var coin = new Coin(); coin.x = self.x; coin.y = self.y; // More forward motion and higher initial jump coin.velocityX = Math.random() * 8 + 4; // Minimum 4, maximum 12 right velocity coin.velocityY = -(Math.random() * 10 + 12); // Higher jump game.addChild(coin); coins.push(coin); } LK.getSound('jarbreak').play(); self.destroy(); }; return self; }); var JarPiece = Container.expand(function (pieceNum) { var self = Container.call(this); self.sprite = self.attachAsset('jarpiece' + pieceNum, { anchorX: 0.5, anchorY: 0.5, tint: 0xC0C0C0 // Apply grey tint }); self.velocityX = 0; self.velocityY = 0; self.rotationSpeed = 0; self.fadeSpeed = 0.02; self.bounceCount = 0; self.maxBounces = 2; // Number of bounces before stopping self.update = function () { // Apply physics self.velocityY += 0.5; // gravity self.x += self.velocityX; self.y += self.velocityY; self.rotation += self.rotationSpeed; // Check for platform collision with bounce if (self.checkPlatformCollision()) { if (self.bounceCount < self.maxBounces) { // Bounce with reduced velocity self.velocityY = -(self.velocityY * 0.4); // 40% of original velocity self.velocityX *= 0.8; // Reduce horizontal speed self.bounceCount++; } else { // Stop moving after max bounces self.velocityY = 0; self.velocityX = -5; // Match platform speed // Start fading self.alpha -= self.fadeSpeed; if (self.alpha <= 0) { self.destroy(); } } } // Destroy if off screen if (self.x < -50 || self.y > 2732) { self.destroy(); } }; self.checkPlatformCollision = function () { for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; if (Math.abs(self.y - (platform.y - 80)) < 10 && self.x > platform.x - 500 && self.x < platform.x + 500) { self.y = platform.y - 80; return true; } } return false; }; return self; }); var ParticlePool = Container.expand(function (maxParticles) { var self = Container.call(this); self.particles = []; self.activeParticles = []; self.redTints = [0xff0000, 0xff3333, 0xcc0000]; for (var i = 0; i < maxParticles; i++) { var particle = self.attachAsset('pixel', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.2, // 4% of original size (4px from 100px) scaleY: 0.2 // 4% of original size (4px from 100px) }); particle.alpha = 0; particle.velocityX = 0; particle.velocityY = 0; particle.lifespan = 0; particle.fadeSpeed = 0; self.particles.push(particle); } self.emitFromHit = function (x, y, playerX) { var directionX = x - playerX; var directionSign = Math.sign(directionX); for (var i = 0; i < 20; i++) { if (self.particles.length === 0) { break; } var particle = self.particles.pop(); self.activeParticles.push(particle); particle.x = x; particle.y = y; particle.alpha = 1; particle.tint = self.redTints[Math.floor(Math.random() * self.redTints.length)]; // Set scale instead of width/height var particleSize = Math.random() * 0.2 + 0.2; // 2-4% of original size particle.scaleX = particleSize; particle.scaleY = particleSize; var angle = Math.random() * Math.PI / 2 - Math.PI / 4; var speed = Math.random() * 5 + 10; particle.velocityX = Math.cos(angle) * speed * directionSign; particle.velocityY = Math.sin(angle) * speed; particle.lifespan = 100; particle.fadeSpeed = 1 / 60; } }; self.update = function () { for (var i = self.activeParticles.length - 1; i >= 0; i--) { var particle = self.activeParticles[i]; particle.x += particle.velocityX; particle.y += particle.velocityY; particle.alpha -= particle.fadeSpeed; particle.lifespan--; if (particle.lifespan <= 0 || particle.alpha <= 0) { particle.alpha = 0; self.activeParticles.splice(i, 1); self.particles.push(particle); } } }; return self; }); var Platform = Container.expand(function () { var self = Container.call(this); var platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; self.passed = false; self.update = function () { self.x -= self.speed; if (self.x < -500) { // Increased value to ensure platforms are fully off-screen self.destroy(); } }; }); //<Assets used in the game will automatically appear here> var Player = Container.expand(function () { var self = Container.call(this); // Animation properties self.runAnimation = ['playerrun1', 'playerrun2', 'playerrun3', 'playerrun4', 'playerrun5', 'playerrun6']; self.jumpAnimation = ['playerjump1', 'playerjump2', 'playerjump3']; self.attackAnimation = ['playerattack1', 'playerattack2', 'playerattack3', 'playerattack4', 'playerattack5']; self.isAttacking = false; self.attackFrame = 0; self.runFrame = 0; self.animationSpeed = 0.08; self.attackAnimationSpeed = 0.15; // Higher number = faster animation self.animationCounter = 0; self.sprites = []; self.groundY = 2732 * 0.9; // Move ground much lower to allow falling from all platforms // Add bounding box properties self.hitboxWidth = 150; // Smaller than the 600px animation frames self.hitboxHeight = 300; // Adjusted for player height self.attackHitboxWidth = 200; // Width of attack hitbox self.attackHitboxHeight = 375; // Height of attack hitbox self.attackHitboxOffset = 50; // How far in front of player the attack hitbox extends // Platform collision properties self.isOnGround = true; self.currentPlatform = null; // Pre-attach all animation frames but make only the first one visible // First add run animation sprites for (var i = 0; i < self.runAnimation.length; i++) { var sprite = self.attachAsset(self.runAnimation[i], { anchorX: 0.5, anchorY: 0.5 }); // Set all frames except the first to be invisible sprite.alpha = i === 0 ? 1 : 0; self.sprites.push(sprite); } // Then add jump animation sprites for (var i = 0; i < self.jumpAnimation.length; i++) { var sprite = self.attachAsset(self.jumpAnimation[i], { anchorX: 0.5, anchorY: 0.5 }); // Set all jump frames to invisible initially sprite.alpha = 0; self.sprites.push(sprite); } for (var i = 0; i < self.attackAnimation.length; i++) { var sprite = self.attachAsset(self.attackAnimation[i], { anchorX: 0.5, anchorY: 0.5 }); sprite.alpha = 0; self.sprites.push(sprite); } // Movement properties self.speed = 5; self.jumpHeight = 40; // Keeping the original jump height self.isJumping = false; self.velocityY = 0; self.jumpState = "none"; // Added to track jump animation phases self.jumpStartTime = 0; // Add method to get actual collision bounds self.getBounds = function () { return { left: self.x - self.hitboxWidth / 2, right: self.x + self.hitboxWidth / 2, top: self.y - self.hitboxHeight / 2, bottom: self.y + self.hitboxHeight / 2 }; }; self.update = function () { // Hide all sprites first for (var i = 0; i < self.sprites.length; i++) { self.sprites[i].alpha = 0; } // Handle platform collision and falling physics first if (!self.isOnGround && !self.isJumping) { self.velocityY += 0.7; self.y += self.velocityY; self.checkPlatformCollision(); } // Handle jumping physics if (self.isJumping) { self.y += self.velocityY; self.velocityY += 0.7; // Get jump frame index offset var jumpOffset = self.runAnimation.length; // Check for landing on platforms while falling during a jump self.checkPlatformCollision(); // End jump if hitting the original ground (for backward compatibility) if (self.y >= self.groundY && !self.currentPlatform) { self.y = self.groundY; self.isJumping = false; self.velocityY = 0; self.jumpState = "none"; self.isOnGround = true; } } // IMPORTANT: Platform collision check - runs EVERY frame var onAnyPlatform = false; var platformHalfWidth = 500; // half of platform width (1000/2) // First, check platform collisions for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; var leftEdge = platform.x - platformHalfWidth; var rightEdge = platform.x + platformHalfWidth; // Check if player is within horizontal bounds of platform if (self.x >= leftEdge && self.x <= rightEdge) { // If we're at platform height and not jumping if (Math.abs(self.y - (platform.y - 250)) < 5 && !self.isJumping) { onAnyPlatform = true; self.currentPlatform = platform; self.y = platform.y - 250; self.isOnGround = true; self.velocityY = 0; break; } } } // Handle falling state if (!onAnyPlatform && !self.isJumping) { self.isOnGround = false; self.currentPlatform = null; // Apply gravity if (self.velocityY === 0) { self.velocityY = 0.1; } self.velocityY += 0.1; self.y += self.velocityY; // Ground collision check comes AFTER falling movement if (self.y >= self.groundY) { // Reached the bottom of the screen - game over LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } } // Now handle animations - attack takes priority if active if (self.isAttacking) { var attackOffset = self.runAnimation.length + self.jumpAnimation.length; self.animationCounter += self.attackAnimationSpeed; if (self.animationCounter >= 1) { self.animationCounter = 0; self.attackFrame++; if (self.attackFrame >= self.attackAnimation.length) { self.isAttacking = false; self.attackFrame = 0; } } self.sprites[attackOffset + self.attackFrame].alpha = 1; } // If not attacking, show jump or run animation else if (self.isJumping || !self.isOnGround) { var jumpOffset = self.runAnimation.length; var currentTime = Date.now(); if (currentTime - self.jumpStartTime < 100) { self.sprites[jumpOffset + 0].alpha = 1; } else if (self.velocityY < 0) { self.sprites[jumpOffset + 1].alpha = 1; } else if (self.velocityY > 0) { self.sprites[jumpOffset + 2].alpha = 1; } } else if (self.isOnGround) { self.animationCounter += self.animationSpeed; if (self.animationCounter >= 1) { self.animationCounter = 0; self.runFrame = (self.runFrame + 1) % self.runAnimation.length; } self.sprites[self.runFrame].alpha = 1; } // If on a platform, check if we're still above it if (self.currentPlatform) { var platformHalfWidth = platformWidth / 2; // Use platformWidth constant var stillOnPlatform = self.x > self.currentPlatform.x - platformHalfWidth && self.x < self.currentPlatform.x + platformHalfWidth; if (!stillOnPlatform) { var foundAnotherPlatform = false; for (var i = 0; i < platforms.length; i++) { var otherPlatform = platforms[i]; if (otherPlatform === self.currentPlatform) { continue; } var otherHalfWidth = platformWidth / 2; if (self.x > otherPlatform.x - otherHalfWidth && self.x < otherPlatform.x + otherHalfWidth) { // We found another platform directly below player self.currentPlatform = otherPlatform; foundAnotherPlatform = true; break; } } // Only fall if we didn't find another platform if (!foundAnotherPlatform) { self.isOnGround = false; self.currentPlatform = null; // Start falling with initial velocity self.velocityY = 0.1; } } } // Check if player has fallen off the bottom of the screen if (self.y > 2732) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } }; self.getAttackBounds = function () { // Only return attack bounds when actually attacking if (!self.isAttacking) { return null; } // Create a forward-facing hitbox return { left: self.x + (self.attackHitboxOffset - self.attackHitboxWidth / 2), right: self.x + (self.attackHitboxOffset + self.attackHitboxWidth / 2), top: self.y - self.attackHitboxHeight / 2, bottom: self.y + self.attackHitboxHeight / 2 }; }; self.jump = function () { if (self.isOnGround) { self.isJumping = true; self.isOnGround = false; self.velocityY = -self.jumpHeight; self.jumpState = "start"; self.jumpStartTime = Date.now(); LK.getSound('playerjump').play(); self.currentPlatform = null; } else if (self.isJumping && self.velocityY < 10) { // Allow for a small double-jump to reach higher platforms // Only if not falling too fast self.velocityY = -self.jumpHeight * 0.7; self.jumpStartTime = Date.now(); } }; self.attack = function () { if (!self.isAttacking) { self.isAttacking = true; self.attackFrame = 0; self.animationCounter = 0; LK.getSound('swordslash').play(); } }; self.checkPlatformCollision = function () { for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; var platformHalfWidth = platform.width / 2; // The offset should match exactly how the player aligns with the lower platform initially var playerPlatformOffset = 250; // This is the exact offset between player.y and lowPlatformHeight // Check if player is above the platform and falling if (self.velocityY > 0 && // Must be falling down self.y < platform.y - playerPlatformOffset && self.y + self.velocityY >= platform.y - playerPlatformOffset && self.x > platform.x - platformHalfWidth && self.x < platform.x + platformHalfWidth) { // Land on the platform with the exact same positioning as on the low platform self.y = platform.y - playerPlatformOffset; self.velocityY = 0; self.isJumping = false; self.isOnGround = true; self.currentPlatform = platform; return; } } }; }); // Add this to your existing classes var ScorePopup = Container.expand(function (x, y, amount) { var self = Container.call(this); // Create the text with the actual score amount self.text = new Text2('+' + amount, { size: 80, fill: 0xFFFFFF, anchorX: 0.5, anchorY: 0.5 }); self.addChild(self.text); self.x = x; self.y = y; self.velocityY = -3; self.lifespan = 45; self.update = function () { self.y += self.velocityY; self.lifespan--; if (self.lifespan < 15) { self.alpha -= 0.07; } if (self.alpha <= 0 || self.lifespan <= 0) { self.destroy(); } }; return self; }); var Torch = Container.expand(function () { var self = Container.call(this); // Create base torch sprite self.base = self.attachAsset('torch', { anchorX: 0.5, anchorY: 1 // Anchor at bottom }); // Create flame sprite self.flame = self.attachAsset('torchflame', { anchorX: 0.5, anchorY: 1, // Anchor at bottom to scale from base y: -180 // Position at top of torch }); // Create aura sprite self.aura = self.attachAsset('torchaura', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3, // Start with low opacity y: -250 // Match flame position }); // Animation properties self.flameTime = Math.random() * Math.PI * 2; // Random start phase self.auraTime = Math.random() * Math.PI * 2; self.flameSpeed = 0.05; self.auraSpeed = 0.03; // Update animation self.update = function () { // Animate flame scale self.flameTime += self.flameSpeed; var flameScale = 1 + Math.sin(self.flameTime) * 0.2; // Scale between 0.8 and 1.2 self.flame.scaleY = flameScale; // Random flip chance for flame if (Math.random() < 0.02) { // 2% chance per frame self.flame.scaleX *= -1; } // Animate aura alpha self.auraTime += self.auraSpeed; var auraAlpha = 0.3 + Math.sin(self.auraTime) * 0.15; // Pulse between 0.15 and 0.45 self.aura.alpha = auraAlpha; }; return self; }); var TreasureChest = Container.expand(function () { var self = Container.call(this); // Attach chest sprite self.sprite = self.attachAsset('treasurechest', { anchorX: 0.5, anchorY: 0.5, tint: 0xC0C0C0 // Change tint to match jar's grey tint }); self.isBreaking = false; self.currentPlatform = null; self["break"] = function () { if (self.isBreaking) { return; } self.isBreaking = true; // Spawn chest pieces for (var i = 1; i <= 4; i++) { var piece = new TreasureChestPiece(i); piece.x = self.x; piece.y = self.y; piece.velocityX = Math.random() * 12 - 6; piece.velocityY = -(Math.random() * 12 + 6); piece.rotationSpeed = Math.random() * 0.2 - 0.1; game.addChild(piece); } // Spawn valuables var totalItems = Math.floor(Math.random() * 6) + 3; // 3-8 items for (var i = 0; i < totalItems; i++) { // Random chance for different gems var rand = Math.random(); var item; if (rand < 0.05) { // 5% diamond item = new Coin('diamond'); } else if (rand < 0.15) { // 10% emerald item = new Coin('emerald'); } else if (rand < 0.30) { // 15% ruby item = new Coin('ruby'); } else { // 70% gold coin item = new Coin('coin'); } item.x = self.x; item.y = self.y; item.velocityX = Math.random() * 10 + 2; item.velocityY = -(Math.random() * 12 + 14); game.addChild(item); coins.push(item); } LK.getSound('woodbreak').play(); self.destroy(); }; return self; }); var TreasureChestPiece = Container.expand(function (pieceNum) { var self = Container.call(this); self.sprite = self.attachAsset('treasurechestpiece' + pieceNum, { anchorX: 0.5, anchorY: 0.5, tint: 0xC0C0C0 // Change tint to match jar's grey tint }); self.velocityX = 0; self.velocityY = 0; self.rotationSpeed = 0; self.fadeSpeed = 0.02; self.bounceCount = 0; self.maxBounces = 2; self.update = function () { self.velocityY += 0.5; // gravity self.x += self.velocityX; self.y += self.velocityY; self.rotation += self.rotationSpeed; if (self.checkPlatformCollision()) { if (self.bounceCount < self.maxBounces) { self.velocityY = -(self.velocityY * 0.4); self.velocityX *= 0.8; self.bounceCount++; } else { self.velocityY = 0; self.velocityX = -5; self.alpha -= self.fadeSpeed; if (self.alpha <= 0) { self.destroy(); } } } if (self.x < -50 || self.y > 2732) { self.destroy(); } }; self.checkPlatformCollision = function () { for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; if (Math.abs(self.y - (platform.y - 80)) < 10 && self.x > platform.x - 500 && self.x < platform.x + 500) { self.y = platform.y - 80; return true; } } return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Black background }); /**** * Game Code ****/ var ScoreManager = function ScoreManager() { var self = {}; // Initialize score and UI self.score = 0; self.scoreText = new Text2('0', { size: 160, fill: 0xFFFFFF, anchorX: 1, anchorY: 0.5 }); self.coinIcon = LK.getAsset('coin', { anchorX: 0, anchorY: 0.5, scaleX: 2, scaleY: 2 }); // Initialize container self.container = new Container(); self.container.addChild(self.scoreText); self.container.addChild(self.coinIcon); // Position container self.container.x = 2048 - 100; self.container.y = 100; // Position elements self.scoreText.x = -100; self.scoreText.y = -100; self.coinIcon.x = 0; self.coinIcon.y = 0; // Getter and setter for score self.getScore = function () { return self.score; }; self.setScore = function (newScore) { self.score = newScore; self.scoreText.setText(newScore); // Adjust position based on digit count if (newScore >= 10 && newScore < 100) { self.scoreText.x = -200; // Adjust for 2 digits } else if (newScore >= 100 && newScore < 1000) { self.scoreText.x = -300; // Adjust for 3 digits } else if (newScore >= 1000) { self.scoreText.x = -400; // Adjust for 4+ digits } else { self.scoreText.x = -100; // Default for single digit } }; // Add score and display popup self.addScore = function (amount, x, y) { self.setScore(self.score + amount); // Create score popup if position is provided if (x !== undefined && y !== undefined) { var popup = new ScorePopup(x, y - 30, amount); game.addChild(popup); } }; return self; }; var backgroundContainer = game.addChild(new Container()); var midgroundContainer = game.addChild(new Container()); var foregroundContainer = game.addChild(new Container()); var scoreManager = new ScoreManager(); game.addChild(scoreManager.container); var scoreContainer = game.addChild(new Container()); var GAME_WIDTH = 2048; var ENEMY_PLATFORM_OFFSET = 225; // Adjust this value var platforms = []; var platformWidth = 1000; // Define platform width based on asset size var platformSpawnInterval = 60; var platformSpawnCounter = 0; var platformOverlap = 50; var platformSpeed = 5; // Define platform speed globally var platformSpawnInterval = 190; var chestSpawnInterval = 100; // Longer than jar interval var chestSpawnCounter = 0; // = (1000 - 50) / 5 = 190 // Define the two fixed platform heights var lowPlatformHeight = 2732 / 1.5 + 250; // Regular height (player.y + 250) var highPlatformHeight = lowPlatformHeight - 600; // High platform (600 pixels higher) var minPlatformsInSequence = 2; // Minimum platforms in a sequence var maxPlatformsInSequence = 5; // Maximum platforms in a sequence var platformsUntilNextChange = 5; // Initial longer ground sequence var currentPlatformHeight = lowPlatformHeight; var lastPlatformHeight = lowPlatformHeight; // Simple toggle for alternating platform heights var useHighPlatform = false; var platformGap = 200; // Gap between platforms var lastPlatformX = 0; // Track the last platform position var touchStartX = 0; var touchStartY = 0; var touchEndX = 0; var touchEndY = 0; var coins = []; var collectibles = []; var jarSpawnCounter = 0; var jarSpawnInterval = 20; // Adjust as needed var titleScreen = true; var gameStarted = false; var title, playButton; var titleTween, buttonTween; var particleSystem; //<Assets used in the game will automatically appear here> // Play background music with fade-in effect LK.playMusic('backgroundmusic1', { fade: { start: 0, end: 0.7, duration: 1000 } }); // Background layer (slowest) var bg1 = backgroundContainer.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 1 })); var bg2 = backgroundContainer.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 1 })); bg1.y = 2732; // Position at bottom of screen bg2.y = 2732; bg2.x = GAME_WIDTH; // Midground layer var mg1 = midgroundContainer.addChild(LK.getAsset('midground', { anchorX: 0, anchorY: 1 })); var mg2 = midgroundContainer.addChild(LK.getAsset('midground', { anchorX: 0, anchorY: 1 })); mg1.y = 2732; mg2.y = 2732; mg2.x = GAME_WIDTH; // Foreground layer (fastest) var fg1 = foregroundContainer.addChild(LK.getAsset('foreground', { anchorX: 0, anchorY: 1 })); var fg2 = foregroundContainer.addChild(LK.getAsset('foreground', { anchorX: 0, anchorY: 1 })); fg1.y = 2732 * 1.25; fg2.y = 2732 * 1.25; fg1.x = 0; fg2.x = GAME_WIDTH; // Initialize player var player = game.addChild(new Player()); player.x = 2048 / 4.5; player.y = 2732 / 1.5; // Initialize enemies var enemies = []; var enemySpawnInterval = 100; var enemySpawnCounter = 0; var goblinSpawnInterval = 100; var goblinSpawnCounter = 0; var eyeballSpawnInterval = 300; // Longer interval for eyeballs var eyeballSpawnCounter = 75; function canSpawnAtPosition(x, safeDistance) { safeDistance = safeDistance || 200; // Minimum distance between objects for (var i = 0; i < collectibles.length; i++) { var existingItem = collectibles[i]; if (Math.abs(existingItem.x - x) < safeDistance) { return false; } } return true; } function initializeTorches() { // Calculate number of torches needed based on screen width var torchSpacing = GAME_WIDTH; // One torch per background width // Create two torches for the two background sections var torch1 = new Torch(); torch1.x = 25; torch1.y = 2732 * 0.7; // Adjust Y position as needed midgroundContainer.addChild(torch1); var torch2 = new Torch(); torch2.x = GAME_WIDTH + 25; torch2.y = 2732 * 0.7; midgroundContainer.addChild(torch2); } function startTitleSequence() { // Fade in title with black tint tween(title, { alpha: 1 }, { duration: 1000, onFinish: function onFinish() { tween(title, { tint: 0xFFFFFF }, { duration: 1000, onFinish: startPlayButtonBlink }); } }); } function startPlayButtonBlink() { // Show button initially playButton.alpha = 1; // Create repeating blink sequence function blink() { if (titleScreen) { tween(playButton, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { tween(playButton, { alpha: 1 }, { duration: 500, onFinish: function onFinish() { setTimeout(blink, 1000); // Wait for remaining time in 2-second cycle } }); } }); } } blink(); } function startGame() { if (!gameStarted) { gameStarted = true; titleScreen = false; // Fade out title and button tween(title, { alpha: 0 }, { duration: 500 }); tween(playButton, { alpha: 0 }, { duration: 500 }); // Run player in tween(player, { x: 2048 / 4.5 }, { duration: 2000, onFinish: function onFinish() { // Start regular game title.destroy(); playButton.destroy(); // Normal game initialization continues here } }); } } // Initialize the game with starting platforms function initializeGame() { // Create initial platforms at the low level for (var i = 0; i < 5; i++) { var platform = new Platform(); if (i === 0) { platform.x = player.x; } else { platform.x = lastPlatformX + platformWidth - platformOverlap; } platform.y = lowPlatformHeight; platforms.push(platform); game.addChild(platform); lastPlatformX = platform.x; } lastPlatformHeight = lowPlatformHeight; // Create title screen elements title = game.addChild(LK.getAsset('title', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_WIDTH / 3, alpha: 0, tint: 0x000000 })); playButton = game.addChild(LK.getAsset('playbutton', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_WIDTH / 3 + 300, alpha: 0 })); // Start title sequence startTitleSequence(); // Initialize player off screen player = game.addChild(new Player()); player.x = -200; // Off screen left player.y = 2732 / 1.5; player.isOnGround = true; player.currentPlatform = platforms[0]; } initializeGame(); initializeTorches(); particleSystem = new ParticlePool(100); game.addChild(particleSystem); // Handle game updates game.update = function () { // Scroll backgrounds bg1.x -= platformSpeed * 0.3; bg2.x -= platformSpeed * 0.3; if (bg1.x <= -GAME_WIDTH) { bg1.x = bg2.x + GAME_WIDTH; } if (bg2.x <= -GAME_WIDTH) { bg2.x = bg1.x + GAME_WIDTH; } mg1.x -= platformSpeed * 0.6; mg2.x -= platformSpeed * 0.6; if (mg1.x <= -GAME_WIDTH) { mg1.x = mg2.x + GAME_WIDTH; } if (mg2.x <= -GAME_WIDTH) { mg2.x = mg1.x + GAME_WIDTH; } // Scroll foreground (four instances) fg1.x -= platformSpeed; fg2.x -= platformSpeed; if (fg1.x <= -GAME_WIDTH) { fg1.x = fg2.x + GAME_WIDTH; } if (fg2.x <= -GAME_WIDTH) { fg2.x = fg1.x + GAME_WIDTH; } player.update(); if (particleSystem) { particleSystem.update(); } // Check if we need to spawn a new sequence of platforms var lastPlatform = platforms[platforms.length - 1]; if (lastPlatform && lastPlatform.x < GAME_WIDTH + 500) { // Spawn further off-screen to prevent pop-in // Time to spawn a new sequence if (platformsUntilNextChange <= 0) { // Switch height currentPlatformHeight = currentPlatformHeight === lowPlatformHeight ? highPlatformHeight : lowPlatformHeight; // Generate new random sequence length platformsUntilNextChange = Math.floor(Math.random() * (maxPlatformsInSequence - minPlatformsInSequence + 1)) + minPlatformsInSequence; // Make ground sequences longer if (currentPlatformHeight === lowPlatformHeight) { platformsUntilNextChange += 5; } } // Spawn a single platform in the sequence var platform = new Platform(); platform.x = lastPlatform.x + (platformWidth - platformOverlap); platform.y = currentPlatformHeight; platforms.push(platform); game.addChild(platform); // Decrement the counter for each platform added platformsUntilNextChange--; } // Update platforms for (var i = platforms.length - 1; i >= 0; i--) { platforms[i].update(); // Remove platforms that are destroyed if (platforms[i].destroyed) { platforms.splice(i, 1); } } jarSpawnCounter++; if (jarSpawnCounter >= jarSpawnInterval) { var availablePlatforms = platforms.filter(function (p) { return p.x > 2048 && p.x < 2048 + 300; }); if (availablePlatforms.length > 0 && Math.random() < 0.3) { var platform = availablePlatforms[Math.floor(Math.random() * availablePlatforms.length)]; // Only spawn if position is clear if (canSpawnAtPosition(platform.x)) { var jar = new Jar(); jar.x = platform.x; jar.y = platform.y - 130; jar.currentPlatform = platform; collectibles.push(jar); // Add to collectibles array instead of jars array game.addChild(jar); } } jarSpawnCounter = 0; } chestSpawnCounter++; if (chestSpawnCounter >= chestSpawnInterval) { var availablePlatforms = platforms.filter(function (p) { return p.x > 2048 && p.x < 2048 + 300; }); if (availablePlatforms.length > 0 && Math.random() < 0.15) { // 15% chance to spawn var platform = availablePlatforms[Math.floor(Math.random() * availablePlatforms.length)]; // Only spawn if position is clear if (canSpawnAtPosition(platform.x)) { var chest = new TreasureChest(); chest.x = platform.x; chest.y = platform.y - 130; chest.currentPlatform = platform; collectibles.push(chest); // Add to collectibles array game.addChild(chest); } } chestSpawnCounter = 0; } // Replace the existing jar update code with this: for (var i = collectibles.length - 1; i >= 0; i--) { var collectible = collectibles[i]; if (collectible.currentPlatform) { collectible.x = collectible.currentPlatform.x; } var attackBounds = player.getAttackBounds(); if (attackBounds) { var itemBounds = { left: collectible.x - 50, right: collectible.x + 50, top: collectible.y - 75, bottom: collectible.y + 75 }; if (attackBounds.left < itemBounds.right && attackBounds.right > itemBounds.left && attackBounds.top < itemBounds.bottom && attackBounds.bottom > itemBounds.top) { collectible["break"](); collectibles.splice(i, 1); continue; } } if (collectible.x < -50) { collectible.destroy(); collectibles.splice(i, 1); } } for (var i = 0; i < midgroundContainer.children.length; i++) { var child = midgroundContainer.children[i]; if (child instanceof Torch) { child.update(); // Move torch with midground child.x -= platformSpeed * 0.6; // Reset torch position when it goes off screen if (child.x <= -GAME_WIDTH) { child.x = child.x + GAME_WIDTH * 2; } } } // Update coins for (var i = coins.length - 1; i >= 0; i--) { coins[i].update(); if (coins[i].destroyed) { coins.splice(i, 1); } } for (var i = game.children.length - 1; i >= 0; i--) { var child = game.children[i]; if (child instanceof ScorePopup) { child.update(); } } // Handle goblin spawning goblinSpawnCounter++; if (goblinSpawnCounter >= goblinSpawnInterval) { var availablePlatforms = platforms.filter(function (p) { return p.x > 2048 - 100 && p.x < 2048 + 300; }); if (availablePlatforms.length > 0) { var enemy = new Enemy('goblin'); var platform = availablePlatforms[Math.floor(Math.random() * availablePlatforms.length)]; enemy.x = platform.x; enemy.y = platform.y - ENEMY_PLATFORM_OFFSET; enemy.currentPlatform = platform; enemies.push(enemy); game.addChild(enemy); goblinSpawnInterval = Math.floor(Math.random() * 150) + 100; goblinSpawnCounter = 0; } else { // No valid platforms, just reset counter but don't spawn goblinSpawnCounter = Math.max(0, goblinSpawnCounter - 20); // Back up a bit to try again soon } } // Handle eyeball spawning eyeballSpawnCounter++; if (eyeballSpawnCounter >= eyeballSpawnInterval) { var enemy = new Enemy('eyeball'); var randomHeight = Math.random() * 400 + 200; enemy.x = 2048 + 100; enemy.y = highPlatformHeight - randomHeight; enemies.push(enemy); game.addChild(enemy); eyeballSpawnInterval = Math.floor(Math.random() * 200) + 150; eyeballSpawnCounter = 0; } // Update enemies for (var j = enemies.length - 1; j >= 0; j--) { enemies[j].update(); var playerBounds = player.getBounds(); var enemyBounds = enemies[j].getBounds(); var attackBounds = player.getAttackBounds(); // Add check if enemy is behind player if (enemies[j].x < player.x - 100) { // Added 100px buffer continue; // Skip collision checks for enemies behind player } // Check for attack collision first if (attackBounds && !enemies[j].isHit && !enemies[j].isDying) { if (enemies[j].x > player.x && attackBounds.left < enemyBounds.right && attackBounds.right > enemyBounds.left && attackBounds.top < enemyBounds.bottom && attackBounds.bottom > enemyBounds.top) { enemies[j].hit(); if (enemies[j].type === 'eyeball') { LK.getSound('eyeballhit').play(); } else { LK.getSound('enemyhit').play(); } continue; } } // Check for body collision second if (playerBounds.left < enemyBounds.right && playerBounds.right > enemyBounds.left && playerBounds.top < enemyBounds.bottom && playerBounds.bottom > enemyBounds.top) { if (!enemies[j].isHit && !enemies[j].isDying) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } } } }; // Handle player jump game.down = function (x, y, obj) { touchStartX = x; touchStartY = y; }; var originalGameUp = game.up; game.up = function (x, y, obj) { if (titleScreen) { // Check if click/tap is on play button var buttonBounds = { left: playButton.x - 50, right: playButton.x + 50, top: playButton.y - 14, bottom: playButton.y + 14 }; if (x >= buttonBounds.left && x <= buttonBounds.right && y >= buttonBounds.top && y <= buttonBounds.bottom) { startGame(); } } else { originalGameUp(x, y, obj); } };
===================================================================
--- original.js
+++ change.js
2D Single Monster. In-Game asset. 2d. Blank background. High contrast. No shadows..
A gold coin. 8 bit pixel art. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Dark and moody dungeon background. Infinite repeatable texture. 8 bit pixel art.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A ruby. Pixel art.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A wooden arrow with white feathers and a steel arrow head. Horizontal. Pixel art. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
backgroundmusic1
Music
playerjump
Sound effect
swordslash
Sound effect
jarbreak
Sound effect
enemyhit
Sound effect
eyeballhit
Sound effect
coincollect
Sound effect
woodbreak
Sound effect
coinbounce
Sound effect
potion
Sound effect
playerouch
Sound effect
bowfiring
Sound effect
arrowfire
Sound effect
arrowpickup
Sound effect
gameover
Sound effect