Code edit (1 edits merged)
Please save this source code
Code edit (9 edits merged)
Please save this source code
User prompt
The click sound effect isn't playing, fix that
User prompt
The click sound effect isn't playing, fix that
User prompt
play 'click' when any button get pressed
Code edit (1 edits merged)
Please save this source code
Code edit (2 edits merged)
Please save this source code
User prompt
Make a function that deserialization that string
Code edit (10 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'stringify')' in or related to this line: 'array.push(JSON.stringify(obj));' Line Number: 372
Code edit (1 edits merged)
Please save this source code
Code edit (4 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Converting circular structure to JSON --> starting at object with constructor 't.Stage' --- property 'stage' closes the circle' in or related to this line: 'self.costText.y = 335 / 2 + 40;' Line Number: 201
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.gameStatus = {' Line Number: 538 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.gameStatus = gameStatus;' Line Number: 439 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Use the storage plugin to save `gameStatus` when a new fish is added, money changed or an item is bought in shop. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
Code edit (4 edits merged)
Please save this source code
User prompt
The last fish on the cast screen is stuck, fix that
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'hasAI')' in or related to this line: 'if (!self.hasAI) {' Line Number: 259
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'margin')' in or related to this line: 'self.x = self.margin + Math.random() * (2048 - self.margin * 2);' Line Number: 234
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'margin')' in or related to this line: 'self.x = self.margin + Math.random() * (2048 - self.margin * 2);' Line Number: 234
/****
* Classes
****/
var Button = Container.expand(function (onPress, config) {
var self = Container.call(this);
self.onPress = onPress;
self.isPressed = false;
self.id = config.id;
self.disable = false;
if (config.size) {
var buttonWidth = config.size;
var buttonHeight = config.size;
} else {
var buttonWidth = config.width;
var buttonHeight = config.height;
}
self.textSize = config.textSize | Math.max(buttonWidth, buttonHeight) / 5;
// Use custom background if provided, otherwise use default
var backgroundAsset = config.background || 'buttonBackground';
var backgroundPressedAsset = backgroundAsset + 'Pressed';
var background = self.attachAsset(backgroundAsset, {
width: buttonWidth,
height: buttonHeight
});
var backgroundPressed = self.attachAsset(backgroundPressedAsset, {
visible: false,
width: buttonWidth,
height: buttonHeight
});
self.text = config.text || "";
var buttonText = new Text2(self.text, {
size: self.textSize,
fill: 0xFFFFFF,
weight: 700
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = buttonWidth / 2;
buttonText.y = buttonHeight / 2 - 23;
self.addChild(buttonText);
self.icon = config.icon;
if (self.icon) {
var buttonIcon = self.attachAsset(self.icon, {});
}
self.down = function (x, y, obj) {
if (self.disable) {
return;
}
if (self.onPress) {
// If onPress return false, then the button won't do the animation
if (!self.onPress(self)) {
return;
}
}
self.isPressed = true;
background.visible = false;
backgroundPressed.visible = true;
currentButton = self;
if (buttonIcon) {
buttonIcon.y = 46;
}
buttonText.y = buttonHeight / 2 + 23;
};
self.up = function (x, y, obj) {
self.isPressed = false;
background.visible = true;
backgroundPressed.visible = false;
if (buttonIcon) {
buttonIcon.y = 0;
}
buttonText.y = buttonHeight / 2 - 23;
};
self.setDisable = function (disable) {
self.disable = disable;
self.tint = disable ? 0xAAAAAA : 0xFFFFFF;
};
return self;
});
// ButtonShop width and height is fixed.
var ButtonShop = Button.expand(function (config) {
var self = Button.call(this, null, {
background: 'rectButtonBackground',
width: 818,
height: 335
});
self.config = config;
// Initialize shop level in gameStatus if not exists
if (!gameStatus.shopLevel[config.value]) {
gameStatus.shopLevel[config.value] = 1;
}
// Get current cost based on level
self.calculateCost = function () {
var cost = config.baseCost;
for (var i = 1; i < gameStatus.shopLevel[config.value]; i++) {
if (config.calculateCost) {
cost = config.calculateCost(i);
} else {
cost = Math.ceil(cost * 1.5);
}
}
return cost;
};
// Get current value based on level
self.calculateValue = function () {
var isMaxLevel = config.maxLevel && gameStatus.shopLevel[config.value] >= config.maxLevel;
var isMaxValue = config.maxValue && gameStatus[config.value] >= config.maxValue;
if (config.calculateValue) {
return config.calculateValue(gameStatus.shopLevel[config.value], isMaxLevel || isMaxValue);
}
return gameStatus.shopLevel[config.value];
};
// Create label text
self.labelText = new Text2(config.label + " LV: ", {
size: 60,
fill: 0xFFFFFF,
weight: 700
});
self.labelText.anchor.set(0.5, 0.5);
self.labelText.x = 818 / 2;
self.addChild(self.labelText);
// Calculate initial cost before creating cost text
self.cost = self.calculateCost();
// Create cost text
self.costText = new Text2("Cost: " + formatMoney(self.cost), {
size: 100,
fill: 0xC7FFC7,
weight: 700
});
self.costText.anchor.set(0.5, 0.5);
self.costText.x = 818 / 2;
self.addChild(self.costText);
self.updateDisplay = function () {
var isMaxLevel = config.maxLevel && gameStatus.shopLevel[config.value] >= config.maxLevel;
var isMaxValue = config.maxValue && gameStatus[config.value] >= config.maxValue;
if (isMaxLevel || isMaxValue) {
self.costText.setText("MAX LEVEL");
self.labelText.setText(config.label + ": MAX");
} else {
var costText = formatMoney(self.cost);
self.costText.setText("Cost: " + costText);
self.labelText.setText(config.label + ": LV " + gameStatus.shopLevel[config.value]);
}
};
self.onPress = function () {
var currentCost = self.cost;
if (gameStatus.money >= currentCost) {
gameStatus.money -= currentCost;
gameStatus.shopLevel[config.value]++;
// Update the game status value based on the new level
gameStatus[config.value] = self.calculateValue();
self.cost = self.calculateCost();
console.log(gameStatus[config.value]);
gameStatus.updateMoney();
self.updateDisplay();
// Check if we've reached max level or max value and disable button
var isMaxLevel = config.maxLevel && gameStatus.shopLevel[config.value] >= config.maxLevel;
var isMaxValue = config.maxValue && gameStatus[config.value] >= config.maxValue;
if (isMaxLevel || isMaxValue) {
self.setDisable(true);
}
}
return true;
};
self.update = function () {
if (self.isPressed) {
self.labelText.y = 335 / 2 - 70 + 46;
self.costText.y = 335 / 2 + 40 + 46;
} else {
self.labelText.y = 335 / 2 - 70;
self.costText.y = 335 / 2 + 40;
}
};
// Initialize game status value
gameStatus[config.value] = self.calculateValue();
// Check if already at max level/value and disable if needed
var isMaxLevel = config.maxLevel && gameStatus.shopLevel[config.value] >= config.maxLevel;
var isMaxValue = config.maxValue && gameStatus[config.value] >= config.maxValue;
if (isMaxLevel || isMaxValue) {
self.setDisable(true);
}
self.updateDisplay();
return self;
});
var Fish = Container.expand(function (fishType) {
var self = Container.call(this);
// Store fish type
if (fishType) {
self.fishType = fishType;
} else {
throw "You must add a fish type.";
}
// Create fish visual
var fishGraphics = self.attachAsset(self.fishType, {
anchorX: 0.5,
anchorY: 0.5
});
// Swimming properties
self.speed = 2 + Math.random() * 3; // Random speed between 2-5
self.direction = Math.random() * Math.PI * 2; // Random initial direction
self.turnSpeed = 0.02 + Math.random() * 0.03; // How fast fish can turn
self.targetDirection = self.direction;
self.wobbleAmount = 0.1 + Math.random() * 0.2; // Slight wobble for natural movement
self.wobbleSpeed = 0.05 + Math.random() * 0.05;
self.wobbleOffset = Math.random() * Math.PI * 2;
// Boundaries with margin
self.margin = 100;
// Initialize hasAI property
self.hasAI = true;
// Initialize position
self.randomPosition = function () {
if (!self || self.margin === undefined) {
return;
}
self.x = self.margin + Math.random() * (2048 - self.margin * 2);
self.y = self.margin + Math.random() * (2732 - self.margin * 2);
};
// Call randomPosition after margin is defined
self.randomPosition();
self.format = function () {
if (self.rate.toFixed(2) <= 0.5) {
var rate = "frame";
} else {
var rate = formatTime(self.rate, 2);
}
return formatMoney(self.value) + " every " + rate;
};
self.destroy = function () {
if (self.incomeTimer) {
LK.clearInterval(self.incomeTimer);
self.incomeTimer = null;
}
Container.prototype.destroy.call(self);
self = undefined;
};
self.update = function () {
if (!self.hasAI) {
return;
}
self.scale.set(2);
// Add wobble to movement
var wobble = Math.sin(LK.ticks * self.wobbleSpeed + self.wobbleOffset) * self.wobbleAmount;
// Gradually turn towards target direction
var directionDiff = self.targetDirection - self.direction;
// Normalize angle difference to -PI to PI
while (directionDiff > Math.PI) {
directionDiff -= Math.PI * 2;
}
while (directionDiff < -Math.PI) {
directionDiff += Math.PI * 2;
}
self.direction += directionDiff * self.turnSpeed;
// Move fish
self.x += Math.cos(self.direction + wobble) * self.speed;
self.y += Math.sin(self.direction + wobble) * self.speed;
// Face the direction of movement
fishGraphics.rotation = self.direction;
// Check boundaries and change direction
var turnAwayForce = 0.1;
var boundaryDistance = 200;
if (self.x < self.margin + boundaryDistance) {
self.targetDirection = 0; // Turn right
} else if (self.x > 2048 - self.margin - boundaryDistance) {
self.targetDirection = Math.PI; // Turn left
}
if (self.y < self.margin + boundaryDistance) {
self.targetDirection = Math.PI / 2; // Turn down
} else if (self.y > 2732 - self.margin - boundaryDistance - 200) {
self.targetDirection = -Math.PI / 2; // Turn up
}
// Occasionally change direction randomly
if (Math.random() < 0.005) {
// 0.5% chance per frame
self.targetDirection = Math.random() * Math.PI * 2;
}
// Keep fish within bounds (hard limit)
self.x = Math.max(self.margin, Math.min(2048 - self.margin, self.x));
self.y = Math.max(self.margin, Math.min(2732 - self.margin, self.y));
};
return self;
});
// Anything stored in GameStatus will be saved
var GameStatus = Container.expand(function () {
var self = Container.call(this);
self.money = 0;
self.fishes = [];
self.bait = 20;
self.baitTimer = 300;
self.fishValue = 1;
self.fishMax = 3;
self.fishRate = 3.6e+6;
self.shopLevel = {};
self.fishesAtCapacity = function () {
return self.fishes.length >= self.fishMax;
};
self.formatMoney = function () {
if (self.money === Infinity) {
return "$Infinity";
}
var str = "$";
if (self.money >= 1000) {
suffixes = ["K", "M", "B", "T", "Qa", "Qi", "Sx", "Sp", "Oc", "No", "De"];
var digits = countNumber(self.money);
var sf = suffixes[Math.floor((digits - 1) / 3) - 1];
if (sf === undefined) {
str += String(self.money.toExponential(2));
} else {
str += (self.money / Math.pow(10, Math.floor((digits - 1) / 3) * 3)).toFixed(2) + sf;
}
} else {
str += self.money.toFixed(2);
}
return str;
};
self.updateMoney = function () {
if (self.children.length > 0) {
self.removeChildAt(0);
}
var moneyText = new Text2(self.formatMoney(), {
size: 125,
fill: 0xD7FFD7,
weight: 750
});
moneyText.y = 50;
moneyText.x = 50;
self.addChildAt(moneyText, 0);
};
self.updateMoney();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x83C7FF
});
/****
* Game Code
****/
function countNumber(number) {
return Math.floor(Math.log10(Math.abs(number))) + 1;
}
function formatTime(time, point) {
time = time / 1000;
var str = "";
if (time > 3600) {
str += String((time / 3600).toFixed(point)) + " hour";
} else if (time > 60) {
str += String((time / 60).toFixed(point)) + " minute";
} else {
str += String(time.toFixed(point)) + " second";
}
if (time != 1) {
str += "s";
}
return str;
}
function formatMoney(money) {
if (money === Infinity) {
return "$Infinity";
}
var str = "$";
if (money >= 1000) {
var suffixes = ["K", "M", "B", "T", "Qa", "Qi", "Sx", "Sp", "Oc", "No", "De"];
var digits = countNumber(money);
var sf = suffixes[Math.floor((digits - 1) / 3) - 1];
if (sf === undefined) {
str += String(money.toExponential(2));
} else {
str += (money / Math.pow(10, Math.floor((digits - 1) / 3) * 3)).toFixed(2) + sf;
}
} else {
str += money.toFixed(2);
}
return str;
}
function normalRandom(min, max, skew) {
skew = skew | 1;
var u = 0,
v = 0;
while (u === 0) {
u = Math.random();
}
while (v === 0) {
v = Math.random();
}
var num = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
num = num / 10.0 + 0.5;
if (num > 1 || num < 0) {
num = normalRandom(min, max, skew);
} else {
num = Math.pow(num, skew);
num *= max - min;
num += min;
}
return num;
}
var shine;
var shine2;
var gameStatus = new GameStatus();
var tabLayout = {};
var fishTypes = ['blueFish', 'greenFish', 'pinkFish', 'redFish'];
function addFish(fish) {
gameStatus.caughtFish.scaleX = 1;
gameStatus.caughtFish.scaleY = 1;
fish.randomPosition();
gameStatus.fishes.push(fish);
fishLayer.addChild(fish);
// Add interval timer for this fish
fish.incomeTimer = LK.setInterval(function () {
gameStatus.money += fish.value;
gameStatus.updateMoney();
}, fish.rate);
}
function randomFish(value, rate) {
if (value === undefined) {
var r = 0;
var v = 0;
} else {
var r = normalRandom(rate / 1.5, rate * 1.5);
var v = Number(normalRandom(value / 1.5, value * 1.5).toFixed(2));
if (r < 0) {
r = 0;
}
}
var randomType = fishTypes[Math.floor(Math.random() * fishTypes.length)];
var fish = new Fish(randomType);
fish.value = v;
fish.rate = r;
return fish;
}
// Initialise the cast screen
var castLayer = new Container();
castLayer.visible = false;
castLayer.attachAsset('castBackground', {
alpha: 0.5
});
var text = new Text2("You caught a fish!", {
size: 150,
fill: 0xFFFFFF,
weight: 700
});
text.x = 2048 / 2 - text.width / 2;
text.y = 2732 / 2 - 900;
castLayer.addChild(text);
var fishText;
function hideCast() {
if (gameStatus.caughtFish) {
game.removeChild(gameStatus.caughtFish);
gameStatus.caughtFish.destroy();
}
shine.destroy();
shine2.destroy();
fishText.destroy();
castLayer.visible = false;
}
var keepButton = new Button(function () {
hideCast();
gameStatus.caughtFish.hasAI = true;
addFish(gameStatus.caughtFish);
castLayer.visible = false;
gameStatus.caughtFish = undefined;
}, {
text: "Keep",
background: 'rectButtonBackground',
width: 818,
height: 335
});
keepButton.x = 2048 / 2 - 818 - 50;
keepButton.y = 2732 / 2 + 900;
castLayer.addChild(keepButton);
var sellButton = new Button(function () {
hideCast();
gameStatus.money += gameStatus.caughtFish.value;
gameStatus.updateMoney();
gameStatus.caughtFish = undefined;
}, {
text: "Sell",
background: 'rectButtonBackground',
width: 818,
height: 335
});
sellButton.x = 2048 / 2 + 50;
sellButton.y = 2732 / 2 + 900;
castLayer.addChild(sellButton);
var closeButton = new Button(hideCast, {
size: 150,
icon: 'closeIcon'
});
closeButton.x = 2048 - 250;
closeButton.y = 50;
castLayer.addChild(closeButton);
var passiveIncome = new Text2("Passive Income:", {
size: 125,
fill: 0xFFFFFF,
weight: 700
});
passiveIncome.x = 2048 / 2;
passiveIncome.y = 2732 / 2 - 800 + text.height;
passiveIncome.anchor.set(0.5, 0);
castLayer.addChild(passiveIncome);
game.addChild(castLayer);
function cast() {
if (gameStatus.caughtFish === undefined) {
gameStatus.bait--;
gameStatus.caughtFish = randomFish(gameStatus.fishValue, gameStatus.fishRate);
// Update bait counter
baitText.setText("Bait: " + gameStatus.bait + "/20");
}
keepButton.setDisable(gameStatus.fishesAtCapacity());
shine = LK.getAsset('shine', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.7
});
shine.x = 2048 / 2;
shine.y = 2732 / 2 + 300;
shine.rotation = 0;
castLayer.addChild(shine);
shine2 = LK.getAsset('shine', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
shine2.x = 2048 / 2;
shine2.y = 2732 / 2 + 300;
shine2.rotation = 0;
castLayer.addChild(shine2);
// Render fish on cast screen
gameStatus.caughtFish.x = 2048 / 2;
gameStatus.caughtFish.y = 2732 / 2 + 300;
gameStatus.caughtFish.scaleX = 2.5;
gameStatus.caughtFish.scaleY = 2.5;
gameStatus.caughtFish.hasAI = false;
castLayer.addChild(gameStatus.caughtFish);
fishText = new Text2(gameStatus.caughtFish.format(), {
size: 125,
fill: 0xC7FFC7,
weight: 750
});
fishText.x = 2048 / 2;
fishText.y = 2732 / 2 - 790 + passiveIncome.height + text.height;
fishText.anchor.set(0.5, 0);
castLayer.addChild(fishText);
// Display the cast screen
castLayer.visible = true;
hideTab();
}
function hideTab() {
tabBackground.visible = false;
if (currTab) {
tabLayout[currTab].visible = false;
currTab = null;
}
}
function updateFishesDisplay() {
if (currTab !== 'fishes') {
return;
}
fishesHeader.setText('Capacity: ' + gameStatus.fishes.length + '/' + gameStatus.fishMax);
fishesHeader.x = (946 - fishesHeader.width) / 2;
// Clear previous fish display - properly destroy assets first
while (tabLayout.fishes.children.length > 1) {
var childToRemove = tabLayout.fishes.children[tabLayout.fishes.children.length - 1];
if (childToRemove.destroy) {
childToRemove.destroy();
} else {
tabLayout.fishes.removeChildAt(tabLayout.fishes.children.length - 1);
}
}
// Display each fish
var yOffset = 230;
for (var i = 0; i < gameStatus.fishes.length; i++) {
var fish = gameStatus.fishes[i];
// Fish icon
var fishIcon = LK.getAsset(fish.fishType, {});
fishIcon.scale.set(0.75);
fishIcon.x = 100;
fishIcon.y = yOffset;
tabLayout.fishes.addChild(fishIcon);
// Fish info text
var fishInfo = new Text2(fish.format(), {
size: 60,
fill: 0xFFFFFF,
weight: 600
});
fishInfo.anchor.set(0, 0.5);
fishInfo.x = 100;
fishInfo.y = yOffset + fishIcon.height + 22;
tabLayout.fishes.addChild(fishInfo);
// Sell button for this fish
var sellFishButton = new Button(function (fishIndex) {
return function () {
var fishToSell = gameStatus.fishes[fishIndex];
// Add money from selling
gameStatus.money += fishToSell.value;
gameStatus.updateMoney();
// Remove fish from array and destroy
gameStatus.fishes.splice(fishIndex, 1);
fishToSell.destroy();
// Update the fishes display
updateFishesDisplay();
return true;
};
}(i), {
text: "Sell",
width: 250,
height: 90
});
sellFishButton.x = 600;
sellFishButton.y = yOffset + fishIcon.height / 2 - 60;
tabLayout.fishes.addChild(sellFishButton);
yOffset += fishIcon.height + fishInfo.height + 25;
// Add separator
if (i < gameStatus.fishes.length - 1) {
var separator = LK.getAsset('separator', {});
separator.x = 85;
separator.y = yOffset;
tabLayout.fishes.addChild(separator);
yOffset += separator.height + 20;
}
}
}
var currTab;
function tabPressed(button) {
if (castLayer.visible) {
return false;
}
tabBackground.visible = true;
if (currTab == button.id) {
return true;
}
if (currTab) {
tabLayout[currTab].visible = false;
}
currTab = button.id;
tabLayout[button.id].visible = true;
if (gameStatus.bait <= 0) {
castButton.setDisable(true);
}
if (currTab == 'fishes') {
updateFishesDisplay();
}
return true;
}
var tabLayer = new Container();
var tabBackground = new Container();
var tabElements = new Container();
tabLayout.cast = tabElements.addChild(new Container());
tabLayout.cast.visible = false;
tabLayout.fishes = tabElements.addChild(new Container());
tabLayout.fishes.visible = false;
tabLayout.shop = tabElements.addChild(new Container());
tabLayout.shop.visible = false;
var baitText = new Text2("Bait: " + gameStatus.bait + "/20", {
size: 100,
fill: 0xFFFFFF,
weight: 700
});
baitText.x = (946 - baitText.width) / 2;
baitText.y = 70;
tabLayout.cast.addChild(baitText);
var baitTimerText = new Text2("", {
size: 80,
fill: 0xFFFFFF,
weight: 600
});
baitTimerText.x = (946 - baitTimerText.width) / 2;
baitTimerText.y = baitText.y + baitText.height + 10;
tabLayout.cast.addChild(baitTimerText);
var castButton = new Button(cast, {
width: 818,
height: 335,
background: 'rectButtonBackground',
text: "Cast"
});
castButton.x = (946 - 818) / 2;
castButton.y = 95 + baitText.height;
tabLayout.cast.addChild(castButton);
var fishesHeader = new Text2('Capacity: ', {
size: 100,
fill: 0xFFFFFF,
weight: 700
});
fishesHeader.x = (946 - fishesHeader.width) / 2;
fishesHeader.y = 70;
tabLayout.fishes.addChild(fishesHeader);
var fishValueShop = new ButtonShop({
value: 'fishValue',
baseCost: 1,
label: 'Caught Fish Value'
});
fishValueShop.x = (946 - 818) / 2;
fishValueShop.y = 70;
var fishValueShop = new ButtonShop({
value: 'fishValue',
baseCost: 1,
label: 'Caught Fish Value'
});
fishValueShop.x = (946 - 818) / 2;
fishValueShop.y = 70;
tabLayout.shop.addChild(fishValueShop);
var fishRateShop = new ButtonShop({
value: 'fishRate',
baseCost: 100,
label: 'Caught Fish Rate',
maxLevel: 195,
calculateValue: function calculateValue(level, isMax) {
if (isMax) {
return 0;
}
// Use exponential decay: rate decreases a lot at first, then less at higher levels
// Lower rate = faster income generation (better for player)
var baseRate = 3.6e+6;
var decayRate = 0.95;
var currentRate = baseRate * Math.pow(decayRate, level - 1);
return currentRate;
}
});
fishRateShop.x = (946 - 818) / 2;
fishRateShop.y = 70 + 25 + 335 * 1;
tabLayout.shop.addChild(fishRateShop);
var fishMaxShop = new ButtonShop({
value: 'fishMax',
baseCost: 2500,
label: 'Fish Capacity',
maxValue: 8,
calculateValue: function calculateValue(level) {
return Math.min(8, level * 3);
}
});
fishMaxShop.x = (946 - 818) / 2;
fishMaxShop.y = 70 + (335 + 25) * 2;
tabLayout.shop.addChild(fishMaxShop);
tabLayer.addChild(tabBackground);
tabLayer.addChild(tabElements);
tabBackground.x = 2048 - 976;
tabBackground.y = 25;
tabElements.x = 2048 - 976;
tabElements.y = 25;
tabBackground.visible = false;
tabBackground.attachAsset('tabBackgroundTL', {});
tabBackground.attachAsset('tabBackgroundBL', {
y: 1155
});
tabBackground.attachAsset('tabBackgroundBR', {
x: 473,
y: 1155
});
tabBackground.attachAsset('tabBackgroundTR', {
x: 473
});
var castTab = new Button(tabPressed, {
width: 300,
height: 346,
background: "tabButtonBackground",
icon: 'castIcon',
id: "cast"
});
castTab.x = 2048 - 325 * 3;
castTab.y = 2732 - 350;
tabLayer.addChild(castTab);
var fishesTab = new Button(tabPressed, {
width: 300,
height: 346,
background: "tabButtonBackground",
icon: "fishesIcon",
id: "fishes"
});
fishesTab.x = 2048 - 325 * 2;
fishesTab.y = 2732 - 350;
tabLayer.addChild(fishesTab);
var shopTab = new Button(tabPressed, {
width: 300,
height: 346,
background: "tabButtonBackground",
icon: "shopIcon",
id: "shop"
});
shopTab.x = 2048 - 325;
shopTab.y = 2732 - 350;
tabLayer.addChild(shopTab);
var fishLayer = new Container();
game.addChild(fishLayer);
var fishes = [];
game.attachAsset('waterBackground', {});
game.addChild(fishLayer);
game.addChild(gameStatus);
game.addChild(tabLayer);
game.addChild(castLayer);
// Bait regeneration timer
LK.setInterval(function () {
// Only decrease timer if bait is not at maximum
if (gameStatus.bait < 20) {
gameStatus.baitTimer--;
// When timer reaches 0, increase bait and reset timer
if (gameStatus.baitTimer <= 0) {
gameStatus.bait++;
gameStatus.baitTimer = 300;
// Update bait display
baitText.setText("Bait: " + gameStatus.bait + "/20");
// Re-enable cast button if we have bait now
if (gameStatus.bait > 0) {
castButton.setDisable(false);
}
}
// Update timer display
var minutes = Math.floor(gameStatus.baitTimer / 60);
var seconds = gameStatus.baitTimer % 60;
var timerString = minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
baitTimerText.setText("Next bait in: " + timerString);
baitTimerText.x = (946 - baitTimerText.width) / 2;
castButton.y = 95 + baitText.height + baitTimerText.height;
}
if (gameStatus.bait >= 20) {
// Hide timer when bait is at maximum
baitTimerText.setText("");
castButton.y = 95 + baitText.height;
}
}, 1000); // Run every 1000ms (1 second)
game.update = function () {
// Rotate shine clockwise if visible
if (shine) {
shine.rotation += 0.01; // Rotate clockwise
}
if (shine2) {
shine2.rotation -= 0.0075; // Rotate anti-clockwise, slower
}
};
game.down = function (x, y, obj) {
if (tabBackground.x > x) {
hideTab();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -202,8 +202,10 @@
self.wobbleSpeed = 0.05 + Math.random() * 0.05;
self.wobbleOffset = Math.random() * Math.PI * 2;
// Boundaries with margin
self.margin = 100;
+ // Initialize hasAI property
+ self.hasAI = true;
// Initialize position
self.randomPosition = function () {
if (!self || self.margin === undefined) {
return;