User prompt
update with: game.down = function(x, y, obj) { var localX = x - menuContainer.x; var localY = y - menuContainer.y; // Tab click handling var tabBounds = { x: -menuTab.width * menuTab.scaleX / 2, y: -menuTab.height * menuTab.scaleY, width: menuTab.width * menuTab.scaleX, height: menuTab.height * menuTab.scaleY }; if (localX >= tabBounds.x && localX <= tabBounds.x + tabBounds.width && localY >= tabBounds.y && localY <= tabBounds.y + tabBounds.height) { menuOpen = !menuOpen; var targetY = menuOpen ? menuTab.height : game.height; if (menuOpen) { game.setChildIndex(menuContainer, game.children.length - 1); } tween(menuContainer, { y: targetY }, { duration: 300, easing: tween.easeOutBack, onFinish: function onFinish() { if (!menuOpen) { game.setChildIndex(menuContainer, 1); } } }); return true; } if (menuOpen) { return true; // Let containers handle their own clicks } // Bubble popping logic remains the same var popped = false; for (var i = game.bubbles.length - 1; i >= 0; i--) { var bubble = game.bubbles[i]; var dx = x - bubble.x; var dy = y - bubble.y; var distance = Math.sqrt(dx * dx + dy * dy); if (!popped && distance <= bubble.size / 2 + 10 && bubble.down) { bubble.down(); popped = true; break; } } };
Code edit (2 edits merged)
Please save this source code
User prompt
update with: hitContainer.down = function () { console.log('Click on:', upgrade.name); const cost = getUpgradeCost(upgrade); if (game.bp >= cost) { if (category === 'machines') { if (upgrade.amount < 4) { // Limit to 4 clams upgrade.amount++; game.bp -= cost; bpText.setText(formatBP(game.bp) + " BP"); costText.setText(getUpgradeCost(upgrade) + " BP"); updateClamVisuals(); } } else if (upgrade.currentLevel < upgrade.maxLevel) { upgrade.currentLevel++; game.bp -= cost; bpText.setText(formatBP(game.bp) + " BP"); costText.setText(getUpgradeCost(upgrade) + " BP"); } } return true; };
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'UPGRADE_CONFIG.machines[clamType] is undefined' in or related to this line: 'if (UPGRADE_CONFIG.machines[clamType].amount <= i) {' Line Number: 783
Code edit (1 edits merged)
Please save this source code
User prompt
update with: function updateClamVisuals() { // Clear existing clams while (clamContainer.children.length) { clamContainer.children[0].destroy(); } // Calculate positions for clams on each side const leftStart = game.width * 0.15; const rightStart = game.width * 0.85; const spacing = 150; // Space between clams on same side const y = game.height - 100; // Offset from bottom // Get counts of each type const basicCount = UPGRADE_CONFIG.machines.basicClam.amount; const advancedCount = UPGRADE_CONFIG.machines.advancedClam.amount; const premiumCount = UPGRADE_CONFIG.machines.premiumClam.amount; // Determine current clam type let clamType = 'basicClam'; if (basicCount >= 4) { clamType = 'advancedClam'; if (advancedCount >= 4) { clamType = 'premiumClam'; } } const count = UPGRADE_CONFIG.machines[clamType].amount; // Place clams one by one, alternating sides for (let i = 0; i < count; i++) { const isRight = i % 2 === 1; // Odd numbers go on right const baseX = isRight ? rightStart : leftStart; const direction = isRight ? -1 : 1; const position = Math.floor(i/2); // How far from edge const x = baseX + (direction * position * spacing); const sprite = LK.getAsset(clamType, { anchorX: 0.5, anchorY: 1, x: x, y: y, scaleX: 0.5, scaleY: 0.5 }); clamContainer.addChild(sprite); } }
User prompt
update with: function updateClamVisuals() { // Previous clear code stays the same... // Determine current clam type and count let clamType, count; if (UPGRADE_CONFIG.machines.premiumClam.amount > 0) { clamType = 'premiumClam'; count = UPGRADE_CONFIG.machines.premiumClam.amount; } else if (UPGRADE_CONFIG.machines.advancedClam.amount > 0) { clamType = 'advancedClam'; count = UPGRADE_CONFIG.machines.advancedClam.amount; } else { clamType = 'basicClam'; count = UPGRADE_CONFIG.machines.basicClam.amount; } // Rest of the function stays the same... }
User prompt
update with: function updateClamVisuals() { while (clamContainer.children.length) { clamContainer.children[0].destroy(); } const leftStart = game.width * 0.15; const rightStart = game.width * 0.85; const spacing = 150; const y = game.height - 100; // We'll store type of each clam position (0-3) const clamTypes = []; // Fill with basic clams first for (let i = 0; i < UPGRADE_CONFIG.machines.basicClam.amount; i++) { clamTypes.push('basicClam'); } // Replace some with advanced for (let i = 0; i < UPGRADE_CONFIG.machines.advancedClam.amount; i++) { if (clamTypes[i]) { clamTypes[i] = 'advancedClam'; } } // Replace some with premium for (let i = 0; i < UPGRADE_CONFIG.machines.premiumClam.amount; i++) { if (clamTypes[i]) { clamTypes[i] = 'premiumClam'; } } // Place clams clamTypes.forEach((type, i) => { const isRight = i % 2 === 1; const baseX = isRight ? rightStart : leftStart; const direction = isRight ? -1 : 1; const position = Math.floor(i/2); const x = baseX + (direction * position * spacing); const sprite = LK.getAsset(type, { anchorX: 0.5, anchorY: 1, x: x, y: y, scaleX: 0.5, scaleY: 0.5 }); clamContainer.addChild(sprite); }); }
User prompt
update with: hitContainer.down = function () { const cost = getUpgradeCost(upgrade); if (game.bp >= cost) { if (category === 'machines') { const totalClams = UPGRADE_CONFIG.machines.basicClam.amount + UPGRADE_CONFIG.machines.advancedClam.amount + UPGRADE_CONFIG.machines.premiumClam.amount; if (key === 'basicClam' && totalClams < 4) { upgrade.amount++; game.bp -= cost; } else if (key === 'advancedClam' && UPGRADE_CONFIG.machines.basicClam.amount > UPGRADE_CONFIG.machines.advancedClam.amount) { upgrade.amount++; game.bp -= cost; } else if (key === 'premiumClam' && UPGRADE_CONFIG.machines.advancedClam.amount > UPGRADE_CONFIG.machines.premiumClam.amount) { upgrade.amount++; game.bp -= cost; } bpText.setText(formatBP(game.bp) + " BP"); costText.setText(getUpgradeCost(upgrade) + " BP"); updateClamVisuals(); } else { // Rest of upgrade logic stays the same... } } return true; };
User prompt
update with: function updateClamVisuals() { while (clamContainer.children.length) { clamContainer.children[0].destroy(); } // Increase edge distance and spacing const leftStart = game.width * 0.1; // Moved further left from 0.15 const rightStart = game.width * 0.9; // Moved further right from 0.85 const spacing = 250; // Increased from 150 const y = game.height - 100; // Rest of clam type determination stays the same... // Place clams clamTypes.forEach((type, i) => { const isRight = i % 2 === 1; const baseX = isRight ? rightStart : leftStart; const direction = isRight ? -1 : 1; const position = Math.floor(i/2); const x = baseX + (direction * position * spacing); const sprite = LK.getAsset(type, { anchorX: 0.5, anchorY: 1, x: x, y: y, scaleX: isRight ? -0.5 : 0.5, // Flip right-side clams scaleY: 0.5 }); clamContainer.addChild(sprite); }); }
User prompt
update as needed with: // Add these calculations to updateClamVisuals: function updateClamVisuals() { // ... existing clear code ... const leftStart = game.width * 0.1; const rightStart = game.width * 0.9; const spacing = 250; // Add this to store spawn positions game.clamSpawnPoints = []; clamTypes.forEach((type, i) => { const isRight = i % 2 === 1; const baseX = isRight ? rightStart : leftStart; const direction = isRight ? -1 : 1; const position = Math.floor(i/2); const x = baseX + (direction * position * spacing); const sprite = LK.getAsset(type, { anchorX: 0.5, anchorY: 1, x: x, y: y, scaleX: isRight ? -0.5 : 0.5, scaleY: 0.5 }); // Store spawn point for this clam game.clamSpawnPoints.push({ x: x + (isRight ? -75 : 75), // 25% from edge y: y - 50, // Slightly above clam type: type, isRight }); clamContainer.addChild(sprite); }); } // Update the clam spawning logic: function updateClams() { if (!game.clamSpawnPoints) return; game.clamSpawnPoints.forEach(spawnPoint => { const config = UPGRADE_CONFIG.machines[spawnPoint.type]; // Calculate production time with speed upgrade const baseTime = config.production * 60; // Convert to frames const speedMultiplier = Math.pow(1 - UPGRADE_EFFECTS.autoBubbleSpeed.decrementPercent / 100, UPGRADE_CONFIG.machine.autoBubbleSpeed.currentLevel); const adjustedTime = Math.max(1, Math.floor(baseTime * speedMultiplier)); if (LK.ticks % adjustedTime === 0) { if (game.bubbles.length < game.MAX_BUBBLES) { spawnSplitBubble( spawnPoint.x, spawnPoint.y, config.bubbleSize, spawnPoint.isRight ? -0.5 : 0.5 ); } } }); }
User prompt
update with: UPGRADE_CONFIG.machines.basicClam.bubbleSize = 50; // Was 25 UPGRADE_CONFIG.machines.advancedClam.bubbleSize = 75; // Was 35 UPGRADE_CONFIG.machines.premiumClam.bubbleSize = 100; // Was 50
User prompt
update with: game.bubblePool = Array(250).fill(null).map(() => new Bubble()); game.activeBubbles = []; game.MAX_BUBBLES = 200; // Active bubble limit
Code edit (6 edits merged)
Please save this source code
User prompt
update with: self.deactivate = function() { self.visible = false; const index = game.activeBubbles.indexOf(self); if (index > -1) { game.activeBubbles.splice(index, 1); } // Don't award points here - let the calling function handle it };
User prompt
update with: if (self.y < -self.size) { // Just deactivate, no points self.visible = false; const index = game.activeBubbles.indexOf(self); if (index > -1) { game.activeBubbles.splice(index, 1); } return; }
User prompt
update with: self.autoPop = function () { // Only award points if bubble is on screen if (!self.autoPopDisplayed && self.y > -self.size) { var points = Math.floor(self.getBP() * 0.5); game.addBP(points, self.x, self.y, true); self.autoPopDisplayed = true; } self.deactivate(); return; };
User prompt
update with: if (self.size > 60 && !self.justSplit) { var splitCount = 2 + UPGRADE_CONFIG.machine.bubbleDurability.currentLevel; var newSize = Math.max(self.MIN_SPLIT_SIZE, self.size * 0.6); for (var i = 0; i < splitCount; i++) { var angle = i / splitCount * Math.PI * 2; // Reduce the direction multiplier to 0.5 to make movement more gentle spawnBubble(self.x, self.y, newSize, Math.cos(angle) * 0.5, false); } }
User prompt
update with: self.activate = function(x, y, size, isPlayerBlown = false) { self.x = x; self.y = y; self.size = size; self.lifetime = 0; self.hasSplit = false; self.splitHeight = null; self.justSplit = false; self.autoPopDisplayed = false; // For player bubbles, base lifetime on max possible size if (isPlayerBlown) { self.maxLifetime = Math.floor(Math.random() * 960 + 1440); // Use game.maxBubbleSize instead of initial size self.maxLifetime *= Math.min(1, game.maxBubbleSize / 100); } else { self.initLifetime(); } self.visible = true; // Reset velocities self.verticalVelocity = 0; self.driftX = (Math.random() * 20 - 10) / 60; self.floatSpeed = 50 * (120 / size * (0.9 + Math.random() * 0.2)) / 60; };
User prompt
update with: self.activate = function(x, y, size, isPlayerBlown = false) { self.x = x; self.y = y; self.size = size; self.lifetime = 0; self.hasSplit = false; self.splitHeight = null; self.justSplit = false; self.autoPopDisplayed = false; // For player bubbles, base lifetime on max possible size if (isPlayerBlown) { self.maxLifetime = Math.floor(Math.random() * 960 + 1440); // Use game.maxBubbleSize instead of initial size self.maxLifetime *= Math.min(1, game.maxBubbleSize / 100); self.floatSpeed = (50 * (120 / size * (0.9 + Math.random() * 0.2)) / 60) * 0.7; console.log('Player bubble lifetime:', self.maxLifetime); } else { self.initLifetime(); self.floatSpeed = 50 * (120 / size * (0.9 + Math.random() * 0.2)) / 60; } self.visible = true; self.verticalVelocity = 0; self.driftX = (Math.random() * 20 - 10) / 60; };
User prompt
update with: if (self.lifetime > self.maxLifetime) { console.log('Bubble dying - lifetime:', self.lifetime, 'maxLifetime:', self.maxLifetime); // rest of the code... }
User prompt
update with: self.activate = function(x, y, size, isPlayerBlown = false) { // Reset ALL state self.x = x; self.y = y; self.size = size; self.lifetime = 0; self.hasSplit = false; self.splitHeight = null; self.justSplit = false; self.autoPopDisplayed = false; self.lastPopTime = 0; self.verticalVelocity = 0; self.driftX = (Math.random() * 20 - 10) / 60; self.floatSpeed = 50 * (120 / size * (0.9 + Math.random() * 0.2)) / 60; self.initLifetime(); // Always get fresh lifetime self.visible = true; // Add some debug logs console.log('Activating bubble:', { size: self.size, maxLifetime: self.maxLifetime, isPlayerBlown: isPlayerBlown }); };
User prompt
update with: if (game.growingBubble) { if (facekit.mouthOpen) { game.growingBubble.x = playerMask.x; game.growingBubble.y = playerMask.y + playerMask.height * 0.15; game.growingBubble.size = Math.min(game.growingBubble.size + game.growthRate, game.maxBubbleSize); game.growingBubble.verticalVelocity = 0; game.growingBubble.driftX = 0; } else { // Recalculate properties based on final size game.growingBubble.initLifetime(); game.growingBubble.floatSpeed = 50 * (120 / game.growingBubble.size * (0.9 + Math.random() * 0.2)) / 60; game.growingBubble.verticalVelocity = -12; game.growingBubble.driftX = (Math.random() * 2 - 1) * 2.5; game.growingBubble = null; game.mouthOpenDuration = 0; } } ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
User prompt
update with: if (game.growingBubble) { // Recalculate float speed and lifetime based on final size game.growingBubble.floatSpeed = 50 * (120 / game.growingBubble.size * (0.9 + Math.random() * 0.2)) / 60; game.growingBubble.initLifetime(); // Then apply the release velocity game.growingBubble.verticalVelocity = -12; game.growingBubble.driftX = (Math.random() * 2 - 1) * 2.5; game.growingBubble = null; game.mouthOpenDuration = 0; }
===================================================================
--- original.js
+++ change.js
@@ -14,15 +14,43 @@
self.hasSplit = false;
self.splitHeight = null;
self.AUTO_POP_SIZE = 40;
self.MIN_SPLIT_SIZE = 30;
- self.lastPopTime = 0; // Add timestamp tracking
+ self.lastPopTime = 0;
+ self.visible = false; // Start invisible in pool
var sprite = self.attachAsset('bubble', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
self.size = 100;
+ self.activate = function (x, y, size) {
+ self.x = x;
+ self.y = y;
+ self.size = size;
+ self.lifetime = 0;
+ self.hasSplit = false;
+ self.splitHeight = null;
+ self.justSplit = false;
+ self.autoPopDisplayed = false;
+ self.initLifetime();
+ self.visible = true;
+ // Reset velocities
+ self.verticalVelocity = 0;
+ self.driftX = (Math.random() * 20 - 10) / 60;
+ self.floatSpeed = 50 * (120 / size * (0.9 + Math.random() * 0.2)) / 60;
+ };
+ self.deactivate = function () {
+ self.visible = false;
+ var index = game.activeBubbles.indexOf(self);
+ if (index > -1) {
+ game.activeBubbles.splice(index, 1);
+ }
+ // Don't award BP for off-screen bubbles
+ if (self.y > -self.size) {
+ game.addBP(self.getBP(), self.x, self.y, true);
+ }
+ };
self.initLifetime = function () {
self.maxLifetime = Math.floor(Math.random() * 960 + 1440);
self.maxLifetime *= Math.min(1, self.size / 100);
};
@@ -32,80 +60,64 @@
self.floatSpeed = 50 * speedMultiplier / 60;
self.driftX = (Math.random() * 20 - 10) / 60; // Normal drift variance
self.verticalVelocity = 0;
self.down = function (e) {
- // Add cooldown check (100ms)
var currentTime = Date.now();
if (currentTime - self.lastPopTime < 100) {
- return true; // Ignore clicks too close together
+ return true;
}
self.lastPopTime = currentTime;
- var index = game.bubbles.indexOf(self);
- if (index > -1) {
- game.bubbles.splice(index, 1);
- }
var points = self.getBP();
- game.addBP(points, self.x, self.y, false); // Pass position and flag for manual pop
- // Only split if manually popped and large enough
+ game.addBP(points, self.x, self.y, false);
if (self.size > 60 && !self.justSplit) {
var splitCount = 2 + UPGRADE_CONFIG.machine.bubbleDurability.currentLevel;
var newSize = Math.max(self.MIN_SPLIT_SIZE, self.size * 0.6);
for (var i = 0; i < splitCount; i++) {
var angle = i / splitCount * Math.PI * 2;
- spawnSplitBubble(self.x, self.y, newSize, Math.cos(angle),
- // More even distribution
- false);
+ spawnBubble(self.x, self.y, newSize, Math.cos(angle), false);
}
}
- self.destroy();
- return true; // Stop event propagation
+ self.deactivate();
+ return true;
};
self.getBP = function () {
return Math.max(1, Math.floor(Math.pow(self.size, 1.4) * 0.02));
};
self.update = function () {
self.lifetime++;
- // Add subtle drift variation
if (self.lifetime % 60 === 0) {
- // Every second
- self.driftX += (Math.random() - 0.5) * 0.3; // Add small random drift
+ self.driftX += (Math.random() - 0.5) * 0.3;
}
- // Increase overall horizontal movement
- self.x += self.driftX * 1.2; // 20% more horizontal movement
- // Auto-pop or split when lifetime exceeded
+ self.x += self.driftX * 1.2;
if (self.lifetime > self.maxLifetime) {
- // Just check size and not already split
if (self.size > 60 && !self.hasSplit) {
self.hasSplit = true;
var newSize = Math.max(self.MIN_SPLIT_SIZE, self.size * 0.6);
for (var i = 0; i < 2; i++) {
- var split = spawnSplitBubble(self.x, self.y, newSize, i === 0 ? -1 : 1, true);
- split.maxLifetime *= 0.7; // Shorter lifetime for split bubbles
+ var split = spawnBubble(self.x, self.y, newSize, i === 0 ? -1 : 1, true);
+ if (split) {
+ split.maxLifetime *= 0.7;
+ }
}
- self.destroy();
+ self.deactivate();
return;
}
- // If too small to split, just pop
self.autoPop();
return;
}
- // Clear off-screen bubbles
if (self.y < -self.size) {
- self.destroy();
+ self.deactivate();
return;
}
- self.justSplit = false; // Clear the flag after first update
- // More gradual vertical speed transition
+ self.justSplit = false;
if (self.verticalVelocity < self.floatSpeed) {
- self.verticalVelocity += 0.08; // More gentle transition
+ self.verticalVelocity += 0.08;
}
self.y -= self.verticalVelocity;
- // Gradually reduce horizontal speed after split
if (Math.abs(self.driftX) > (Math.random() * 20 - 10) / 60) {
- self.driftX *= 0.98; // Slowly return to normal drift speed
+ self.driftX *= 0.98;
}
self.x += self.driftX;
- // Bounce off edges
if (self.x < self.size) {
self.x = self.size;
self.driftX = Math.abs(self.driftX);
} else if (self.x > game.width - self.size) {
@@ -117,13 +129,13 @@
sprite.scaleY = scale;
};
self.autoPop = function () {
if (!self.autoPopDisplayed) {
- var points = Math.floor(self.getBP() * 0.5); // Half points for auto-pop
- game.addBP(points, self.x, self.y, true); // Added true flag for autoPop
+ var points = Math.floor(self.getBP() * 0.5);
+ game.addBP(points, self.x, self.y, true);
self.autoPopDisplayed = true;
}
- self.destroy();
+ self.deactivate();
return;
};
return self;
});
@@ -805,32 +817,36 @@
return new Bubble();
});
game.activeBubbles = [];
game.MAX_BUBBLES = 200; // Active bubble limit
+game.bubblePool.forEach(function (bubble) {
+ game.addChild(bubble);
+});
game.baseSpawnRate = 180; // Every 3 seconds
-function spawnSplitBubble(parentX, parentY, size, direction) {
+function spawnBubble(x, y, size) {
+ var direction = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
var isAutoPop = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
- var bubble = new Bubble();
- bubble.x = parentX;
- bubble.y = parentY;
- bubble.size = size;
- bubble.initLifetime(); // Recalculate after size is set
- bubble.justSplit = true;
- var speedMultiplier = 120 / size * (0.9 + Math.random() * 0.2);
+ if (game.activeBubbles.length >= game.MAX_BUBBLES) {
+ return null;
+ }
+ // Find first available bubble in pool
+ var bubble = game.bubblePool.find(function (b) {
+ return !b.visible;
+ });
+ if (!bubble) {
+ return null;
+ }
+ bubble.activate(x, y, size);
if (isAutoPop) {
- // Pure upward/sideways motion for natural splits
- bubble.verticalVelocity = bubble.floatSpeed; // Start at float speed
+ bubble.verticalVelocity = bubble.floatSpeed;
bubble.driftX = direction * (Math.random() * 0.8 + 0.5);
} else {
- // Manual pop physics
bubble.verticalVelocity = -(Math.random() * 2 + 4);
bubble.driftX = direction * (Math.random() * 1.5 + 2);
}
- game.addChild(bubble);
- game.bubbles.push(bubble);
+ game.activeBubbles.push(bubble);
return bubble;
}
-game.bubbles = []; // Track bubble array
// Initialize game variables
//<Assets used in the game will automatically appear here>
game.bp = 0; // Track total BP
game.combo = 0;
@@ -930,16 +946,14 @@
// Only allow bubble creation if menu is closed and mouth has been open long enough
if (!menuOpen && facekit.mouthOpen && game.mouthOpenDuration >= game.MOUTH_OPEN_THRESHOLD) {
// Only allow new bubbles after cooldown
if (!game.growingBubble && game.blowCooldown <= 0) {
- // Calculate spawn position relative to pufferfish mask
var spawnX = playerMask.x;
var spawnY = playerMask.y + playerMask.height * 0.15;
- game.growingBubble = new Bubble();
- game.growingBubble.size = game.MIN_SPAWN_SIZE;
- game.addChild(game.growingBubble);
- game.bubbles.push(game.growingBubble);
- game.blowCooldown = game.BLOW_COOLDOWN_TIME;
+ game.growingBubble = spawnBubble(spawnX, spawnY, game.MIN_SPAWN_SIZE, 0, false);
+ if (game.growingBubble) {
+ game.blowCooldown = game.BLOW_COOLDOWN_TIME;
+ }
}
if (game.growingBubble) {
game.growingBubble.x = playerMask.x;
game.growingBubble.y = playerMask.y + playerMask.height * 0.15;
@@ -968,27 +982,19 @@
var fish = new Fish();
game.addChild(fish);
}
}
- // Update all children (bubbles)
- // Only spawn if under max bubbles
- if (game.bubbles.length < game.MAX_BUBBLES) {
+ if (game.activeBubbles.length < game.MAX_BUBBLES) {
if (LK.ticks % game.baseSpawnRate == 0) {
var x = Math.random() * (game.width - 200) + 100;
- spawnSplitBubble(x, game.height + 100, 100, 0);
+ spawnBubble(x, game.height + 100, 100, 0, true);
}
}
- // Clean up destroyed bubbles from array
- game.bubbles = game.bubbles.filter(function (bubble) {
- return !bubble.destroyed;
- });
- // Update all children (bubbles)
- for (var i = game.bubbles.length - 1; i >= 0; i--) {
- var bubble = game.bubbles[i];
+ game.activeBubbles.forEach(function (bubble) {
if (bubble.update) {
bubble.update();
}
- }
+ });
};
// Handle touch/mouse events for the game
game.down = function (x, y, obj) {
var localX = x - menuContainer.x;
@@ -1023,10 +1029,11 @@
return true; // Let containers handle their own clicks
}
// Bubble popping logic remains the same
var popped = false;
- for (var i = game.bubbles.length - 1; i >= 0; i--) {
- var bubble = game.bubbles[i];
+ // NEW:
+ for (var i = game.activeBubbles.length - 1; i >= 0; i--) {
+ var bubble = game.activeBubbles[i];
var dx = x - bubble.x;
var dy = y - bubble.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (!popped && distance <= bubble.size / 2 + 10 && bubble.down) {
A treasure chest with gold coins. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A golden skull with diamonds for eyes. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A golden necklace with a ruby pendant. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A filled in white circle.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A yellow star. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a game logo for a game called 'Bubble Blower Tycoon' about a happy purple pufferfish with yellow fins and spines that builds an underwater empire of bubbles. Cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
an SVG of the word 'Start'. word should be yellow and the font should look like its made out of bubbles. cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
bubblelow
Sound effect
backgroundmusic
Music
bubblehigh
Sound effect
bubble1
Sound effect
bubble2
Sound effect
bubble3
Sound effect
bubble4
Sound effect
blowing
Sound effect
bubbleshoot
Sound effect
fishtank
Sound effect
menuopen
Sound effect
upgrade
Sound effect
jellyfish
Sound effect
titlemusic
Music
startbutton
Sound effect