Code edit (1 edits merged)
Please save this source code
User prompt
play drown sound when player drown
User prompt
in player resetRun move the reset coin code into coinManager
Code edit (3 edits merged)
Please save this source code
User prompt
prevent jump when drown until reset run
User prompt
apply this fix
User prompt
in WaterHole Manager, update, pass a callback to drownPlayer to remove the waterhole and move the left ground to the right to hide the gap left by the waterhole removal
Code edit (3 edits merged)
Please save this source code
User prompt
in resetRun, player should be restored to morph mode 0 (directly, without animation)
User prompt
in resetRun, player should be restored to morph mode 0
Code edit (1 edits merged)
Please save this source code
User prompt
extract game.update's coins' code in a separate Manager class
Code edit (2 edits merged)
Please save this source code
User prompt
extract game.update() mushroom code in a separate function or Manager class (decide what's best)
User prompt
in WaterHoleManager.update(), only check collisions if distance between player and waterHole is < 400
Code edit (1 edits merged)
Please save this source code
User prompt
separate properly checkPlatformCollision in two clean independent functions: checkPlatformCollision and checkWaterHoleCollision
User prompt
add console.log("Distance to hole #"+j, distanceToWaterHole);
User prompt
Don't checkPlatformCollision if distance beween player and waterhole is > 400
Code edit (1 edits merged)
Please save this source code
Code edit (3 edits merged)
Please save this source code
User prompt
pass a callback to drownAnim to act when anim is finished
User prompt
in drownAnim, instead of `var animLoop = true;` use a public property like self.isDrownAnimPlaying
User prompt
Now Mushrooms should only spawn on the middle of platforms
Code edit (1 edits merged)
Please save this source code
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Coin = Container.expand(function () { var self = Container.call(this); self.frames = [self.attachAsset('coinFrame1', { anchorX: 0.5, anchorY: 0.5, alpha: 1 }), self.attachAsset('coinFrame2', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('coinFrame3', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('coinFrame4', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('coinFrame5', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('coinFrame6', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('coinFrame7', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('coinFrame8', { anchorX: 0.5, anchorY: 0.5, alpha: 0 })]; self.currentFrame = 0; self.speed = 10; self.collected = false; self.animationSpeed = 4; self.reset = function (x, y) { self.x = x; self.y = y; self.collected = false; self.alpha = 1; self.currentFrame = 0; for (var i = 0; i < self.frames.length; i++) { self.frames[i].alpha = i === 0 ? 1 : 0; } self.animationTimer = 0; }; self.startAnimation = function () { self.animationTimer = 0; }; self.animate = function () { self.frames[self.currentFrame].alpha = 0; self.currentFrame = (self.currentFrame + 1) % self.frames.length; self.frames[self.currentFrame].alpha = 1; }; self.getBounds = function () { return { left: self.x - 40, right: self.x + 40, top: self.y - 40, bottom: self.y + 40 }; }; self.update = function () { self.animationTimer += 1; if (self.animationTimer >= 6) { self.animate(); self.animationTimer = 0; } if ((!player || !player.isHit && lives >= 0) && !gamePaused) { self.x -= self.speed * globalSpeed; } if (self.x < -100) { var coinIndex = coinManager.coins.indexOf(self); if (coinIndex > -1) { coinManager.coins.splice(coinIndex, 1); } if (self.parent) { self.parent.removeChild(self); } self.visible = false; coinManager.coinPool.push(self); } if (!self.collected && player && player.getBounds && player.canJump && !gamePaused) { var coinBounds = self.getBounds(); var playerBounds = player.getBounds(); if (playerBounds.left < coinBounds.right && playerBounds.right > coinBounds.left && playerBounds.top < coinBounds.bottom && playerBounds.bottom > coinBounds.top) { self.collected = true; LK.getSound('coin').play(); LK.setScore(LK.getScore() + 10); if (scoreText) { scoreText.setText(LK.getScore()); } if (coinCounter) { coinCount++; coinCounter.updateCount(coinCount); } tween(self, { y: self.y - 100, alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { var coinIndex = coinManager.coins.indexOf(self); if (coinIndex > -1) { coinManager.coins.splice(coinIndex, 1); } if (self.parent) { self.parent.removeChild(self); } self.visible = false; coinManager.coinPool.push(self); } }); } } }; self.startAnimation(); return self; }); var CoinCounter = Container.expand(function () { var self = Container.call(this); var coinIcon = self.attachAsset('coinFrame1', { anchorX: 0.5, anchorY: 0.5, x: 220, y: 50, width: 96, height: 96 }); self.hundreds = new Text2('0', { size: 100, fill: 0xFFFFFF }); self.hundreds.anchor.set(0.5); self.hundreds.x = 0; self.hundreds.y = 50; self.addChild(self.hundreds); self.tens = new Text2('0', { size: 100, fill: 0xFFFFFF }); self.tens.anchor.set(0.5); self.tens.x = 60; self.tens.y = 50; self.addChild(self.tens); self.units = new Text2('0', { size: 100, fill: 0xFFFFFF }); self.units.anchor.set(0.5); self.units.x = 120; self.units.y = 50; self.addChild(self.units); self.updateCount = function (count) { count = Math.min(999, Math.max(0, count)); var h = Math.floor(count / 100); var t = Math.floor(count % 100 / 10); var u = count % 10; self.hundreds.setText(h.toString()); self.tens.setText(t.toString()); self.units.setText(u.toString()); }; self.updateCount(0); return self; }); var CoinManager = Container.expand(function () { var self = Container.call(this); self.coins = []; self.coinPool = []; self.spawnInterval = Math.floor(Math.random() * 100) + 50; self.spawnCounter = 0; self.init = function () { self.coins = []; self.coinPool = []; self.spawnInterval = Math.floor(Math.random() * 100) + 50; self.spawnCounter = 0; }; self.update = function () { if (player && player.isHit || lives < 0 || gamePaused) { return; } // Spawn logic self.spawnCounter++; if (self.coins.length < 10 && self.spawnCounter >= self.spawnInterval) { self.spawnCoin(); self.spawnCounter = 0; } }; self.spawnCoin = function () { var coin; if (self.coinPool.length > 0) { coin = self.coinPool.pop(); coin.visible = true; } else { coin = new Coin(); } coin.x = 2500; var randomHeight = Math.random(); if (randomHeight < 0.33) { coin.y = groundLevel - 100; } else if (randomHeight < 0.66) { coin.y = level1Height - 100; } else { coin.y = level2Height - 100; } if (self.coinPool.indexOf(coin) > -1) { coin.reset(coin.x, coin.y); } self.coins.push(coin); if (!coin.parent) { middlegroundContainer.addChild(coin); } self.spawnInterval = Math.floor(Math.random() * 200) + 100; self.spawnCounter = 0; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.startAnimation = function () { tween(self, { scaleX: 1.15 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { scaleX: 0.9 }, { duration: 200, easing: tween.easeInOut, onFinish: self.startAnimation }); } }); }; self.speed = 15; self.velocityY = 0; self.gravity = 0.7; self.currentPlatform = null; self.reset = function (x, y) { self.x = x; self.y = y; self.velocityY = 0; self.currentPlatform = null; self.passed = false; self.startAnimation(); }; self.update = function () { if (player && player.isHit || lives < 0 || gamePaused) { return; } self.x -= self.speed * globalSpeed; if (self.currentPlatform) { var enemyBounds = self.getBounds(); var platformBounds = { left: self.currentPlatform.x - 500, right: self.currentPlatform.x + 500 }; if (enemyBounds.left > platformBounds.right || enemyBounds.right < platformBounds.left) { self.currentPlatform = null; } } if (!self.currentPlatform) { self.velocityY += self.gravity * globalSpeed; self.y += self.velocityY * globalSpeed; } var enemyVisualBottomOffset = 75; if (self.y >= groundLevel - enemyVisualBottomOffset) { self.y = groundLevel - enemyVisualBottomOffset; self.velocityY = 0; self.currentPlatform = null; } if (self.velocityY > 0) { for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; var enemyBounds = self.getBounds(); var platformBounds = { left: platform.x - 500, right: platform.x + 500, top: platform.y - 50, bottom: platform.y + 50 }; if (enemyBounds.bottom >= platformBounds.top && enemyBounds.bottom - self.velocityY < platformBounds.top && enemyBounds.right > platformBounds.left && enemyBounds.left < platformBounds.right) { self.y = platform.y - 75; self.velocityY = 0; self.currentPlatform = platform; break; } } } if (self.x < -50) { if (self.parent) { self.parent.removeChild(self); } var index = enemies.indexOf(self); if (index > -1) { enemies.splice(index, 1); } self.visible = false; enemyPool.push(self); } }; self.getBounds = function () { return { left: self.x - 50, right: self.x + 50, top: self.y - 50, bottom: self.y + 50 }; }; self.startAnimation(); return self; }); var LivesCounter = Container.expand(function () { var self = Container.call(this); self.hearts = []; var maxHearts = 3; for (var i = 0; i < maxHearts; i++) { var heart = self.attachAsset('playerRunFrame2', { anchorX: 0.5, anchorY: 0.5, x: i * 70, y: 0, width: 60, height: 60 }); self.hearts.push(heart); } self.updateLives = function (livesCount) { livesCount = Math.min(maxHearts, Math.max(0, livesCount)); for (var i = 0; i < maxHearts; i++) { self.hearts[i].visible = i < livesCount; } }; self.updateLives(3); return self; }); var Mushroom = Container.expand(function () { var self = Container.call(this); var mushroomGraphics = self.attachAsset('mushroom', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; self.collected = false; self.reset = function (x, y) { self.x = x; self.y = y; self.collected = false; self.alpha = 1; }; self.getBounds = function () { return { left: self.x - 50, right: self.x + 50, top: self.y - 45, bottom: self.y + 45 }; }; self.update = function () { if ((!player || !player.isHit && lives >= 0) && !gamePaused) { self.x -= self.speed * globalSpeed; } if (self.x < -100) { var mushroomIndex = mushroomManager.mushrooms.indexOf(self); if (mushroomIndex > -1) { mushroomManager.mushrooms.splice(mushroomIndex, 1); } if (self.parent) { self.parent.removeChild(self); } self.visible = false; mushroomManager.mushroomPool.push(self); } if (!self.collected && player && player.getBounds && player.canJump && !gamePaused) { var mushroomBounds = self.getBounds(); var playerBounds = player.getBounds(); if (playerBounds.left < mushroomBounds.right && playerBounds.right > mushroomBounds.left && playerBounds.top < mushroomBounds.bottom && playerBounds.bottom > mushroomBounds.top) { self.collected = true; if (player.morphState === 0) { LK.getSound('mushroomEat').play(); player.morphState = 1; player.updateRefScale(); } LK.setScore(LK.getScore() + 100); if (scoreText) { scoreText.setText(LK.getScore()); } tween(self, { y: self.y - 100, alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { var mushroomIndex = mushroomManager.mushrooms.indexOf(self); if (mushroomIndex > -1) { mushroomManager.mushrooms.splice(mushroomIndex, 1); } if (self.parent) { self.parent.removeChild(self); } self.visible = false; mushroomManager.mushroomPool.push(self); } }); } } }; return self; }); var MushroomManager = Container.expand(function () { var self = Container.call(this); self.mushrooms = []; self.mushroomPool = []; self.spawnInterval = Math.floor(Math.random() * 500) + 500; self.spawnCounter = 0; self.init = function () { self.mushrooms = []; self.mushroomPool = []; self.spawnInterval = Math.floor(Math.random() * 500) + 500; self.spawnCounter = 0; }; self.update = function () { if (player && player.isHit || lives < 0 || gamePaused) { return; } // Spawn logic self.spawnCounter++; if (self.mushrooms.length < 2 && self.spawnCounter >= self.spawnInterval) { self.spawnMushroom(); self.spawnCounter = 0; } }; self.spawnMushroom = function () { var mushroom; if (self.mushroomPool.length > 0) { mushroom = self.mushroomPool.pop(); mushroom.visible = true; } else { mushroom = new Mushroom(); } mushroom.x = 2500; // Only spawn on platforms instead of random heights var availablePlatforms = []; for (var p = 0; p < platforms.length; p++) { if (platforms[p].x > 2048 && platforms[p].x < 2800) { availablePlatforms.push(platforms[p]); } } // If we have platforms in the spawn zone, put mushroom on one of them if (availablePlatforms.length > 0) { var randomPlatform = availablePlatforms[Math.floor(Math.random() * availablePlatforms.length)]; mushroom.x = randomPlatform.x; // Place at center of platform mushroom.y = randomPlatform.y - 100; // Adjust height to be above platform } else { // Fallback if no platforms are in the spawn zone mushroom.x = 2500; mushroom.y = groundLevel - 100; } if (self.mushroomPool.indexOf(mushroom) > -1) { mushroom.reset(mushroom.x, mushroom.y); } self.mushrooms.push(mushroom); if (!mushroom.parent) { middlegroundContainer.addChild(mushroom); } self.spawnInterval = Math.floor(Math.random() * 500) + 500; self.spawnCounter = 0; }; 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 = 10; self.passed = false; self.update = function () { if (player && player.isHit || lives < 0 || gamePaused) { return; } self.x -= self.speed * globalSpeed; if (self.x < -500) { if (self.parent) { self.parent.removeChild(self); } var index = platforms.indexOf(self); if (index > -1) { platforms.splice(index, 1); } self.visible = false; platformPool.push(self); } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); self.morphState = 0; self.refScaleX = 0.5; self.refScaleY = 0.5; self.resetRun = function () { console.log("Reset run..."); for (var i = enemies.length - 1; i >= 0; i--) { if (enemies[i].parent) { enemies[i].parent.removeChild(enemies[i]); } enemies[i].visible = false; enemyPool.push(enemies[i]); } enemies = []; // Reset coins using the manager if (coinManager) { for (var i = coinManager.coins.length - 1; i >= 0; i--) { if (coinManager.coins[i].parent) { coinManager.coins[i].parent.removeChild(coinManager.coins[i]); } coinManager.coins[i].visible = false; coinManager.coinPool.push(coinManager.coins[i]); } coinManager.coins = []; coinManager.spawnCounter = 0; } // Reset mushrooms using the manager if (mushroomManager) { for (var i = mushroomManager.mushrooms.length - 1; i >= 0; i--) { var mushroom = mushroomManager.mushrooms[i]; if (mushroom.parent) { mushroom.parent.removeChild(mushroom); } mushroom.visible = false; mushroomManager.mushroomPool.push(mushroom); } mushroomManager.mushrooms = []; mushroomManager.spawnCounter = 0; } if (waterHoleManager && waterHoleManager.waterHoles) { for (var i = waterHoleManager.waterHoles.length - 1; i >= 0; i--) { var waterHole = waterHoleManager.waterHoles[i]; if (waterHole.parent) { waterHole.parent.removeChild(waterHole); } waterHole.visible = false; waterHoleManager.waterHolePool.push(waterHole); } waterHoleManager.waterHoles = []; waterHoleManager.spawnCounter = 0; } LK.effects.flashScreen(0xFFFFFF, 600); self.x = 2048 / 6; self.y = groundLevel - 100; self.velocityY = 0; self.isJumping = false; self.currentPlatform = null; self.shadow.alpha = 0.5; console.log("RESET FRAMES!"); self.isDrownAnimPlaying = false; for (var i = 0; i < self.dieFrames.length; i++) { self.dieFrames[i].alpha = 0; } self.morphState = 0; self.scale.x = 0.5; self.scale.y = 0.5; self.updateRefScale(); self.runFrames[self.currentRunFrame].alpha = 1; gamePaused = false; }; self.init = function () { self.updateRefScale(); }; self.updateRefScale = function () { var oldScaleY = self.refScaleY; var visualBottomOffset = self.playerHeight * oldScaleY / 2; if (self.morphState === 0) { self.refScaleX = 0.5; self.refScaleY = 0.5; } else { self.refScaleX = 1.0; self.refScaleY = 1.0; } var newVisualBottomOffset = self.playerHeight * self.refScaleY / 2; if (!self.isJumping) { if (self.currentPlatform) { self.y = self.currentPlatform.y - newVisualBottomOffset; } else { self.y = groundLevel - newVisualBottomOffset; } } tween(self.scale, { x: self.refScaleX, y: self.refScaleY }, { duration: 1000, easing: tween.easeOut }); }; self.shadow = self.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, scaleX: 2.0, scaleY: 0.4, tint: 0x000000, y: 200 }); self.runFrames = [self.attachAsset('playerRunFrame1', { anchorX: 0.5, anchorY: 0.5, alpha: 1 }), self.attachAsset('playerRunFrame2', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('playerRunFrame', { anchorX: 0.5, anchorY: 0.5, alpha: 0 })]; self.currentRunFrame = 0; self.speed = 5; self.jumpHeight = 35; self.isJumping = false; self.velocityY = 0; self.isFalling = false; self.currentPlatform = null; self.playerHeight = 400; self.canJump = false; self.isHit = false; self.boundingBox = self.attachAsset('boundingBox', { anchorX: 0.5, anchorY: 0.5, width: 150, height: 380, alpha: isDebug ? 0.5 : 0 }); self.hitFrame = self.attachAsset('playerHitFrame1', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.jumpFrame = self.attachAsset('playerJumpFrame', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.getBounds = function () { return { left: self.x - 75, right: self.x + 75, top: self.y - 100, bottom: self.y + 100 }; }; self.update = function () { if (self.isHit || lives < 0) { return; } if (self.isJumping) { var height = Math.min(1, (groundLevel - self.y) / 300); self.shadow.alpha = 0.5 - height * 0.3; self.shadow.scaleX = 2.0 - height; self.shadow.scaleY = 0.5 - height * 0.2; } else { self.shadow.alpha = 0.5; self.shadow.scaleX = 2.0; self.shadow.scaleY = 0.5; } if (self.isJumping) { self.y += self.velocityY * globalSpeed; self.velocityY += 2.0 * globalSpeed; self.isFalling = self.velocityY > 0; self.jumpFrame.alpha = 1; self.runFrames[self.currentRunFrame].alpha = 0; //self.checkWaterHoleCollision(); self.checkPlatformCollision(); var visualBottomOffset = self.playerHeight * self.refScaleY / 2; if (self.y >= groundLevel - visualBottomOffset && !self.currentPlatform) { self.y = groundLevel - visualBottomOffset; self.isJumping = false; self.velocityY = 0; self.jumpFrame.alpha = 0; self.runFrames[self.currentRunFrame].alpha = 1; tween(self, { scaleX: self.refScaleX * 1.2, scaleY: self.refScaleY * 0.8 }, { duration: 100, easing: tween.elasticOut, onFinish: function onFinish() { tween(self, { scaleX: self.refScaleX, scaleY: self.refScaleY }, { duration: 500, easing: tween.elasticOut }); } }); } } else { if (self.currentPlatform) { var platformBounds = { left: self.currentPlatform.x - 500, right: self.currentPlatform.x + 500 }; var playerBounds = self.getBounds(); if (playerBounds.left > platformBounds.right || playerBounds.right < platformBounds.left) { self.isJumping = true; self.velocityY = 0.1; self.isFalling = true; self.currentPlatform = null; self.jumpFrame.alpha = 1; self.runFrames[self.currentRunFrame].alpha = 0; } } if (LK.ticks % 5 === 0 && !self.isDrownAnimPlaying) { self.runFrames[self.currentRunFrame].alpha = 0; self.currentRunFrame = (self.currentRunFrame + 1) % self.runFrames.length; self.runFrames[self.currentRunFrame].alpha = 1; } } }; self.jump = function () { if (!self.isJumping && !self.isDrownAnimPlaying) { self.isJumping = true; self.velocityY = -self.jumpHeight * 1.5; self.jumpFrame.alpha = 1; LK.getSound('jump').play(); self.currentPlatform = null; } }; self.dieFrames = [self.attachAsset('playerDieFrame1', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('playerDieFrame2', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('playerDieFrame3', { anchorX: 0.5, anchorY: 0.5, alpha: 0 })]; self.die = function () { console.log("Die..."); for (var i = 0; i < self.runFrames.length; i++) { self.runFrames[i].alpha = 0; } self.jumpFrame.alpha = 0; self.hitFrame.alpha = 0; self.shadow.alpha = 0; LK.getSound('loose').play(); LK.getSound('loose2').play(); LK.stopMusic(); var currentFrame = 0; function showNextFrame() { if (currentFrame > 0) { self.dieFrames[currentFrame - 1].alpha = 0; } self.dieFrames[currentFrame].alpha = 1; currentFrame++; if (currentFrame < self.dieFrames.length) { LK.setTimeout(showNextFrame, 100); } else { startDeathMovement(); } } function startDeathMovement() { var animLoop = true; var loopFrame = 1; function loopDieFrames() { for (var i = 0; i < self.dieFrames.length; i++) { self.dieFrames[i].alpha = 0; } self.dieFrames[loopFrame].alpha = 1; loopFrame = loopFrame === 1 ? 2 : 1; if (animLoop) { LK.setTimeout(loopDieFrames, 120); } } loopDieFrames(); tween(self, { y: self.y - 1024, scaleX: 5, scaleY: 5 }, { duration: 600, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { y: 4000 }, { duration: 1200, easing: tween.easeIn, onFinish: function onFinish() { animLoop = false; } }); } }); } showNextFrame(); }; self.hitPlayer = function () { if (self.isHit) { return; } console.log("Hit..."); self.isHit = true; for (var i = 0; i < self.runFrames.length; i++) { self.runFrames[i].alpha = 0; } self.jumpFrame.alpha = 0; if (self.morphState === 0) { lives--; livesCounter.updateLives(lives); } self.hitFrame.alpha = 1; if (lives <= 0) { self.die(); return; } if (self.morphState === 1) { LK.getSound('hit').play(); self.morphState = 0; self.updateRefScale(); LK.setTimeout(function () { self.hitFrame.alpha = 0; if (self.isJumping) { self.jumpFrame.alpha = 1; } else { self.runFrames[self.currentRunFrame].alpha = 1; } self.isHit = false; }, 330); } else { LK.getSound('hitSmall').play(); LK.setTimeout(function () { self.hitFrame.alpha = 0; if (self.isJumping) { self.jumpFrame.alpha = 1; } else { self.runFrames[self.currentRunFrame].alpha = 1; } self.isHit = false; }, 330); } }; self.drownAnim = function (callback) { console.log("drownAnim..."); self.jumpFrame.alpha = 0; self.hitFrame.alpha = 0; self.shadow.alpha = 0; self.isDrownAnimPlaying = true; for (var i = 0; i < self.runFrames.length; i++) { self.runFrames[i].alpha = 0; } var loopFrame = 1; function loopDrownFrames() { for (var i = 0; i < self.dieFrames.length; i++) { self.dieFrames[i].alpha = 0; } if (self.isDrownAnimPlaying) { self.dieFrames[loopFrame].alpha = 1; loopFrame = loopFrame === 1 ? 2 : 1; LK.setTimeout(loopDrownFrames, 120); } } loopDrownFrames(); tween(self, { y: 4000 }, { duration: 1500, easing: tween.easeIn, onFinish: function onFinish() { self.isDrownAnimPlaying = false; if (typeof callback === 'function') { callback(); } } }); }; self.drownPlayer = function (callback) { console.log("drownAnim..."); gamePaused = true; self.drownAnim(function () { if (lives > 0) { self.resetRun(); } if (typeof callback === 'function') { callback(); } }); if (lives > 0) { lives--; livesCounter.updateLives(lives); if (lives <= 0) { player.die(); LK.setTimeout(function () { LK.showGameOver(); }, 4000); } } }; self.checkWaterHoleCollision = function () { if (!waterHoleManager || !waterHoleManager.waterHoles) { return true; // No water holes, so platform collision should proceed } var shouldCheckPlatforms = true; for (var j = 0; j < waterHoleManager.waterHoles.length; j++) { var waterHole = waterHoleManager.waterHoles[j]; var distanceToWaterHole = Math.abs(self.x - waterHole.x); console.log("Distance to hole #" + j, distanceToWaterHole); if (distanceToWaterHole <= 400) { shouldCheckPlatforms = true; break; } } return shouldCheckPlatforms; }; self.checkPlatformCollision = function () { for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; var platformBounds = { left: platform.x - 500, right: platform.x + 500, top: platform.y - 50, bottom: platform.y + 50 }; var playerBounds = self.getBounds(); var adjustedVelocity = self.velocityY * globalSpeed; if (self.velocityY > 0 && playerBounds.bottom >= platformBounds.top && playerBounds.bottom - adjustedVelocity < platformBounds.top && playerBounds.right > platformBounds.left && playerBounds.left < platformBounds.right) { var visualBottomOffset = self.playerHeight * self.refScaleY / 2; self.y = platform.y - visualBottomOffset; self.velocityY = 0; self.isJumping = false; self.isFalling = false; self.currentPlatform = platform; self.jumpFrame.alpha = 0; self.runFrames[self.currentRunFrame].alpha = 1; tween(self, { scaleX: self.refScaleX * 1.2, scaleY: self.refScaleY * 0.8 }, { duration: 100, easing: tween.elasticOut, onFinish: function onFinish() { tween(self, { scaleX: self.refScaleX, scaleY: self.refScaleY }, { duration: 500, easing: tween.elasticOut }); } }); return true; } } return false; }; self.init(); }); var StartButton = Container.expand(function () { var self = Container.call(this); var buttonGraphics = self.attachAsset('startButton', { anchorX: 0.5, anchorY: 0.5, width: 1024, height: 1024 }); self.animate = function () { if (!self.scale) { self.scale = { x: 1, y: 1 }; } tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 800, easing: tween.easeInOut, onFinish: self.animate }); } }); }; self.down = function (x, y, obj) { LK.getSound('start').play(); tween(self, { scale: 0.9 }, { duration: 100, easing: tween.easeOut }); }; self.up = function (x, y, obj) { tween(self, { scale: 0, alpha: 0 }, { duration: 300, easing: tween.elasticIn, onFinish: function onFinish() { if (self.parent) { self.parent.removeChild(self); } enemySpawnCounter = 0; if (player) { player.canJump = true; } } }); }; return self; }); var WaterHole = Container.expand(function () { var self = Container.call(this); self.frames = [self.attachAsset('waterHoleFrame1', { anchorX: 0.5, anchorY: 0.5, alpha: 1 }), self.attachAsset('waterHoleFrame2', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('waterHoleFrame3', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('waterHoleFrame4', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('waterHoleFrame5', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('waterHoleFrame6', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('waterHoleFrame7', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }), self.attachAsset('waterHoleFrame8', { anchorX: 0.5, anchorY: 0.5, alpha: 0 })]; self.boundingBox = self.attachAsset('boundingBox', { anchorX: 0.5, anchorY: 0.5, width: 256, height: 1024, alpha: isDebug ? 0.5 : 0 }); self.leftBorder = self.attachAsset('waterHoleBorder', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, x: -230 }); self.leftBorder = self.attachAsset('waterHoleBorder', { anchorX: 0.5, anchorY: 0.5, scaleX: -1.0, x: 230 }); self.currentFrame = 0; self.speed = groundSpeedBase; self.reset = function (x, y) { self.x = x; self.y = y; self.alpha = 1; self.currentFrame = 0; for (var i = 0; i < self.frames.length; i++) { self.frames[i].alpha = i === 0 ? 1 : 0; } self.animationTimer = 0; }; self.startAnimation = function () { self.animationTimer = 0; }; self.animate = function () { self.frames[self.currentFrame].alpha = 0; self.currentFrame = (self.currentFrame + 1) % self.frames.length; self.frames[self.currentFrame].alpha = 1; }; self.update = function () { self.animationTimer += 1; if (self.animationTimer >= 6) { self.animate(); self.animationTimer = 0; } if ((!player || !player.isHit && lives >= 0) && !gamePaused) { self.x -= self.speed * globalSpeed; } }; self.startAnimation(); return self; }); var WaterHoleManager = Container.expand(function () { var self = Container.call(this); self.waterHoles = []; self.waterHolePool = []; self.spawnInterval = 200; self.spawnCounter = 0; self.checkPlayerCollision = function (playerBounds, waterHole) { var holeX = waterHole.x; console.log("Player bounds:", { left: playerBounds.left, right: playerBounds.right, top: playerBounds.top, bottom: playerBounds.bottom }); console.log("Water hole:", { x: holeX, boundingBoxWidth: waterHole.boundingBox.width, groundLevel: groundLevel }); var condition1 = playerBounds.left < holeX + waterHole.boundingBox.width / 2; var condition2 = playerBounds.right > holeX - waterHole.boundingBox.width / 2; var condition3 = playerBounds.bottom > groundLevel - 150; console.log("Collision conditions:", { horizontalOverlap1: condition1, horizontalOverlap2: condition2, belowThreshold: condition3, allConditions: condition1 && condition2 && condition3 }); return condition1 && condition2 && condition3; }; self.init = function () { self.waterHoles = []; self.waterHolePool = []; self.spawnCounter = 0; }; self.spawnWaterHole = function () { var spawnX; var rightmostGround; if (ground && ground2) { if (ground.x > ground2.x) { rightmostGround = ground; } else { rightmostGround = ground2; } var gapStartX = rightmostGround.x; spawnX = gapStartX + 256; } if (!spawnX || spawnX < 2304) { return; } rightmostGround.x += 512; var leftmostGround = ground.x < ground2.x ? ground : ground2; if (self.waterHoles.length > 0 && self.waterHoles[0].x < -150) { leftmostGround.x -= 512; } var waterHole; var wasReused = false; if (self.waterHolePool.length > 0) { waterHole = self.waterHolePool.pop(); waterHole.visible = true; wasReused = true; } else { waterHole = new WaterHole(); } waterHole.x = spawnX; waterHole.y = groundLevel + 512; if (wasReused) { waterHole.reset(waterHole.x, waterHole.y); } self.waterHoles.push(waterHole); if (!waterHole.parent) { middlegroundContainer.addChild(waterHole); } self.spawnInterval = Math.floor(Math.random() * 300) + 200; self.spawnCounter = 0; }; self.update = function () { if (player && player.isHit || lives < 0) { return; } self.spawnCounter++; if (self.waterHoles.length < 3 && self.spawnCounter >= self.spawnInterval) { self.spawnWaterHole(); } for (var i = self.waterHoles.length - 1; i >= 0; i--) { var waterHole = self.waterHoles[i]; if (waterHole.x < -300) { if (waterHole.parent) { waterHole.parent.removeChild(waterHole); } self.waterHoles.splice(i, 1); waterHole.visible = false; self.waterHolePool.push(waterHole); } if (player && player.getBounds) { var distanceToWaterHole = Math.abs(player.x - waterHole.x); console.log("Distance to hole #" + i, distanceToWaterHole); if (distanceToWaterHole < 400) { var playerBounds = player.getBounds(); if (self.checkPlayerCollision(playerBounds, waterHole)) { if (!waterHole.triggered) { waterHole.triggered = true; if (player.canJump) { var currentHole = waterHole; var currentIndex = i; player.drownPlayer(function () { // Remove the waterhole if (currentHole.parent) { currentHole.parent.removeChild(currentHole); } self.waterHoles.splice(currentIndex, 1); currentHole.visible = false; self.waterHolePool.push(currentHole); // Move the left ground to the right to hide the gap if (ground && ground2) { var leftmostGround = ground.x < ground2.x ? ground : ground2; leftmostGround.x += 512; } }); } else { player.jump(); } } } else { waterHole.triggered = false; } } } } }; self.init(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ /**** * Global Variables ****/ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) { return t; } var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) { return i; } throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } var isDebug = true; var level1Height; var level2Height; var game; var background; var player; var enemies; var enemySpawnInterval; var enemySpawnCounter; var startButton; var coinManager; var mushroomManager; var scoreText; var coinCounter; var coinCount = 0; var lives = 3; var backgroundContainer; var middlegroundContainer; var foregroundContainer; var bgClose; var bgClose2; var bgFar; var bgFar2; var platforms; var ground; var ground2; var groundLevel; var groundSpeedBase = 10; var globalSpeed = 1.0; var gamePaused = false; var waterHoleManager; function backgroundUpdate() { if ((!player || !player.isHit) && lives >= 0 && !gamePaused) { bgClose.x -= 4 * globalSpeed; bgClose2.x -= 4 * globalSpeed; bgFar.x -= 2 * globalSpeed; bgFar2.x -= 2 * globalSpeed; if (bgClose.x <= -bgClose.width) { bgClose.x = bgClose2.x + bgClose2.width; } if (bgClose2.x <= -bgClose2.width) { bgClose2.x = bgClose.x + bgClose.width; } if (bgFar.x <= -bgFar.width) { bgFar.x = bgFar2.x + bgFar2.width; } if (bgFar2.x <= -bgFar2.width) { bgFar2.x = bgFar.x + bgFar.width; } ground.x -= groundSpeedBase * globalSpeed; ground2.x -= groundSpeedBase * globalSpeed; if (ground.x <= -ground.width) { ground.x = ground2.x + ground2.width; } if (ground2.x <= -ground2.width) { ground2.x = ground.x + ground.width; } } } function platformsUpdate() { if (player && player.isHit || lives < 0 || gamePaused) { return; } for (var i = platforms.length - 1; i >= 0; i--) { if (platforms[i].destroyed) { platforms.splice(i, 1); } } if (platforms.length > 0) { var lastPlatform = platforms[platforms.length - 1]; if (lastPlatform.x < 2048 + 500) { spawnPlatform(); } } } game.update = function () { backgroundUpdate(); platformsUpdate(); if (enemySpawnCounter !== 9999) { enemySpawnCounter++; if (enemySpawnCounter >= enemySpawnInterval) { var enemy; if (enemyPool.length > 0) { enemy = enemyPool.pop(); enemy.visible = true; } else { enemy = new Enemy(); } enemy.x = 2500; var spawnOnPlatform = Math.random() < 0.5 && platforms.length > 0; if (spawnOnPlatform) { var visiblePlatforms = []; for (var p = 0; p < platforms.length; p++) { if (platforms[p].x > 2200 && platforms[p].x < 2700) { visiblePlatforms.push(platforms[p]); } } if (visiblePlatforms.length > 0) { var randomPlatform = visiblePlatforms[Math.floor(Math.random() * visiblePlatforms.length)]; enemy.y = randomPlatform.y - 150; } else { enemy.y = player.y; } } else { enemy.y = player.y; } if (enemyPool.indexOf(enemy) > -1) { enemy.reset(enemy.x, enemy.y); } enemies.push(enemy); if (!enemy.parent) { middlegroundContainer.addChild(enemy); } enemySpawnInterval = Math.floor(Math.random() * 150) + 50; enemySpawnCounter = 0; } } var playerBounds = player.getBounds(); for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (!enemy.visible) { continue; } var enemyBounds = enemy.getBounds(); if (playerBounds.left < enemyBounds.right && playerBounds.right > enemyBounds.left && playerBounds.top < enemyBounds.bottom && playerBounds.bottom > enemyBounds.top) { if (player.isFalling && player.velocityY > 0 && playerBounds.bottom > enemyBounds.top && playerBounds.bottom - player.velocityY < enemyBounds.top) { if (enemy.parent) { enemy.parent.removeChild(enemy); } enemies.splice(j, 1); enemy.visible = false; enemyPool.push(enemy); LK.getSound('enemyStomp').play(); player.velocityY = -15; LK.setScore(LK.getScore() + 5); scoreText.setText(LK.getScore()); } else { if (lives < 0) { return; } player.hitPlayer(); LK.effects.flashScreen(0xff0000, 150); if (lives <= 0) { LK.setTimeout(function () { LK.showGameOver(); }, 4000); } else { if (enemy.parent) { enemy.parent.removeChild(enemy); } enemies.splice(j, 1); enemy.visible = false; enemyPool.push(enemy); } } } else if (player.x > enemy.x && !enemy.passed) { enemy.passed = true; LK.setScore(LK.getScore() + 1); scoreText.setText(LK.getScore()); } } }; game.down = function (x, y, obj) { player.jump(); }; function initializeGame() { backgroundContainer = new Container(); middlegroundContainer = new Container(); foregroundContainer = new Container(); game.addChild(backgroundContainer); game.addChild(middlegroundContainer); game.addChild(foregroundContainer); groundLevel = 2732 / 2 + 450; bgFar = LK.getAsset('bgFar', { anchorX: 0, anchorY: 0 }); bgFar.x = 0; bgFar.y = 0; bgFar.width = 2732; backgroundContainer.addChild(bgFar); bgFar2 = LK.getAsset('bgFar', { anchorX: 0, anchorY: 0 }); bgFar2.x = bgFar.width; bgFar2.y = 0; bgFar2.width = 2732; backgroundContainer.addChild(bgFar2); bgClose = LK.getAsset('bgClose', { anchorX: 0, anchorY: 0 }); bgClose.x = 0; bgClose.y = 0; bgClose.width = 2732; backgroundContainer.addChild(bgClose); bgClose2 = LK.getAsset('bgClose', { anchorX: 0, anchorY: 0 }); bgClose2.x = bgClose.width; bgClose2.y = 0; bgClose2.width = 2732; backgroundContainer.addChild(bgClose2); ground = LK.getAsset('ground', { anchorX: 0, anchorY: 0 }); ground.x = 0; ground.y = groundLevel; ground.width = 2048; middlegroundContainer.addChild(ground); ground2 = LK.getAsset('ground', { anchorX: 0, anchorY: 0 }); ground2.x = ground.width; ground2.y = groundLevel; ground2.width = 2048; middlegroundContainer.addChild(ground2); player = new Player(); player.x = 2048 / 6; player.y = groundLevel - 100; foregroundContainer.addChild(player); enemies = []; enemyPool = []; enemySpawnInterval = 100; enemySpawnCounter = 9999; startButton = new StartButton(); startButton.x = 2048 / 2; startButton.y = 2732 / 2; startButton.scale = { x: 0, y: 0 }; foregroundContainer.addChild(startButton); startButton.animate(); startButton.visible = true; player.canJump = false; lives = 3; coinManager = new CoinManager(); middlegroundContainer.addChild(coinManager); mushroomManager = new MushroomManager(); middlegroundContainer.addChild(mushroomManager); platforms = []; level1Height = groundLevel - 450; level2Height = level1Height - 450; for (var i = 0; i < 2; i++) { var platform = new Platform(); if (i === 0) { platform.x = player.x + 800; platform.y = level1Height; } else { platform.x = platforms[i - 1].x + 1200; platform.y = level2Height; } platforms.push(platform); middlegroundContainer.addChild(platform); } scoreText = new Text2('0', { size: 100, fill: 0xFFFFFF }); LK.gui.top.addChild(scoreText); scoreText.x = 2048 / 2; scoreText.y = 0; coinCounter = new CoinCounter(); coinCounter.x = -300; coinCounter.y = 30; LK.gui.topRight.addChild(coinCounter); livesCounter = new LivesCounter(); livesCounter.x = 250; livesCounter.y = 80; LK.gui.topLeft.addChild(livesCounter); livesCounter.updateLives(lives); waterHoleManager = new WaterHoleManager(); middlegroundContainer.addChild(waterHoleManager); LK.playMusic('bgMusic'); } var platformPool = []; var enemyPool = []; function spawnPlatform() { var platform; if (platformPool.length > 0) { platform = platformPool.pop(); platform.visible = true; } else { platform = new Platform(); } var lastPlatform = platforms[platforms.length - 1]; var lastHeight = lastPlatform.y; if (lastHeight === level1Height) { platform.y = level2Height; platform.x = lastPlatform.x + 1200; } else { platform.y = level1Height; platform.x = lastPlatform.x + 1500; } if (Math.random() < 0.2) { lastPlatform.x += 500; if (platform.parent) { platform.parent.removeChild(platform); } platformPool.push(platform); return; } platforms.push(platform); middlegroundContainer.addChild(platform); } initializeGame();
===================================================================
--- original.js
+++ change.js
@@ -741,9 +741,9 @@
}
}
};
self.jump = function () {
- if (!self.isJumping) {
+ if (!self.isJumping && !self.isDrownAnimPlaying) {
self.isJumping = true;
self.velocityY = -self.jumpHeight * 1.5;
self.jumpFrame.alpha = 1;
LK.getSound('jump').play();