User prompt
For some reasons, sometimes the dragon can't shoot bubbles for quite a long time. Can you please fix that and only that?
User prompt
Remove all .context(...). They don't exist at all!
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'context')' in or related to this line: 'tween(enemy, {' Line Number: 583
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'context')' in or related to this line: 'tween(enemy, {' Line Number: 580
User prompt
Fix these issues: 1. Some enemies don't move. 2. Some platforms seem ephimerous - the dragon player don't stop on them when falling, it crosses them. 3. Sometimes the dragon stops throwing bubbles. Maybe there is something wrong with skipping frames or something like that? Make sure to change only what's necessary.
User prompt
I have several performance issues in the game when jumping with the dragon, possibly due to the tweens and other stuff. Please fix performance issues, simplify, make it lighter to run. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: floors is not defined' in or related to this line: 'for (var i = 0; i < floors.length; i++) {' Line Number: 50
Code edit (12 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught ReferenceError: bubbles is not defined' in or related to this line: 'bubbles.push(bubble);' Line Number: 103
User prompt
Please fix the bug: 'Uncaught ReferenceError: bubbles is not defined' in or related to this line: 'bubbles.push(bubble);' Line Number: 103
Code edit (1 edits merged)
Please save this source code
User prompt
Modify the game.down = function () { console.log("click") to only trigger if clicking on start
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Class for Bubbles - optimized for performance var Bubble = Container.expand(function () { var self = Container.call(this); var bubbleGraphics = self.attachAsset('bubble', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -5; self.lastX = 0; self.lastY = 0; self.update = function () { // Store last position self.lastX = self.x; self.lastY = self.y; // Move bubble self.x += self.speed; // Check for intersection with any floor var intersectingFloor = null; for (var i = 0; i < floors.length; i++) { if (self.intersects(floors[i])) { intersectingFloor = floors[i]; break; } } // Handle collision with floor if (intersectingFloor) { // Create a PoppedBubble at the bubble's position var pop = game.addChild(new PoppedBubble()); pop.x = self.x; pop.y = self.y; // Remove from bubbles array before destroying var bubbleIndex = bubbles.indexOf(self); if (bubbleIndex !== -1) { bubbles.splice(bubbleIndex, 1); } // Destroy the bubble self.destroy(); // Destroy the PoppedBubble after 0.5 seconds LK.setTimeout(function () { pop.destroy(); }, 500); } }; }); var CapturingBubble = Container.expand(function () { var self = Container.call(this); var bubbleGraphics = self.attachAsset('bubble', { anchorX: 0.5, anchorY: 0.5 }); self.alpha = 0.5; self.scaleX = 2; self.scaleY = 2; self.update = function () {}; }); //<Assets used in the game will automatically appear here> // Class for the Dragon character - optimized for performance var Dragon = Container.expand(function () { var self = Container.call(this); self.dragonGraphics = self.attachAsset('dragon', { anchorX: 0.5, anchorY: 0.5 }); self.isIntersectingBubble = false; self.lastWasIntersecting = false; self.lastX = 0; self.lastY = 0; self.shootBubble = function () { // Create new bubble and ensure it's properly initialized var bubble = new Bubble(); bubble.x = self.x + 200 * self.scale.x; bubble.y = self.y - 5; bubble.lastX = bubble.x; bubble.lastY = bubble.y; // If the dragon is looking right, the bubble should move to the right if (self.scale.x == 1) { bubble.speed = 25; } else { // If the dragon is looking left, the bubble should move to the left bubble.speed = -25; } // Add bubble to game display list game.addChild(bubble); // Make sure the bubble gets tracked in our global array // Use this pattern to ensure we don't lose track of bubbles if (bubbles) { bubbles.push(bubble); } // Play bubble sound when a bubble is shot LK.getSound('bubble').play(); }; }); // Class for Pop - optimized version var PoppedBubble = Container.expand(function () { var self = Container.call(this); var popGraphics = self.attachAsset('poppedBubble', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x09899d }); /**** * Game Code ****/ function tweenDragonContainer() { tween(dragonOnContainer, { y: dragonOnContainer.y + 300 }, { duration: 1000, onFinish: function onFinish() { tween(dragonOnContainer, { y: dragonOnContainer.y - 300 }, { duration: 1000 }); } }); } var started = false; // Initialize started flag var intervalId = LK.setInterval(function () { if (!started) { tweenDragonContainer(); } else { LK.clearInterval(intervalId); // Clear interval if started is true } }, 4000); var controlPanel = new Container(); var panelBackground = LK.getAsset('game_background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0.8 }); controlPanel.addChild(panelBackground); var instructionsText = new Text2('INSTRUCTIONS', { size: 100, fill: 0xffffff, align: "center", font: "Comic Sans MS", fontWeight: "bold" }); instructionsText.anchor.set(0.5, 0.5); instructionsText.x = 2048 / 2; instructionsText.y = 75; controlPanel.addChild(instructionsText); // Rainbow color array var rainbowColors = [0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x8B00FF]; var colorIndex = 0; // Function to cycle through rainbow colors function cycleRainbowColors() { instructionsText.tint = rainbowColors[colorIndex]; colorIndex = (colorIndex + 1) % rainbowColors.length; } // Set interval to change color less frequently to improve performance LK.setInterval(cycleRainbowColors, 1000); var controlText = new Text2('- Click on 🐲 to shoot 🫧\n- Click above the 🐲 to jump ⬆️.\n- The higher you click, the bigger the jump ⬆️⬆️!', { size: 85, // Increased size for better visibility fill: 0x000000, align: "center", font: "Comic Sans MS" // Adding a cool font and bold style }); controlText.anchor.set(0.5, 0.5); controlText.x = 2048 / 2; controlText.y = 400; controlPanel.addChild(controlText); var understoodButtonBackgroundBg = LK.getAsset('understoodBg', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 800, width: 2000, alpha: 0.5 }); controlPanel.addChild(understoodButtonBackgroundBg); var dragonOnContainer = LK.getAsset('dragon', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 1200, scaleX: 2, scaleY: 2 }); controlPanel.addChild(dragonOnContainer); var bubbleOnContainer = LK.getAsset('bubble', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, alpha: 0.35 }); dragonOnContainer.addChild(bubbleOnContainer); var understoodButton = new Text2('Click anywhere to start', { size: 150, fill: 0x1570e0, align: "center" }); understoodButton.anchor.set(0.5, 0.5); understoodButton.x = 2048 / 2; understoodButton.y = 800; controlPanel.addChild(understoodButton); game.addChild(controlPanel); // Add event listener to the 'Understood' button understoodButton.interactive = true; understoodButton.buttonMode = true; game.down = function (x, y, obj) { controlPanel.destroy(); startGame(); }; // Properly initialize all global variables to prevent undefined errors var bubbles = []; // Initialize bubbles array to store bubble instances var floors = []; // Initialize floors array to store floor instances var behaviours = {}; // Initialize behaviours object var enemies = []; var capturingBubbles = []; var jumpStartY = 0; var dragon; // Will be initialized later var background; // Will be initialized with a background image function startGame() { started = true; var level = 1; function restartGame() { // Clear existing platforms and enemies floors.forEach(function (floor) { floor.destroy(); }); floors = []; enemies.forEach(function (enemy) { enemy.destroy(); }); enemies = []; // Recreate floors at the bottom, left, and right margins for (var i = 0; i < 21; i++) { var floor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: i * 100, y: 2732 - 30 }); game.addChild(floor); floors.push(floor); } for (var j = 0; j < 27; j++) { var leftFloor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 0, y: j * 100 }); game.addChild(leftFloor); floors.push(leftFloor); } for (var k = 0; k < 27; k++) { var rightFloor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 50, y: k * 100 }); game.addChild(rightFloor); floors.push(rightFloor); } // Destroy the existing dragon dragon.destroy(); // Recreate the dragon and add it to the game dragon = game.addChild(new Dragon()); // Reposition dragon at the bottom dragon.x = 1024; // Center horizontally dragon.y = 2532; // Position the dragon on top of the floor // Add new platforms and enemies for the new level for (var j = 0; j < platformYPositions.length; j++) { var platformLength = Math.floor(Math.random() * (maxPlatformLength - minPlatformLength + 1)) + minPlatformLength; var startX = Math.floor(Math.random() * (2048 - platformLength * 100)); var startY = platformYPositions[j]; var randomTint = Math.floor(Math.random() * 16777215); for (var i = 0; i < platformLength; i++) { var newX = startX + i * 100; if (newX > 1900 || newX < 120) { continue; } var platform = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: startX + i * 100, y: platformYPositions[j] }); platform.tint = randomTint; game.addChild(platform); floors.push(platform); } var enemyType = 'enemy' + (i % 5 + 1); var behaviour = behaviours[enemyType] || easingFunctions[Math.floor(Math.random() * easingFunctions.length)]; behaviours[enemyType] = behaviour; var enemy = LK.getAsset(enemyType, { anchorX: 0.5, anchorY: 0.5, x: startX + 100, y: platformYPositions[j] - 100, type: enemyType }); if (enemyType === 'enemy5' || enemyType === 'enemy2') { enemy.tint = Math.floor(Math.random() * 0x7FFFFF) + 0x808080; } enemy.captured = false; game.addChild(enemy); enemies.push(enemy); } } var background = LK.getAsset('pixel_background_' + level.toString(), { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0.95 }); game.addChild(background); // Simplified utility function that replaces all the complex array handlers function getMinMaxFromFloors(floors, property) { var min = Infinity; var max = -Infinity; for (var i = 0; i < floors.length; i++) { var value = floors[i][property]; if (value < min) { min = value; } if (value > max) { max = value; } } return { min: min, max: max }; } var jumpStartTime; // Declare jumpStartTime to track the start of the jump var easingFunctions = [tween.linear, tween.easeIn, tween.easeOut, tween.easeInOut, tween.bounceIn, tween.bounceOut, tween.bounceInOut, tween.elasticIn, tween.elasticOut, tween.elasticInOut, tween.cubicIn, tween.cubicOut, tween.cubitInOut, tween.expoIn, tween.expoOut, tween.expoInOut, tween.sineIn, tween.sineOut, tween.sineInOut]; LK.playMusic('music'); function isStandingOnFloor() { // Store the dragon's position var dragonBottom = dragon.y + dragon.height / 2; for (var i = 0; i < floors.length; i++) { var floor = floors[i]; var floorTop = floor.y - floor.height / 2; // More precise collision detection for standing on platforms if (dragon.intersects(floor) && Math.abs(dragonBottom - floorTop) < 20 && dragon.lastY < dragon.y) { return true; } } return false; } function updateFall() { if (isFalling) { // Store last position before moving var lastY = dragon.y; // Move dragon downwards with a smaller increment to prevent passing through platforms dragon.y += 20; // Check for collisions after moving var isIntersecting = false; for (var i = 0; i < floors.length; i++) { // Check if dragon is intersecting with a floor if (dragon.intersects(floors[i])) { isIntersecting = true; // Only stop falling if we weren't intersecting before (just collided) if (!dragon.lastWasIntersecting || lastY < floors[i].y - floors[i].height) { isJumping = false; // Stop jumping isFalling = false; // Stop falling when colliding with a floor canJump = true; // Allow jumping again when the dragon hits a floor dragon.y = floors[i].y - floors[i].height * 1.5; // Align dragon to the top of the floor break; } } } // Update last known intersection state dragon.lastWasIntersecting = isIntersecting; } } //<Assets used in the game will automatically appear here> // Handle mouse move events to move the dragon game.move = function (x, y, obj) { // Ignore the event if the target is outside the screen or close to its margins if (x > 150 && x < 2048 - 200) { // Set the target x position for the dragon dragon.targetX = x; } }; var isFalling = false; // Initialize isFalling to track dragon's fall state var dragon = game.addChild(new Dragon()); dragon.lastY = dragon.y; // Initialize lastY position dragon.x = 1024; // Center horizontally dragon.y = 2532; // Position the dragon on top of the floor // Handle game updates with improved frame handling game.update = function () { // Move dragon incrementally towards target x with improved movement if (dragon.targetX !== undefined) { var increment = (dragon.targetX - dragon.x) / 5; // Faster movement for better responsiveness if (Math.abs(dragon.targetX - dragon.x) > 1) { dragon.x += increment; } // Update last known position dragon.lastX = dragon.x; dragon.lastY = dragon.y; // Adjust dragon's scale based on targetX position if (dragon.targetX < dragon.x) { dragon.scale.x = -1; } else { dragon.scale.x = 1; } } // Always check floor standing to prevent falling through platforms var standingOnFloor = isStandingOnFloor(); if (!standingOnFloor && !isJumping) { isFalling = true; } // Always update jumping and falling updateJump(); updateFall(); // Update bubbles every frame for consistent collision detection updateBubbles(); // Keep enemy movement at higher frequency to fix enemies not moving if (LK.ticks % 5 === 0) { updateEnemiesMovement(); } }; // Handle touch events for shooting bubbles var lastShot = 0; var lastClick = 0; var isJumping = false; // Add a variable to track if the dragon is jumping var canJump = true; // Initialize canJump flag to allow jumping game.down = function (x, y, obj) { var now = Date.now(); if (y < dragon.y - dragon.height && canJump && !isJumping) { isJumping = true; // Set isJumping to true when the dragon starts jumping // Play jump sound when the dragon starts jumping LK.getSound('jump').play(); jumpStartY = y; // Capture the Y position of the mouse click jumpStartTime = Date.now(); // Initialize jump start time } else if (!isJumping) { if (now - lastClick > 500) { dragon.shootBubble(); lastShot = now; } } lastClick = now; }; function updateEnemiesMovement() { // Process all enemies every frame to ensure consistent movement for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (!enemy) { continue; } if (enemy.captured) { if (enemy.isMoving) { tween.stop(enemy); enemy.isMoving = false; enemy.floating = true; } else if (enemy.floating) { tween(enemy, { y: 100 }, { duration: 5000, easing: tween.linear, onFinish: function onFinish() { if (enemy.children && enemy.children[1]) { enemy.children[1].tint = 0xbf5555; } if (enemies.length === 0) { if (level < 5) { level++; background.destroy(); // Remove the previous background background = LK.getAsset('pixel_background_' + level.toString(), { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 - background.height / 2, alpha: 0.95 }); game.addChild(background); // Add the new background // Combined level text creation to reduce object creation var levelText = new Text2('LEVEL ' + level.toString(), { size: 200, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0.5); levelText.x = 2048 / 2; levelText.y = 2732 / 2; game.addChild(levelText); LK.setTimeout(function () { levelText.destroy(); }, 2000); // Restart game with new platforms and enemies restartGame(); } else { LK.showYouWin(); } } } }); } } else { // Initialize movement if not already moving if (!enemy.isMoving && !enemy.tweenInitialized) { enemy.isMoving = true; enemy.tweenInitialized = true; // Find all platform floors for this enemy var platformFloors = []; var platformY = enemy.y + 100; for (var j = 0; j < floors.length; j++) { if (Math.abs(floors[j].y - platformY) < 10 && floors[j].x > 0 && floors[j].x < 2048 - 50) { platformFloors.push(floors[j]); } } // Only proceed if we found platform floors if (platformFloors.length > 0) { // Find min and max X positions var startX = 2048; var endX = 0; for (var j = 0; j < platformFloors.length; j++) { if (platformFloors[j].x < startX) { startX = platformFloors[j].x; } if (platformFloors[j].x > endX) { endX = platformFloors[j].x; } } // Ensure we have a valid range to move in if (startX < endX) { enemy.alpha = 0.75; // Apply alpha when starting to move // Store the platform range for this enemy enemy.startX = startX; enemy.endX = endX; // Start the movement tween tween(enemy, { x: endX }, { duration: 3000, easing: behaviours[enemy.type] || tween.linear, onFinish: function onFinish() { var thisEnemy = this; thisEnemy.isMovingRight = false; tween(thisEnemy, { x: thisEnemy.startX }, { duration: 3000, easing: tween.linear, onFinish: function onFinish() { var thisEnemy = this; thisEnemy.isMovingRight = true; // Restart movement tween(thisEnemy, { x: thisEnemy.endX }, { duration: 3000, easing: tween.linear, onFinish: arguments.callee }); } }); } }).context(enemy); enemy.isMovingRight = true; } } } // Update enemy direction based on movement if (enemy.x !== enemy.lastX) { enemy.scale.x = enemy.x > enemy.lastX ? 1 : -1; } // Check for collision with dragon if (!enemy.captured && dragon.intersects(enemy)) { // Play game over sound when the dragon dies LK.getSound('gameover').play(); // Rotate the dragon 90 degrees dragon.rotation = -3 * Math.PI * dragon.scale.x; // Animate the dragon falling down - simplified tween tween(dragon, { y: 2732 + dragon.height, tint: 0xFF0000 }, { duration: 500, easing: tween.linear, onFinish: function onFinish() { LK.showGameOver(); } }); } } // Update last known position enemy.lastX = enemy.x; enemy.lastY = enemy.y; } // Always check for collisions with the dragon for all enemies for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (!enemy.captured && dragon.intersects(enemy)) { // Game over handling moved outside the loop to avoid duplicate calls // Just mark for game over if (!game.gameOverTriggered) { game.gameOverTriggered = true; // Play game over sound when the dragon dies LK.getSound('gameover').play(); // Rotate the dragon 90 degrees dragon.rotation = -3 * Math.PI * dragon.scale.x; // Animate the dragon falling down - simplified tween tween(dragon, { y: 2732 + dragon.height, tint: 0xFF0000 }, { duration: 500, easing: tween.linear, onFinish: function onFinish() { LK.showGameOver(); } }); } break; } } } function updateBubbles() { // Process all bubbles every frame for consistent collision detection for (var i = bubbles.length - 1; i >= 0; i--) { var bubble = bubbles[i]; if (!bubble) { continue; } // Call the bubble's update method to move it if (bubble.update) { bubble.update(); } // Check for bubble-bubble intersections for (var j = i - 1; j >= 0; j--) { var otherBubble = bubbles[j]; if (!otherBubble) { continue; } if (bubble.intersects(otherBubble)) { // Create a PoppedBubble for each intersecting bubble var pop1 = game.addChild(new PoppedBubble()); pop1.x = bubble.x; pop1.y = bubble.y; var pop2 = game.addChild(new PoppedBubble()); pop2.x = otherBubble.x; pop2.y = otherBubble.y; // Destroy both bubbles safely bubble.destroy(); otherBubble.destroy(); // Remove from bubbles array safely bubbles.splice(i, 1); // Adjust index after removing item at position i if (j >= i) { bubbles.splice(j, 1); } else { bubbles.splice(j, 1); } // Play pop sound when a bubble is popped LK.getSound('pop').play(); // Destroy the PoppedBubbles after 0.5 seconds LK.setTimeout(function () { pop1.destroy(); pop2.destroy(); }, 500); // Exit inner loop break; } } // Skip if bubble was destroyed in collision check if (!bubble || i >= bubbles.length) { continue; } // Remove bubbles that go off-screen if (bubble.y < -50 || bubble.x < -50 || bubble.x > 2100) { bubble.destroy(); bubbles.splice(i, 1); } } // Check for bubble-enemy collisions every frame for more reliable hits for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (!enemy || enemy.captured) { continue; } for (var j = bubbles.length - 1; j >= 0; j--) { var bubble = bubbles[j]; if (!bubble) { continue; } if (bubble.intersects(enemy)) { // Destroy the original bubble bubble.destroy(); bubbles.splice(j, 1); // Create a new bubble as a child of the enemy var newBubble = new CapturingBubble(); newBubble.x = 0; // Position relative to the enemy newBubble.y = 0; // Position relative to the enemy enemy.addChild(newBubble); enemy.captured = true; capturingBubbles.push(newBubble); break; } } } // Check if the dragon is intersecting a bubble - every frame for reliability for (var i = bubbles.length - 1; i >= 0; i--) { if (i >= bubbles.length) { continue; } // Safety check var bubble = bubbles[i]; if (!bubble) { continue; } if (dragon.intersects(bubble)) { // Create a PoppedBubble at the bubble's position var pop = game.addChild(new PoppedBubble()); pop.x = bubble.x; pop.y = bubble.y; // Destroy the bubble safely bubble.destroy(); bubbles.splice(i, 1); // Play pop sound when a bubble is popped LK.getSound('pop').play(); // Destroy the PoppedBubble after 0.5 seconds LK.setTimeout(function () { pop.destroy(); }, 500); break; } } // Process capturing bubbles every frame for better reliability if (capturingBubbles.length > 0) { // Check if the dragon is intersecting a CapturingBubble for (var i = capturingBubbles.length - 1; i >= 0; i--) { if (i >= capturingBubbles.length) { continue; } // Safety check var capturingBubble = capturingBubbles[i]; if (!capturingBubble) { continue; } if (dragon.intersects(capturingBubble)) { // Find and destroy the enemy that is the parent of the CapturingBubble for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (!enemy) { continue; } if (enemy.children && enemy.children.indexOf(capturingBubble) !== -1) { // Create a PoppedBubble at the capturingBubble's position var pop = game.addChild(new PoppedBubble()); pop.x = enemy.x; pop.y = enemy.y; // Destroy the enemy and capturingBubble enemy.destroy(); enemies.splice(j, 1); // Remove from capturing bubbles array capturingBubbles.splice(i, 1); // Play pop sound when a capturing bubble is popped LK.getSound('pop').play(); // Destroy the PoppedBubble after 1 second LK.setTimeout(function () { pop.destroy(); }, 1000); break; } } } } } // Update capturing bubbles for (var i = capturingBubbles.length - 1; i >= 0; i--) { if (i >= capturingBubbles.length) { continue; } // Safety check var capturingBubble = capturingBubbles[i]; if (!capturingBubble) { continue; } var enemy = capturingBubble.parent; if (enemy && enemy.captured && !enemy.floating) { enemy.y -= 5; // Make the enemy float up more smoothly } } } function updateJump() { if (isJumping) { var jumpHeight = (dragon.y - jumpStartY) / 10; dragon.y -= jumpHeight; // Move dragon upwards based on calculated jump height // More efficient intersection check with early termination var dragonIntersectsFloor = false; for (var i = 0; i < floors.length; i++) { if (dragon.intersects(floors[i])) { dragonIntersectsFloor = true; if (!dragon.lastWasIntersecting) { isJumping = false; // Stop jumping isFalling = true; // Start falling when colliding with a floor canJump = false; // Disallow jumping again until the dragon hits a floor dragon.y -= 25; } break; } } // Check if jump duration has exceeded 0.4 seconds if (Date.now() - jumpStartTime >= 400) { isJumping = false; isFalling = true; } // Update last known intersection state dragon.lastWasIntersecting = dragonIntersectsFloor; } } // BLOCKS // Add a floor to the bottom of the screen var floors = []; for (var i = 0; i < 21; i++) { var floor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: i * 100, y: 2732 - 30 }); game.addChild(floor); floors.push(floor); } // Add continuous floor on the left margin of the screen for (var j = 0; j < 27; j++) { var leftFloor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 0, y: j * 100 }); game.addChild(leftFloor); floors.push(leftFloor); } // Add continuous floor on the right margin of the screen for (var k = 0; k < 27; k++) { var rightFloor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 50, y: k * 100 }); game.addChild(rightFloor); floors.push(rightFloor); } // Add random platforms with irregular heights and positions var platformYPositions = []; var distinctHeights = [2300, 1900, 1500, 1100, 700]; // Define 4-5 distinct heights var minPlatformLength = 5; var maxPlatformLength = 14; distinctHeights.forEach(function (height) { platformYPositions.push(height); }); // Add random platforms with irregular heights and positions for (var j = 0; j < platformYPositions.length; j++) { var _behaviours$enemyType; var platformLength = Math.floor(Math.random() * (maxPlatformLength - minPlatformLength + 1)) + minPlatformLength; var startX = Math.floor(Math.random() * (2048 - platformLength * 100)); // Random start position var startY = platformYPositions[j]; // Generate a random tint color for the platforms var randomTint = Math.floor(Math.random() * 16777215); for (var i = 0; i < platformLength; i++) { var newX = startX + i * 100; if (newX > 1900 || newX < 120) { continue; } var platform = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: startX + i * 100, y: platformYPositions[j] }); platform.tint = randomTint; // Apply the random tint to the platform game.addChild(platform); floors.push(platform); } // Spawn an enemy on top of each platform var enemyType = 'enemy' + (i % 5 + 1); // Cycle through enemy1 to enemy5 var behaviour = (_behaviours$enemyType = behaviours[enemyType]) !== null && _behaviours$enemyType !== void 0 ? _behaviours$enemyType : easingFunctions[Math.floor(Math.random() * easingFunctions.length)]; // Assign random easing function; behaviours[enemyType] = behaviour; var enemy = LK.getAsset(enemyType, { anchorX: 0.5, anchorY: 0.5, x: startX + 100, y: platformYPositions[j] - 100, type: enemyType }); if (enemyType === 'enemy5' || enemyType === 'enemy2') { enemy.tint = Math.floor(Math.random() * 0x7FFFFF) + 0x808080; // Ensure light tint } enemy.captured = false; game.addChild(enemy); enemies.push(enemy); } /* LEVEL MANAGEMENT 1 */ var levelTextBackground = new Text2('LEVEL ' + level.toString(), { size: 210, fill: 0x000000 }); levelTextBackground.anchor.set(0.5, 0.5); levelTextBackground.x = 2048 / 2; levelTextBackground.y = 2732 / 2; game.addChild(levelTextBackground); LK.setTimeout(function () { levelTextBackground.destroy(); }, 2000); var levelText = new Text2('LEVEL ' + level.toString(), { size: 200, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0.5); levelText.x = 2048 / 2; levelText.y = 2732 / 2; game.addChild(levelText); LK.setTimeout(function () { levelText.destroy(); }, 2000); }
===================================================================
--- original.js
+++ change.js
@@ -16,29 +16,39 @@
self.speed = -5;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
+ // Store last position
+ self.lastX = self.x;
+ self.lastY = self.y;
+ // Move bubble
self.x += self.speed;
// Check for intersection with any floor
+ var intersectingFloor = null;
for (var i = 0; i < floors.length; i++) {
if (self.intersects(floors[i])) {
- // Create a PoppedBubble at the bubble's position
- var pop = game.addChild(new PoppedBubble());
- pop.x = self.x;
- pop.y = self.y;
- // Destroy the bubble
- self.destroy();
- bubbles.splice(bubbles.indexOf(self), 1);
- // Destroy the PoppedBubble after 0.5 seconds
- LK.setTimeout(function () {
- pop.destroy();
- }, 500);
+ intersectingFloor = floors[i];
break;
}
}
- // Update last known positions
- self.lastX = self.x;
- self.lastY = self.y;
+ // Handle collision with floor
+ if (intersectingFloor) {
+ // Create a PoppedBubble at the bubble's position
+ var pop = game.addChild(new PoppedBubble());
+ pop.x = self.x;
+ pop.y = self.y;
+ // Remove from bubbles array before destroying
+ var bubbleIndex = bubbles.indexOf(self);
+ if (bubbleIndex !== -1) {
+ bubbles.splice(bubbleIndex, 1);
+ }
+ // Destroy the bubble
+ self.destroy();
+ // Destroy the PoppedBubble after 0.5 seconds
+ LK.setTimeout(function () {
+ pop.destroy();
+ }, 500);
+ }
};
});
var CapturingBubble = Container.expand(function () {
var self = Container.call(this);
@@ -63,20 +73,28 @@
self.lastWasIntersecting = false;
self.lastX = 0;
self.lastY = 0;
self.shootBubble = function () {
+ // Create new bubble and ensure it's properly initialized
var bubble = new Bubble();
bubble.x = self.x + 200 * self.scale.x;
bubble.y = self.y - 5;
+ bubble.lastX = bubble.x;
+ bubble.lastY = bubble.y;
// If the dragon is looking right, the bubble should move to the right
if (self.scale.x == 1) {
bubble.speed = 25;
} else {
// If the dragon is looking left, the bubble should move to the left
bubble.speed = -25;
}
+ // Add bubble to game display list
game.addChild(bubble);
- bubbles.push(bubble);
+ // Make sure the bubble gets tracked in our global array
+ // Use this pattern to ensure we don't lose track of bubbles
+ if (bubbles) {
+ bubbles.push(bubble);
+ }
// Play bubble sound when a bubble is shot
LK.getSound('bubble').play();
};
});
@@ -205,13 +223,17 @@
game.down = function (x, y, obj) {
controlPanel.destroy();
startGame();
};
+// Properly initialize all global variables to prevent undefined errors
var bubbles = []; // Initialize bubbles array to store bubble instances
var floors = []; // Initialize floors array to store floor instances
var behaviours = {}; // Initialize behaviours object
var enemies = [];
var capturingBubbles = [];
+var jumpStartY = 0;
+var dragon; // Will be initialized later
+var background; // Will be initialized with a background image
function startGame() {
started = true;
var level = 1;
function restartGame() {
@@ -330,31 +352,40 @@
var jumpStartTime; // Declare jumpStartTime to track the start of the jump
var easingFunctions = [tween.linear, tween.easeIn, tween.easeOut, tween.easeInOut, tween.bounceIn, tween.bounceOut, tween.bounceInOut, tween.elasticIn, tween.elasticOut, tween.elasticInOut, tween.cubicIn, tween.cubicOut, tween.cubitInOut, tween.expoIn, tween.expoOut, tween.expoInOut, tween.sineIn, tween.sineOut, tween.sineInOut];
LK.playMusic('music');
function isStandingOnFloor() {
+ // Store the dragon's position
+ var dragonBottom = dragon.y + dragon.height / 2;
for (var i = 0; i < floors.length; i++) {
- if (dragon.intersects(floors[i])) {
+ var floor = floors[i];
+ var floorTop = floor.y - floor.height / 2;
+ // More precise collision detection for standing on platforms
+ if (dragon.intersects(floor) && Math.abs(dragonBottom - floorTop) < 20 && dragon.lastY < dragon.y) {
return true;
}
}
return false;
}
function updateFall() {
if (isFalling) {
- dragon.y += 85; // Move dragon downwards faster
- // More efficient method to check intersections
+ // Store last position before moving
+ var lastY = dragon.y;
+ // Move dragon downwards with a smaller increment to prevent passing through platforms
+ dragon.y += 20;
+ // Check for collisions after moving
var isIntersecting = false;
for (var i = 0; i < floors.length; i++) {
- if (!dragon.lastWasIntersecting && dragon.intersects(floors[i])) {
- isJumping = false; // Stop jumping
- isFalling = false; // Stop falling when colliding with a floor
- canJump = true; // Allow jumping again when the dragon hits a floor
- dragon.y = floors[i].y - floors[i].height * 1.5; // Align dragon to the top of the floor
- isIntersecting = true;
- break;
- }
+ // Check if dragon is intersecting with a floor
if (dragon.intersects(floors[i])) {
isIntersecting = true;
+ // Only stop falling if we weren't intersecting before (just collided)
+ if (!dragon.lastWasIntersecting || lastY < floors[i].y - floors[i].height) {
+ isJumping = false; // Stop jumping
+ isFalling = false; // Stop falling when colliding with a floor
+ canJump = true; // Allow jumping again when the dragon hits a floor
+ dragon.y = floors[i].y - floors[i].height * 1.5; // Align dragon to the top of the floor
+ break;
+ }
}
}
// Update last known intersection state
dragon.lastWasIntersecting = isIntersecting;
@@ -373,13 +404,13 @@
var dragon = game.addChild(new Dragon());
dragon.lastY = dragon.y; // Initialize lastY position
dragon.x = 1024; // Center horizontally
dragon.y = 2532; // Position the dragon on top of the floor
- // Handle game updates - optimized for better performance
+ // Handle game updates with improved frame handling
game.update = function () {
- // Move dragon incrementally towards target x - simplified movement calculation
+ // Move dragon incrementally towards target x with improved movement
if (dragon.targetX !== undefined) {
- var increment = (dragon.targetX - dragon.x) / 10; // Move in 0.5 seconds assuming 60 FPS
+ var increment = (dragon.targetX - dragon.x) / 5; // Faster movement for better responsiveness
if (Math.abs(dragon.targetX - dragon.x) > 1) {
dragon.x += increment;
}
// Update last known position
@@ -391,29 +422,20 @@
} else {
dragon.scale.x = 1;
}
}
- // Check floor standing less frequently to improve performance
- if (LK.ticks % 2 === 0) {
- var standingOnFloor = isStandingOnFloor();
- if (!standingOnFloor && !isJumping) {
- isFalling = true;
- }
+ // Always check floor standing to prevent falling through platforms
+ var standingOnFloor = isStandingOnFloor();
+ if (!standingOnFloor && !isJumping) {
+ isFalling = true;
}
- // Stagger updates to different game cycles to distribute load
- if (LK.ticks % 2 === 0) {
- updateJump();
- }
- if (LK.ticks % 2 === 1) {
- // Offset by 1 tick from jump update
- updateFall();
- }
- if (LK.ticks % 3 === 0) {
- // Less frequent bubble updates
- updateBubbles();
- }
- if (LK.ticks % 15 === 0) {
- // Keep enemy movement at same frequency
+ // Always update jumping and falling
+ updateJump();
+ updateFall();
+ // Update bubbles every frame for consistent collision detection
+ updateBubbles();
+ // Keep enemy movement at higher frequency to fix enemies not moving
+ if (LK.ticks % 5 === 0) {
updateEnemiesMovement();
}
};
// Handle touch events for shooting bubbles
@@ -437,13 +459,10 @@
}
lastClick = now;
};
function updateEnemiesMovement() {
- // Only process a subset of enemies per frame to reduce performance impact
- var enemiesToProcess = Math.max(1, Math.floor(enemies.length / 3));
- var startEnemy = LK.ticks % 3 * enemiesToProcess;
- var endEnemy = Math.min(startEnemy + enemiesToProcess, enemies.length);
- for (var i = startEnemy; i < endEnemy; i++) {
+ // Process all enemies every frame to ensure consistent movement
+ for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (!enemy) {
continue;
}
@@ -494,73 +513,96 @@
}
}
});
}
- } else if (!enemy.isMoving) {
- enemy.isMoving = true;
- // Find all platform floors for this enemy
- var platformFloors = [];
- var platformY = enemy.y + 100;
- for (var j = 0; j < floors.length; j++) {
- if (floors[j].y === platformY && floors[j].x > 0 && floors[j].x < 2048 - 50) {
- platformFloors.push(floors[j]);
+ } else {
+ // Initialize movement if not already moving
+ if (!enemy.isMoving && !enemy.tweenInitialized) {
+ enemy.isMoving = true;
+ enemy.tweenInitialized = true;
+ // Find all platform floors for this enemy
+ var platformFloors = [];
+ var platformY = enemy.y + 100;
+ for (var j = 0; j < floors.length; j++) {
+ if (Math.abs(floors[j].y - platformY) < 10 && floors[j].x > 0 && floors[j].x < 2048 - 50) {
+ platformFloors.push(floors[j]);
+ }
}
- }
- // Find min and max X positions
- var startX = 2048;
- var endX = 0;
- for (var j = 0; j < platformFloors.length; j++) {
- if (platformFloors[j].x < startX) {
- startX = platformFloors[j].x;
- }
- if (platformFloors[j].x > endX) {
- endX = platformFloors[j].x;
- }
- }
- enemy.alpha = 0.75; // Apply alpha when starting to move
- // Use a simplified tween chain
- tween(enemy, {
- x: endX
- }, {
- duration: 3000 + Math.random() * 5000,
- // Reduced range for more consistent performance
- easing: behaviours[enemy.type] || tween.linear,
- onFinish: function onFinish() {
- tween(enemy, {
- x: startX
- }, {
- duration: 2000,
- easing: tween.linear,
- onFinish: function onFinish() {
- enemy.isMoving = false;
- enemy.alpha = 1; // Restore alpha on finish
+ // Only proceed if we found platform floors
+ if (platformFloors.length > 0) {
+ // Find min and max X positions
+ var startX = 2048;
+ var endX = 0;
+ for (var j = 0; j < platformFloors.length; j++) {
+ if (platformFloors[j].x < startX) {
+ startX = platformFloors[j].x;
}
- });
+ if (platformFloors[j].x > endX) {
+ endX = platformFloors[j].x;
+ }
+ }
+ // Ensure we have a valid range to move in
+ if (startX < endX) {
+ enemy.alpha = 0.75; // Apply alpha when starting to move
+ // Store the platform range for this enemy
+ enemy.startX = startX;
+ enemy.endX = endX;
+ // Start the movement tween
+ tween(enemy, {
+ x: endX
+ }, {
+ duration: 3000,
+ easing: behaviours[enemy.type] || tween.linear,
+ onFinish: function onFinish() {
+ var thisEnemy = this;
+ thisEnemy.isMovingRight = false;
+ tween(thisEnemy, {
+ x: thisEnemy.startX
+ }, {
+ duration: 3000,
+ easing: tween.linear,
+ onFinish: function onFinish() {
+ var thisEnemy = this;
+ thisEnemy.isMovingRight = true;
+ // Restart movement
+ tween(thisEnemy, {
+ x: thisEnemy.endX
+ }, {
+ duration: 3000,
+ easing: tween.linear,
+ onFinish: arguments.callee
+ });
+ }
+ });
+ }
+ }).context(enemy);
+ enemy.isMovingRight = true;
+ }
}
- });
+ }
+ // Update enemy direction based on movement
+ if (enemy.x !== enemy.lastX) {
+ enemy.scale.x = enemy.x > enemy.lastX ? 1 : -1;
+ }
+ // Check for collision with dragon
+ if (!enemy.captured && dragon.intersects(enemy)) {
+ // Play game over sound when the dragon dies
+ LK.getSound('gameover').play();
+ // Rotate the dragon 90 degrees
+ dragon.rotation = -3 * Math.PI * dragon.scale.x;
+ // Animate the dragon falling down - simplified tween
+ tween(dragon, {
+ y: 2732 + dragon.height,
+ tint: 0xFF0000
+ }, {
+ duration: 500,
+ easing: tween.linear,
+ onFinish: function onFinish() {
+ LK.showGameOver();
+ }
+ });
+ }
}
- // Update enemy direction
- if (enemy.x !== enemy.lastX) {
- enemy.scale.x = enemy.lastX < enemy.x ? 1 : -1;
- }
- // Check for collision with dragon
- if (!enemy.captured && dragon.intersects(enemy)) {
- // Play game over sound when the dragon dies
- LK.getSound('gameover').play();
- // Rotate the dragon 90 degrees
- dragon.rotation = -3 * Math.PI * dragon.scale.x;
- // Animate the dragon falling down - simplified tween
- tween(dragon, {
- y: 2732 + dragon.height,
- tint: 0xFF0000
- }, {
- duration: 500,
- easing: tween.linear,
- onFinish: function onFinish() {
- LK.showGameOver();
- }
- });
- }
// Update last known position
enemy.lastX = enemy.x;
enemy.lastY = enemy.y;
}
@@ -592,118 +634,144 @@
}
}
}
function updateBubbles() {
- // Update bubbles - optimized version to reduce calculations
- // Process only a subset of bubbles each frame to distribute load
- var bubblesPerFrame = Math.max(1, Math.floor(bubbles.length / 3));
- var startIndex = LK.ticks % 3 * bubblesPerFrame;
- var endIndex = Math.min(startIndex + bubblesPerFrame, bubbles.length);
- // Update bubbles in batches
+ // Process all bubbles every frame for consistent collision detection
for (var i = bubbles.length - 1; i >= 0; i--) {
var bubble = bubbles[i];
if (!bubble) {
continue;
}
- // Check for bubble-bubble intersections less frequently
- if (i >= startIndex && i < endIndex) {
- for (var j = i - 1; j >= 0; j--) {
- var otherBubble = bubbles[j];
- if (!otherBubble) {
- continue;
- }
- if (bubble.intersects(otherBubble)) {
- // Create a PoppedBubble for each intersecting bubble
- var pop1 = game.addChild(new PoppedBubble());
- pop1.x = bubble.x;
- pop1.y = bubble.y;
- var pop2 = game.addChild(new PoppedBubble());
- pop2.x = otherBubble.x;
- pop2.y = otherBubble.y;
- // Destroy both bubbles
- bubble.destroy();
- otherBubble.destroy();
- bubbles.splice(i, 1);
+ // Call the bubble's update method to move it
+ if (bubble.update) {
+ bubble.update();
+ }
+ // Check for bubble-bubble intersections
+ for (var j = i - 1; j >= 0; j--) {
+ var otherBubble = bubbles[j];
+ if (!otherBubble) {
+ continue;
+ }
+ if (bubble.intersects(otherBubble)) {
+ // Create a PoppedBubble for each intersecting bubble
+ var pop1 = game.addChild(new PoppedBubble());
+ pop1.x = bubble.x;
+ pop1.y = bubble.y;
+ var pop2 = game.addChild(new PoppedBubble());
+ pop2.x = otherBubble.x;
+ pop2.y = otherBubble.y;
+ // Destroy both bubbles safely
+ bubble.destroy();
+ otherBubble.destroy();
+ // Remove from bubbles array safely
+ bubbles.splice(i, 1);
+ // Adjust index after removing item at position i
+ if (j >= i) {
bubbles.splice(j, 1);
- // Play pop sound when a bubble is popped
- LK.getSound('pop').play();
- // Destroy the PoppedBubbles after 0.5 seconds
- LK.setTimeout(function () {
- pop1.destroy();
- pop2.destroy();
- }, 500);
- break;
+ } else {
+ bubbles.splice(j, 1);
}
+ // Play pop sound when a bubble is popped
+ LK.getSound('pop').play();
+ // Destroy the PoppedBubbles after 0.5 seconds
+ LK.setTimeout(function () {
+ pop1.destroy();
+ pop2.destroy();
+ }, 500);
+ // Exit inner loop
+ break;
}
}
- if (!bubble) {
+ // Skip if bubble was destroyed in collision check
+ if (!bubble || i >= bubbles.length) {
continue;
}
- if (bubble.y < -50) {
+ // Remove bubbles that go off-screen
+ if (bubble.y < -50 || bubble.x < -50 || bubble.x > 2100) {
bubble.destroy();
bubbles.splice(i, 1);
}
}
- // Check for bubble-enemy collisions less frequently
- if (LK.ticks % 2 === 0) {
- for (var i = enemies.length - 1; i >= 0; i--) {
- var enemy = enemies[i];
- for (var j = bubbles.length - 1; j >= 0; j--) {
- var bubble = bubbles[j];
- if (bubble && bubble.intersects(enemy)) {
- // Destroy the original bubble
- bubble.destroy();
- bubbles.splice(j, 1);
- // Create a new bubble as a child of the enemy
- var newBubble = new CapturingBubble();
- newBubble.x = 0; // Position relative to the enemy
- newBubble.y = 0; // Position relative to the enemy
- enemy.addChild(newBubble);
- enemy.captured = true;
- capturingBubbles.push(newBubble);
- break;
- }
- }
+ // Check for bubble-enemy collisions every frame for more reliable hits
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ if (!enemy || enemy.captured) {
+ continue;
}
- }
- // Check if the dragon is intersecting a bubble
- if (bubbles.length > 0) {
- for (var i = 0; i < bubbles.length; i++) {
- if (bubbles[i] && dragon.intersects(bubbles[i])) {
- // Create a PoppedBubble at the bubble's position
- var pop = game.addChild(new PoppedBubble());
- pop.x = bubbles[i].x;
- pop.y = bubbles[i].y;
- // Destroy the bubble
- bubbles[i].destroy();
- bubbles.splice(i, 1);
- // Play pop sound when a bubble is popped
- LK.getSound('pop').play();
- // Destroy the PoppedBubble after 0.5 seconds
- LK.setTimeout(function () {
- pop.destroy();
- }, 500);
+ for (var j = bubbles.length - 1; j >= 0; j--) {
+ var bubble = bubbles[j];
+ if (!bubble) {
+ continue;
+ }
+ if (bubble.intersects(enemy)) {
+ // Destroy the original bubble
+ bubble.destroy();
+ bubbles.splice(j, 1);
+ // Create a new bubble as a child of the enemy
+ var newBubble = new CapturingBubble();
+ newBubble.x = 0; // Position relative to the enemy
+ newBubble.y = 0; // Position relative to the enemy
+ enemy.addChild(newBubble);
+ enemy.captured = true;
+ capturingBubbles.push(newBubble);
break;
}
}
}
- // Process capturing bubbles less frequently
- if (LK.ticks % 3 === 0 && capturingBubbles.length > 0) {
+ // Check if the dragon is intersecting a bubble - every frame for reliability
+ for (var i = bubbles.length - 1; i >= 0; i--) {
+ if (i >= bubbles.length) {
+ continue;
+ } // Safety check
+ var bubble = bubbles[i];
+ if (!bubble) {
+ continue;
+ }
+ if (dragon.intersects(bubble)) {
+ // Create a PoppedBubble at the bubble's position
+ var pop = game.addChild(new PoppedBubble());
+ pop.x = bubble.x;
+ pop.y = bubble.y;
+ // Destroy the bubble safely
+ bubble.destroy();
+ bubbles.splice(i, 1);
+ // Play pop sound when a bubble is popped
+ LK.getSound('pop').play();
+ // Destroy the PoppedBubble after 0.5 seconds
+ LK.setTimeout(function () {
+ pop.destroy();
+ }, 500);
+ break;
+ }
+ }
+ // Process capturing bubbles every frame for better reliability
+ if (capturingBubbles.length > 0) {
// Check if the dragon is intersecting a CapturingBubble
for (var i = capturingBubbles.length - 1; i >= 0; i--) {
+ if (i >= capturingBubbles.length) {
+ continue;
+ } // Safety check
var capturingBubble = capturingBubbles[i];
+ if (!capturingBubble) {
+ continue;
+ }
if (dragon.intersects(capturingBubble)) {
// Find and destroy the enemy that is the parent of the CapturingBubble
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
- if (enemy.children.includes(capturingBubble)) {
+ if (!enemy) {
+ continue;
+ }
+ if (enemy.children && enemy.children.indexOf(capturingBubble) !== -1) {
// Create a PoppedBubble at the capturingBubble's position
var pop = game.addChild(new PoppedBubble());
pop.x = enemy.x;
pop.y = enemy.y;
// Destroy the enemy and capturingBubble
enemy.destroy();
enemies.splice(j, 1);
+ // Remove from capturing bubbles array
+ capturingBubbles.splice(i, 1);
// Play pop sound when a capturing bubble is popped
LK.getSound('pop').play();
// Destroy the PoppedBubble after 1 second
LK.setTimeout(function () {
@@ -714,17 +782,21 @@
}
}
}
}
- // Update capturing bubbles less frequently to improve performance
- if (LK.ticks % 4 === 0) {
- for (var i = 0; i < capturingBubbles.length; i++) {
- var capturingBubble = capturingBubbles[i];
- var enemy = capturingBubble.parent;
- if (enemy && !enemy.captured) {
- enemy.y -= 150; // Make the enemy jump with the dragon
- }
+ // Update capturing bubbles
+ for (var i = capturingBubbles.length - 1; i >= 0; i--) {
+ if (i >= capturingBubbles.length) {
+ continue;
+ } // Safety check
+ var capturingBubble = capturingBubbles[i];
+ if (!capturingBubble) {
+ continue;
}
+ var enemy = capturingBubble.parent;
+ if (enemy && enemy.captured && !enemy.floating) {
+ enemy.y -= 5; // Make the enemy float up more smoothly
+ }
}
}
function updateJump() {
if (isJumping) {
A pixel slime, funny, looking right. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
brick, brown color, pixel style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Draw wings to the dragon
better wings, pixel style, more contrasted, more visible, blue color
A pixel based enemy from the world of Bubble Bobble. It should be ghost-like. Make it very 80s 90s like in pixel, arcade style.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A pixel based enemy from the world of Bubble Bobble. It should be blob like. Make it very 80s 90s like in pixel, arcade style.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a pixel clouds background. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a pixel clouds background, with mountains, full height full width Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a similar image. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a pixel clouds background, with mountains, full height full width Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows