User prompt
Move the background initialization to before updateallupgrade texts
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Can't find variable: menuContainer' in or related to this line: 'menuContainer.addChild(tabContainer);' Line Number: 443
Code edit (6 edits merged)
Please save this source code
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'upgradeTexts.forEach')' in or related to this line: 'upgradeTexts.forEach(function (text) {' Line Number: 398
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'upgradeTexts.forEach')' in or related to this line: 'upgradeTexts.forEach(function (text) {' Line Number: 398
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'upgradeSections.bubbles')' in or related to this line: 'upgradeSections.bubbles.visible = true; // Show default tab' Line Number: 403
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'upgradeSections.bubbles')' in or related to this line: 'upgradeSections.bubbles.visible = true; // Show default tab' Line Number: 397
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'upgradeSections.bubbles')' in or related to this line: 'upgradeSections.bubbles.visible = true; // Show default tab' Line Number: 397
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'menuTextContainer.addChild')' in or related to this line: 'menuTextContainer.addChild(section);' Line Number: 406
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'menuTextContainer.addChild')' in or related to this line: 'menuTextContainer.addChild(section);' Line Number: 406
Code edit (2 edits merged)
Please save this source code
User prompt
Update with: // Set up menus var currentTab = 'bubbles'; // Default tab var menuTabs = ['bubbles', 'clams', 'colors', 'decorations']; var tabButtons = {}; // Will hold references to tab buttons var menuOpen = false; // Create menu container var menuContainer = new Container(); menuContainer.x = game.width / 2; menuContainer.y = game.height; // Position at bottom initially // Create upgrade button (visible when menu closed) var upgradeTab = LK.getAsset('upgradetab', { anchorX: 0.5, anchorY: 1, y: 0, scaleX: 3, scaleY: 0.8, alpha: 0.9 }); // Add button text var upgradeText = new Text2("Upgrades", { size: 70, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 3, font: "Impact" }); upgradeText.anchor = { x: 0.5, y: 0.5 }; upgradeText.x = 0; upgradeText.y = -upgradeTab.height * upgradeTab.scaleY / 2; upgradeTab.addChild(upgradeText); // Create main panel (full screen size minus margins) var menuPanel = LK.getAsset('upgradetab', { anchorX: 0.5, anchorY: 0, y: -upgradeTab.height * upgradeTab.scaleY, // Position above the button scaleX: 2048 / 200, scaleY: (game.height - 2 * (upgradeTab.height * upgradeTab.scaleY)) / 299, alpha: 0.9 }); // Add panel and button to container menuContainer.addChild(menuPanel); menuContainer.addChild(upgradeTab); // Create text container for upgrades var menuTextContainer = new Container(); menuTextContainer.y = -menuPanel.height * menuPanel.scaleY / 2; // Center in panel menuContainer.addChild(menuTextContainer); // Create tab container at the bottom of the menu panel var tabContainer = new Container(); tabContainer.y = -menuPanel.height * menuPanel.scaleY + 100; // Position at bottom of panel menuContainer.addChild(tabContainer); // Create upgrade sections var upgradeSections = { bubbles: new Container(), clams: new Container(), colors: new Container(), decorations: new Container() }; // Add sections to text container Object.values(upgradeSections).forEach(function(section) { menuTextContainer.addChild(section); section.visible = false; // Hide all initially }); // Add menu container to game game.addChild(menuContainer);
User prompt
Update with: // Inside game.down function // Check if upgrade tab was clicked var localX = x - menuContainer.x; var localY = y - menuContainer.y; if (localX >= -upgradeTab.width * upgradeTab.scaleX / 2 && localX <= upgradeTab.width * upgradeTab.scaleX / 2 && localY >= -upgradeTab.height * upgradeTab.scaleY && localY <= 0) { menuOpen = !menuOpen; var targetY = menuOpen ? upgradeTab.height * upgradeTab.scaleY : game.height; if (menuOpen) { game.setChildIndex(menuContainer, game.children.length - 1); } tween(menuContainer, { y: targetY }, { duration: 300, easing: tween.easeOutBack, onFinish: function() { if (!menuOpen) { game.setChildIndex(menuContainer, 1); } } }); return true; } ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Update only as needed with: // Set up menus var currentTab = 'bubbles'; // Default tab var menuTabs = ['bubbles', 'clams', 'colors', 'decorations']; var tabButtons = {}; // Will hold references to tab buttons var menuOpen = false; // Create menu container var menuContainer = new Container(); menuContainer.x = game.width / 2; menuContainer.y = game.height; // Position at bottom initially // Create main panel first (taller to fill more screen space) var menuPanel = LK.getAsset('upgradetab', { anchorX: 0.5, anchorY: 1, // Anchor at bottom y: 0, scaleX: game.width / 200, scaleY: game.height * 0.8 / 299, // Make it taller - 80% of screen height alpha: 0.9 }); menuContainer.addChild(menuPanel); // Create upgrade button at top of panel var upgradeTab = LK.getAsset('upgradetab', { anchorX: 0.5, anchorY: 1, // Anchor at bottom y: -menuPanel.height * menuPanel.scaleY, // Position at top of panel scaleX: 3, scaleY: 0.8, alpha: 0.9 }); menuContainer.addChild(upgradeTab); // Add upgrade text to button (correctly sized) var upgradeText = new Text2("Upgrades", { size: 70, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 3, font: "Impact" }); upgradeText.anchor = { x: 0.5, y: 0.5 }; upgradeText.x = 0; upgradeText.y = -upgradeTab.height * upgradeTab.scaleY / 2; upgradeTab.addChild(upgradeText); // Create text container for upgrades var menuTextContainer = new Container(); menuTextContainer.y = -menuPanel.height * menuPanel.scaleY / 2; // Center in panel menuContainer.addChild(menuTextContainer); // Create upgrade sections var upgradeSections = { bubbles: new Container(), clams: new Container(), colors: new Container(), decorations: new Container() }; // Add sections to text container Object.values(upgradeSections).forEach(function(section) { menuTextContainer.addChild(section); section.visible = false; // Hide all initially }); // Create tab container at the BOTTOM of the menu panel var tabContainer = new Container(); tabContainer.y = -50; // Position near bottom of panel, adjust as needed menuContainer.addChild(tabContainer); function switchToTab(tabName) { if (currentTab === tabName) return; // Update current tab currentTab = tabName; // Highlight active tab highlightTab(tabName); // Hide all upgrade sections Object.values(upgradeSections).forEach(function(section) { section.visible = false; }); // Show selected section upgradeSections[tabName].visible = true; } function highlightTab(tabName) { // Reset all tabs Object.keys(tabButtons).forEach(function(tab) { tabButtons[tab].bg.alpha = 0.6; tabButtons[tab].text.fill = 0xFFFFFF; }); // Highlight selected tab tabButtons[tabName].bg.alpha = 1; tabButtons[tabName].text.fill = 0xFFFF00; } function initializeMenuTabs() { // Create tab buttons var tabWidth = menuPanel.width * menuPanel.scaleX / menuTabs.length; menuTabs.forEach(function(tabName, index) { // Create tab background var tabBg = LK.getAsset('upgradetab', { anchorX: 0.5, anchorY: 0.5, x: (index - 1.5) * tabWidth + tabWidth / 2, scaleX: tabWidth / 200, scaleY: 0.5, alpha: 0.6 }); // Tab text var tabText = new Text2(tabName.charAt(0).toUpperCase() + tabName.slice(1), { size: 60, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 2, font: "Impact" }); tabText.anchor = { x: 0.5, y: 0.5 }; tabText.x = (index - 1.5) * tabWidth + tabWidth / 2; // Add to tab container tabContainer.addChild(tabBg); tabContainer.addChild(tabText); // Store reference to tab button tabButtons[tabName] = { bg: tabBg, text: tabText }; // Add click handler tabBg.down = function() { switchToTab(tabName); return true; }; }); // Highlight default tab highlightTab(currentTab); // Show bubbles section by default upgradeSections.bubbles.visible = true; } // Add menu container to game game.addChild(menuContainer); initializeMenuTabs(); // Update click handling in game.down upgradeTab.down = function() { menuOpen = !menuOpen; var targetY = menuOpen ? menuPanel.height * menuPanel.scaleY : game.height; if (menuOpen) { game.setChildIndex(menuContainer, game.children.length - 1); } tween(menuContainer, { y: targetY }, { duration: 300, easing: tween.easeOutBack, onFinish: function() { if (!menuOpen) { game.setChildIndex(menuContainer, 1); } } }); return true; }; ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Update as needed with: // Set up menus var currentTab = 'bubbles'; // Default tab var menuTabs = ['bubbles', 'clams', 'colors', 'decorations']; var tabButtons = {}; // Will hold references to tab buttons var menuOpen = false; // Create menu container var menuContainer = new Container(); menuContainer.x = game.width / 2; menuContainer.y = game.height; // Position at bottom initially // Create main panel first (taller to fill more screen space) var menuPanel = LK.getAsset('upgradetab', { anchorX: 0.5, anchorY: 1, // Anchor at bottom y: 0, scaleX: game.width / 200, scaleY: game.height * 0.8 / 299, // Make it taller - 80% of screen height alpha: 0.9 }); menuContainer.addChild(menuPanel); // Create upgrade button at top of panel var upgradeTab = LK.getAsset('upgradetab', { anchorX: 0.5, anchorY: 1, // Anchor at bottom y: -menuPanel.height * menuPanel.scaleY, // Position at top of panel scaleX: 3, scaleY: 0.8, alpha: 0.9 }); menuContainer.addChild(upgradeTab); // Add upgrade text to button (correctly sized) var upgradeText = new Text2("Upgrades", { size: 70, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 3, font: "Impact" }); upgradeText.anchor = { x: 0.5, y: 0.5 }; upgradeText.x = 0; upgradeText.y = -upgradeTab.height * upgradeTab.scaleY / 2; upgradeTab.addChild(upgradeText); // Create text container for upgrades var menuTextContainer = new Container(); menuTextContainer.y = -menuPanel.height * menuPanel.scaleY / 2; // Center in panel menuContainer.addChild(menuTextContainer); // Create upgrade sections var upgradeSections = { bubbles: new Container(), clams: new Container(), colors: new Container(), decorations: new Container() }; // Add sections to text container Object.values(upgradeSections).forEach(function(section) { menuTextContainer.addChild(section); section.visible = false; // Hide all initially }); // Create tab container at the BOTTOM of the menu panel var tabContainer = new Container(); tabContainer.y = -50; // Position near bottom of panel, adjust as needed menuContainer.addChild(tabContainer); function switchToTab(tabName) { if (currentTab === tabName) return; // Update current tab currentTab = tabName; // Highlight active tab highlightTab(tabName); // Hide all upgrade sections Object.values(upgradeSections).forEach(function(section) { section.visible = false; }); // Show selected section upgradeSections[tabName].visible = true; } function highlightTab(tabName) { // Reset all tabs Object.keys(tabButtons).forEach(function(tab) { tabButtons[tab].bg.alpha = 0.6; tabButtons[tab].text.fill = 0xFFFFFF; }); // Highlight selected tab tabButtons[tabName].bg.alpha = 1; tabButtons[tabName].text.fill = 0xFFFF00; } function initializeMenuTabs() { // Create tab buttons var tabWidth = menuPanel.width * menuPanel.scaleX / menuTabs.length; menuTabs.forEach(function(tabName, index) { // Create tab background var tabBg = LK.getAsset('upgradetab', { anchorX: 0.5, anchorY: 0.5, x: (index - 1.5) * tabWidth + tabWidth / 2, scaleX: tabWidth / 200, scaleY: 0.5, alpha: 0.6 }); // Tab text var tabText = new Text2(tabName.charAt(0).toUpperCase() + tabName.slice(1), { size: 60, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 2, font: "Impact" }); tabText.anchor = { x: 0.5, y: 0.5 }; tabText.x = (index - 1.5) * tabWidth + tabWidth / 2; // Add to tab container tabContainer.addChild(tabBg); tabContainer.addChild(tabText); // Store reference to tab button tabButtons[tabName] = { bg: tabBg, text: tabText }; // Add click handler tabBg.down = function() { switchToTab(tabName); return true; }; }); // Highlight default tab highlightTab(currentTab); // Show bubbles section by default upgradeSections.bubbles.visible = true; } // Add menu container to game game.addChild(menuContainer); initializeMenuTabs(); // Update click handling in game.down upgradeTab.down = function() { menuOpen = !menuOpen; var targetY = menuOpen ? menuPanel.height * menuPanel.scaleY : game.height; if (menuOpen) { game.setChildIndex(menuContainer, game.children.length - 1); } tween(menuContainer, { y: targetY }, { duration: 300, easing: tween.easeOutBack, onFinish: function() { if (!menuOpen) { game.setChildIndex(menuContainer, 1); } } }); return true; }; ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Update with: // Update the tween function where menu is opened/closed tween(menuContainer, { y: targetY }, { duration: 300, easing: tween.easeOutBack, onUpdate: function(progress) { // Show tabs only when menu is fully open tabsContainer.visible = progress > 0.9 && menuOpen; }, onFinish: function() { tabsContainer.visible = menuOpen; if (!menuOpen) { game.setChildIndex(menuContainer, 1); } } }); ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (2 edits merged)
Please save this source code
User prompt
Update with: Object.values(tabContainers).forEach(function(tabContainer) { tabContainer.children.forEach(function (child) { // ...existing code that finds and updates text elements }); });
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'menuTextContainer.addChild')' in or related to this line: 'menuTextContainer.addChild(contentContainer);' Line Number: 741
User prompt
Please fix the bug: 'Can't find variable: getTabForUpgrade' in or related to this line: 'var targetContainer = tabContainers[getTabForUpgrade(category, key)];' Line Number: 914
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'menuTextContainer.addChild')' in or related to this line: 'menuTextContainer.addChild(contentContainer);' Line Number: 741
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'menuTextContainer.addChild')' in or related to this line: 'menuTextContainer.addChild(contentContainer);' Line Number: 741
===================================================================
--- original.js
+++ change.js
@@ -283,9 +283,256 @@
/****
* Game Code
****/
-// Initialize game variables
+var UPGRADE_EFFECTS = {
+ lungCapacity: {
+ baseValue: 160,
+ // Base max bubble size
+ incrementPercent: 25 // +25% per level
+ },
+ quickBreath: {
+ baseValue: 1.6,
+ // Base growth rate
+ incrementPercent: 25 // +25% per level
+ },
+ autoBubbleSpeed: {
+ decrementPercent: 10 // -10% production time per level
+ },
+ bubbleDurability: {
+ extraSplits: 1 // +1 split per level
+ },
+ autoPop: {
+ timeReduction: 0.8 // Reduces lifetime by 20% per level
+ }
+};
+function _slicedToArray3(r, e) {
+ return _arrayWithHoles3(r) || _iterableToArrayLimit3(r, e) || _unsupportedIterableToArray3(r, e) || _nonIterableRest3();
+}
+function _nonIterableRest3() {
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+}
+function _unsupportedIterableToArray3(r, a) {
+ if (r) {
+ if ("string" == typeof r) {
+ return _arrayLikeToArray3(r, a);
+ }
+ var t = {}.toString.call(r).slice(8, -1);
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray3(r, a) : void 0;
+ }
+}
+function _arrayLikeToArray3(r, a) {
+ (null == a || a > r.length) && (a = r.length);
+ for (var e = 0, n = Array(a); e < a; e++) {
+ n[e] = r[e];
+ }
+ return n;
+}
+function _iterableToArrayLimit3(r, l) {
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
+ if (null != t) {
+ var e,
+ n,
+ i,
+ u,
+ a = [],
+ f = !0,
+ o = !1;
+ try {
+ if (i = (t = t.call(r)).next, 0 === l) {
+ if (Object(t) !== t) {
+ return;
+ }
+ f = !1;
+ } else {
+ for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) {
+ ;
+ }
+ }
+ } catch (r) {
+ o = !0, n = r;
+ } finally {
+ try {
+ if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) {
+ return;
+ }
+ } finally {
+ if (o) {
+ throw n;
+ }
+ }
+ }
+ return a;
+ }
+}
+function _arrayWithHoles3(r) {
+ if (Array.isArray(r)) {
+ return r;
+ }
+}
+function getUpgradeCost(upgrade) {
+ if (upgrade.amount !== undefined) {
+ // For clams
+ return Math.floor(upgrade.baseCost * Math.pow(upgrade.costScale, upgrade.amount));
+ } else {
+ // For regular upgrades
+ return Math.floor(upgrade.baseCost * Math.pow(upgrade.costScale, upgrade.currentLevel));
+ }
+}
+function _slicedToArray2(r, e) {
+ return _arrayWithHoles2(r) || _iterableToArrayLimit2(r, e) || _unsupportedIterableToArray2(r, e) || _nonIterableRest2();
+}
+function _nonIterableRest2() {
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+}
+function _unsupportedIterableToArray2(r, a) {
+ if (r) {
+ if ("string" == typeof r) {
+ return _arrayLikeToArray2(r, a);
+ }
+ var t = {}.toString.call(r).slice(8, -1);
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray2(r, a) : void 0;
+ }
+}
+function _arrayLikeToArray2(r, a) {
+ (null == a || a > r.length) && (a = r.length);
+ for (var e = 0, n = Array(a); e < a; e++) {
+ n[e] = r[e];
+ }
+ return n;
+}
+function _iterableToArrayLimit2(r, l) {
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
+ if (null != t) {
+ var e,
+ n,
+ i,
+ u,
+ a = [],
+ f = !0,
+ o = !1;
+ try {
+ if (i = (t = t.call(r)).next, 0 === l) {
+ if (Object(t) !== t) {
+ return;
+ }
+ f = !1;
+ } else {
+ for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) {
+ ;
+ }
+ }
+ } catch (r) {
+ o = !0, n = r;
+ } finally {
+ try {
+ if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) {
+ return;
+ }
+ } finally {
+ if (o) {
+ throw n;
+ }
+ }
+ }
+ return a;
+ }
+}
+function _arrayWithHoles2(r) {
+ if (Array.isArray(r)) {
+ return r;
+ }
+}
+function updateClams() {
+ if (!game.clamSpawnPoints) {
+ return;
+ }
+ game.clamSpawnPoints.forEach(function (spawnPoint) {
+ var config = UPGRADE_CONFIG.machines[spawnPoint.type];
+ // Calculate production time with speed upgrade
+ var baseTime = config.production * 60; // Convert to frames
+ var speedMultiplier = Math.pow(1 - UPGRADE_EFFECTS.autoBubbleSpeed.decrementPercent / 100, UPGRADE_CONFIG.machine.autoBubbleSpeed.currentLevel);
+ var adjustedTime = Math.max(1, Math.floor(baseTime * speedMultiplier));
+ if (LK.ticks % adjustedTime === 0) {
+ // Find first available bubble in pool
+ var bubble = game.bubblePool.find(function (b) {
+ return !b.visible;
+ });
+ if (bubble && game.activeBubbles.length < game.MAX_BUBBLES) {
+ bubble.activate(spawnPoint.x, spawnPoint.y, config.bubbleSize, false // not player blown
+ );
+ // Set initial velocities for clam bubbles
+ bubble.verticalVelocity = 0;
+ bubble.driftX = (spawnPoint.isRight ? -1 : 1) * (Math.random() * 1.5 + 2);
+ game.activeBubbles.push(bubble);
+ }
+ }
+ });
+}
+function _slicedToArray(r, e) {
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
+}
+function _nonIterableRest() {
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+}
+function _unsupportedIterableToArray(r, a) {
+ if (r) {
+ if ("string" == typeof r) {
+ return _arrayLikeToArray(r, a);
+ }
+ var t = {}.toString.call(r).slice(8, -1);
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
+ }
+}
+function _arrayLikeToArray(r, a) {
+ (null == a || a > r.length) && (a = r.length);
+ for (var e = 0, n = Array(a); e < a; e++) {
+ n[e] = r[e];
+ }
+ return n;
+}
+function _iterableToArrayLimit(r, l) {
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
+ if (null != t) {
+ var e,
+ n,
+ i,
+ u,
+ a = [],
+ f = !0,
+ o = !1;
+ try {
+ if (i = (t = t.call(r)).next, 0 === l) {
+ if (Object(t) !== t) {
+ return;
+ }
+ f = !1;
+ } else {
+ for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) {
+ ;
+ }
+ }
+ } catch (r) {
+ o = !0, n = r;
+ } finally {
+ try {
+ if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) {
+ return;
+ }
+ } finally {
+ if (o) {
+ throw n;
+ }
+ }
+ }
+ return a;
+ }
+}
+function _arrayWithHoles(r) {
+ if (Array.isArray(r)) {
+ return r;
+ }
+}
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: game.width / 2,
@@ -300,39 +547,50 @@
player: {
lungCapacity: {
name: "Lung Capacity",
baseCost: 100,
+ // About 1-2 max bubbles
costScale: 3.0,
+ // Steeper scaling
maxLevel: 10,
currentLevel: 0
},
quickBreath: {
name: "Quick Breath",
baseCost: 100,
+ // 2-3 max bubbles
costScale: 3.0,
+ // Steeper scaling
maxLevel: 10,
currentLevel: 0
},
autoPop: {
+ // Moved here from machine section
name: "Fish Friends",
+ // Updated name
baseCost: 400,
+ // Changed from 1000
costScale: 3,
maxLevel: 6,
+ // Changed from 5
currentLevel: 0
}
},
machines: {
basicClam: {
name: "Basic Clam",
baseCost: 300,
+ // 6-7 max bubbles
costScale: 2,
+ // Slightly steeper scaling
amount: 0,
production: 3,
bubbleSize: 80
},
advancedClam: {
name: "Advanced Clam",
baseCost: 3000,
+ // Requires running basic clams for a while
costScale: 3.0,
amount: 0,
production: 2,
bubbleSize: 100,
@@ -340,8 +598,9 @@
},
premiumClam: {
name: "Premium Clam",
baseCost: 20000,
+ // True end-game content
costScale: 3,
amount: 0,
production: 1,
bubbleSize: 150,
@@ -352,8 +611,9 @@
bubbleDurability: {
name: "Bubble Splitting",
baseCost: 500,
costScale: 5,
+ // Significant scaling
maxLevel: 3,
currentLevel: 0
},
autoBubbleSpeed: {
@@ -364,42 +624,26 @@
currentLevel: 0
}
}
};
-var UPGRADE_EFFECTS = {
- lungCapacity: {
- baseValue: 160,
- incrementPercent: 25
- },
- quickBreath: {
- baseValue: 1.6,
- incrementPercent: 25
- },
- autoBubbleSpeed: {
- decrementPercent: 10
- },
- bubbleDurability: {
- extraSplits: 1
- },
- autoPop: {
- timeReduction: 0.8
- }
-};
game.showError = function (message) {
var errorText = new Text2(message, {
size: 120,
fill: 0xFF0000,
stroke: 0x000000,
strokeThickness: 5,
font: "Impact"
});
+ // Set the anchor point to center the text
errorText.anchor = {
x: 0.5,
y: 0.5
};
+ // Position at the center of the screen
errorText.x = game.width / 2;
errorText.y = game.height / 2;
game.addChild(errorText);
+ // Animate the text
tween(errorText, {
alpha: 0,
y: errorText.y - 50
}, {
@@ -408,190 +652,165 @@
errorText.destroy();
}
});
};
-function getUpgradeCost(upgrade) {
- if (upgrade.amount !== undefined) {
- // For clams
- return Math.floor(upgrade.baseCost * Math.pow(upgrade.costScale, upgrade.amount));
- } else {
- // For regular upgrades
- return Math.floor(upgrade.baseCost * Math.pow(upgrade.costScale, upgrade.currentLevel));
- }
-}
-function formatBP(value) {
- var units = ['', 'K', 'M', 'B', 'T'];
- var unitIndex = 0;
- while (value >= 1000 && unitIndex < units.length - 1) {
- value /= 1000;
- unitIndex++;
- }
- return Math.floor(value * 10) / 10 + units[unitIndex];
-}
-// Set up menus
var currentTab = 'bubbles'; // Default tab
var menuTabs = ['bubbles', 'clams', 'colors', 'decorations'];
var tabButtons = {}; // Will hold references to tab buttons
-var menuOpen = false;
-// Create menu container
-var menuContainer = new Container();
-menuContainer.x = game.width / 2;
-menuContainer.y = game.height; // Position at bottom initially
-// Create main panel first (taller to fill more screen space)
-var menuPanel = LK.getAsset('upgradetab', {
+// Create upgrade menu elements
+// Menu tab (handle)
+// First position the panel relative to container at y=0
+// Menu panel should be below the tab in the container
+var menuTab = LK.getAsset('upgradetab', {
anchorX: 0.5,
anchorY: 1,
- // Anchor at bottom
+ // Change to bottom anchor
y: 0,
- scaleX: game.width / 200,
- scaleY: game.height * 0.8 / 299,
- // Make it taller - 80% of screen height
+ // Will be at container's position
+ scaleX: 3,
+ scaleY: 0.8,
alpha: 0.9
});
-menuContainer.addChild(menuPanel);
-// Create upgrade button at top of panel
-var upgradeTab = LK.getAsset('upgradetab', {
+var menuPanel = LK.getAsset('upgradetab', {
anchorX: 0.5,
+ anchorY: 0,
+ y: -570,
+ alpha: 0.9,
+ scaleX: 2048 / 200,
+ // Use the width of the asset directly
+ scaleY: game.height * 0.4 / 100.3
+});
+// Initialize menu structure
+// Initialize menu container at the right position
+var menuContainer = new Container();
+menuContainer.x = game.width / 2;
+menuContainer.y = game.height; // Position at bottom
+var menuPanel = LK.getAsset('upgradetab', {
+ anchorX: 0.5,
+ anchorY: 0,
+ y: -570,
+ alpha: 0.9,
+ scaleX: 2048 / 200,
+ scaleY: game.height * 0.4 / 100.3
+});
+var menuTab = LK.getAsset('upgradetab', {
+ anchorX: 0.5,
anchorY: 1,
- // Anchor at bottom
- y: -menuPanel.height * menuPanel.scaleY,
- // Position at top of panel
+ y: 0,
scaleX: 3,
scaleY: 0.8,
alpha: 0.9
});
-menuContainer.addChild(upgradeTab);
-// Add upgrade text to button (correctly sized)
-var upgradeText = new Text2("Upgrades", {
- size: 70,
+// Add panel first (so it's behind tab)
+menuContainer.addChild(menuPanel);
+menuContainer.addChild(menuTab);
+// Add this after the menuPanel is created but before upgradeTexts are created
+var tabContainers = {};
+var tabHeight = 80;
+var tabWidth = menuPanel.width / menuTabs.length;
+// Create tab container (only visible when menu is open)
+var tabsContainer = new Container();
+tabsContainer.y = -menuPanel.height * menuPanel.scaleY; // Position at bottom of panel
+menuContainer.addChild(tabsContainer);
+// Create tab for each category
+menuTabs.forEach(function (tab, index) {
+ // Create container for this tab's content
+ var contentContainer = new Container();
+ contentContainer.visible = tab === currentTab;
+ tabContainers[tab] = contentContainer;
+ menuTextContainer.addChild(contentContainer);
+ // Create tab button
+ var tabButton = LK.getAsset('upgradetab', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: (index + 0.5) * tabWidth - menuPanel.width / 2,
+ scaleX: tabWidth / 200,
+ scaleY: tabHeight / 100,
+ alpha: tab === currentTab ? 1.0 : 0.7
+ });
+ // Tab label
+ var tabLabel = new Text2(tab.charAt(0).toUpperCase() + tab.slice(1), {
+ size: 70,
+ fill: 0xFFFFFF,
+ stroke: 0x000000,
+ strokeThickness: 2,
+ font: "Impact"
+ });
+ tabLabel.anchor = {
+ x: 0.5,
+ y: 0.5
+ };
+ tabLabel.x = tabButton.x;
+ tabLabel.y = tabHeight / 2;
+ // Add hit detection
+ tabButton.down = function () {
+ if (tab !== currentTab) {
+ switchTab(tab);
+ }
+ return true;
+ };
+ tabsContainer.addChild(tabButton);
+ tabsContainer.addChild(tabLabel);
+ tabButtons[tab] = tabButton;
+});
+// Function to switch between tabs
+function switchTab(newTab) {
+ // Hide old tab content, show new tab content
+ tabContainers[currentTab].visible = false;
+ tabContainers[newTab].visible = true;
+ // Update tab button appearance
+ tabButtons[currentTab].alpha = 0.7;
+ tabButtons[newTab].alpha = 1.0;
+ currentTab = newTab;
+}
+// Menu text setup - should be good as is
+var menuText = new Text2("Upgrades", {
+ size: 90,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3,
font: "Impact"
});
-upgradeText.anchor = {
+menuText.anchor = {
x: 0.5,
y: 0.5
};
-upgradeText.x = 0;
-upgradeText.y = -upgradeTab.height * upgradeTab.scaleY / 2;
-upgradeTab.addChild(upgradeText);
-// Create text container for upgrades
+menuText.x = 0; // Relative to container
+menuText.y = -menuTab.height / 2; // Position relative to container bottom
+menuContainer.addChild(menuText);
+// Add to game
+game.addChild(menuContainer);
+// Create text container AFTER panel scaling
var menuTextContainer = new Container();
-menuTextContainer.y = -menuPanel.height * menuPanel.scaleY / 2; // Center in panel
menuContainer.addChild(menuTextContainer);
-// Create tab container at the BOTTOM of the menu panel
-var tabContainer = new Container();
-tabContainer.y = -50; // Position near bottom of panel, adjust as needed
-menuContainer.addChild(tabContainer);
-// Create upgrade sections
-var upgradeSections = {
- bubbles: new Container(),
- clams: new Container(),
- colors: new Container(),
- decorations: new Container()
-};
-// Add sections to text container
-Object.values(upgradeSections).forEach(function (section) {
- menuTextContainer.addChild(section);
- section.visible = false; // Hide all initially
-});
-// Add menu container to game
-game.addChild(menuContainer);
-function switchToTab(tabName) {
- if (currentTab === tabName) {
- return;
- }
- // Update current tab
- currentTab = tabName;
- // Highlight active tab
- highlightTab(tabName);
- // Hide all upgrade sections
- Object.values(upgradeSections).forEach(function (section) {
- section.visible = false;
- });
- // Show selected section
- upgradeSections[tabName].visible = true;
-}
-function highlightTab(tabName) {
- // Reset all tabs
- Object.keys(tabButtons).forEach(function (tab) {
- tabButtons[tab].bg.alpha = 0.8;
- tabButtons[tab].text.fill = 0xFFFFFF;
- });
- // Highlight selected tab
- tabButtons[tabName].bg.alpha = 1;
- tabButtons[tabName].text.fill = 0xFFFF00;
-}
-function initializeMenuTabs() {
- // Create tab container at the bottom of the menu panel
- var tabContainer = new Container();
- tabContainer.y = -150; // Position above the bottom of the panel
- menuContainer.addChild(tabContainer);
- // Create tab buttons
- var tabWidth = menuPanel.width * menuPanel.scaleX / menuTabs.length;
- menuTabs.forEach(function (tabName, index) {
- // Create tab background
- var tabBg = LK.getAsset('upgradetab', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: (index - 1.5) * tabWidth + tabWidth / 2,
- scaleX: tabWidth / 200,
- scaleY: 0.5,
- alpha: 0.8
- });
- // Tab text
- var tabText = new Text2(tabName.charAt(0).toUpperCase() + tabName.slice(1), {
- size: 60,
- fill: 0xFFFFFF,
- stroke: 0x000000,
- strokeThickness: 2,
- font: "Impact"
- });
- tabText.anchor = {
- x: 0.5,
- y: 0.5
- };
- tabText.x = (index - 1.5) * tabWidth + tabWidth / 2;
- // Add to tab container
- tabContainer.addChild(tabBg);
- tabContainer.addChild(tabText);
- // Store reference to tab button
- tabButtons[tabName] = {
- bg: tabBg,
- text: tabText
- };
- // Add click handler
- tabBg.down = function () {
- switchToTab(tabName);
- return true;
- };
- });
- // Highlight default tab
- highlightTab(currentTab);
-}
+// Add upgrade texts to text container instead of panel
+var upgradeTexts = [];
var startY = 150;
var upgradeSpacing = 250;
var columnWidth = 1024;
-function createUpgradeText(category, key, index, isLeftColumn, tabSection) {
+// Create arrays to hold upgrade categories in desired order
+var leftColumnUpgrades = [['player', 'lungCapacity'], ['player', 'quickBreath'], ['player', 'autoPop']];
+var rightColumnUpgrades = [['machines', 'basicClam'], ['machines', 'advancedClam'], ['machines', 'premiumClam'], ['machine', 'bubbleDurability'], ['machine', 'autoBubbleSpeed']];
+// Function to create upgrade text
+function createUpgradeText(category, key, index, isLeftColumn) {
var upgrade = UPGRADE_CONFIG[category][key];
var xOffset = isLeftColumn ? -550 : 100;
- var yPos = startY + index % 5 * upgradeSpacing;
+ var yPos = startY + index * upgradeSpacing;
// Create hit container first (so it's behind text)
var hitContainer = new Container();
- // Create a shape for the hit area
+ // Create a shape for the hit area (can make visible for debugging)
var hitArea = LK.getAsset('blower', {
width: 400,
height: 150,
color: 0xFFFFFF,
alpha: 0.0 // Set to 0.2 to see hit areas
});
hitContainer.addChild(hitArea);
- hitContainer.x = xOffset;
- hitContainer.y = yPos;
+ hitContainer.x = xOffset; // Center on the text position
+ hitContainer.y = yPos; // Align with the text
// Adjust the hitArea position within the container to center properly
- hitArea.x = 0;
- hitArea.y = -40;
+ hitArea.x = 0; // Center horizontally
+ hitArea.y = -40; // Slightly above text to cover both name and cost
// Create name text
var nameText = new Text2(upgrade.name, {
size: 96,
fill: 0xFFFFFF,
@@ -613,96 +832,83 @@
costText.x = xOffset;
costText.y = yPos + 100;
// Add click handler to hit container
hitContainer.down = function () {
- // Your existing upgrade logic here
- return true;
- };
- // Add to the correct section
- upgradeSections[tabSection].addChild(hitContainer);
- upgradeSections[tabSection].addChild(nameText);
- upgradeSections[tabSection].addChild(costText);
-}
-// Organize upgrades by tab
-var bubbleUpgrades = [['player', 'lungCapacity'], ['player', 'quickBreath'], ['machine', 'bubbleDurability']];
-var clamUpgrades = [['machines', 'basicClam'], ['machines', 'advancedClam'], ['machines', 'premiumClam'], ['machine', 'autoBubbleSpeed'], ['player', 'autoPop']];
-// Add color upgrades from the new plans
-var colorUpgrades = [
- // Will add color upgrades from the Prismatic Bubbles section later
-];
-// Add decoration upgrades from the new plans
-var decorationUpgrades = [
- // Will add Bubble Coral and Sunken Treasures later
-];
-function initializeAllUpgrades() {
- // Add bubble upgrades
- bubbleUpgrades.forEach(function (upgrade, index) {
- createUpgradeText(upgrade[0], upgrade[1], index, index % 2 === 0, 'bubbles');
- });
- // Add clam upgrades
- clamUpgrades.forEach(function (upgrade, index) {
- createUpgradeText(upgrade[0], upgrade[1], index, index % 2 === 0, 'clams');
- });
- // Will add color and decoration upgrades later
-}
-function updateAllUpgradeTexts() {
- // Process bubble upgrades
- bubbleUpgrades.forEach(function (upgrade) {
- var category = upgrade[0];
- var key = upgrade[1];
- var upgradeConfig = UPGRADE_CONFIG[category][key];
- // Find the cost text for this upgrade in the bubbles section
- upgradeSections.bubbles.children.forEach(function (child) {
- if (child.text && child.text.includes("BP") && upgradeSections.bubbles.children.some(function (c) {
- return c.text === upgradeConfig.name && child.y > c.y;
- })) {
- // Check if max level reached
- if (upgradeConfig.currentLevel >= upgradeConfig.maxLevel) {
- child.setText("SOLD OUT");
+ var cost = getUpgradeCost(upgrade);
+ if (game.bp >= cost) {
+ if (category === 'machines') {
+ var 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;
} else {
- child.setText(getUpgradeCost(upgradeConfig) + " BP");
+ game.showError("Not enough space for more clams!");
+ return true;
}
- }
- });
- });
- // Process clam upgrades
- clamUpgrades.forEach(function (upgrade) {
- var category = upgrade[0];
- var key = upgrade[1];
- if (category === 'machines') {
- var upgradeConfig = UPGRADE_CONFIG[category][key];
- var totalClams = UPGRADE_CONFIG.machines.basicClam.amount + UPGRADE_CONFIG.machines.advancedClam.amount + UPGRADE_CONFIG.machines.premiumClam.amount;
- // Find the cost text for this upgrade in the clams section
- upgradeSections.clams.children.forEach(function (child) {
- if (child.text && child.text.includes("BP") && upgradeSections.clams.children.some(function (c) {
- return c.text === upgradeConfig.name && child.y > c.y;
- })) {
- // Check if sold out based on clam logic
- if (totalClams >= 4 && key === 'basicClam' || UPGRADE_CONFIG.machines.basicClam.amount <= UPGRADE_CONFIG.machines.advancedClam.amount && key === 'advancedClam' || UPGRADE_CONFIG.machines.advancedClam.amount <= UPGRADE_CONFIG.machines.premiumClam.amount && key === 'premiumClam') {
- child.setText("SOLD OUT");
- } else {
- child.setText(getUpgradeCost(upgradeConfig) + " BP");
- }
+ bpText.setText(formatBP(game.bp) + " BP");
+ // Update cost text based on whether more can be purchased
+ if (totalClams >= 4 && key === 'basicClam' || UPGRADE_CONFIG.machines.basicClam.amount <= UPGRADE_CONFIG.machines.advancedClam.amount && key === 'advancedClam' || UPGRADE_CONFIG.machines.advancedClam.amount <= UPGRADE_CONFIG.machines.premiumClam.amount && key === 'premiumClam') {
+ costText.setText("SOLD OUT");
+ } else {
+ costText.setText(getUpgradeCost(upgrade) + " BP");
}
- });
- } else {
- var upgradeConfig = UPGRADE_CONFIG[category][key];
- // Find the cost text for this upgrade in the clams section
- upgradeSections.clams.children.forEach(function (child) {
- if (child.text && child.text.includes("BP") && upgradeSections.clams.children.some(function (c) {
- return c.text === upgradeConfig.name && child.y > c.y;
- })) {
- // Check if max level reached
- if (upgradeConfig.currentLevel >= upgradeConfig.maxLevel) {
- child.setText("SOLD OUT");
- } else {
- child.setText(getUpgradeCost(upgradeConfig) + " BP");
- }
+ updateClamVisuals();
+ } else if (upgrade.currentLevel < upgrade.maxLevel) {
+ upgrade.currentLevel++;
+ game.bp -= cost;
+ // Add this section to update maxBubbleSize when lung capacity changes
+ if (category === 'player' && key === 'lungCapacity') {
+ var baseSize = UPGRADE_EFFECTS.lungCapacity.baseValue;
+ var increasePercent = UPGRADE_EFFECTS.lungCapacity.incrementPercent;
+ var multiplier = 1 + increasePercent / 100 * upgrade.currentLevel;
+ game.maxBubbleSize = baseSize * multiplier;
}
- });
+ bpText.setText(formatBP(game.bp) + " BP");
+ // Update cost text based on whether more levels can be purchased
+ if (upgrade.currentLevel >= upgrade.maxLevel) {
+ costText.setText("SOLD OUT");
+ } else {
+ costText.setText(getUpgradeCost(upgrade) + " BP");
+ }
+ if (key === 'quickBreath') {
+ game.growthRate = UPGRADE_EFFECTS.quickBreath.baseValue * (1 + UPGRADE_EFFECTS.quickBreath.incrementPercent / 100 * upgrade.currentLevel);
+ }
+ }
+ } else {
+ // Show not enough BP error
+ game.showError("Not enough BP!");
}
- });
+ return true;
+ };
+ menuTextContainer.addChild(hitContainer);
+ menuTextContainer.addChild(nameText);
+ menuTextContainer.addChild(costText);
}
+// Clear existing texts
+upgradeTexts.forEach(function (text) {
+ return text.destroy();
+});
+upgradeTexts = [];
+// Create left column
+leftColumnUpgrades.forEach(function (upgrade, index) {
+ createUpgradeText(upgrade[0], upgrade[1], index, true);
+});
+// Create right column
+rightColumnUpgrades.forEach(function (upgrade, index) {
+ createUpgradeText(upgrade[0], upgrade[1], index, false);
+});
+// Move the entire text container down by adjusting its Y position
+menuTextContainer.y = 0; // This should align it with the top of the panel instead of being above it
+menuTextContainer.x = 0; // Center in panel
+// Menu state and animation
+var menuOpen = false;
+var menuTargetY = game.height;
function updateClamVisuals() {
while (clamContainer.children.length) {
clamContainer.children[0].destroy();
}
@@ -756,8 +962,64 @@
});
clamContainer.addChild(sprite);
});
}
+updateClamVisuals();
+// Add this to the end of the game initialization code, after updating the clam visuals
+function updateAllUpgradeTexts() {
+ // Process left column upgrades
+ leftColumnUpgrades.forEach(function (upgrade) {
+ var category = upgrade[0];
+ var key = upgrade[1];
+ var upgradeConfig = UPGRADE_CONFIG[category][key];
+ // Find the cost text for this upgrade
+ menuTextContainer.children.forEach(function (child) {
+ if (child.text && child.text.includes("BP") && child.y > menuTextContainer.children.find(function (c) {
+ return c.text === upgradeConfig.name;
+ }).y) {
+ // Check if max level reached
+ if (upgradeConfig.currentLevel >= upgradeConfig.maxLevel) {
+ child.setText("SOLD OUT");
+ }
+ }
+ });
+ });
+ // Process right column upgrades
+ rightColumnUpgrades.forEach(function (upgrade) {
+ var category = upgrade[0];
+ var key = upgrade[1];
+ if (category === 'machines') {
+ var upgradeConfig = UPGRADE_CONFIG[category][key];
+ var totalClams = UPGRADE_CONFIG.machines.basicClam.amount + UPGRADE_CONFIG.machines.advancedClam.amount + UPGRADE_CONFIG.machines.premiumClam.amount;
+ // Find the cost text for this upgrade
+ menuTextContainer.children.forEach(function (child) {
+ if (child.text && child.text.includes("BP") && child.y > menuTextContainer.children.find(function (c) {
+ return c.text === upgradeConfig.name;
+ }).y) {
+ // Check if sold out based on clam logic
+ if (totalClams >= 4 && key === 'basicClam' || UPGRADE_CONFIG.machines.basicClam.amount <= UPGRADE_CONFIG.machines.advancedClam.amount && key === 'advancedClam' || UPGRADE_CONFIG.machines.advancedClam.amount <= UPGRADE_CONFIG.machines.premiumClam.amount && key === 'premiumClam') {
+ child.setText("SOLD OUT");
+ }
+ }
+ });
+ } else if (category === 'machine') {
+ var upgradeConfig = UPGRADE_CONFIG[category][key];
+ // Find the cost text for this upgrade
+ menuTextContainer.children.forEach(function (child) {
+ if (child.text && child.text.includes("BP") && child.y > menuTextContainer.children.find(function (c) {
+ return c.text === upgradeConfig.name;
+ }).y) {
+ // Check if max level reached
+ if (upgradeConfig.currentLevel >= upgradeConfig.maxLevel) {
+ child.setText("SOLD OUT");
+ }
+ }
+ });
+ }
+ });
+}
+// Call the function after creating all upgrades
+updateAllUpgradeTexts();
// Initialize game variables
game.growingBubble = null;
game.lastMouthState = false; // Track previous mouth state
game.mouthOpenDuration = 0; // Track how long mouth has been open
@@ -799,14 +1061,24 @@
}
game.activeBubbles.push(bubble);
return bubble;
}
-// Initialize BP system
+// Initialize game variables
+//<Assets used in the game will automatically appear here>
game.bp = 0; // Track total BP
game.combo = 0;
game.lastPopTime = 0;
game.COMBO_WINDOW = 60; // 1 second in frames
-// Create BP display text
+function formatBP(value) {
+ var units = ['', 'K', 'M', 'B', 'T'];
+ var unitIndex = 0;
+ while (value >= 1000 && unitIndex < units.length - 1) {
+ value /= 1000;
+ unitIndex++;
+ }
+ return Math.floor(value * 10) / 10 + units[unitIndex];
+}
+// Create BP display text (add near game initialization)
var bpText = new Text2("0 BP", {
size: 120,
fill: 0xFFFFFF,
stroke: 0x33caf8,
@@ -888,48 +1160,8 @@
}
});
}
};
-// Menu state and animation
-var menuOpen = false;
-var menuTargetY = game.height;
-function updateClams() {
- if (!game.clamSpawnPoints) {
- return;
- }
- game.clamSpawnPoints.forEach(function (spawnPoint) {
- var config = UPGRADE_CONFIG.machines[spawnPoint.type];
- // Calculate production time with speed upgrade
- var baseTime = config.production * 60; // Convert to frames
- var speedMultiplier = Math.pow(1 - UPGRADE_EFFECTS.autoBubbleSpeed.decrementPercent / 100, UPGRADE_CONFIG.machine.autoBubbleSpeed.currentLevel);
- var adjustedTime = Math.max(1, Math.floor(baseTime * speedMultiplier));
- if (LK.ticks % adjustedTime === 0) {
- // Find first available bubble in pool
- var bubble = game.bubblePool.find(function (b) {
- return !b.visible;
- });
- if (bubble && game.activeBubbles.length < game.MAX_BUBBLES) {
- bubble.activate(spawnPoint.x, spawnPoint.y, config.bubbleSize, false // not player blown
- );
- // Set initial velocities for clam bubbles
- bubble.verticalVelocity = 0;
- bubble.driftX = (spawnPoint.isRight ? -1 : 1) * (Math.random() * 1.5 + 2);
- game.activeBubbles.push(bubble);
- }
- }
- });
-}
-// Set the default visible tab
-upgradeSections.bubbles.visible = true;
-// Initialize tabs and upgrades
-initializeMenuTabs();
-initializeAllUpgrades();
-// Set the default visible tab
-upgradeSections.bubbles.visible = true;
-// Update clam visuals initially
-updateClamVisuals();
-// Update upgrade texts initially
-updateAllUpgradeTexts();
game.update = function () {
// Update mouth state and duration
if (!game.lastMouthState) {
game.mouthOpenDuration = 0;
@@ -998,11 +1230,18 @@
// Handle touch/mouse events for the game
game.down = function (x, y, obj) {
var localX = x - menuContainer.x;
var localY = y - menuContainer.y;
- if (localX >= -upgradeTab.width * upgradeTab.scaleX / 2 && localX <= upgradeTab.width * upgradeTab.scaleX / 2 && localY >= -upgradeTab.height * upgradeTab.scaleY && localY <= 0) {
+ // 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 ? menuPanel.height * menuPanel.scaleY : game.height;
+ var targetY = menuOpen ? menuTab.height : game.height;
if (menuOpen) {
game.setChildIndex(menuContainer, game.children.length - 1);
}
tween(menuContainer, {
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