User prompt
Create boxes at half the probability as are created now
User prompt
Lanterns (bubbles) should be spawned at a 10% from the bottom of the screen
User prompt
Box1 is causing many issues - it's rendering some times loooots of harpoons. That can't never happen, if a box1 gets active destroy the harpoons created by the currently active box1
User prompt
Boxes that destroy bubbles will prevent those bubbles from creating boxes
User prompt
Mark harpoons generated with boxes - those harpoons will never create boxes by triggering a bubble.
User prompt
Make sure that the popped ballons with the boxes power (the bomb - destruction, the multi harpoon, etc) - they don't produce any box. Boxes can only be produced if I manually pop the balloons with my harpoon.
User prompt
There is an issue: the effects of the boxes seem accumulative? Every time I pick a box it has the effect of the previous boxes otr something like that? Please fix it: one box one effect.
User prompt
When the player collisions / intersects any of the reward boxes (box, box1, box2, box3) they should be picked up and applied.
User prompt
Make the harpoon has less speed. Don't change antyhing else.
Code edit (4 edits merged)
Please save this source code
User prompt
Make the harpoon have a bigger vertical reach
Code edit (3 edits merged)
Please save this source code
User prompt
The death effect, now tints to red. Please make it so that it tints sequentially using rainbow colors
Code edit (1 edits merged)
Please save this source code
User prompt
When the player ends, be creative and create something during 2-3 seconds to let knwo the playe rhas died. And then the game over, as usual.
Code edit (1 edits merged)
Please save this source code
User prompt
The bubbles / lamps don't get destroyed by colliding with the player.
User prompt
Make the harpoon and trail go much quicker up ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Please don't hurt / harm / remove life from the player with collisions between bubbles and the player. Remove that. The player only looses life when the lamps go out of the screen from the top of the screen.
User prompt
Ok. Now the lanterns can NOT really harm / hit the player. Instead, they will hit the player if they have not been destroyed when they go out of the screen from the top
User prompt
My bubbles - they go from top to bottom, as they fall. But they are really lanterns, so they should fly from the bottom to the top, the other way around. PLease make the fix
Code edit (1 edits merged)
Please save this source code
Initial prompt
Lantern Splash
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Box class var Box = Container.expand(function () { var self = Container.call(this); var boxGraphics = self.attachAsset('box', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, // Increase the scale to enlarge the bounding box scaleY: 1.2 }); self.speed = 5; self.lastIntersecting = false; // Track last intersection state with player self.update = function () { self.y += self.speed; // Check for player intersection transitions var currentIntersecting = self.intersects(player); if (!self.lastIntersecting && currentIntersecting) { // Flash the box briefly to indicate collection is possible tween(boxGraphics, { tint: 0xFFFF00, scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(boxGraphics, { tint: 0xFFFFFF, scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeIn }); } }); } self.lastIntersecting = currentIntersecting; if (self.y > 2732) { self.destroy(); } }; }); // Box1 class var Box1 = Container.expand(function () { var self = Container.call(this); var boxGraphics = self.attachAsset('box1', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, // Increase the scale to enlarge the bounding box scaleY: 1.2 }); self.speed = 5; self.lastIntersecting = false; // Track last intersection state with player self.update = function () { self.y += self.speed; // Check for player intersection transitions var currentIntersecting = self.intersects(player); if (!self.lastIntersecting && currentIntersecting) { // Flash the box briefly to indicate collection is possible tween(boxGraphics, { tint: 0xFF00FF, scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(boxGraphics, { tint: 0xFFFFFF, scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeIn }); } }); } self.lastIntersecting = currentIntersecting; if (self.y > 2732) { self.destroy(); } }; }); // Box2 class var Box2 = Container.expand(function () { var self = Container.call(this); var boxGraphics = self.attachAsset('box2', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, // Increase the scale to enlarge the bounding box scaleY: 1.2 }); self.speed = 7; self.lastIntersecting = false; // Track last intersection state with player self.update = function () { self.y += self.speed; // Check for player intersection transitions var currentIntersecting = self.intersects(player); if (!self.lastIntersecting && currentIntersecting) { // Flash the box briefly to indicate collection is possible tween(boxGraphics, { tint: 0x00FFFF, scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(boxGraphics, { tint: 0xFFFFFF, scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeIn }); } }); } self.lastIntersecting = currentIntersecting; if (self.y > 2732) { self.destroy(); } }; }); // Box3 class var Box3 = Container.expand(function () { var self = Container.call(this); var boxGraphics = self.attachAsset('box3', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, // Increase the scale to enlarge the bounding box scaleY: 1.2 }); self.speed = 9; self.lastIntersecting = false; // Track last intersection state with player self.update = function () { self.y += self.speed; // Check for player intersection transitions var currentIntersecting = self.intersects(player); if (!self.lastIntersecting && currentIntersecting) { // Flash the box briefly to indicate collection is possible with heart color tween(boxGraphics, { tint: 0xFF0000, scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(boxGraphics, { tint: 0xFFFFFF, scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeIn }); } }); } self.lastIntersecting = currentIntersecting; if (self.y > 2732) { self.destroy(); } }; }); // The assets will be automatically created and loaded by the LK engine. // Bubble class var Bubble = Container.expand(function () { var self = Container.call(this); var bubbleGraphics = self.attachAsset('bubble', { anchorX: 0.5, anchorY: 0.5, alpha: 0 // Start transparent }); // Make the bubble opaque after 1 second tween(bubbleGraphics, { alpha: 1 }, { duration: 1000 }); self.speed = -10; // Negative speed to move upward self.lastY = undefined; // Track last position for intersection checks self.hasHitTop = false; // Flag to track if lantern has gone off screen at top self.update = function () { if (self.lastY === undefined) { self.lastY = self.y; } self.y += self.speed; if (self.y < 1200) { // Start tinting when approaching the top tween(self, { tint: 0xFF0000 }, { duration: 500, easing: tween.linear }); } // Check if the lantern is going off the top of the screen without being destroyed if (self.lastY >= 0 && self.y < 0 && !self.hasHitTop) { self.hasHitTop = true; // Mark as hit top to prevent multiple life deductions // Player didn't destroy the lantern in time lives -= 1; // Create explosion effect at the top where the lantern left var explosion = new Explosion(); explosion.x = self.x; explosion.y = 10; // Just at the edge of the screen game.addChild(explosion); // Play explosion sound LK.getSound('explosion').play(); // Remove a heart icon when a life is lost if (hearts.length > lives) { var heartToRemove = hearts.pop(); if (heartToRemove) { tween(heartToRemove.scale, { x: 0, y: 0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { heartToRemove.destroy(); } }); } } if (lives < 0) { // Handle player death with dramatic effect handlePlayerDeath(); return; } self.destroy(); } // Handle going completely off screen // Note: Not removing the lantern when it intersects with player // as per the requirement that player collision shouldn't remove lives if (self.y < -200) { self.destroy(); } self.lastY = self.y; }; }); // Explosion class with color customization var Explosion = Container.expand(function () { var self = Container.call(this); var explosionGraphics = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5 }); // Extend self with tint property accessor/mutator to allow tinting the explosion Object.defineProperty(self, 'tint', { get: function get() { return explosionGraphics.tint; }, set: function set(value) { explosionGraphics.tint = value; } }); // Apply explosion animation tween(explosionGraphics, { scaleX: explosionGraphics.scaleX + 1, scaleY: explosionGraphics.scaleY + 1 }, { duration: 1000, easing: tween.bounceOut, onFinish: function onFinish() { self.destroy(); } }); self.update = function () { // The explosion will disappear after a while if (self.alpha > 0) { self.alpha -= 0.005; } else { self.destroy(); } }; }); // Harpoon class var Harpoon = Container.expand(function () { var self = Container.call(this); var harpoonGraphics = self.attachAsset('harpoon', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -30; // Reduced speed for slower movement self.originalSpeed = -30; self.maxDistance = 2732 * 0.85; // Increased maximum distance - 85% of screen height self.startY = 0; // Will store the starting Y position self.trail = game.addChild(new Trail()); // Apply a quick acceleration tween to give a nice launch effect tween(self, { speed: self.speed * 1.5 // Accelerate to 1.5x the slower speed }, { duration: 200, easing: tween.easeOut }); self.update = function () { // Store initial position on first update if (self.startY === 0) { self.startY = self.y; } self.y += self.speed; self.trail.height = self.startY - self.y; self.trail.y = self.y + self.trail.height / 2; // Destroy when reaching max distance or going off-screen if (self.y < 0 || self.startY - self.y > self.maxDistance) { self.destroy(); self.trail.destroy(); } }; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; self.update = function () { if (self.direction && self.direction === 'left') { self.x -= self.speed; } else if (self.direction === 'right') { self.x += self.speed; } }; self.shoot = function () { var harpoon = new Harpoon(); harpoon.x = player.x; harpoon.y = player.y - 200; harpoon.trail.x = player.x; harpoon.trail.y = player.y - 200; // Create a more dramatic scale effect for shooting with extended range harpoon.scale.x = 0.7; harpoon.scale.y = 1.3; // Flag normal harpoons (from player) to allow them to create boxes harpoon.isPlayerCreated = true; // Apply a tween to normalize the scale while launching, with longer stretch for better visual feedback tween(harpoon.scale, { x: 1, y: 1 }, { duration: 250, easing: tween.easeOut }); // Add a slight acceleration boost via a separate tween for the trail tween(harpoon.trail, { scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); game.addChild(harpoon); LK.getSound('crossbow').play(); }; }); // PlayerDeathEffect class - creates a dramatic death sequence with rainbow colors var PlayerDeathEffect = Container.expand(function () { var self = Container.call(this); // Create the main container for all death effect elements var effectContainer = new Container(); self.addChild(effectContainer); // Rainbow colors array (red, orange, yellow, green, blue, indigo, violet) var rainbowColors = [ // Indigo 0x9400D3, // Violet 0xfaadad, // Red 0xFF7F00, // Orange 0xFFFF00, // Yellow 0x00FF00, // Green 0x0000FF, // Blue 0x4B0082]; // Add a full-screen overlay for dramatic effect var overlay = LK.getAsset('deadBg', { anchorX: 0, anchorY: 0, scaleX: 20.48, // Full width (2048px) scaleY: 27.32, // Full height (2732px) tint: rainbowColors[0], // Start with red alpha: 0 }); effectContainer.addChild(overlay); // Add dramatic text var gameOverText = new Text2('GAME OVER', { size: 150, fill: 0xFFFFFF, font: "'Comic Sans MS', cursive, sans-serif" }); gameOverText.anchor.set(0.5, 0.5); gameOverText.x = 2048 / 2; gameOverText.y = 2732 / 2; gameOverText.alpha = 0; gameOverText.scale.set(0.1); effectContainer.addChild(gameOverText); // Function to create a rainbow tint sequence function createRainbowTintSequence(target, startIndex, duration) { var colorIndex = startIndex % rainbowColors.length; var nextColorIndex = (colorIndex + 1) % rainbowColors.length; tween(target, { tint: rainbowColors[nextColorIndex] }, { duration: duration, easing: tween.linear, onFinish: function onFinish() { createRainbowTintSequence(target, nextColorIndex, duration); } }); } // Add rainbow flickering effect self.startEffect = function () { // Pulse the overlay with rainbow colors tween(overlay, { alpha: 0.5 }, { duration: 400, easing: tween.easeIn, onFinish: function onFinish() { // Start the rainbow color sequence createRainbowTintSequence(overlay, 0, 300); } }); // Show and scale the text tween(gameOverText, { alpha: 1, scaleX: 1.5, scaleY: 1.5 }, { duration: 1000, easing: tween.elasticOut }); // Create explosion effects at random positions with rainbow colors for (var i = 0; i < 5; i++) { LK.setTimeout(function (colorIndex) { var explosion = new Explosion(); explosion.x = Math.random() * 2048; explosion.y = Math.random() * 2732; // Give each explosion a different color from the rainbow explosion.tint = rainbowColors[colorIndex % rainbowColors.length]; effectContainer.addChild(explosion); // Play explosion sound LK.getSound('explosion').play(); }.bind(null, i), 300 * i); } // Show actual game over screen after the effect LK.setTimeout(function () { self.destroy(); LK.showGameOver(); }, 2500); // Show game over after 2.5 seconds }; return self; }); // PowerUpText class var PowerUpText = Container.expand(function () { var self = Container.call(this); var textGraphics = self.attachAsset('PowerUpText', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.y -= 2; if (self.y < 0) { self.destroy(); } }; }); // Trail class var Trail = Container.expand(function () { var self = Container.call(this); var trailGraphics = self.attachAsset('line', { anchorX: 0.5, anchorY: 0.5, width: 18, alpha: 0.9, // Slightly transparent to enhance visual effect with faster movement scaleY: 1.5 // Scale the trail to support longer reach }); // The trail doesn't need its own update movement since it's positioned relative to the harpoon self.update = function () { // Trail no longer moves independently // Its position is now fully controlled by the Harpoon if (self.y > 2732) { self.destroy(); } }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xFFFFFFFF // Init game with black background }); /**** * Game Code ****/ var background = game.attachAsset('Landscape', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.setChildIndex(background, 0); // Add a warning zone at the top to indicate the danger area var warningZone = new Container(); var warningGraphics = LK.getAsset('scoreBg', { anchorX: 0, anchorY: 0, scaleX: 20.48, // Make it span the entire width (2048px) scaleY: 1.5, tint: 0xFF3333, // Red tint to indicate danger alpha: 0.3 // Semi-transparent }); warningZone.addChild(warningGraphics); warningZone.x = 0; warningZone.y = 0; game.addChild(warningZone); var player = new Player(); player.x = 2048 / 2; player.y = 2732 - 180; game.addChild(player); // Add player after trail to ensure correct rendering order // Add a description text for the warning zone var warningText = new Text2('Lanterns escaping at the top will cost a life!', { size: 30, fill: 0xFFFFFF, font: "'Comic Sans MS', cursive, sans-serif" }); warningText.anchor.set(0.5, 0); warningText.x = 2048 / 2; warningText.y = 130; game.addChild(warningText); // Make the warning text pulse to draw attention var _pulseWarning = function pulseWarning() { tween(warningText.scale, { x: 1.2, y: 1.2 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(warningText.scale, { x: 1.0, y: 1.0 }, { duration: 800, easing: tween.easeInOut, onFinish: _pulseWarning }); } }); }; _pulseWarning(); game.move = function (x, y, obj) { player.x = x; if (x < 2048 / 2 && player.scaleX > 0 || x >= 2048 / 2 && player.scaleX < 0) { player.scaleX *= -1; // Mirror the player image } }; var score = 0; var lives = 3; var scoreBackground = new Container(); var scoreBgGraphics = scoreBackground.attachAsset('scoreBg', { anchorX: 0.5, anchorY: 0.1, scaleX: 5, scaleY: 5, alpha: 1 }); scoreBackground.addChild(scoreBgGraphics); scoreBackground.x = 0; scoreBackground.y = 0; LK.gui.top.addChild(scoreBackground); var scoreTxt = new Text2('Lanterns destroyed: 0', { size: 30, fill: 0xFF3659, font: "'Comic Sans MS', cursive, sans-serif" }); scoreTxt.anchor.set(0.5, -0.1); scoreBackground.addChild(scoreTxt); var hearts = []; for (var i = 0; i < lives; i++) { var heart = LK.getAsset('heart', { anchorX: 0.5, anchorY: 0.5, x: -1 * (i + 1) * 50, // Position hearts with some spacing y: 50 }); LK.gui.topRight.addChild(heart); hearts.push(heart); } // Function to apply box effects based on box type function applyBoxEffect(box) { // Check if the collected box is an instance of Box1 if (box instanceof Box1) { // Create six additional harpoons and trails for (var i = 1; i <= 3; i++) { var leftHarpoon = new Harpoon(); leftHarpoon.x = player.x - i * 150; leftHarpoon.y = player.y; leftHarpoon.trail.x = player.x - i * 150; leftHarpoon.trail.y = player.y; // Mark harpoons created by box power-up leftHarpoon.isPlayerCreated = false; game.addChild(leftHarpoon); var rightHarpoon = new Harpoon(); rightHarpoon.x = player.x + i * 150; rightHarpoon.y = player.y; rightHarpoon.trail.x = player.x + i * 150; rightHarpoon.trail.y = player.y; // Mark harpoons created by box power-up rightHarpoon.isPlayerCreated = false; game.addChild(rightHarpoon); // Set a timeout to remove the additional harpoons after 5 seconds LK.setTimeout(function (lh, rh) { lh.destroy(); lh.trail.destroy(); rh.destroy(); rh.trail.destroy(); }.bind(null, leftHarpoon, rightHarpoon), 5000); } } // Check if the collected box is an instance of Box and reduce bubble speed if (box instanceof Box) { var bubbles = game.children.filter(function (child) { return child instanceof Bubble; }); bubbles.forEach(function (bubble) { bubble.speed /= 2; }); LK.setTimeout(function () { bubbles.forEach(function (bubble) { bubble.speed *= 2; }); }, 5000); } // Check if the collected box is an instance of Box3 and lives are less than 3 if (box instanceof Box3 && lives < 3) { lives += 1; var heart = LK.getAsset('heart', { anchorX: 0.5, anchorY: 0.5, x: -1 * lives * 50, y: 50 }); LK.gui.topRight.addChild(heart); hearts.push(heart); } // Check if the collected box is an instance of Box2 if (box instanceof Box2) { var bubbles = game.children.filter(function (child) { return child instanceof Bubble; }); var bubblesDestroyed = bubbles.length; bubbles.forEach(function (bubble) { bubble.destroy(); }); score += bubblesDestroyed; scoreTxt.setText("Lanterns destroyed: " + score.toString()); tween(scoreTxt.scale, { x: 2, y: 2 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(scoreTxt.scale, { x: 1, y: 1 }, { duration: 500, easing: tween.easeInOut }); } }); } // Create toast message based on box type showToastForBox(box); } // Function to show toast message for box effects function showToastForBox(box) { var toastText = new Text2('', { size: 250, fill: 0xFFC0CB, font: "'Comic Sans MS', cursive, sans-serif" }); var toastTextBg = new Text2('', { size: 255, fill: 0xFF00AA, font: "'Comic Sans MS', cursive, sans-serif" }); toastText.anchor.set(0.5, 0.5); toastText.x = 2048 / 2; toastText.y = 2732 / 2; toastTextBg.anchor.set(0.5, 0.5); toastTextBg.x = 2048 / 2; toastTextBg.y = 2732 / 2; game.addChild(toastText); game.addChild(toastTextBg); if (box instanceof Box1) { toastText.setText("Smash!"); toastTextBg.setText("Smash!"); } else if (box instanceof Box2) { toastText.setText("Destruction!"); toastTextBg.setText("Destruction!"); } else if (box instanceof Box) { toastText.setText("Less madness!"); toastTextBg.setText("Less madness!"); } else if (box instanceof Box3) { toastText.setText("Life up!"); toastTextBg.setText("Life up!"); } // Tween the toast text to fade out and destroy after 2 seconds tween(toastText, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { toastText.destroy(); } }); tween(toastTextBg, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { toastTextBg.destroy(); } }); } // Function to handle player death sequence with rainbow colors function handlePlayerDeath() { // Rainbow colors array var rainbowColors = [0xFF0000, // Red 0xFF7F00, // Orange 0xFFFF00, // Yellow 0x00FF00, // Green 0x0000FF, // Blue 0x4B0082, // Indigo 0x9400D3 // Violet ]; // Create dramatic death effect var deathEffect = new PlayerDeathEffect(); game.addChild(deathEffect); deathEffect.startEffect(); // Mark game as over to stop spawning bubbles game.isGameOver = true; // Create a function for sequential rainbow color animation function playerRainbowSequence(colorIndex) { if (colorIndex >= rainbowColors.length) { // One full cycle completed, start fading out tween(player, { alpha: 0, tint: 0xFFFFFF }, { duration: 500, easing: tween.easeOut }); return; } tween(player, { alpha: 0.3, tint: rainbowColors[colorIndex] }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { playerRainbowSequence(colorIndex + 1); } }); } // Start the rainbow sequence playerRainbowSequence(0); } var lastShot = -999; game.down = function (x, y, obj) { if (LK.ticks - lastShot > 30) { player.shoot(); lastShot = LK.ticks; } }; // Start the music 'chinese' upon starting the game LK.playMusic('chinese'); game.update = function () { // Initialize game.isGameOver if it doesn't exist if (game.isGameOver === undefined) { game.isGameOver = false; } // Only spawn new bubbles if game isn't over if (!game.isGameOver && LK.ticks % 50 == 0) { var newBubble = new Bubble(); newBubble.x = Math.random() * 2048; newBubble.y = 2732; // Start from bottom of screen game.addChild(newBubble); var randomTween = { delta: Math.random() * (300 - 100) + 100, // Random delta between 100 and 300 duration: Math.random() * (1500 - 800) + 800, // Random duration between 800 and 1500 easing: [tween.easeIn, tween.easeOut, tween.elasticIn, tween.elasticOut, tween.bounceIn, tween.bounceOut, tween.easeInOut, tween.bounceInOut, tween.elasticInOut][Math.floor(Math.random() * 9)] // Random easing }; tween(newBubble, { x: Math.max(0, Math.min(2048, newBubble.x + randomTween.delta)) }, { duration: randomTween.duration, easing: randomTween.easing, onFinish: function onFinish() { tween(newBubble, { x: Math.max(0, Math.min(2048, newBubble.x - randomTween.delta)) }, { duration: randomTween.duration, easing: randomTween.easing }); } }); } var bubbles = game.children.filter(function (child) { return child instanceof Bubble; }); var harpoons = game.children.filter(function (child) { return child instanceof Harpoon; }); for (var i = 0; i < bubbles.length; i++) { var bubble = bubbles[i]; // Check for player intersection but don't damage the player // We allow lanterns to pass through the player harmlessly if (bubble.intersects(player)) { // Don't destroy the bubble or harm the player // This allows the bubble to continue moving up // It will only damage the player if it exits off the top without being destroyed } for (var j = 0; j < harpoons.length; j++) { var harpoon = harpoons[j]; // Enhanced collision detection for longer harpoon reach if (bubble.intersects(harpoon) || Math.abs(bubble.x - harpoon.x) < 50 && Math.abs(bubble.y - harpoon.trail.y - harpoon.trail.height / 4) < harpoon.trail.height / 2) { bubble.destroy(); LK.getSound('explosion').play(); harpoon.trail.destroy(); // Destroy the harpoon trail harpoon.destroy(); bubbles.splice(i, 1); // Remove bubble from the array score += 1; scoreTxt.setText("Lanterns destroyed: " + score.toString()); tween(scoreTxt.scale, { x: 2, y: 2 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(scoreTxt.scale, { x: 1, y: 1 }, { duration: 500, easing: tween.easeInOut }); } }); harpoons.splice(j, 1); // Remove harpoon from the array // Create an explosion at the intersection point var explosion = new Explosion(); explosion.x = bubble.x; explosion.y = bubble.y; game.addChild(explosion); // Create a box at the intersection point with a 10% probability // Only spawn boxes when balloons are popped by player harpoons, not by explosion effects if (!game.children.some(function (child) { return child instanceof Box || child instanceof Box1 || child instanceof Box2 || child instanceof Box3; })) { // Only create boxes when bubble is popped by a player-created harpoon, not by power-up harpoons if (Math.random() < 1 && harpoon instanceof Harpoon && harpoon.isPlayerCreated === true) { var boxType = Math.floor(Math.random() * 4); var box; switch (boxType) { case 0: box = new Box(); break; case 1: box = new Box1(); break; case 2: box = new Box2(); break; case 3: box = new Box3(); break; } box.x = bubble.x; box.y = bubble.y; game.addChild(box); } } } } var boxes = game.children.filter(function (child) { return child instanceof Box || child instanceof Box1 || child instanceof Box2 || child instanceof Box3; }); for (var k = 0; k < boxes.length; k++) { var box = boxes[k]; // Check if player collects/intersects the box if (box.intersects(player)) { // Create collection animation tween(box.scale, { x: 0, y: 0 }, { duration: 300, easing: tween.easeInOut, onFinish: function (boxToDestroy) { boxToDestroy.destroy(); }.bind(null, box) }); // Play pickup sound LK.getSound('powerup').play(); // Apply the power-up effect based on box type using centralized handler applyBoxEffect(box); // Remove box from tracking array boxes.splice(k, 1); // Break out of the loop since we've handled the box break; } // Check for harpoon intersecting with boxes for (var l = 0; l < harpoons.length; l++) { var harpoon = harpoons[l]; if (box.intersects(harpoon)) { // Store reference to box before destroying it var boxToApplyEffect = box; // Destroy elements box.destroy(); LK.getSound('powerup').play(); harpoon.trail.destroy(); harpoon.destroy(); // Apply the power-up effect based on box type using centralized handler applyBoxEffect(boxToApplyEffect); // Remove from arrays boxes.splice(k, 1); harpoons.splice(l, 1); break; } } } } };
===================================================================
--- original.js
+++ change.js
@@ -347,8 +347,10 @@
harpoon.trail.y = player.y - 200;
// Create a more dramatic scale effect for shooting with extended range
harpoon.scale.x = 0.7;
harpoon.scale.y = 1.3;
+ // Flag normal harpoons (from player) to allow them to create boxes
+ harpoon.isPlayerCreated = true;
// Apply a tween to normalize the scale while launching, with longer stretch for better visual feedback
tween(harpoon.scale, {
x: 1,
y: 1
@@ -623,14 +625,18 @@
leftHarpoon.x = player.x - i * 150;
leftHarpoon.y = player.y;
leftHarpoon.trail.x = player.x - i * 150;
leftHarpoon.trail.y = player.y;
+ // Mark harpoons created by box power-up
+ leftHarpoon.isPlayerCreated = false;
game.addChild(leftHarpoon);
var rightHarpoon = new Harpoon();
rightHarpoon.x = player.x + i * 150;
rightHarpoon.y = player.y;
rightHarpoon.trail.x = player.x + i * 150;
rightHarpoon.trail.y = player.y;
+ // Mark harpoons created by box power-up
+ rightHarpoon.isPlayerCreated = false;
game.addChild(rightHarpoon);
// Set a timeout to remove the additional harpoons after 5 seconds
LK.setTimeout(function (lh, rh) {
lh.destroy();
@@ -892,10 +898,10 @@
// Only spawn boxes when balloons are popped by player harpoons, not by explosion effects
if (!game.children.some(function (child) {
return child instanceof Box || child instanceof Box1 || child instanceof Box2 || child instanceof Box3;
})) {
- // Check if the bubble was destroyed by a harpoon (not by an explosion or other means)
- if (Math.random() < 1 && harpoon instanceof Harpoon) {
+ // Only create boxes when bubble is popped by a player-created harpoon, not by power-up harpoons
+ if (Math.random() < 1 && harpoon instanceof Harpoon && harpoon.isPlayerCreated === true) {
var boxType = Math.floor(Math.random() * 4);
var box;
switch (boxType) {
case 0:
a green cross, icon, pixel style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a sand clock pixel style.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a bomb, pixel style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a pixel harpoon, vertical and looking up, retro like in pang games.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A banner to show a message, pixel art. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
two harpoons looking up, retro, pixel. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A chinese flying paper lantern, retro pixel style. In-Game asset. 2d. High contrast. No shadows
fireworks, retro pixel style, colorful. In-Game asset. 2d. High contrast. No shadows
A chinese pixel background of an arcade game, sunset, retro style,. In-Game asset. 2d. High contrast. No shadows