User prompt
It sounds like two beebuzz are playing at the same time. Fix
User prompt
Please fix the bug: 'TypeError: LK.getSound('BeeBuzz').isPlaying is not a function. (In 'LK.getSound('BeeBuzz').isPlaying()', 'LK.getSound('BeeBuzz').isPlaying' is undefined)' in or related to this line: 'if (!LK.getSound('BeeBuzz').isPlaying()) {' Line Number: 332
User prompt
Can you please use that syntax to set beebuzz to loop while the bee is moving
User prompt
While the bee is moving play the beebuzz sound, if the sound ends, play it again immediately.
User prompt
Loop beebuzz continually and smoothly. Add a second copy of the sound and switch between the two if need be
User prompt
Make sure the BeeBuzz loops continually while the bee is moving
User prompt
Play BeeBuzz on a loop whenever the bee is moving.
User prompt
Move it back to the right 1%
User prompt
Move the placement of the red color meter left 2%
User prompt
Update color meter class with: Create fill rectangle with corrected anchoring for upward fill self.fill = meterContainer.attachAsset('marker', { anchorX: 0.5, anchorY: orientation === 'bottom' ? 0.5 : 1 // Anchor to bottom for side meters }); // Match background dimensions self.fill.width = self.background.width; self.fill.height = self.background.height; // Position the fill correctly for upward fill if (orientation !== 'bottom') { self.fill.y = self.background.height/2; // Align with bottom of background }
User prompt
Update color meter class as needed with: var ColorMeter = Container.expand(function(color, orientation) { var self = Container.call(this); self.color = color; self.orientation = orientation; self.fillLevel = 0; self.maxFill = 100; self.active = true; // Create meter container var meterContainer = new Container(); self.addChild(meterContainer); // Thicker meters const METER_THICKNESS = 40; // Create background rectangle self.background = meterContainer.attachAsset('marker', { anchorX: 0.5, anchorY: 0.5 }); // Set size based on orientation if (orientation === 'bottom') { self.background.width = garden.cellSize * 8 * 0.85; self.background.height = METER_THICKNESS; } else { self.background.width = METER_THICKNESS; self.background.height = garden.cellSize * 8 * 0.85; } self.background.tint = 0x333333; // Create fill rectangle with corrected anchoring self.fill = meterContainer.attachAsset('marker', { anchorX: orientation === 'bottom' ? 0.5 : 0.5, anchorY: orientation === 'bottom' ? 0.5 : 0 // Anchor to bottom for side meters }); // Match background dimensions self.fill.width = self.background.width; self.fill.height = self.background.height; // Position the fill at the bottom for side meters if (orientation !== 'bottom') { self.fill.y = self.background.height/2; // Offset to align with bottom } // Set fill color var colorMap = { red: 0xFF0000, blue: 0x0000FF, yellow: 0xFFFF00 }; self.fill.tint = colorMap[color]; // Initial fill state if (orientation === 'bottom') { self.fill.scale.x = 0; } else { self.fill.scale.y = 0; } self.update = function() { if (!self.active) return; var targetFill = self.fillLevel / self.maxFill; if (self.orientation === 'bottom') { var newScale = targetFill; self.fill.scale.x += (newScale - self.fill.scale.x) * 0.1; } else { var newScale = targetFill; self.fill.scale.y += (newScale - self.fill.scale.y) * 0.1; } // Pulse effect when full if (self.isFull()) { var pulse = 1 + Math.sin(LK.ticks * 0.1) * 0.1; meterContainer.scale.set(pulse); } }; self.addFill = function(amount) { self.fillLevel = Math.min(self.maxFill, self.fillLevel + amount); }; self.empty = function() { self.fillLevel = 0; }; self.isFull = function() { return self.fillLevel >= self.maxFill; }; return self; });
User prompt
Update ColorMeter class with: var ColorMeter = Container.expand(function(color, orientation) { var self = Container.call(this); self.color = color; self.orientation = orientation; // 'left', 'right', or 'bottom' self.fillLevel = 0; self.maxFill = 100; self.active = true; // Create meter container var meterContainer = new Container(); self.addChild(meterContainer); // Create background rectangle self.background = meterContainer.attachAsset('marker', { anchorX: 0.5, anchorY: 0.5 }); // Set size based on orientation if (orientation === 'bottom') { self.background.width = garden.cellSize * 8 * 0.85; self.background.height = 20; } else { self.background.width = 20; self.background.height = garden.cellSize * 8 * 0.85; } self.background.tint = 0x333333; // Create fill rectangle self.fill = meterContainer.attachAsset('marker', { anchorX: 0.5, anchorY: orientation === 'bottom' ? 0.5 : 1 // Bottom anchor for vertical meters }); // Match background dimensions self.fill.width = self.background.width; self.fill.height = self.background.height; // Set fill color var colorMap = { red: 0xFF0000, blue: 0x0000FF, yellow: 0xFFFF00 }; self.fill.tint = colorMap[color]; // Initial fill state if (orientation === 'bottom') { self.fill.scale.x = 0; } else { self.fill.scale.y = 0; } self.update = function() { if (!self.active) return; var targetFill = self.fillLevel / self.maxFill; if (self.orientation === 'bottom') { // Center-out fill var newScale = targetFill; self.fill.scale.x += (newScale - self.fill.scale.x) * 0.1; self.fill.x = 0; // Keep centered } else { // Bottom-up fill var newScale = targetFill; self.fill.scale.y += (newScale - self.fill.scale.y) * 0.1; } // Pulse effect when full if (self.isFull()) { var pulse = 1 + Math.sin(LK.ticks * 0.1) * 0.1; meterContainer.scale.set(pulse); } }; self.addFill = function(amount) { self.fillLevel = Math.min(self.maxFill, self.fillLevel + amount); }; self.empty = function() { self.fillLevel = 0; }; self.isFull = function() { return self.fillLevel >= self.maxFill; }; return self; });
Code edit (1 edits merged)
Please save this source code
User prompt
Replace ColorMeter class with: var ColorMeter = Container.expand(function(color, orientation) { var self = Container.call(this); self.color = color; self.orientation = orientation; // 'left', 'right', or 'bottom' self.fillLevel = 0; self.maxFill = 100; self.active = true; // Create meter container var meterContainer = new Container(); self.addChild(meterContainer); // Create background rectangle self.background = meterContainer.attachAsset('marker', { anchorX: 0.5, anchorY: 0.5 }); // Set size based on orientation if (orientation === 'bottom') { self.background.width = garden.cellSize * 8 * 0.85; // 85% of garden width self.background.height = 20; } else { self.background.width = 20; self.background.height = garden.cellSize * 8 * 0.85; // 85% of garden height } self.background.tint = 0x333333; // Create fill rectangle self.fill = meterContainer.attachAsset('marker', { anchorX: orientation === 'bottom' ? 0.5 : 0.5, anchorY: orientation === 'bottom' ? 0.5 : 1 }); // Match width of background self.fill.width = self.background.width; self.fill.height = self.background.height; // Set fill color var colorMap = { red: 0xFF0000, blue: 0x0000FF, yellow: 0xFFFF00 }; self.fill.tint = colorMap[color]; // For bottom meter, start at center if (orientation === 'bottom') { self.fill.scale.x = 0; // Start with zero width self.fill.width = 0; // Start centered } else { self.fill.scale.y = 0; // Start with zero height for vertical meters } self.update = function() { if (!self.active) return; var targetFill = self.fillLevel / self.maxFill; if (self.orientation === 'bottom') { // Fill from center outward var newWidth = self.background.width * targetFill; self.fill.width += (newWidth - self.fill.width) * 0.1; } else { // Fill from bottom up self.fill.scale.y += (targetFill - self.fill.scale.y) * 0.1; } // Pulse effect when full if (self.isFull()) { var pulse = 1 + Math.sin(LK.ticks * 0.1) * 0.1; meterContainer.scale.set(pulse); } }; self.addFill = function(amount) { self.fillLevel = Math.min(self.maxFill, self.fillLevel + amount); }; self.empty = function() { self.fillLevel = 0; }; self.isFull = function() { return self.fillLevel >= self.maxFill; }; return self; });
Code edit (4 edits merged)
Please save this source code
User prompt
Update ColorMeter class with: var ColorMeter = Container.expand(function(color) { var self = Container.call(this); self.color = color; self.fillLevel = 0; self.maxFill = 100; self.active = true; // Create meter container var meterContainer = new Container(); self.addChild(meterContainer); // Create background hexagon self.background = meterContainer.attachAsset('HoneyComb', { anchorX: 0.5, anchorY: 0.5 }); self.background.tint = 0x333333; // Create fill hexagon - adjust anchor to bottom self.fill = meterContainer.attachAsset('HoneyComb', { anchorX: 0.5, anchorY: 1 // Anchor to bottom }); // Move the fill up by half height to align with background self.fill.y = self.background.height/2; // Set colors var colorMap = { red: 0xFF0000, blue: 0x0000FF, yellow: 0xFFFF00 }; self.fill.tint = colorMap[color]; // Scale overall meter meterContainer.scale.set(1.2); // Initially empty self.fill.scale.y = 0; self.update = function() { if (!self.active) return; // Smooth fill level updates var targetScale = self.fillLevel / self.maxFill; self.fill.scale.y += (targetScale - self.fill.scale.y) * 0.1; // Pulse effect when full if (self.isFull()) { var pulse = 1 + Math.sin(LK.ticks * 0.1) * 0.1; meterContainer.scale.set(1.2 * pulse); } }; self.addFill = function(amount) { self.fillLevel = Math.min(self.maxFill, self.fillLevel + amount); }; self.empty = function() { self.fillLevel = 0; }; self.isFull = function() { return self.fillLevel >= self.maxFill; }; return self; });
Code edit (3 edits merged)
Please save this source code
User prompt
Update color meter class with: var ColorMeter = Container.expand(function(color) { var self = Container.call(this); self.color = color; self.fillLevel = 0; self.maxFill = 100; self.active = true; // Always active unlike warmth meter // Create meter container to handle scaling var meterContainer = new Container(); self.addChild(meterContainer); // Create background hexagon (make it darker) self.background = meterContainer.attachAsset('HoneyComb', { anchorX: 0.5, anchorY: 0.5 }); self.background.tint = 0x333333; // Create fill hexagon self.fill = meterContainer.attachAsset('HoneyComb', { anchorX: 0.5, anchorY: 0.5 }); // Set colors var colorMap = { red: 0xFF0000, blue: 0x0000FF, yellow: 0xFFFF00 }; self.fill.tint = colorMap[color]; // Scale overall meter meterContainer.scale.set(1.2); // Initially empty self.fill.scale.y = 0; self.update = function() { if (!self.active) return; // Smooth fill level updates var targetScale = self.fillLevel / self.maxFill; self.fill.scale.y += (targetScale - self.fill.scale.y) * 0.1; // Pulse effect when full if (self.isFull()) { var pulse = 1 + Math.sin(LK.ticks * 0.1) * 0.1; meterContainer.scale.set(1.2 * pulse); } }; self.addFill = function(amount) { self.fillLevel = Math.min(self.maxFill, self.fillLevel + amount); }; self.empty = function() { self.fillLevel = 0; }; self.isFull = function() { return self.fillLevel >= self.maxFill; }; return self; });
Code edit (1 edits merged)
Please save this source code
User prompt
Refactor Bud class to improve code organization organization and efficiency.
User prompt
Add a check to setActiveSeason that clears the bees pollen state and pollenUI
User prompt
Update updateFlowerCounts method with: if (garden.goalQueue && garden.goalQueue.length > 0) { // First verify the goal display exists and has the expected child if (garden.goalDisplay && garden.goalDisplay.children.length > 1) { var displayedGoal = garden.goalDisplay.children[1]; var goalColor = garden.goalQueue[0].color; if (garden.currentFlowers[goalColor] >= garden.flowerGoals[goalColor]) { // Verify displayedGoal still exists before animating if (displayedGoal && displayedGoal.parent === garden.goalDisplay) { tween(displayedGoal, { alpha: 0, y: displayedGoal.y - 50 }, { duration: 500, onFinish: function onFinish() { // Double check goal display still exists if (garden.goalDisplay && garden.goalDisplay.children.includes(displayedGoal)) { garden.goalDisplay.removeChild(displayedGoal); garden.goalQueue.splice(0, 1); // Update progress text var completedGoals = Object.keys(garden.flowerGoals).length - garden.goalQueue.length; var totalGoals = Object.keys(garden.flowerGoals).length; // Show next goal if available if (garden.goalQueue.length > 0) { var nextGoal = self.createGoalIndicator(garden.goalQueue[0], false); nextGoal.x = 400; nextGoal.alpha = 0; garden.goalDisplay.addChild(nextGoal); tween(nextGoal, { alpha: 1 }, { duration: 500 }); garden.progressText.setText(completedGoals + "/" + totalGoals + " flower goals met"); } else { // All goals complete garden.progressText.setText("All flower goals met!"); garden.progressText.fill = 0x00FF00; } } } }); } } } } ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (6 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Timeout.tick error: self.addLeafObstacles is not a function' in or related to this line: 'self.addLeafObstacles();' Line Number: 3138
Code edit (1 edits merged)
Please save this source code
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Bee = Container.expand(function () {
var self = Container.call(this);
self.currentColor = null; // Add this back
// Movement properties
var beeSprite = self.attachAsset('Bee', {
anchorX: 0.5,
anchorY: 0.5
});
// Add animation properties
self.hoverOffset = Math.random() * Math.PI * 2; // Randomize starting position
self.wingPhase = Math.random() * Math.PI * 2; // Randomize wing movement
self.currentAnimationSpeed = 0.05; // Base speed for wings
self.lastRotation = Math.PI / 2; // Start facing up
self.state = 'free'; // 'free', 'transit'
self.targetX = self.x;
self.targetY = self.y;
self.transitSpeed = 18; // Set bee transit speed to 18
self.arrivalThreshold = 20; // How close we need to be to count as "arrived"
self.moveSpeed = 0.1; // Adjust this for faster/slower following
self.isMoving = false;
// New pollen properties
self.pollenUI = [];
self.pollenOrbitSpeed = 0.02;
self.pollenOrbitRadius = 80;
self.pollenOrbitOffsets = [0, Math.PI * 2 / 3, Math.PI * 4 / 3]; // Evenly space 3 positions
self.maxPollen = 3;
self.currentPollen = 0; // Current amount being carried
// Add trail property
self.pollenTrail = new PollenTrail();
game.addChild(self.pollenTrail); // Add to game so it renders behind bee
// Pollen collection method
self.collectPollen = function (flower) {
// Only proceed if it's a source flower
if (!flower.isSourceFlower) {
return;
}
// If holding and we have a different primary color, mix
if (self.currentColor && self.currentColor !== flower.color) {
var mixColor = self.getMixedColor(self.currentColor, flower.color);
if (mixColor) {
self.currentColor = mixColor;
self.currentPollen = 3;
self.pollenTrail.currentColor = mixColor;
}
}
// Otherwise just take the flower's color
else {
self.currentColor = flower.color;
self.currentPollen = 3;
self.pollenTrail.currentColor = flower.color;
}
var colorTints = {
'red': 0xFF0000,
'blue': 0x0000FF,
'yellow': 0xFFFF00,
'purple': 0x800080,
'green': 0x00FF00,
'orange': 0xFFA500
};
// Start trail if we have pollen
if (self.currentPollen > 0) {
if (self.pollenTrail) {
self.pollenTrail.active = false; // Reset trail
self.pollenTrail.startTrail(self.x, self.y, garden, self);
}
}
// Create collection effect
for (var i = 0; i < 12; i++) {
var particle = new PollenParticle().init('burst');
var angle = i / 12 * Math.PI * 2;
particle.x = flower.x;
particle.y = flower.y;
particle.vx = Math.cos(angle) * 3;
particle.vy = Math.sin(angle) * 3;
particle.tint = colorTints[self.currentColor];
if (flower.parent) {
flower.parent.addChild(particle);
}
}
self.updatePollenUI();
};
self.getMixedColor = function (color1, color2) {
if (color1 === 'red' && color2 === 'blue' || color1 === 'blue' && color2 === 'red') {
return 'purple';
}
if (color1 === 'blue' && color2 === 'yellow' || color1 === 'yellow' && color2 === 'blue') {
return 'green';
}
if (color1 === 'red' && color2 === 'yellow' || color1 === 'yellow' && color2 === 'red') {
return 'orange';
}
return null;
};
self.checkFlowerCollision = function () {
if (self.state === 'transit') {
return;
} // Skip collision check during transit
// Convert bee position to garden's local space
var localPos = garden.toLocal({
x: self.x,
y: self.y
}, game);
// Check source flowers first
if (garden.sourceFlowers) {
garden.sourceFlowers.children.forEach(function (flower) {
var dx = localPos.x - flower.x;
var dy = localPos.y - flower.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < garden.cellSize * 0.75 && !flower.isBeingCollectedFrom) {
flower.isBeingCollectedFrom = true;
self.collectPollen(flower);
} else if (distance >= garden.cellSize * 0.75) {
// Use same distance
flower.isBeingCollectedFrom = false;
}
});
}
// Calculate grid position
var gridX = Math.floor(localPos.x / garden.cellSize);
var gridY = Math.floor(localPos.y / garden.cellSize);
// Check if position is within grid bounds
if (gridX >= 0 && gridX < garden.cols && gridY >= 0 && gridY < garden.rows) {
var gridItem = garden.grid[gridY][gridX];
if (gridItem) {
if (gridItem.isFlower && gridItem.hasActivePollen && gridItem.scale.x >= 1 && gridItem.color === self.currentColor) {
// Collect pollen from flower
self.collectPollen(gridItem);
} else if (gridItem && gridItem.isBud && self.currentPollen > 0) {
if (gridItem.isBeingPollinated) {
return;
}
gridItem.isBeingPollinated = true;
var pollenColor = self.usePollen(gridItem);
if (!pollenColor) {
gridItem.isBeingPollinated = false;
return;
}
// Double-check the bud is still there
if (garden.grid[gridY][gridX] === gridItem && gridItem.isBud) {
// Force remove the bud and clear grid position
garden.removeChild(gridItem);
garden.grid[gridY][gridX] = null;
gridItem.destroy(); // Fully destroy the bud
// Only create flower if position is clear
if (!garden.grid[gridY][gridX]) {
var newFlower = new BasicFlower(pollenColor);
newFlower.x = gridItem.x;
newFlower.y = gridItem.y;
newFlower.isFlower = true;
garden.grid[gridY][gridX] = newFlower;
garden.addChild(newFlower);
newFlower.bloom();
// Check for game over in arcade mode
if (!game.seasonManager) {
var hasBuds = false;
for (var y = 0; y < garden.rows; y++) {
for (var x = 0; x < garden.cols; x++) {
if (garden.grid[y][x] && garden.grid[y][x].isBud) {
hasBuds = true;
break;
}
}
if (hasBuds) {
break;
}
}
if (!hasBuds && garden.grid.every(function (row) {
return row.every(function (cell) {
return cell && cell.isFlower;
});
})) {
var gameOverText = new Text2("GAME OVER!", {
size: 120,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2;
game.addChild(gameOverText);
tween(gameOverText, {
alpha: 0
}, {
duration: 1000,
delay: 1500,
onFinish: function onFinish() {
gameOverText.destroy();
LK.showGameOver();
}
});
}
}
}
} else {
gridItem.isBeingPollinated = false;
}
}
}
}
};
self.checkDestinationInteraction = function () {
// Convert bee position to garden's local space
var localPos = garden.toLocal({
x: self.x,
y: self.y
}, game);
// Check source flowers
if (garden.sourceFlowers) {
garden.sourceFlowers.children.forEach(function (flower) {
var dx = localPos.x - flower.x;
var dy = localPos.y - flower.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < garden.cellSize / 2) {
self.collectPollen(flower);
}
});
}
// Check grid position for buds
var gridX = Math.floor(localPos.x / garden.cellSize);
var gridY = Math.floor(localPos.y / garden.cellSize);
if (gridX >= 0 && gridX < garden.cols && gridY >= 0 && gridY < garden.rows) {
var gridItem = garden.grid[gridY][gridX];
if (gridItem && gridItem.isBud && self.currentPollen > 0) {
self.checkFlowerCollision(); // Use existing collision logic
}
}
};
self.update = function () {
if (self.state === 'free' && self.isMoving) {
// Existing drag behavior
self.x += (self.targetX - self.x) * self.moveSpeed;
self.y += (self.targetY - self.y) * self.moveSpeed;
} else if (self.state === 'transit') {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.arrivalThreshold) {
// Normalize movement vector
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.transitSpeed;
self.y += Math.sin(angle) * self.transitSpeed;
} else {
// We've arrived - check for interactions
self.checkDestinationInteraction();
self.state = 'free';
}
}
// Calculate actual movement speed
var dx = self.x - self.prevX || 0;
var dy = self.y - self.prevY || 0;
var currentSpeed = Math.sqrt(dx * dx + dy * dy);
// Store positions for next frame
self.prevX = self.x;
self.prevY = self.y;
// Smoothly adjust animation speed
var targetSpeed = 0.05; // Base speed when not moving
if (currentSpeed > 0.1) {
// Only increase speed if actually moving
targetSpeed = Math.min(0.05 + currentSpeed * 0.002, 0.1); // Cap maximum speed
}
// Smoothly interpolate to target speed
self.currentAnimationSpeed += (targetSpeed - self.currentAnimationSpeed) * 0.1;
// Wing flutter effect
self.wingPhase += self.currentAnimationSpeed;
var wingFlutter = Math.sin(self.wingPhase) * 0.08;
// Hover effect (keep as is)
var hoverSpeed = 0.03;
var hoverAmount = 0.05;
self.hoverOffset += hoverSpeed;
var hover = Math.sin(self.hoverOffset) * hoverAmount;
// Apply both scaling effects
beeSprite.scale.x = 1 + wingFlutter;
beeSprite.scale.y = 1 + hover;
// Calculate rotation based on movement direction
if (currentSpeed > 0.1) {
// Only update rotation if actually moving
self.lastRotation = Math.atan2(dy, dx) + Math.PI / 2;
}
var tiltAmount = Math.min(currentSpeed * 0.005, 0.1);
self.rotation = self.lastRotation + Math.sin(self.wingPhase * 2) * tiltAmount;
// Update trail when carrying pollen
if (self.currentPollen > 0) {
// Make sure trail starts if not already active
if (!self.pollenTrail.active) {
self.pollenTrail.startTrail(self.x, self.y, garden);
}
self.pollenTrail.updateTrail(self.x, self.y);
}
if (self.currentPollen <= 0 && self.currentColor) {
self.currentColor = null;
}
self.pollenUI.forEach(function (pollen, index) {
var offset = self.pollenOrbitOffsets[index];
var time = LK.ticks * self.pollenOrbitSpeed;
pollen.x = self.x + Math.cos(time + offset) * self.pollenOrbitRadius;
pollen.y = self.y + Math.sin(time + offset) * self.pollenOrbitRadius;
// Add gentle rotation
pollen.rotation = Math.sin(time * 0.5) * 0.2;
});
// Add collision check
self.checkFlowerCollision();
};
self.updatePollenUI = function () {
// First, update color of all existing honeycombs
var colorTints = {
'red': 0xFF0000,
'blue': 0x0000FF,
'yellow': 0xFFFF00,
'purple': 0x800080,
'green': 0x00FF00,
'orange': 0xFFA500
};
self.pollenUI.forEach(function (honeycomb) {
if (honeycomb.tint !== colorTints[self.currentColor]) {
// Animate color change
tween(honeycomb, {
alpha: 0
}, {
duration: 150,
onFinish: function onFinish() {
honeycomb.tint = colorTints[self.currentColor];
tween(honeycomb, {
alpha: 1
}, {
duration: 150
});
}
});
}
});
// Remove excess pollen UI elements
while (self.pollenUI.length > self.currentPollen) {
var pollen = self.pollenUI.pop();
tween(pollen, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
onFinish: function onFinish() {
if (pollen.parent) {
pollen.parent.removeChild(pollen);
}
}
});
}
// Add new pollen UI elements
while (self.pollenUI.length < self.currentPollen) {
var honeycomb = LK.getAsset('HoneyComb', {
anchorX: 0.5,
anchorY: 0.5
});
honeycomb.scale.set(0); // Set initial scale to 0
// Set color based on current pollen color
honeycomb.tint = colorTints[self.currentColor] || 0xFFFFFF;
self.pollenUI.push(honeycomb);
game.addChild(honeycomb);
// Animate in
tween(honeycomb, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 500,
ease: 'elasticOut'
});
}
};
// Pollen usage method
self.usePollen = function (bud) {
if (self.currentPollen > 0 && self.currentColor) {
// Store current color before reducing pollen
var color = self.currentColor;
// Use one charge
self.currentPollen--;
// If we're out of charges, clear pollen trail and color
if (self.currentPollen <= 0) {
self.pollenTrail.active = false;
self.pollenTrail.points = [];
self.currentColor = null;
}
// Update UI after changes
self.updatePollenUI();
return color; // Return the stored color
}
return null;
};
return self;
});
// Bud class
var Bud = Container.expand(function () {
var self = Container.call(this);
var budGraphics = self.attachAsset('Bud', {
anchorX: 0.5,
anchorY: 0.5
});
// Properties
self.isBeingPollinated = false;
self.bloomTimer = 5 * 60; // 5 seconds (assuming 60fps)
self.isBud = true;
self.isFlower = false;
self.isBeingReplaced = false; // Add this flag
// Update method for handling animation
self.update = function () {
self.animate();
};
// Animation method
self.animate = function () {
self.rotation = Math.sin(LK.ticks * 0.05) * 0.1;
};
return self;
});
// Add BudSpawner to handle progressive difficulty
var BudSpawner = Container.expand(function () {
var self = Container.call(this);
self.originalSelectSpawnPosition = self.selectSpawnPosition;
self.enabled = true;
self.patterns = {
single: [[[0, 0]]],
pairs: [[[0, 0], [0, 1]],
// horizontal
[[0, 0], [1, 0]],
// vertical
[[0, 0], [1, 1]] // diagonal
],
triples: [[[0, 0], [0, 1], [0, 2]],
// horizontal
[[0, 0], [1, 0], [2, 0]],
// vertical
[[0, 0], [1, 1], [2, 2]],
// diagonal
[[0, 0], [0, 1], [1, 0]] // L shape
]
};
self.warningTime = 180; // 3 seconds at 60fps
self.currentPattern = null;
self.warningSprites = [];
self.nextSpawnPosition = null;
self.createWarning = function (x, y) {
var warning = new Container();
var crack = warning.attachAsset('Crack', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
warning.x = x;
warning.y = y;
warning.scale.set(0);
// Create the growing crack animation
tween(warning.scale, {
x: 1,
y: 1
}, {
duration: 1000,
ease: 'elasticOut'
});
tween(crack, {
alpha: 0.8
}, {
duration: 500
});
// Add rotation animation
warning.update = function () {
warning.rotation = Math.sin(LK.ticks * 0.03) * 0.1;
};
self.garden.addChild(warning);
return warning;
};
self.updateWarningEffects = function () {
var timeProgress = (180 - self.warningTime) / 180; // 0 to 1
var intensity = Math.sin(timeProgress * Math.PI * 4) * 0.5 + 0.5; // Pulsing effect
self.warningSprites.forEach(function (sprite) {
// Increase glow and intensity as spawn time approaches
sprite.children[0].alpha = 0.3 + intensity * 0.7;
sprite.children[0].scale.set(0.8 + intensity * 0.4);
// Add subtle shake when close to spawning
if (self.warningTime < 60) {
// Last second
sprite.x += (Math.random() - 0.5) * 2;
sprite.y += (Math.random() - 0.5) * 2;
}
});
};
self.garden = null;
self.gameTime = 0;
self.init = function (garden) {
self.garden = garden;
self.gameTime = 0;
self.firstBloom = false;
// Just set the first bloom timer
self.nextBloomTime = 90; // 1.5 seconds for first bloom
};
self.findEmptySpot = function () {
var validSpots = [];
// Match flower removal coordinate system [gridY][gridX]
for (var gridY = 0; gridY < self.garden.rows; gridY++) {
for (var gridX = 0; gridX < self.garden.cols; gridX++) {
if (!self.garden.grid[gridY][gridX]) {
validSpots.push({
x: gridX,
y: gridY
});
}
}
}
if (validSpots.length > 0) {
return validSpots[Math.floor(Math.random() * validSpots.length)];
}
return null;
};
self.selectSpawnPosition = function () {
if (game.seasonManager && game.seasonManager.currentSeason === game.seasonManager.SEASONS.FALL) {
// First priority: spots next to leaves
var leafPairs = [];
var singleSpots = [];
// Original leaf-adjacent checking logic remains...
for (var row = 0; row < self.garden.rows; row++) {
for (var col = 0; col < self.garden.cols; col++) {
var _self$garden$grid$row;
if ((_self$garden$grid$row = self.garden.grid[row][col]) !== null && _self$garden$grid$row !== void 0 && _self$garden$grid$row.isLeaf) {
// Check each direction for empty pairs
var directions = [[{
r: -1,
c: 0
}, {
r: -2,
c: 0
}],
// Up pair
[{
r: 1,
c: 0
}, {
r: 2,
c: 0
}],
// Down pair
[{
r: 0,
c: -1
}, {
r: 0,
c: -2
}],
// Left pair
[{
r: 0,
c: 1
}, {
r: 0,
c: 2
}]];
directions.forEach(function (dir) {
var spot1 = {
row: row + dir[0].r,
col: col + dir[0].c
};
var spot2 = {
row: row + dir[1].r,
col: col + dir[1].c
};
if (spot1.row >= 0 && spot1.row < self.garden.rows && spot1.col >= 0 && spot1.col < self.garden.cols && spot2.row >= 0 && spot2.row < self.garden.rows && spot2.col >= 0 && spot2.col < self.garden.cols && self.garden.grid[spot1.row][spot1.col] === null && self.garden.grid[spot2.row][spot2.col] === null) {
leafPairs.push({
start: spot1,
pattern: [[0, 0], [dir[1].r - dir[0].r, dir[1].c - dir[0].c]]
});
}
});
// Also store single spots for fallback
var adjacent = [{
r: -1,
c: 0
}, {
r: 1,
c: 0
}, {
r: 0,
c: -1
}, {
r: 0,
c: 1
}];
adjacent.forEach(function (dir) {
var checkRow = row + dir.r;
var checkCol = col + dir.c;
if (checkRow >= 0 && checkRow < self.garden.rows && checkCol >= 0 && checkCol < self.garden.cols && self.garden.grid[checkRow][checkCol] === null) {
singleSpots.push({
row: checkRow,
col: checkCol
});
}
});
}
}
}
if (leafPairs.length > 0 && Math.random() < 0.7) {
var pair = leafPairs[Math.floor(Math.random() * leafPairs.length)];
return {
row: pair.start.row,
col: pair.start.col,
pattern: pair.pattern
};
} else if (singleSpots.length > 0) {
var spot = singleSpots[Math.floor(Math.random() * singleSpots.length)];
return {
row: spot.row,
col: spot.col,
pattern: self.patterns.single[0]
};
}
// Second priority: spots next to recent spawn positions
var secondarySpots = [];
for (var row = 0; row < self.garden.rows; row++) {
for (var col = 0; col < self.garden.cols; col++) {
var _self$garden$grid$row2, _self$garden$grid$row3;
if ((_self$garden$grid$row2 = self.garden.grid[row][col]) !== null && _self$garden$grid$row2 !== void 0 && _self$garden$grid$row2.isBud || (_self$garden$grid$row3 = self.garden.grid[row][col]) !== null && _self$garden$grid$row3 !== void 0 && _self$garden$grid$row3.isFlower) {
// Check for empty spots around this bud/flower
var patterns = self.checkPatternsAtPosition(row, col);
if (patterns.length > 0) {
secondarySpots.push({
row: row,
col: col,
patterns: patterns
});
}
}
}
}
if (secondarySpots.length > 0) {
var position = secondarySpots[Math.floor(Math.random() * secondarySpots.length)];
var highestPriority = Math.max.apply(Math, _toConsumableArray2(position.patterns.map(function (p) {
return p.priority;
})));
var bestPatterns = position.patterns.filter(function (p) {
return p.priority === highestPriority;
});
var selectedPattern = bestPatterns[Math.floor(Math.random() * bestPatterns.length)];
return {
row: position.row,
col: position.col,
pattern: selectedPattern.pattern
};
}
}
// Fall back to default spawn logic if no priority spots found
return self.defaultSpawnPosition();
};
self.checkPatternsAtPosition = function (row, col) {
var validPatterns = [];
var patternFits = function patternFits(pattern) {
return pattern.every(function (_ref) {
var _ref2 = _slicedToArray10(_ref, 2),
dy = _ref2[0],
dx = _ref2[1];
var newRow = row + dy;
var newCol = col + dx;
return newRow >= 0 && newRow < garden.rows && newCol >= 0 && newCol < garden.cols && garden.grid[newRow][newCol] === null;
});
};
// Check patterns in priority order: triples, pairs, singles
if (garden.grid[row][col] === null) {
// Check triples first
self.patterns.triples.forEach(function (pattern) {
if (patternFits(pattern)) {
validPatterns.push({
pattern: pattern,
priority: 3
});
}
});
// Only check pairs if no triples found
if (validPatterns.length === 0) {
self.patterns.pairs.forEach(function (pattern) {
if (patternFits(pattern)) {
validPatterns.push({
pattern: pattern,
priority: 2
});
}
});
}
// Only check singles if no pairs or triples found
if (validPatterns.length === 0 && patternFits(self.patterns.single[0])) {
validPatterns.push({
pattern: self.patterns.single[0],
priority: 1
});
}
}
return validPatterns;
};
self.defaultSpawnPosition = function () {
// Count empty spaces and validate pattern placement
var validPositions = [];
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
if (garden.grid[row][col] === null) {
var patterns = self.checkPatternsAtPosition(row, col);
if (patterns.length > 0) {
validPositions.push({
row: row,
col: col,
patterns: patterns
});
}
}
}
}
if (validPositions.length === 0) {
return null;
}
// Select random position but use highest priority pattern available
var position = validPositions[Math.floor(Math.random() * validPositions.length)];
var highestPriority = Math.max.apply(Math, _toConsumableArray(position.patterns.map(function (p) {
return p.priority;
})));
var bestPatterns = position.patterns.filter(function (p) {
return p.priority === highestPriority;
});
var selectedPattern = bestPatterns[Math.floor(Math.random() * bestPatterns.length)];
return {
row: position.row,
col: position.col,
pattern: selectedPattern.pattern
};
};
self.getSpawnRate = function () {
if (!game.seasonManager) {
// Arcade mode - use level-based scaling
var baseRate = 240; // Start at 4 seconds
var minRate = 60; // Minimum 1 seconds
var rate = Math.max(baseRate - (game.currentLevel - 1) * 20, minRate);
return rate;
}
return 16; // Default for other modes
};
// Add to BudSpawner class:
self.update = function () {
if (!self.enabled) {
return;
}
// Add summer mode timing controls
if (game.seasonManager && game.seasonManager.currentSeason === game.seasonManager.SEASONS.SUMMER) {
var gameTime = game.gameTimer ? game.gameTimer.timeRemaining : 60;
var baseDelay = Math.max(240 - (game.seasonManager.yearNumber - 1) * 20, 120);
// Adjust required delay based on time remaining
var requiredDelay = baseDelay;
if (gameTime < 15) {
// Last 15 seconds
requiredDelay *= 0.5; // Spawn twice as fast
} else {
requiredDelay *= 1 - (60 - gameTime) / 60 * 0.3; // Gradually speed up by up to 30%
}
// Update the timing check
if (!self.currentPattern) {
if (LK.ticks - self.lastSpawnTime < requiredDelay) {
return;
}
}
}
// Initialize timing trackers
if (!self.lastSpawnTime) {
self.lastSpawnTime = LK.ticks;
self.isFirstSpawn = true;
}
// Quick first spawn (2 seconds), then 5 seconds for subsequent spawns
if (!self.currentPattern) {
var requiredDelay = self.isFirstSpawn ? 120 : 240; // 2 seconds vs 4 seconds
if (LK.ticks - self.lastSpawnTime < requiredDelay) {
return;
}
// Update spawn time and first spawn flag
self.lastSpawnTime = LK.ticks;
self.isFirstSpawn = false;
// Select new spawn position and pattern
var spawnInfo = self.selectSpawnPosition();
if (spawnInfo && spawnInfo.row !== undefined && spawnInfo.col !== undefined) {
self.currentPattern = spawnInfo.pattern;
self.nextSpawnPosition = {
row: parseInt(spawnInfo.row),
col: parseInt(spawnInfo.col)
};
self.warningTime = 180; // Reset warning timer
// Create warning indicators for pattern
self.warningSprites = [];
if (self.currentPattern) {
var _iterator3 = _createForOfIteratorHelper4(self.currentPattern),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var _step3$value = _slicedToArray5(_step3.value, 2),
dy = _step3$value[0],
dx = _step3$value[1];
if (dx !== undefined && dy !== undefined) {
var targetRow = self.nextSpawnPosition.row + dy;
var targetCol = self.nextSpawnPosition.col + dx;
var worldPos = self.garden.gridToWorld(targetCol, targetRow);
var warning = self.createWarning(worldPos.x - 400 + self.garden.cellSize, worldPos.y - 400 - 50);
self.warningSprites.push(warning);
}
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
}
}
} else if (self.nextSpawnPosition && self.currentPattern) {
self.warningTime--;
self.updateWarningEffects();
if (self.warningTime <= 0) {
// Spawn animation
self.warningSprites.forEach(function (sprite) {
tween(sprite.scale, {
x: 1,
y: 1
}, {
duration: 300,
onFinish: function onFinish() {
tween(sprite, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
return sprite.destroy();
}
});
}
});
});
// Cache spawn position before clearing
var spawnRow = self.nextSpawnPosition.row;
var spawnCol = self.nextSpawnPosition.col;
var pattern = self.currentPattern;
// Clear state before spawning to prevent timing issues
self.warningSprites = [];
self.currentPattern = null;
self.nextSpawnPosition = null;
// Spawn buds with delay between each
pattern.forEach(function (pos, index) {
var _pos = _slicedToArray8(pos, 2),
dy = _pos[0],
dx = _pos[1];
LK.setTimeout(function () {
var targetRow = spawnRow + dy;
var targetCol = spawnCol + dx;
if (targetRow >= 0 && targetRow < self.garden.rows && targetCol >= 0 && targetCol < self.garden.cols && !self.garden.grid[targetRow][targetCol]) {
var worldPos = self.garden.gridToWorld(targetCol, targetRow);
var targetX = worldPos.x - 400 + self.garden.cellSize;
var targetY = worldPos.y - 400 - 50;
// Clear any existing sprite at this position
for (var i = self.garden.children.length - 1; i >= 0; i--) {
var child = self.garden.children[i];
if (child.x === targetX && child.y === targetY) {
self.garden.removeChild(child);
}
}
var newBud = new Bud();
newBud.x = targetX;
newBud.y = targetY;
newBud.scale.set(0);
self.garden.grid[targetRow][targetCol] = newBud;
self.garden.addChild(newBud);
// Then do scale animation
tween(newBud.scale, {
x: 1,
y: 1
}, {
duration: 1000,
ease: 'elasticOut'
});
}
}, index * 200);
});
}
}
};
});
var ColorMeter = Container.expand(function (color) {
var self = Container.call(this);
self.color = color;
self.fillLevel = 0;
self.maxFill = 100;
self.active = true; // Always active unlike warmth meter
// Create meter container to handle scaling
var meterContainer = new Container();
self.addChild(meterContainer);
// Create background hexagon (make it darker)
self.background = meterContainer.attachAsset('HoneyComb', {
anchorX: 0.5,
anchorY: 0.5
});
self.background.tint = 0x333333;
// Create fill hexagon - adjust anchor to bottom
self.fill = meterContainer.attachAsset('HoneyComb', {
anchorX: 0.5,
anchorY: 1 // Anchor to bottom
});
// Move the fill up by half height to align with background
self.fill.y = self.background.height / 2;
// Set colors
var colorMap = {
red: 0xFF0000,
blue: 0x0000FF,
yellow: 0xFFFF00
};
self.fill.tint = colorMap[color];
// Scale overall meter
meterContainer.scale.set(1.2);
// Initially empty
self.fill.scale.y = 0;
self.update = function () {
if (!self.active) {
return;
}
// Smooth fill level updates
var targetScale = self.fillLevel / self.maxFill;
self.fill.scale.y += (targetScale - self.fill.scale.y) * 0.1;
// Pulse effect when full
if (self.isFull()) {
var pulse = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
meterContainer.scale.set(1.2 * pulse);
}
};
self.addFill = function (amount) {
self.fillLevel = Math.min(self.maxFill, self.fillLevel + amount);
};
self.empty = function () {
self.fillLevel = 0;
};
self.isFull = function () {
return self.fillLevel >= self.maxFill;
};
return self;
});
// Simplified FlowerManager - mainly for flower conversion and management
var FlowerManager = Container.expand(function () {
var self = Container.call(this);
// Convert a bud to a flower
self.convertBudToFlower = function (bud, garden) {
var gridPos = {
x: Math.floor((bud.y - garden.y) / garden.cellSize),
y: Math.floor((bud.x - garden.x) / garden.cellSize)
};
var newFlower = new BasicFlower();
newFlower.x = bud.x;
newFlower.y = bud.y;
newFlower.isFlower = true;
garden.removeChild(bud);
garden.grid[gridPos.x][gridPos.y] = newFlower;
garden.addChild(newFlower);
// When a flower blooms:
createPollenBurst(newFlower.x, newFlower.y);
return newFlower;
};
// Empty touch handler as we're using the new trail system
self.handleTouch = function () {};
});
var FlowerMatcher = Container.expand(function () {
var self = Container.call(this);
self.checkForMatches = function (garden, x, y) {
// First check if we're in spring finale
if (game.seasonManager && game.seasonManager.currentSeason === game.seasonManager.SEASONS.SPRING && game.seasonManager.springFinaleStarted && !game.seasonManager.springMatchingEnabled) {
// Block all matching during spring finale except when explicitly enabled
return false;
}
// Only prevent matches in spring if we're not in the matching phase
if (game.seasonManager && game.seasonManager.currentSeason === game.seasonManager.SEASONS.SPRING && !game.seasonManager.springMatchingEnabled) {
return false;
}
var matches = self.findMatches(garden, x, y);
if (matches.length >= 3) {
// Check for rainbow flower creation BEFORE clearing matches
var rainbowCreated = false;
if (!rainbowCreated && matches.length >= 5 && !matches.some(function (m) {
return m.flower.color === 'rainbow';
}) && matches.every(function (m) {
return m.flower.color === matches[0].flower.color;
}) && !game.seasonManager) {
// Find center of matched group
var centerX = Math.floor(matches.reduce(function (sum, m) {
return sum + m.x;
}, 0) / matches.length);
var centerY = Math.floor(matches.reduce(function (sum, m) {
return sum + m.y;
}, 0) / matches.length);
// Remember the central match for rainbow flower placement
var centerMatch = matches.find(function (m) {
return m.x === centerX && m.y === centerY;
}) || matches[Math.floor(matches.length / 2)];
// Animate center flower first
tween(centerMatch.flower.scale, {
x: 1.5,
y: 1.5
}, {
duration: 300,
onFinish: function onFinish() {
tween(centerMatch.flower, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
// Create rainbow flower only after center flower fades
var rainbowFlower = new BasicFlower('rainbow');
rainbowFlower.x = centerMatch.flower.x;
rainbowFlower.y = centerMatch.flower.y;
rainbowFlower.isFlower = true;
rainbowFlower.scale.set(0);
garden.removeChild(centerMatch.flower);
garden.grid[centerMatch.y][centerMatch.x] = rainbowFlower;
garden.addChild(rainbowFlower);
// Only bloom after clearing the matches
LK.setTimeout(function () {
rainbowFlower.bloom();
}, matches.length * 150 + 200);
}
});
}
});
// Remove this position from matches immediately to prevent double-clearing
matches = matches.filter(function (m) {
return m !== centerMatch;
});
// Clear grid position immediately to prevent new matches
garden.grid[centerMatch.y][centerMatch.x] = null;
}
// Immediately clear ALL matched flowers from grid
matches.forEach(function (match) {
if (garden.grid[match.y][match.x] === match.flower) {
garden.grid[match.y][match.x] = null;
}
});
// Pass matches to clearMatches for animation and scoring
self.clearMatches(garden, matches, true);
return true;
}
return false;
};
self.findMatches = function (garden, startX, startY) {
if (startY < 0 || startY >= garden.rows || startX < 0 || startX >= garden.cols) {
return [];
}
var startFlower = garden.grid[startY][startX];
if (!startFlower || !startFlower.isFlower) {
return [];
}
var matches = [];
var visited = {};
var isRainbowMatch = false;
var matchColor = startFlower.color;
if (startFlower.color === 'rainbow') {
var adjacentColors = {}; // Use object instead of Set
[[0, 1], [0, -1], [1, 0], [-1, 0]].forEach(function (dir) {
var dx = dir[0];
var dy = dir[1];
var checkX = startX + dx;
var checkY = startY + dy;
if (checkX >= 0 && checkX < garden.cols && checkY >= 0 && checkY < garden.rows) {
var flower = garden.grid[checkY][checkX];
if (flower && flower.isFlower && !flower.isSourceFlower && flower.color !== 'rainbow') {
adjacentColors[flower.color] = true; // Use as hash table
}
}
});
// If we find at least one color with multiple matches
var colors = Object.keys(adjacentColors);
for (var i = 0; i < colors.length; i++) {
var color = colors[i];
var colorMatches = [];
var tempVisited = {};
var _checkColorMatch = function checkColorMatch(x, y, targetColor) {
if (x < 0 || x >= garden.cols || y < 0 || y >= garden.rows) {
return;
}
var key = x + ',' + y;
if (tempVisited[key]) {
return;
}
tempVisited[key] = true;
var flower = garden.grid[y][x];
if (flower && flower.isFlower && !flower.isSourceFlower && flower.scale.x >= 1 && (flower.color === targetColor || flower.color === 'rainbow')) {
colorMatches.push({
x: x,
y: y,
flower: flower
});
_checkColorMatch(x + 1, y, targetColor);
_checkColorMatch(x - 1, y, targetColor);
_checkColorMatch(x, y + 1, targetColor);
_checkColorMatch(x, y - 1, targetColor);
}
};
_checkColorMatch(startX, startY, color);
if (colorMatches.length >= 3) {
matches = colorMatches;
matchColor = color;
isRainbowMatch = true;
break;
}
}
}
if (!isRainbowMatch) {
var _checkFlower = function checkFlower(x, y) {
if (x < 0 || x >= garden.cols || y < 0 || y >= garden.rows) {
return;
}
var key = "".concat(x, ",").concat(y);
if (visited[key]) {
return;
}
visited[key] = true;
var flower = garden.grid[y][x];
if (flower && flower.isFlower && !flower.isSourceFlower && flower.scale.x >= 1 && (flower.color === matchColor || flower.color === 'rainbow')) {
matches.push({
x: x,
y: y,
flower: flower
});
_checkFlower(x + 1, y);
_checkFlower(x - 1, y);
_checkFlower(x, y + 1);
_checkFlower(x, y - 1);
}
};
_checkFlower(startX, startY);
}
if (matches.length >= 3 && matches.some(function (m) {
return m.flower.color === 'rainbow';
})) {
var _matches$find;
var targetColor = ((_matches$find = matches.find(function (m) {
return m.flower.color !== 'rainbow';
})) === null || _matches$find === void 0 ? void 0 : _matches$find.flower.color) || matchColor;
if (targetColor !== 'rainbow') {
var allMatches = _toConsumableArray3(matches);
for (var y = 0; y < garden.rows; y++) {
for (var x = 0; x < garden.cols; x++) {
var flower = garden.grid[y][x];
if (flower && flower.isFlower && !flower.isSourceFlower && flower.color === targetColor && !matches.some(function (m) {
return m.x === x && m.y === y;
})) {
allMatches.push({
x: x,
y: y,
flower: flower
});
}
}
}
return allMatches;
}
}
return matches.length >= 3 ? matches : [];
};
self.clearMatches = function (garden, matches, startNewChain) {
var popCount = 0;
var _this2 = this;
var seedTargets = {};
var pollenTargets = {};
matches.forEach(function (match) {
var directions = [{
dx: 0,
dy: -1
}, {
dx: 0,
dy: 1
}, {
dx: -1,
dy: 0
}, {
dx: 1,
dy: 0
}];
directions.forEach(function (dir) {
var checkRow = match.y + dir.dy;
var checkCol = match.x + dir.dx;
var key = "".concat(checkRow, ",").concat(checkCol);
// Skip if out of bounds or is a match position
if (checkRow < 0 || checkRow >= garden.rows || checkCol < 0 || checkCol >= garden.cols || matches.some(function (m) {
return m.y === checkRow && m.x === checkCol;
})) {
return;
}
var cell = garden.grid[checkRow][checkCol];
if (!cell) {
seedTargets[key] = {
row: checkRow,
col: checkCol,
sourceMatch: match
};
} else if (cell && (cell.isBud || cell.isFlower && !cell.isSourceFlower)) {
// Only target if not already being pollinated and is either a bud or base color flower
if (!cell.isBeingPollinated && (cell.isBud || cell.isFlower && ['red', 'blue', 'yellow'].includes(cell.color))) {
// Check if we can make a valid hybrid with this combination
var hybridColor = null;
if (cell.isFlower) {
var baseColor = match.flower.color;
var targetColor = cell.color;
if (baseColor === 'red' && targetColor === 'blue' || baseColor === 'blue' && targetColor === 'red') {
hybridColor = 'purple';
} else if (baseColor === 'blue' && targetColor === 'yellow' || baseColor === 'yellow' && targetColor === 'blue') {
hybridColor = 'green';
} else if (baseColor === 'red' && targetColor === 'yellow' || baseColor === 'yellow' && targetColor === 'red') {
hybridColor = 'orange';
}
}
// Only add to targets if it's a bud or we can make a valid hybrid
if (cell.isBud || hybridColor) {
cell.isBeingPollinated = true;
pollenTargets[key] = {
row: checkRow,
col: checkCol,
targetBud: cell.isBud ? cell : null,
targetFlower: cell.isBud ? null : cell,
sourceMatch: match
};
}
}
}
});
});
if (game.scoreManager && startNewChain) {
game.scoreManager.addToChain();
}
if (game.seasonManager && game.seasonManager.currentSeason === game.seasonManager.SEASONS.SUMMER) {
// Count matches by color
if (game.seasonManager && game.seasonManager.currentSeason === game.seasonManager.SEASONS.SUMMER) {
// Only count matches for current goal color
if (garden.goalQueue && garden.goalQueue.length > 0) {
var currentGoalColor = garden.goalQueue[0].color;
matches.forEach(function (match) {
if (match.flower.color === currentGoalColor) {
garden.currentFlowers[currentGoalColor]++;
// Update the display text
if (garden.currentFlowers[currentGoalColor + "Text"]) {
var currentCount = garden.currentFlowers[currentGoalColor];
var goalCount = garden.flowerGoals[currentGoalColor];
// Check if current goal met
if (currentCount >= goalCount) {
currentCount = goalCount; // Cap at goal
var text = garden.currentFlowers[currentGoalColor + "Text"];
// Create new green text
var newText = new Text2(currentCount + "/" + goalCount, {
size: 120,
fill: 0x00FF00
});
newText.x = text.x;
newText.y = text.y;
text.parent.addChild(newText);
text.parent.removeChild(text);
garden.currentFlowers[currentGoalColor + "Text"] = newText;
// Handle goal completion and queue next goal
if (garden.goalDisplay.children[1]) {
// This is the current goal display
var displayedGoal = garden.goalDisplay.children[1];
// Animate current goal out
tween(displayedGoal, {
alpha: 0,
y: displayedGoal.y - 50
}, {
duration: 500,
onFinish: function onFinish() {
if (garden.goalDisplay && garden.goalDisplay.children.includes(displayedGoal)) {
garden.goalDisplay.removeChild(displayedGoal);
garden.goalQueue.splice(0, 1);
// Update progress text
var completedGoals = Object.keys(garden.flowerGoals).length - garden.goalQueue.length;
var totalGoals = Object.keys(garden.flowerGoals).length;
// Show next goal if available
if (garden.goalQueue.length > 0) {
var nextGoal = game.seasonManager.createGoalIndicator(garden.goalQueue[0], false);
nextGoal.x = 400;
nextGoal.alpha = 0;
garden.goalDisplay.addChild(nextGoal);
// Animate new goal in
tween(nextGoal, {
alpha: 1
}, {
duration: 500
});
garden.progressText.setText(completedGoals + "/" + totalGoals + " match goals met");
} else {
// All goals complete
garden.progressText.setText("All match goals met!");
garden.progressText.fill = 0x00FF00;
}
}
}
});
}
} else {
garden.currentFlowers[currentGoalColor + "Text"].setText(currentCount + "/" + goalCount);
}
}
}
});
}
}
}
var checkForLeafClearing = function checkForLeafClearing(matches) {
var leafPositions = [];
matches.forEach(function (match) {
// Check adjacent cells for leaves
var directions = [{
dx: 1,
dy: 0
}, {
dx: -1,
dy: 0
}, {
dx: 0,
dy: 1
}, {
dx: 0,
dy: -1
}];
directions.forEach(function (dir) {
var checkX = match.x + dir.dx;
var checkY = match.y + dir.dy;
if (checkX >= 0 && checkX < garden.cols && checkY >= 0 && checkY < garden.rows) {
var cell = garden.grid[checkY][checkX];
// Add additional validation
if (cell && cell.isLeaf && cell.parent === garden) {
// Verify grid position matches actual position
var worldPos = garden.gridToWorld(checkX, checkY);
if (cell.x === worldPos.x - 400 + garden.cellSize && cell.y === worldPos.y - 400 - 50) {
leafPositions.push({
x: checkX,
y: checkY,
leaf: cell
});
} else {
// Fix desynchronized position
garden.grid[checkY][checkX] = null;
}
}
}
});
});
// Clear leaves with animation
leafPositions.forEach(function (pos, index) {
LK.setTimeout(function () {
// Double check leaf is still valid before clearing
if (garden.grid[pos.y][pos.x] === pos.leaf && pos.leaf.parent === garden) {
tween(pos.leaf, {
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 500,
onFinish: function onFinish() {
// Double check again before final removal
if (garden.grid[pos.y][pos.x] === pos.leaf) {
garden.grid[pos.y][pos.x] = null;
pos.leaf.destroy();
}
}
});
}
}, index * 100);
});
};
checkForLeafClearing(matches);
matches.forEach(function (match) {
// Removed call to undefined method checkAndSpawnSideEffects
});
// Add meter fill from matches
if (garden.meters) {
// Calculate fill amounts for each color
matches.forEach(function (match) {
var color = match.flower.color;
// Primary colors give full amount
if (color === 'red' && garden.meters.red) {
garden.meters.red.addFill(15);
} else if (color === 'blue' && garden.meters.blue) {
garden.meters.blue.addFill(15);
} else if (color === 'yellow' && garden.meters.yellow) {
garden.meters.yellow.addFill(15);
}
// Hybrid colors give half to each component
else if (color === 'purple') {
if (garden.meters.red) {
garden.meters.red.addFill(7.5);
}
if (garden.meters.blue) {
garden.meters.blue.addFill(7.5);
}
} else if (color === 'green') {
if (garden.meters.blue) {
garden.meters.blue.addFill(7.5);
}
if (garden.meters.yellow) {
garden.meters.yellow.addFill(7.5);
}
} else if (color === 'orange') {
if (garden.meters.red) {
garden.meters.red.addFill(7.5);
}
if (garden.meters.yellow) {
garden.meters.yellow.addFill(7.5);
}
}
});
}
matches.forEach(function (match, index) {
// First animate all the match clears with proper sequencing
LK.setTimeout(function () {
tween(match.flower.scale, {
x: 1.5,
y: 1.5
}, {
duration: 300,
onFinish: function onFinish() {
// Play pop sound with increasing pitch based on match index
var basePitch = 1.0;
var pitchIncrease = Math.min(popCount * 1.0, 5.0);
popCount++; // Increment after calculating pitch
LK.getSound('Pop').play({
pitch: basePitch + pitchIncrease
});
tween(match.flower, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
if (garden.grid[match.y][match.x] === match.flower) {
garden.grid[match.y][match.x] = null;
garden.removeChild(match.flower);
}
// Create particles after pop
self.createPetalBurst(match.x, match.y, match.flower.color);
// Show points for this flower
var worldPos = garden.gridToWorld(match.x, match.y);
var flowerPoints = game.scoreManager.getFlowerBasePoints(match.flower.color);
var pointText = new Text2("+" + flowerPoints, {
size: 100,
fill: 0xFFFF00
});
pointText.anchor.set(0.5);
pointText.x = worldPos.x;
pointText.y = worldPos.y;
game.addChild(pointText);
tween(pointText, {
y: pointText.y - 50,
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
pointText.destroy();
}
});
}
});
}
});
}, index * 150);
// For rainbow matches, delay all pollination effects until after matches are cleared
var isRainbowMatch = matches.some(function (m) {
return m.flower.color === 'rainbow';
});
var baseDelay = matches.length * 150 + 200; // Reduced from 500 to 200
// Create set of matched positions for quick lookup
var matchedPositions = matches.map(function (m) {
return "".concat(m.y, ",").concat(m.x);
});
// Handle seed targets first
Object.values(seedTargets).forEach(function (target, targetIndex) {
var seed_delay = isRainbowMatch ? baseDelay + targetIndex * 100 : baseDelay + (target.sourceMatch ? matches.indexOf(target.sourceMatch) * 100 : 0);
LK.setTimeout(function () {
// Check if target position is still valid
if (!garden.grid[target.row][target.col] && !matchedPositions.includes("".concat(target.row, ",").concat(target.col))) {
var targetPos = garden.gridToWorld(target.col, target.row);
var bud = new Bud();
bud.x = targetPos.x - 400 + garden.cellSize;
bud.y = targetPos.y - 400 - 50;
bud.scale.set(0);
// Set grid position before adding to display
garden.grid[target.row][target.col] = bud;
garden.addChild(bud);
tween(bud.scale, {
x: 1,
y: 1
}, {
duration: 500,
ease: 'elasticOut'
});
}
}, seed_delay);
});
Object.values(pollenTargets).forEach(function (target, targetIndex) {
var pollination_delay = isRainbowMatch ? baseDelay + targetIndex * 100 : baseDelay + (target.sourceMatch ? matches.indexOf(target.sourceMatch) * 100 : 0); // Match timing to original match
LK.setTimeout(function () {
// Verify target position is still valid and not in a matched position
if (!matchedPositions.includes("".concat(target.row, ",").concat(target.col))) {
if (target.targetBud && garden.grid[target.row][target.col] === target.targetBud) {
// Verify bud is still there and hasn't been modified
var newColor = isRainbowMatch ? matches.find(function (m) {
return m.flower.color !== 'rainbow';
}).flower.color : target.sourceMatch.flower.color;
var newFlower = new BasicFlower(newColor);
newFlower.x = target.targetBud.x;
newFlower.y = target.targetBud.y;
newFlower.isFlower = true;
garden.grid[target.row][target.col] = newFlower;
garden.removeChild(target.targetBud);
garden.addChild(newFlower);
newFlower.bloom();
} else if (target.targetFlower && garden.grid[target.row][target.col] === target.targetFlower) {
// Verify flower is still there and hasn't been modified
var hybridColor = null;
var baseColor = target.sourceMatch.flower.color;
var targetColor = target.targetFlower.color;
if (baseColor === 'red' && targetColor === 'blue' || baseColor === 'blue' && targetColor === 'red') {
hybridColor = 'purple';
} else if (baseColor === 'blue' && targetColor === 'yellow' || baseColor === 'yellow' && targetColor === 'blue') {
hybridColor = 'green';
} else if (baseColor === 'red' && targetColor === 'yellow' || baseColor === 'yellow' && targetColor === 'red') {
hybridColor = 'orange';
}
if (hybridColor) {
var newFlower = new BasicFlower(hybridColor);
newFlower.x = target.targetFlower.x;
newFlower.y = target.targetFlower.y;
newFlower.isFlower = true;
newFlower.fromPollination = true;
garden.grid[target.row][target.col] = newFlower;
garden.removeChild(target.targetFlower);
garden.addChild(newFlower);
newFlower.bloom();
}
}
}
}, pollination_delay);
});
});
// After all flowers, show total score
LK.setTimeout(function () {
if (game.scoreManager) {
// Calculate total with multipliers
var totalBase = matches.reduce(function (sum, m) {
return sum + game.scoreManager.getFlowerBasePoints(m.flower.color);
}, 0);
var matchMultiplier = game.scoreManager ? game.scoreManager.getMatchMultiplier(matches.length) : 1;
var chainMultiplier = game.scoreManager ? game.scoreManager.chainMultiplier : 1;
var finalScore = Math.floor(totalBase * matchMultiplier * chainMultiplier);
// Show final score floating up
var totalText = new Text2("+" + finalScore, {
size: 150,
fill: 0x00FFFF
});
totalText.anchor.set(0.5);
totalText.x = 2048 / 2;
totalText.y = 2732 / 2;
game.addChild(totalText);
tween(totalText, {
y: 100,
alpha: 0
}, {
duration: 1500,
onFinish: function onFinish() {
totalText.destroy();
game.scoreManager.addScore(finalScore);
if (!game.seasonManager) {
// Check for level up conditions
var scoreThreshold = game.currentLevel * 15000; // 15000 points per level
if (game.scoreManager.currentScore >= scoreThreshold) {
game.currentLevel++;
// Update level display
if (game.levelDisplay) {
game.levelDisplay.setText("Level " + game.currentLevel);
}
}
}
}
});
// First only show match multiplier if it's greater than 1
if (matchMultiplier > 1) {
var multiplierText = new Text2("Match x" + matchMultiplier.toFixed(1), {
size: 120,
fill: 0x00FFFF
});
multiplierText.anchor.set(0.5);
multiplierText.x = 2048 / 2;
multiplierText.y = 2732 / 2 + 100;
game.addChild(multiplierText);
tween(multiplierText, {
y: multiplierText.y - 50,
alpha: 0
}, {
duration: 1200,
onFinish: function onFinish() {
multiplierText.destroy();
}
});
}
// Separate chain display only if there's an active chain
if (game.scoreManager.chainMultiplier > 1) {
var chainText = new Text2("Chain x" + game.scoreManager.chainMultiplier.toFixed(1), {
size: 120,
fill: 0x00FFFF
});
chainText.anchor.set(0.5);
chainText.x = 2048 / 2;
chainText.y = 2732 / 2 + 150; // Position below match multiplier
game.addChild(chainText);
tween(chainText, {
y: chainText.y - 50,
alpha: 0
}, {
duration: 1200,
onFinish: function onFinish() {
chainText.destroy();
}
});
}
}
}, matches.length * 150 + 1000);
};
self.createPetalBurst = function (x, y, color) {
var colorTints = {
'red': 0xFF0000,
'blue': 0x0000FF,
'yellow': 0xFFFF00,
'purple': 0x800080,
'orange': 0xFFA500,
'green': 0x00FF00,
'rainbow': [0xFF0000, 0x0000FF, 0xFFFF00] // Array of primary colors for rainbow
};
var worldPos = garden.gridToWorld(x, y);
for (var i = 0; i < 12; i++) {
var particle = new PollenParticle().init('burst');
var angle = i / 12 * Math.PI * 2;
particle.x = worldPos.x;
particle.y = worldPos.y;
particle.vx = Math.cos(angle) * 8;
particle.vy = Math.sin(angle) * 8;
particle.scale.set(0.8);
// Handle rainbow color array case
if (color === 'rainbow') {
var rainbowColors = colorTints[color];
particle.tint = rainbowColors[Math.floor(Math.random() * rainbowColors.length)];
} else {
particle.tint = colorTints[color];
}
game.addChild(particle);
}
// Star particles
for (var i = 0; i < 8; i++) {
var star = new PollenParticle().init('star');
var angle = i / 8 * Math.PI * 2;
star.x = worldPos.x;
star.y = worldPos.y;
game.addChild(star);
}
};
return self;
});
var GameTimer = Container.expand(function () {
var self = Container.call(this);
// Then add timer text on top
var timerText = new Text2("0:00", {
size: 120,
fill: 0xFFFFFF
});
var yearText = new Text2("Year 1", {
size: 100,
fill: 0xFFFFFF
});
yearText.anchor.set(0.5, 0);
yearText.y = 135; // Position below timer text
self.addChild(yearText);
self.yearText = yearText;
timerText.anchor.set(0.5, 0);
self.addChild(timerText);
// Position the whole container
self.x = 2048 - 100 - 2048 * 0.03;
self.y = 50;
self.timeRemaining = 0;
self.active = false;
self.lastTick = 0; // Add this to track last update
self.setTime = function (seconds) {
self.timeRemaining = seconds;
self.totalTime = seconds; // Store initial time
self.active = false;
self.lastTick = LK.ticks; // Initialize lastTick
self.updateDisplay();
};
self.updateYear = function (year) {
self.yearText.setText("Year " + year);
};
self.updateDisplay = function () {
var minutes = Math.floor(self.timeRemaining / 60);
var seconds = self.timeRemaining % 60;
var timeString = minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
// Create new text with appropriate color
var newText = new Text2(timeString, {
size: 120,
fill: self.timeRemaining <= 10 ? 0xFF0000 : 0xFFFFFF
});
newText.anchor.set(0.5, 0);
// Replace old text with new
self.removeChild(timerText);
self.addChild(newText);
timerText = newText;
};
self.active = false;
self.update = function () {
if (!self.active) {
return;
}
if (self.active && self.timeRemaining > 0) {
if (LK.ticks - self.lastTick >= 60) {
self.timeRemaining--;
self.lastTick = LK.ticks;
self.updateDisplay();
}
}
};
return self;
});
//<Assets used in the game will automatically appear here>
// Garden class to manage the grid of soil
var Garden = Container.expand(function () {
var self = Container.call(this);
// Add new helper method for safe grid updates
self.updateGridPosition = function (row, col, item) {
if (row >= 0 && row < self.rows && col >= 0 && col < self.cols) {
// First clear any existing item
var existingItem = self.grid[row][col];
if (existingItem && existingItem.parent) {
existingItem.parent.removeChild(existingItem);
}
// Then set new item
self.grid[row][col] = item;
return true;
}
return false;
};
self.grid = [];
self.colorMeters = {
red: 0,
blue: 0,
yellow: 0
};
self.autoBloomRate = {
baseDelay: 300,
// 5 seconds base delay
minDelay: 60,
// Minimum 1 second delay
getCurrentDelay: function getCurrentDelay() {
if (game.seasonManager) {
// Keep seasons mode the same
return Math.max(this.baseDelay - (game.seasonManager.yearNumber - 1) * 60, this.minDelay);
} else {
// Use level-based scaling for arcade mode
return Math.max(this.baseDelay - (game.currentLevel - 1) * 15, this.minDelay);
}
}
};
self.lastBloomTime = LK.ticks; // Reset bloom timer on initialization
self.checkForAutoBloom = function () {
// Don't autobloom in fall
if (game.tutorial || game.seasonManager && (game.seasonManager.currentSeason === game.seasonManager.SEASONS.FALL || game.seasonManager.currentSeason === game.seasonManager.SEASONS.SPRING)) {
return;
}
var currentTime = LK.ticks;
if (currentTime - self.lastBloomTime < self.autoBloomRate.getCurrentDelay()) {
return;
}
// Find all eligible buds
var eligibleBuds = [];
for (var row = 0; row < self.rows; row++) {
for (var col = 0; col < self.cols; col++) {
var bud = self.grid[row][col];
if (bud && bud.isBud && !bud.isBeingReplaced && !bud.isBeingPollinated) {
eligibleBuds.push({
bud: bud,
row: row,
col: col
});
}
}
}
// Bloom one random bud if available
if (eligibleBuds.length > 0) {
var _eligibleBuds$Math$fl = eligibleBuds[Math.floor(Math.random() * eligibleBuds.length)],
bud = _eligibleBuds$Math$fl.bud,
row = _eligibleBuds$Math$fl.row,
col = _eligibleBuds$Math$fl.col;
var flowerColors = ['red', 'blue', 'yellow'];
// Allow hybrid colors in arcade mode after 5 minutes
if (!game.seasonManager) {
var timeElapsed = game.gameTimer ? game.gameTimer.totalTime - game.gameTimer.timeRemaining : 0;
if (timeElapsed > 240 && Math.random() < 0.5) {
flowerColors.push('purple', 'green', 'orange');
}
}
var randomColor = flowerColors[Math.floor(Math.random() * flowerColors.length)];
var newFlower = new BasicFlower(randomColor);
newFlower.x = bud.x;
newFlower.y = bud.y;
newFlower.isFlower = true;
// Update grid and display
self.removeChild(bud);
self.grid[row][col] = newFlower;
self.addChild(newFlower);
newFlower.bloom();
self.lastBloomTime = currentTime;
// Add after the last flower blooms
if (!game.seasonManager) {
// Only check in arcade mode
var hasBuds = false;
for (var y = 0; y < self.rows; y++) {
for (var x = 0; x < self.cols; x++) {
if (self.grid[y][x] && self.grid[y][x].isBud) {
hasBuds = true;
break;
}
}
if (hasBuds) {
break;
}
}
if (!hasBuds && self.grid.every(function (row) {
return row.every(function (cell) {
return cell && cell.isFlower;
});
})) {
var gameOverText = new Text2("GAME OVER!", {
size: 120,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2;
game.addChild(gameOverText);
tween(gameOverText, {
alpha: 0
}, {
duration: 1000,
delay: 1500,
onFinish: function onFinish() {
gameOverText.destroy();
LK.showGameOver();
}
});
}
}
}
};
self.rows = 8;
self.cols = 8;
self.cellSize = 210;
self.init = function () {
var _this = this;
self.lastBloomTime = LK.ticks;
// Add source flowers
this.sourceFlowers = new Container();
this.addChild(this.sourceFlowers);
// Calculate positions
var centerX = this.cols * this.cellSize / 2;
// Blue flower at bottom center
var blueFlower = new SourceFlower('blue');
blueFlower.x = centerX;
blueFlower.y = self.rows * self.cellSize + self.cellSize * 1.5 - 0.02 * 2732; // Move up by 2% of screen height
this.sourceFlowers.addChild(blueFlower);
// Red flower under bottom left bud
var redFlower = new SourceFlower('red');
redFlower.x = self.cellSize / 2 - 0.015 * 2048; // Move 1.5% to the left
redFlower.y = self.rows * self.cellSize + self.cellSize * 1.5 - 0.02 * 2732; // Move up by 2% of screen height
this.sourceFlowers.addChild(redFlower);
// Yellow flower under bottom right bud
var yellowFlower = new SourceFlower('yellow');
yellowFlower.x = self.cols * self.cellSize - self.cellSize / 2 + 0.01 * 2048; // Move 1% to the right
yellowFlower.y = self.rows * self.cellSize + self.cellSize * 1.5 - 0.02 * 2732; // Move up by 2% of screen height
this.sourceFlowers.addChild(yellowFlower);
// Position meters under source flowers
self.meters = {};
// Find positions of source flowers
var redFlower = self.sourceFlowers.children.find(function (f) {
return f.color === 'red';
});
var blueFlower = self.sourceFlowers.children.find(function (f) {
return f.color === 'blue';
});
var yellowFlower = self.sourceFlowers.children.find(function (f) {
return f.color === 'yellow';
});
// Create and position meters
if (redFlower) {
self.meters.red = new ColorMeter('red');
self.meters.red.x = redFlower.x;
self.meters.red.y = redFlower.y + 225;
self.addChild(self.meters.red);
}
if (blueFlower) {
self.meters.blue = new ColorMeter('blue');
self.meters.blue.x = blueFlower.x;
self.meters.blue.y = blueFlower.y + 225;
self.addChild(self.meters.blue);
}
if (yellowFlower) {
self.meters.yellow = new ColorMeter('yellow');
self.meters.yellow.x = yellowFlower.x;
self.meters.yellow.y = yellowFlower.y + 225;
self.addChild(self.meters.yellow);
}
// Center the grid on screen
self.x = (2048 - self.cols * self.cellSize) / 2;
self.y = (2732 - self.rows * self.cellSize) / 2 + 2732 * 0.12 - 400;
// Initialize empty grid
for (var i = 0; i < self.rows; i++) {
self.grid[i] = [];
for (var j = 0; j < self.cols; j++) {
self.grid[i][j] = null;
}
}
};
// Helper method to convert grid position to world position
self.gridToWorld = function (gridX, gridY) {
if (typeof gridX !== 'number' || typeof gridY !== 'number') {
console.log('Invalid grid coordinates:', gridX, gridY);
return {
x: self.x,
y: self.y
}; // Return default position if invalid
}
return {
x: self.x + gridX * self.cellSize + self.cellSize / 2,
y: self.y + gridY * self.cellSize + self.cellSize / 2
};
};
// Helper method to convert world position to grid position
self.worldToGrid = function (worldX, worldY) {
var localX = worldX - self.x;
var localY = worldY - self.y;
return {
x: Math.floor(localX / self.cellSize),
y: Math.floor(localY / self.cellSize)
};
};
self.update = function () {
// First handle the grid updates
for (var i = 0; i < self.rows; i++) {
for (var j = 0; j < self.cols; j++) {
var gridItem = self.grid[i][j];
if (gridItem && gridItem.update) {
gridItem.update();
}
}
}
// Then check for autoblooming
self.checkForAutoBloom();
if (self.meters) {
Object.values(self.meters).forEach(function (meter) {
if (meter && meter.update) {
meter.update();
}
});
}
};
});
var GardenBackground = Container.expand(function () {
var self = Container.call(this);
// Create specific containers for layers
self.bgLayer = new Container(); // for seasonal backgrounds
self.soilLayer = new Container(); // for soil and snow effects
self.addChild(self.bgLayer);
self.addChild(self.soilLayer);
self.seasonalBackground = null;
self.gardenSoil = null;
self.init = function () {
// Default to spring background initially
self.seasonalBackground = LK.getAsset('SpringBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.02,
scaleY: 1.02,
x: 2048 / 2,
y: 2732 / 2 - 0.02 * 2732
});
self.bgLayer.addChild(self.seasonalBackground);
self.gardenSoil = LK.getAsset('GardenSoil', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.02,
scaleY: 1.02,
x: 2048 / 2,
y: 2732 / 2 - 0.02 * 2732
});
self.soilLayer.addChild(self.gardenSoil);
};
self.setSeasonBackground = function (season) {
var newBackground;
switch (season) {
case 'spring':
newBackground = 'SpringBackground';
break;
case 'summer':
newBackground = 'SummerBackground';
break;
case 'fall':
newBackground = 'FallBackground';
break;
case 'winter':
newBackground = 'WinterBackground';
break;
}
if (newBackground) {
var newBg = LK.getAsset(newBackground, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.02,
scaleY: 1.02,
x: 2048 / 2,
y: 2732 / 2 - 0.02 * 2732,
alpha: 0
});
self.addChildAt(newBg, 0); // Add behind current background
// Fade in new, fade out old
tween(newBg, {
alpha: 1
}, {
duration: 1000
});
if (self.seasonalBackground) {
tween(self.seasonalBackground, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.removeChild(self.seasonalBackground);
self.seasonalBackground = newBg;
}
});
} else {
self.seasonalBackground = newBg;
}
}
};
// Method to access garden soil
self.getGardenSoil = function () {
return self.gardenSoil;
};
self.init();
return self;
});
var MenuBackground = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('MenuSquare', {
anchorX: 0.5,
anchorY: 0,
alpha: 0.5
});
// Always start expanded
background.scale.x = 20;
background.scale.y = 3;
// Only need adjustments for winter
self.expandForWinter = function () {
tween(background.scale, {
y: 4 // Just increase height for warmth meter
}, {
duration: 500
});
};
// Add reset method
self.resetFromWinter = function () {
tween(background.scale, {
y: 3 // Back to normal height
}, {
duration: 500
});
};
self.x = 2048 / 2;
self.y = 50;
return self;
});
var PatternParticle = Container.expand(function () {
var self = Container.call(this);
// Store the particle reference
self.particle = self.attachAsset('PollenSparkle', {
anchorX: 0.5,
anchorY: 0.5
});
// Apply scale and tint to the container
self.scale.set(0.7);
self.active = true;
self.twinkleSpeed = 0.1;
self.twinkleOffset = Math.random() * Math.PI * 2;
self.update = function () {
if (self.active) {
self.alpha = 0.8 + Math.sin(LK.ticks * self.twinkleSpeed + self.twinkleOffset) * 0.2; // Increased base alpha
}
};
return self;
});
var PollenMeter = Container.expand(function () {
var self = Container.call(this);
// Create background bar
var background = LK.getAsset('marker', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 0.1
});
self.addChild(background);
// Create fill bar
var fill = LK.getAsset('marker', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0,
scaleY: 0.1
});
fill.tint = 0xFFFF00; // Yellow for pollen
self.fillBar = fill;
self.addChild(fill);
// Update method to show current pollen
self.updateMeter = function (current, max) {
fill.scale.x = current / max;
};
return self;
});
// PollenParticle class
var PollenParticle = Container.expand(function () {
var self = Container.call(this);
// Particle properties
self.velocity = {
x: 0,
y: 0
};
self.lifespan = 1; // Goes from 1 to 0
self.decayRate = 0.02; // How fast the particle fades
self.type = 'trail'; // Can be 'trail' or 'burst'
// Create the visual element
var assetMap = {
'trail': 'PollenSparkle',
'burst': 'Petal',
'fairy': 'PollenSparkle',
'transfer': 'PollenSparkle',
'star': 'StarParticle' // Add this line
};
var pollenGraphics;
// Initialize with random properties for more organic feel
self.init = function (type) {
self.type = type || 'trail';
if (!pollenGraphics) {
pollenGraphics = self.attachAsset(assetMap[self.type], {
anchorX: 0.5,
anchorY: 0.5
});
}
// Set initial scale based on type
if (self.type === 'trail') {
self.scale.set(0.7 + Math.random() * 0.3); // Larger for trail
self.decayRate = 0.03; // Faster decay for trail
// Slight random velocity for trail movement
self.velocity = {
x: (Math.random() - 0.5) * 2,
y: (Math.random() - 0.5) * 2
};
} else if (self.type === 'burst') {
self.scale.set(0.5 + Math.random() * 0.3); // Smaller initial size for bursts
self.decayRate = 0.01; // Slower decay for longer travel
// Radial burst velocity
var angle = Math.random() * Math.PI * 2;
var speed = 3 + Math.random() * 5; // Increased speed for further travel
self.velocity = {
x: Math.cos(angle) * speed,
y: Math.sin(angle) * speed
};
} else if (self.type === 'fairy') {
self.lifespan = undefined; // Don't fade out
self.startAngle = Math.random() * Math.PI * 2; // Random start position
self.orbitRadius = 20 + Math.random() * 40; // Increase orbit radius variation
self.orbitSpeed = 0.005 + Math.random() * 0.03; // Increase orbit speed variation
self.update = function () {
var time = LK.ticks * self.orbitSpeed;
// Orbit motion
self.x = Math.cos(time + self.startAngle) * self.orbitRadius;
self.y = Math.sin(time + self.startAngle) * self.orbitRadius;
// Add bobbing
self.y += Math.sin(time * 2 + self.startAngle) * 10;
};
} else if (self.type === 'star') {
self.scale.set(1 + Math.random() * 0.2);
self.decayRate = 0.015; // Slower decay for more visible effect
// Add sparkle rotation
self.rotationSpeed = (Math.random() - 0.5) * 0.4; // Faster rotation than normal particles
self.alpha = 1;
// Add velocity setup like other particle types
var angle = Math.random() * Math.PI * 2;
var speed = 12 + Math.random() * 4; // Higher speed for farther travel
self.velocity = {
x: Math.cos(angle) * speed,
y: Math.sin(angle) * speed
};
}
// Random rotation speed
self.rotationSpeed = (Math.random() - 0.5) * 0.2;
// Random starting rotation
self.rotation = Math.random() * Math.PI * 2;
// Add random rotation speed for dynamic movement
self.rotationSpeed = (Math.random() - 0.5) * 0.2;
// Full opacity to start
self.alpha = 1;
if (self.type === 'transfer') {
self.scale.set(0.5);
self.alpha = 1;
self.twinkleOffset = 0; // Initialize twinkle offset
self.twinkleSpeed = 0.1; // Initialize twinkle speed
self.update = function () {
// Gentle drift down
self.x += self.vx;
self.y += self.vy;
// Individual twinkle effect
self.alpha = 0.6 + Math.sin(LK.ticks * self.twinkleSpeed + self.twinkleOffset) * 0.4;
// Remove when below hive
if (self.y > 100) {
self.destroy();
}
};
}
return self;
};
self.update = function () {
// Update position based on velocity
self.x += self.velocity.x;
self.y += self.velocity.y;
// Add rotation
self.rotation += self.rotationSpeed;
// Slow down velocity over time
self.velocity.x *= 0.95;
self.velocity.y *= 0.95;
// Update lifespan and alpha
self.lifespan -= self.decayRate;
self.alpha = self.lifespan;
// Scale slightly varies with life
var scalePulse = 1 + Math.sin(LK.ticks * 0.2) * 0.1;
pollenGraphics.scale.set(scalePulse * self.scale.x);
// Remove when lifecycle complete
if (self.lifespan <= 0) {
self.destroy();
}
};
});
// First, let's add a PollenTrail class to handle the dragging mechanic
var PollenTrail = Container.expand(function () {
var self = Container.call(this);
self.points = [];
self.active = false;
self.currentGarden = null; // Store reference to garden
self.MAX_SPEED = 15; // Adjust this value for proper feel
self.startTrail = function (x, y, garden, bee) {
self.active = true;
self.points = [{
x: x,
y: y,
time: Date.now()
}];
self.startTime = Date.now();
self.trailStartTime = Date.now();
self.currentGarden = garden;
self.bee = bee; // Store bee reference
self.lastPoint = {
x: x,
y: y
}; // Initialize lastPoint
// Force red on first particle to verify bee storage
var particle = new PollenParticle().init('trail');
particle.children[0].tint = 0xFF0000;
particle.x = x;
particle.y = y;
game.addChild(particle);
};
self.updateTrail = function (x, y) {
if (!self.active) {
return;
}
// Enforce maximum speed
var dx = x - self.lastPoint.x;
var dy = y - self.lastPoint.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.MAX_SPEED) {
var ratio = self.MAX_SPEED / distance;
x = self.lastPoint.x + dx * ratio;
y = self.lastPoint.y + dy * ratio;
}
self.points.push({
x: x,
y: y,
time: Date.now()
});
self.lastPoint = {
x: x,
y: y
};
// Create particle effect along trail
var particle = new PollenParticle().init('trail');
if (self.bee && self.bee.currentColor) {
var color = self.bee.currentColor;
if (color === 'red') {
particle.children[0].tint = 0xFF0000;
} else if (color === 'blue') {
particle.children[0].tint = 0x0000FF;
} else if (color === 'yellow') {
particle.children[0].tint = 0xFFFF00;
} else if (color === 'purple') {
particle.children[0].tint = 0xA020F0; // Lightened purple
} else if (color === 'green') {
particle.children[0].tint = 0x00FF00;
} else if (color === 'orange') {
particle.children[0].tint = 0xFFA500;
}
}
particle.x = x;
particle.y = y;
game.addChild(particle);
};
// Add the burst effect function
self.createPollenBurst = function (x, y) {
for (var i = 0; i < 12; i++) {
var particle = new PollenParticle().init('burst');
var angle = i / 12 * Math.PI * 2;
var distance = 30;
particle.x = x + Math.cos(angle) * distance;
particle.y = y + Math.sin(angle) * distance;
// Give particles outward velocity
particle.vx = Math.cos(angle) * 3;
particle.vy = Math.sin(angle) * 3;
game.addChild(particle);
}
};
self.endTrail = function () {
if (!self.active) {
return;
}
var affectedBuds = [];
var checkedPositions = {};
self.points.forEach(function (point) {
var localPos = self.currentGarden.toLocal({
x: point.x,
y: point.y
}, game);
var gridX = Math.floor(localPos.x / self.currentGarden.cellSize);
var gridY = Math.floor(localPos.y / self.currentGarden.cellSize);
var posKey = gridX + ',' + gridY;
if (!checkedPositions[posKey] && gridX >= 0 && gridX < self.currentGarden.cols && gridY >= 0 && gridY < self.currentGarden.rows) {
checkedPositions[posKey] = true;
var gridItem = self.currentGarden.grid[gridY][gridX];
// Verify it's a valid bud
if (gridItem && gridItem.isBud === true && gridItem.isFlower === false) {
affectedBuds.push({
bud: gridItem,
gridX: gridX,
gridY: gridY
});
}
}
});
if (affectedBuds.length >= 2) {
affectedBuds.forEach(function (budInfo) {
// IMPORTANT: Clear the grid position first
self.currentGarden.grid[budInfo.gridY][budInfo.gridX] = null;
// Remove the bud from display list
self.currentGarden.removeChild(budInfo.bud);
// Create new flower
var newFlower = new BasicFlower();
newFlower.x = budInfo.bud.x;
newFlower.y = budInfo.bud.y;
newFlower.isFlower = true;
// Update grid position and add to display list
self.currentGarden.grid[budInfo.gridY][budInfo.gridX] = newFlower;
self.currentGarden.addChild(newFlower);
// Start bloom animation
newFlower.bloom();
});
}
self.active = false;
self.points = [];
};
self.update = function () {
// Just update particles, no time checks
// Update all children particles
for (var i = self.children.length - 1; i >= 0; i--) {
var particle = self.children[i];
if (particle && particle.update) {
particle.update();
}
}
};
});
// Add ScoreManager to handle chain reactions and scoring
var ScoreManager = Container.expand(function () {
var self = Container.call(this);
// Properties
self.currentScore = 0;
self.lastMatchTime = 0; // Add this property
self.currentChain = 0;
self.chainMultiplier = 1;
self.BASIC_FLOWER_POINTS = 100; // Add this line
self.HYBRID_FLOWER_POINTS = 200; // Add this line
self.getFlowerBasePoints = function (flowerColor) {
var hybridColors = ['purple', 'green', 'orange', 'rainbow'];
return hybridColors.includes(flowerColor) ? self.HYBRID_FLOWER_POINTS : self.BASIC_FLOWER_POINTS;
};
// Methods need to be defined this way in Container.expand
self.getMatchMultiplier = function (matchSize) {
if (matchSize <= 3) {
return 1;
}
if (matchSize === 4) {
return 1.5;
}
if (matchSize === 5) {
return 2;
}
return 2.5; // 6 or more
};
self.addToChain = function () {
var currentTime = Date.now();
// Only increment chain if less than 2 seconds since last match
if (currentTime - self.lastMatchTime < 2000 && self.lastMatchTime !== 0) {
self.currentChain++;
self.chainMultiplier = Math.min(1 + self.currentChain * 0.5, 5);
} else {
// Reset chain if it's the first match or too much time has passed
self.currentChain = 0;
self.chainMultiplier = 1;
}
self.lastMatchTime = currentTime;
};
self.resetChain = function () {
self.currentChain = 0;
self.chainMultiplier = 1;
};
self.addScore = function (points) {
// Add points to current score
self.currentScore += Math.floor(points);
// Update display immediately
if (game.scoreDisplay) {
game.scoreDisplay.setText(self.currentScore.toString());
}
// Update best score if in arcade mode
if (!game.seasonManager && game.bestScoreDisplay) {
if (self.currentScore > storage.bestScore) {
storage.bestScore = self.currentScore;
game.bestScoreDisplay.setText("Best: " + storage.bestScore);
}
}
};
return self;
});
var SeasonManager = Container.expand(function () {
var self = Container.call(this);
self.springMatchingEnabled = false; // New flag for spring matching phase
self.initiateFallToWinterTransition = function () {
// Transition logic from Fall to Winter
console.log("Transitioning from Fall to Winter");
self.setActiveSeason(self.SEASONS.WINTER);
};
self.SEASONS = {
SPRING: 'spring',
SUMMER: 'summer',
FALL: 'fall',
WINTER: 'winter'
};
self.currentSeason = null;
self.yearNumber = 1;
self.totalScore = 0;
self.seasonStartTime = 0;
self.init = function () {
self.yearNumber = 1;
self.inTransition = false; // Add this line
return;
};
self.forceClearAllBlooms = function () {
if (!garden) {
return;
}
// Clear all setTimeout timers first
if (game.activeTimeouts) {
game.activeTimeouts.forEach(function (timeout) {
LK.clearTimeout(timeout);
});
game.activeTimeouts = [];
}
// Force clear any cell that has an active animation or bloom in progress
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
var item = garden.grid[row][col];
if (item) {
// Stop any active tweens on this item
tween.stop(item);
tween.stop(item.scale);
// If it's mid-bloom or animation
if (item.isBeingReplaced || item.scale.x !== 1 || item.isBud && item.isBeingPollinated) {
garden.removeChild(item);
garden.grid[row][col] = null;
item.destroy();
}
}
}
}
};
self.showSeasonComplete = function () {
// Create a container for the SeasonCompleteText
var textContainer = new Container();
textContainer.x = 2048 / 2;
textContainer.y = 2732 / 2;
// Attach the SeasonCompleteText asset to the container
var seasonCompleteText = textContainer.attachAsset('SeasonCompleteText', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7,
alpha: 0
});
// Add the container to the game
game.addChild(textContainer);
// Animate the text in
tween(seasonCompleteText, {
alpha: 1,
scaleX: 1.1,
scaleY: 1.1,
y: seasonCompleteText.y - 50
}, {
duration: 600,
ease: 'backOut',
onFinish: function onFinish() {
// Settle to normal size
tween(seasonCompleteText, {
scaleX: 1,
scaleY: 1
}, {
duration: 400,
ease: 'backOut'
});
}
});
// Animate the text out after display time
LK.setTimeout(function () {
tween(seasonCompleteText, {
alpha: 0,
y: seasonCompleteText.y - 100,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(textContainer);
}
});
}, 2000);
};
self.setActiveSeason = function (season) {
if (self.transitioningToSpring) {
return;
} // Check both flags
self.forceClearAllBlooms();
// Clear bee's pollen state and pollenUI
if (bee) {
bee.currentPollen = 0;
bee.currentColor = null;
bee.pollenUI.forEach(function (pollen) {
if (pollen.parent) {
pollen.parent.removeChild(pollen);
}
});
bee.pollenUI = [];
if (bee.pollenTrail) {
bee.pollenTrail.active = false;
bee.pollenTrail.points = [];
}
}
if (self.currentSeason && game.scoreDisplay) {
self.totalScore += parseInt(game.scoreDisplay.text);
}
self.currentSeason = season;
if (game.gameTimer) {
game.gameTimer.updateYear(self.yearNumber);
}
self.transitionToSeason(season);
};
self.transitionToSeason = function (season) {
// Clear existing particles first
self.clearTransitionEffects();
// Create transition effects
self.createSeasonTransition(season);
// Update game rules and mechanics
self.updateGameRules(season);
// Show season text
self.showSeasonText(season);
};
self.clearTransitionEffects = function () {
// Remove all existing transition particles
game.children.forEach(function (child) {
if (child.isTransitionEffect) {
game.removeChild(child);
}
});
};
self.createSeasonTransition = function (season) {
var particleConfig = {
spring: {
asset: 'SpringLeaf',
count: 50,
tint: 0x88FF88
},
summer: {
asset: 'Petal',
count: 80,
// Randomly choose a tint for each particle
tint: 0xFF0000
},
fall: {
asset: 'Leaf',
count: 40,
tint: 0xFFFFFF // Set to white (no tint) to show natural color
},
winter: {
asset: 'SnowFlake',
count: 60,
tint: 0xFFFFFF
}
};
var config = particleConfig[season];
for (var i = 0; i < config.count; i++) {
var particle = new TransitionParticle(config.asset);
if (season === 'summer') {
var tints = [0xFF0000, 0xFFFF00, 0x0000FF];
particle.children[0].tint = tints[Math.floor(Math.random() * tints.length)];
} else {
particle.children[0].tint = config.tint;
}
particle.isTransitionEffect = true;
game.addChild(particle);
}
};
self.updateGameRules = function (season) {
// Clear existing timers/rules
if (garden.budSpawner && typeof garden.budSpawner.reset === 'function') {
garden.budSpawner.reset();
}
switch (season) {
case self.SEASONS.SPRING:
self.initSpringMode();
break;
case self.SEASONS.SUMMER:
self.initSummerMode();
break;
case self.SEASONS.FALL:
self.initFallMode();
break;
case self.SEASONS.WINTER:
self.initWinterMode();
break;
}
self.showSeasonInstructions(season);
};
self.startSeasonTimers = function () {
if (game.gameTimer) {
game.gameTimer.active = true;
}
if (self.currentSeason === self.SEASONS.WINTER && garden.warmthMeter) {
garden.warmthMeter.active = true;
}
};
self.showSeasonInstructions = function (season) {
// Only show instructions in year 1
if (self.yearNumber > 1) {
if (self.currentSeason === self.SEASONS.WINTER) {
// For winter in year 2+, wait for warmth meter to initialize
LK.setTimeout(function () {
self.startSeasonTimers();
}, 1500);
} else {
self.startSeasonTimers();
return;
}
}
var instructionAssets = {
spring: 'SpringInstructions',
summer: 'SummerInstructions',
fall: 'FallInstructions',
winter: 'WinterInstructions'
};
// Create container for instructions
var instructionContainer = new Container();
instructionContainer.x = 2048 / 2;
instructionContainer.y = 2732 / 2;
// Attach the asset to the container
var instructions = instructionContainer.attachAsset(instructionAssets[season], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7,
alpha: 0
});
game.addChild(instructionContainer);
// Animate in after season text (which shows for 2 seconds)
LK.setTimeout(function () {
tween(instructions, {
alpha: 1,
scaleX: 1.1,
scaleY: 1.1,
y: instructions.y - 50
}, {
duration: 600,
ease: 'backOut',
onFinish: function onFinish() {
// Settle to normal size
tween(instructions, {
scaleX: 1,
scaleY: 1
}, {
duration: 400,
ease: 'backOut'
});
}
});
// Animate out after display time
LK.setTimeout(function () {
tween(instructions, {
alpha: 0,
y: instructions.y - 100,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(instructionContainer);
self.startSeasonTimers();
}
});
}, 3000);
}, 2500);
};
self.showSeasonText = function (season) {
var textAssets = {
spring: 'SpringText',
summer: 'SummerText',
fall: 'FallText',
winter: 'WinterText'
};
// Create a container for the text
var textContainer = new Container();
textContainer.x = 2048 / 2;
textContainer.y = 2732 / 2;
// Attach the asset to the container
var seasonText = textContainer.attachAsset(textAssets[season], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7,
alpha: 0
});
game.addChild(textContainer);
// First animate in
tween(seasonText, {
alpha: 1,
scaleX: 1.1,
scaleY: 1.1,
y: seasonText.y - 50
}, {
duration: 600,
ease: 'backOut'
});
// Then settle to normal size
LK.setTimeout(function () {
tween(seasonText, {
scaleX: 1,
scaleY: 1
}, {
duration: 400,
ease: 'backOut'
});
}, 600);
// Finally fade out
LK.setTimeout(function () {
tween(seasonText, {
alpha: 0,
y: seasonText.y - 100,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(textContainer);
}
});
}, 2000);
};
// Initialize each season's specific mechanics
self.initSpringMode = function () {
self.springFinaleStarted = false; // Reset finale state at start of spring
self.springMatchingEnabled = false; // Reset matching state
if (game.children[0] instanceof GardenBackground) {
game.children[0].setSeasonBackground('spring');
}
if (!game.gameTimer) {
game.gameTimer = new GameTimer();
game.addChild(game.gameTimer);
game.gameTimer.x = 2048 - 100 - 2048 * 0.03; // Move left by 3% of screen width
game.gameTimer.y = 50; // Align with the top of the screen
}
// Set spring timer
game.gameTimer.setTime(90); // 90 seconds (1 minute and 30 seconds)
// Removed old timer setup as GameTimer is now used
// Disable normal bud spawning
if (garden.budSpawner) {
garden.budSpawner.enabled = false;
}
// Clear and fully populate garden with buds
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
if (garden.grid[row][col]) {
garden.grid[row][col].destroy();
garden.grid[row][col] = null;
}
var bud = new Bud();
var worldPos = garden.gridToWorld(col, row);
bud.x = worldPos.x - 400 + garden.cellSize;
bud.y = worldPos.y - 400 - 50;
garden.grid[row][col] = bud;
garden.addChild(bud);
// Scale in animation
bud.scale.set(0);
tween(bud.scale, {
x: 1,
y: 1
}, {
duration: 500,
ease: 'backOut'
});
}
}
// Check if source flowers need to be recreated
if (!garden.sourceFlowers || garden.sourceFlowers.children.length === 0) {
garden.sourceFlowers = new Container();
garden.addChild(garden.sourceFlowers);
// Calculate positions
var centerX = garden.cols * garden.cellSize / 2;
// Blue flower at bottom center
var blueFlower = new SourceFlower('blue');
blueFlower.x = centerX;
blueFlower.y = garden.rows * garden.cellSize + garden.cellSize * 1.5 - 0.02 * 2732;
garden.sourceFlowers.addChild(blueFlower);
// Red flower under bottom left bud
var redFlower = new SourceFlower('red');
redFlower.x = garden.cellSize / 2 - 0.015 * 2048;
redFlower.y = garden.rows * garden.cellSize + garden.cellSize * 1.5 - 0.02 * 2732;
garden.sourceFlowers.addChild(redFlower);
// Yellow flower under bottom right bud
var yellowFlower = new SourceFlower('yellow');
yellowFlower.x = garden.cols * garden.cellSize - garden.cellSize / 2 + 0.01 * 2048;
yellowFlower.y = garden.rows * garden.cellSize + garden.cellSize * 1.5 - 0.02 * 2732;
garden.sourceFlowers.addChild(yellowFlower);
}
// Calculate total flower requirements based on year
var totalFlowersNeeded = 15 + (self.yearNumber - 1) * 5;
totalFlowersNeeded = Math.min(totalFlowersNeeded, 64); // Cap at 64 total flowers
// Set up random distribution of goals
var primaryGoals = Math.ceil(totalFlowersNeeded * 0.6); // 60% split between red, blue, yellow
var hybridGoals = totalFlowersNeeded - primaryGoals; // Remaining 40% for hybrid colors
// Randomly distribute primary colors (should add up to primaryGoals)
var redGoal = Math.floor(primaryGoals / 3 + (Math.random() - 0.5) * 2);
var blueGoal = Math.floor((primaryGoals - redGoal) / 2 + (Math.random() - 0.5) * 2);
var yellowGoal = primaryGoals - redGoal - blueGoal;
// Randomly distribute hybrid colors (should add up to hybridGoals)
var purpleGoal = Math.floor(hybridGoals / 3 + (Math.random() - 0.5) * 2);
var greenGoal = Math.floor((hybridGoals - purpleGoal) / 2 + (Math.random() - 0.5) * 2);
var orangeGoal = hybridGoals - purpleGoal - greenGoal;
garden.flowerGoals = {
red: Math.max(1, redGoal),
blue: Math.max(1, blueGoal),
yellow: Math.max(1, yellowGoal),
purple: Math.max(1, purpleGoal),
orange: Math.max(1, orangeGoal),
green: Math.max(1, greenGoal)
};
garden.currentFlowers = {
red: 0,
blue: 0,
yellow: 0,
purple: 0,
orange: 0,
green: 0
};
// Create flower goal display
self.createFlowerGoalDisplay();
// Disable normal bud spawning
};
self.createGoalIndicator = function (colorData, isLeft) {
var row = new Container();
var flower = new BasicFlower(colorData.color);
flower.scale.set(0.6);
flower.y = 167;
row.addChild(flower);
var text = new Text2("0/" + colorData.goal, {
size: 120,
fill: 0xFFFFFF
});
text.x = 100;
text.y = 100;
row.addChild(text);
// Store reference to text for updates
garden.currentFlowers[colorData.color + "Text"] = text;
return row;
};
self.createFlowerGoalDisplay = function () {
var display = new Container();
// Create array of goals for tracking
var goalQueue = Object.keys(garden.flowerGoals).map(function (color) {
return {
color: color,
goal: garden.flowerGoals[color]
};
});
// Create total progress display on left
var totalGoals = goalQueue.length;
var progressContainer = new Container(); // Container for progress text
var progressText = new Text2("0/" + totalGoals + " flower goals met", {
size: 80,
fill: 0xFFFFFF
});
progressText.y = 120;
progressContainer.x = -800;
progressContainer.addChild(progressText);
display.addChild(progressContainer);
if (game.seasonManager.currentSeason === game.seasonManager.SEASONS.SUMMER) {
progressText.setText("0/" + totalGoals + " match goals met");
}
// Show first goal on right
if (goalQueue.length > 0) {
var goalContainer = self.createGoalIndicator(goalQueue[0], false);
goalContainer.x = 400; // Position on right
display.addChild(goalContainer);
}
// Store references
garden.goalQueue = goalQueue;
garden.goalDisplay = display;
garden.progressText = progressText;
display.x = 2048 / 2;
display.y = 100;
game.addChild(display);
};
self.updateFlowerCounts = function () {
// Reset ONLY the number counts, not text references
Object.keys(garden.currentFlowers).forEach(function (color) {
if (typeof garden.currentFlowers[color] === 'number' && !color.includes('Text')) {
garden.currentFlowers[color] = 0;
}
});
// Count all flowers in garden
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
var item = garden.grid[row][col];
if (item && item.isFlower && !item.isSourceFlower) {
garden.currentFlowers[item.color]++;
}
}
}
// Update display
Object.keys(garden.flowerGoals).forEach(function (color) {
if (garden.currentFlowers[color + "Text"]) {
var currentCount = garden.currentFlowers[color];
var goalCount = garden.flowerGoals[color];
var text = garden.currentFlowers[color + "Text"];
// Check if goal met
if (currentCount >= goalCount) {
currentCount = goalCount; // Cap the display at goal amount
// Create new green text
var newText = new Text2(currentCount + "/" + goalCount, {
size: 120,
fill: 0x00FF00
});
newText.x = text.x;
newText.y = text.y;
text.parent.addChild(newText);
text.parent.removeChild(text);
garden.currentFlowers[color + "Text"] = newText;
} else {
text.setText(currentCount + "/" + goalCount);
}
}
});
// Replace the "Check for completed goals and cycle display" section with:
// This goes in updateFlowerCounts, replacing the goal cycling section:
if (garden.goalQueue && garden.goalQueue.length > 0) {
// First verify the goal display exists and has the expected child
if (garden.goalDisplay && garden.goalDisplay.children.length > 1) {
var displayedGoal = garden.goalDisplay.children[1];
var goalColor = garden.goalQueue[0].color;
if (garden.currentFlowers[goalColor] >= garden.flowerGoals[goalColor]) {
// Verify displayedGoal still exists before animating
if (displayedGoal && displayedGoal.parent === garden.goalDisplay) {
tween(displayedGoal, {
alpha: 0,
y: displayedGoal.y - 50
}, {
duration: 500,
onFinish: function onFinish() {
// Double check goal display still exists
if (garden.goalDisplay && garden.goalDisplay.children.includes(displayedGoal)) {
garden.goalDisplay.removeChild(displayedGoal);
garden.goalQueue.splice(0, 1);
// Update progress text
var completedGoals = Object.keys(garden.flowerGoals).length - garden.goalQueue.length;
var totalGoals = Object.keys(garden.flowerGoals).length;
// Show next goal if available
if (garden.goalQueue.length > 0) {
var nextGoal = self.createGoalIndicator(garden.goalQueue[0], false);
nextGoal.x = 400;
nextGoal.alpha = 0;
garden.goalDisplay.addChild(nextGoal);
tween(nextGoal, {
alpha: 1
}, {
duration: 500
});
garden.progressText.setText(completedGoals + "/" + totalGoals + " flower goals met");
} else {
// All goals complete
garden.progressText.setText("All flower goals met!");
garden.progressText.fill = 0x00FF00;
}
}
}
});
}
}
}
}
// Check for spring mode completion
var allGoalsMet = Object.keys(garden.flowerGoals).every(function (color) {
return garden.currentFlowers[color] >= garden.flowerGoals[color];
});
};
self.initSummerMode = function () {
// garden.budSpawner.initSummerMode(self.yearNumber);
garden.flowerGoals = {};
// Define base match goals for each color
var baseMatchGoals = {
red: 3,
blue: 3,
yellow: 3,
purple: 2,
orange: 2,
green: 2
};
// Scale goals with year number
Object.keys(baseMatchGoals).forEach(function (color) {
garden.flowerGoals[color] = Math.min(baseMatchGoals[color] + (self.yearNumber - 1) * 2, 12 // Cap at 12 matches per color
);
});
// Initialize counters
garden.currentFlowers = {
red: 0,
blue: 0,
yellow: 0,
purple: 0,
orange: 0,
green: 0
};
// Create goal display after initializing goals
self.createFlowerGoalDisplay();
if (!game.gameTimer) {
game.gameTimer = new GameTimer();
game.addChild(game.gameTimer);
}
game.gameTimer.setTime(90); // 90 seconds
// Set background
if (game.children[0] instanceof GardenBackground) {
game.children[0].setSeasonBackground('summer');
}
// Initialize spawner with year-based settings
garden.budSpawner.enabled = true;
// garden.budSpawner.initSummerMode(self.yearNumber);
};
self.clearBoardForFall = function () {
var itemsToRemove = [];
// First, collect all buds and flowers
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
var item = garden.grid[row][col];
if (item && (item.isBud || item.isFlower)) {
itemsToRemove.push({
item: item,
row: row,
col: col
});
}
}
}
// Set fallInitTime now since we'll handle everything in one sequence
self.fallInitTime = LK.ticks;
// Clear 60% of existing items
itemsToRemove = itemsToRemove.sort(function () {
return Math.random() - 0.5;
}).slice(0, Math.floor(itemsToRemove.length * 0.6));
// If there's nothing to clear, just add leaves
if (itemsToRemove.length === 0) {
self.addLeafObstacles();
return;
}
// Clear items and add leaves simultaneously
// Clear items and add leaves simultaneously
itemsToRemove.forEach(function (info, index) {
LK.setTimeout(function () {
// Clear grid position first
garden.grid[info.row][info.col] = null;
// Do animation
tween(info.item, {
alpha: 0,
rotation: (Math.random() - 0.5) * Math.PI * 2 // Random rotation
}, {
duration: 500
});
tween(info.item.scale, {
x: 0,
y: 0
}, {
duration: 500,
onFinish: function onFinish() {
// Now do force clear at this position
var worldPos = garden.gridToWorld(info.col, info.row);
var expectedX = worldPos.x - 400 + garden.cellSize;
var expectedY = worldPos.y - 400 - 50;
// Force clear any sprites at this position
for (var i = garden.children.length - 1; i >= 0; i--) {
var child = garden.children[i];
if (child.x === expectedX && child.y === expectedY) {
garden.removeChild(child);
child.destroy();
}
}
garden.removeChild(info.item);
// When last item is cleared, add leaves
if (index === itemsToRemove.length - 1) {
// Count empty spaces and track positions
var emptySpaces = 0;
var emptyPositions = [];
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
if (!garden.grid[row][col]) {
emptySpaces++;
emptyPositions.push({
row: row,
col: col
});
}
}
}
// Calculate leaf count with enforced minimum
var baseLeaves = 5; // Minimum leaves
var maxLeaves = Math.min(Math.floor(emptySpaces * 0.7), Math.floor(garden.rows * garden.cols * 0.3));
var totalLeaves = Math.max(baseLeaves, Math.min(baseLeaves + (self.yearNumber - 1) * 3, maxLeaves));
garden.totalLeaves = totalLeaves; // Store total leaves for progress tracking
// Shuffle empty positions
emptyPositions.sort(function () {
return Math.random() - 0.5;
});
// Add leaves immediately after last clear
for (var i = 0; i < totalLeaves; i++) {
if (i >= emptyPositions.length) {
break;
}
var spot = emptyPositions[i];
// Double check spot is still empty
if (!garden.grid[spot.row][spot.col]) {
var leaf = LK.getAsset('Leaf', {
anchorX: 0.5,
anchorY: 0.5
});
}
var worldPos = garden.gridToWorld(spot.col, spot.row);
leaf.x = worldPos.x - 400 + garden.cellSize;
leaf.y = worldPos.y - 400 - 50;
leaf.isLeaf = true;
leaf.update = function () {
this.rotation = Math.sin(LK.ticks * 0.02) * 0.2;
};
garden.grid[spot.row][spot.col] = leaf;
garden.addChild(leaf);
leaf.scale.set(0);
tween(leaf.scale, {
x: 1,
y: 1
}, {
duration: 500,
ease: 'backOut'
});
}
}
}
});
}, index * 50);
});
};
self.initFallMode = function () {
if (!game.gameTimer) {
game.gameTimer = new GameTimer();
game.addChild(game.gameTimer);
}
game.gameTimer.setTime(90);
if (garden.goalDisplay && garden.goalDisplay.parent) {
garden.goalDisplay.parent.removeChild(garden.goalDisplay);
}
var display = new Container();
var progressText = new Text2("0 leaves cleared", {
size: 80,
fill: 0xFFFFFF
});
progressText.y = 120;
var progressContainer = new Container(); // Initialize progressContainer
progressContainer.x = -800;
progressContainer.addChild(progressText);
display.addChild(progressContainer);
garden.goalDisplay = display;
garden.progressText = progressText;
display.x = 2048 / 2;
display.y = 100;
game.addChild(display);
if (game.children[0] instanceof GardenBackground) {
game.children[0].setSeasonBackground('fall');
}
// Clear fallInitTime so updateFall won't start checking yet
self.fallInitTime = undefined;
// Start the board clearing process
self.clearBoardForFall();
// Set fallInitTime after leaves are added - longer delay for year 1 with instructions
var setupDelay = self.yearNumber === 1 ? 2000 : 3500; // Longer base delay for year 2+
LK.setTimeout(function () {
self.fallInitTime = LK.ticks;
if (garden.budSpawner) {
garden.budSpawner.enabled = true;
}
}, setupDelay);
};
self.initWinterMode = function () {
// Add at start of initWinterMode method
// Clear any existing flower goal display
if (garden.goalDisplay && garden.goalDisplay.parent) {
garden.goalDisplay.parent.removeChild(garden.goalDisplay);
garden.goalDisplay = null;
}
var itemsToCheck = [];
// First identify all items that need to be cleared
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
var item = garden.grid[row][col];
if (item) {
itemsToCheck.push({
item: item,
row: row,
col: col
});
}
}
}
// Clear bee's pollen state
if (bee) {
bee.currentPollen = 0;
bee.pollenTypes = [];
bee.currentColor = null;
if (bee.pollenTrail) {
bee.pollenTrail.active = false;
bee.pollenTrail.points = [];
}
}
// Clear any warning cracks
if (garden.budSpawner) {
garden.budSpawner.warningSprites.forEach(function (sprite) {
sprite.destroy();
});
garden.budSpawner.warningSprites = [];
garden.budSpawner.currentPattern = null;
garden.budSpawner.nextSpawnPosition = null;
garden.budSpawner.enabled = false;
}
// Change background
if (game.children[0] instanceof GardenBackground) {
game.children[0].setSeasonBackground('winter');
}
// Setup winter systems after clearing animation
if (!game.gameTimer) {
game.gameTimer = new GameTimer();
game.addChild(game.gameTimer);
}
// Set winter timer
game.gameTimer.setTime(90); // 90 seconds for winter
// Clear grid items with shrinking animation
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
var item = garden.grid[row][col];
if (item) {
// Create closure to handle position and item
(function (item, row, col) {
LK.setTimeout(function () {
// Force clear any sprites at this position
var worldPos = garden.gridToWorld(col, row);
var expectedX = worldPos.x - 400 + garden.cellSize;
var expectedY = worldPos.y - 400 - 50;
// Clear grid position first
garden.grid[row][col] = null;
// Force clear any sprites at this position
for (var i = garden.children.length - 1; i >= 0; i--) {
var child = garden.children[i];
if (child.x === expectedX && child.y === expectedY) {
garden.removeChild(child);
child.destroy();
}
}
// Now do the animation
tween(item.scale, {
x: 0,
y: 0
}, {
duration: 500,
onFinish: function onFinish() {
garden.removeChild(item);
item.destroy();
}
});
}, (row * garden.cols + col) * 50);
})(item, row, col);
}
}
}
LK.setTimeout(function () {
// Verify all items were cleared
itemsToCheck.forEach(function (entry) {
if (entry.item.parent) {
garden.grid[entry.row][entry.col] = null;
garden.removeChild(entry.item);
entry.item.destroy();
}
});
}, garden.rows * garden.cols * 50 + 600);
if (garden.sourceFlowers) {
// Create new container for snowmen
garden.winterSnowmen = new Container();
garden.addChild(garden.winterSnowmen);
// Calculate centerX once
var centerX = garden.cols * garden.cellSize / 2;
var baseY = garden.rows * garden.cellSize + garden.cellSize * 1.5 - 0.02 * 2732;
// Store flowers and their positions together
var flowerData = garden.sourceFlowers.children.map(function (flower) {
return {
flower: flower,
position: {
x: flower.x,
y: flower.y
}
};
});
// Remove flowers and add snowmen
flowerData.forEach(function (data, index) {
tween(data.flower.scale, {
x: 0,
y: 0
}, {
duration: 500,
delay: index * 200,
onFinish: function onFinish() {
garden.sourceFlowers.removeChild(data.flower);
// Add snowman using the stored position
var snowman = new Snowman();
snowman.x = data.position.x;
snowman.y = data.position.y;
snowman.scale.set(0);
garden.winterSnowmen.addChild(snowman);
tween(snowman.scale, {
x: 1.5,
y: 1.5
}, {
duration: 1000,
ease: 'elasticOut'
});
}
});
});
}
// Get garden soil and create snow overlay
var gardenBackground = game.children.find(function (child) {
return child instanceof GardenBackground;
});
var originalSoil = gardenBackground ? gardenBackground.getGardenSoil() : null;
if (originalSoil) {
var snowOverlay = LK.getAsset('marker', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 19,
scaleY: 19,
tint: 0xFFFFFF,
alpha: 0
});
snowOverlay.x = originalSoil.x;
snowOverlay.y = originalSoil.y;
game.children[0].soilLayer.addChild(snowOverlay);
tween(snowOverlay, {
alpha: 0.5 // Adjust this value for snow intensity
}, {
duration: 1000
});
}
// Setup winter systems after clearing animation
LK.setTimeout(function () {
// First expand the background
if (game.scoreDisplay && game.scoreDisplay.background) {
game.scoreDisplay.background.expandForWinter();
}
garden.warmthMeter = new WarmthMeter();
garden.warmthMeter.x = 2048 / 2;
garden.warmthMeter.y = 250; // Move down below score
garden.warmthMeter.scale.set(1.5);
game.addChild(garden.warmthMeter);
garden.patternSystem = new WinterPatternSystem();
game.addChild(garden.patternSystem);
LK.setTimeout(function () {
garden.patternSystem.createPattern();
}, 2000);
}, 1500);
};
self.startSpringFinale = function () {
// Step 1a: Clear UI elements
if (garden.goalDisplay && garden.goalDisplay.parent) {
garden.goalDisplay.parent.removeChild(garden.goalDisplay);
garden.goalDisplay = null;
}
// Step 1b: Initialize score manager while preserving current score
game.scoreManager = new ScoreManager();
game.scoreManager.currentScore = game.scoreDisplay ? parseInt(game.scoreDisplay.text) || 0 : 0;
// Step 1c: Enable matching and chain sequence
self.springMatchingEnabled = true;
self.springFinaleChaining = true;
self.initiateSpringMatching();
};
self.initiateSpringMatching = function () {
// Start from the bottom row and work up
var startMatchingFromBottom = function startMatchingFromBottom() {
var matchFound = false;
// Start from bottom-right corner
for (var row = garden.rows - 1; row >= 0; row--) {
for (var col = garden.cols - 1; col >= 0; col--) {
var flower = garden.grid[row][col];
if (flower && flower.isFlower) {
var matches = game.flowerMatcher.findMatches(garden, col, row);
if (matches.length >= 3) {
matchFound = true;
// Immediately clear grid positions
matches.forEach(function (match) {
if (garden.grid[match.y][match.x] === match.flower) {
garden.grid[match.y][match.x] = null;
}
});
// Handle animation with delay
LK.setTimeout(function () {
self.handleSpringMatch(matches);
}, 800);
return true; // Exit after finding first match
}
}
}
}
return matchFound;
};
// Set up recursive matching with delays
var _continueMatching = function continueMatching() {
if (startMatchingFromBottom()) {
LK.setTimeout(_continueMatching, 1500);
} else {
self.completeSpringPhase();
}
};
_continueMatching();
};
self.handleSpringMatch = function (matches) {
// Step 2a: Update chain multiplier
if (self.springFinaleChaining) {
game.scoreManager.currentChain++;
game.scoreManager.chainMultiplier = Math.min(1 + game.scoreManager.currentChain * 0.5, 5);
}
// Step 2b: Process matches and add to current score
game.flowerMatcher.clearMatches(garden, matches);
};
self.completeSpringPhase = function () {
self.showSeasonComplete();
LK.setTimeout(function () {
// Clear flower goals UI
if (garden.goalDisplay && garden.goalDisplay.parent) {
garden.goalDisplay.parent.removeChild(garden.goalDisplay);
garden.goalDisplay = null;
}
// Transition to summer
self.springFinaleStarted = false;
self.springMatchingEnabled = false;
game.seasonManager.setActiveSeason(game.seasonManager.SEASONS.SUMMER);
}, 3000);
};
self.update = function () {
if (!self.currentSeason) {
return;
}
switch (self.currentSeason) {
case self.SEASONS.SPRING:
// Timer update
// Timer update is now handled by GameTimer class
// Garden check (outside timer check)
var fullyPollinated = true;
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
var _garden$grid$row$col;
if (!((_garden$grid$row$col = garden.grid[row][col]) !== null && _garden$grid$row$col !== void 0 && _garden$grid$row$col.isFlower)) {
fullyPollinated = false;
break;
}
}
if (!fullyPollinated) {
break;
}
}
// Check for end conditions
var goalsMet = Object.keys(garden.flowerGoals).every(function (color) {
return garden.currentFlowers[color] >= garden.flowerGoals[color];
});
if (goalsMet && !self.springFinaleStarted) {
// Start the spring finale sequence immediately when goals are met
self.springFinaleStarted = true;
self.springMatchingEnabled = false;
LK.setTimeout(function () {
self.startSpringFinale();
}, 500);
} else if ((game.gameTimer.timeRemaining <= 0 || fullyPollinated) && !self.springFinaleStarted) {
// Time ran out or board filled, but goals weren't met
var gameOverText = new Text2("GAME OVER! - Flower goals not met!", {
size: 120,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2;
game.addChild(gameOverText);
tween(gameOverText, {
alpha: 0
}, {
duration: 1000,
delay: 2000,
onFinish: function onFinish() {
gameOverText.destroy();
LK.showGameOver();
}
});
}
break;
case self.SEASONS.SUMMER:
self.updateSummer();
break;
case self.SEASONS.FALL:
self.updateFall();
break;
case self.SEASONS.WINTER:
self.updateWinter();
break;
}
};
self.updateSummer = function () {
// Check if all flower goals are met first
var allGoalsMet = garden.goalQueue && garden.goalQueue.length === 0;
// Add transitions flag check to prevent multiple triggers
if (allGoalsMet && !self.inTransition) {
self.inTransition = true; // Set flag to prevent multiple transitions
// Show completion message before transitioning
self.showSeasonComplete();
// Clean up displays after delay
LK.setTimeout(function () {
// Clean up flower goals display
if (garden.goalDisplay && garden.goalDisplay.parent) {
garden.goalDisplay.parent.removeChild(garden.goalDisplay);
garden.goalDisplay = null;
}
// Clean up hive
if (garden.hiveDisplay && garden.hiveDisplay.parent) {
garden.hiveDisplay.parent.removeChild(garden.hiveDisplay);
garden.hiveDisplay = null;
}
self.inTransition = false; // Reset transition flag
// Transition to fall
self.setActiveSeason(self.SEASONS.FALL);
}, 3000);
} else if (game.gameTimer && game.gameTimer.timeRemaining <= 0) {
// Time ran out before goals were met
var gameOverText = new Text2("GAME OVER - Match goals not met!", {
size: 120,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2;
game.addChild(gameOverText);
tween(gameOverText, {
alpha: 0
}, {
duration: 1000,
delay: 2000,
onFinish: function onFinish() {
gameOverText.destroy();
LK.showGameOver();
}
});
}
};
self.updateFall = function () {
// Only start checking for leaves after initial setup time
if (self.fallInitTime === undefined) {
self.fallInitTime = LK.ticks;
return;
}
// Wait at least 2 seconds before checking for leaves
if (LK.ticks - self.fallInitTime < 180) {
return;
}
// Count remaining leaves
var remainingLeaves = 0;
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
if (garden.grid[row][col] && garden.grid[row][col].isLeaf) {
remainingLeaves++;
}
}
}
if (garden.progressText) {
if (remainingLeaves === 0) {
garden.progressText.setText("All leaves cleared!");
garden.progressText.fill = 0x00FF00;
} else {
var clearedLeaves = garden.totalLeaves - remainingLeaves;
garden.progressText.setText(clearedLeaves + "/" + garden.totalLeaves + " leaves cleared");
}
}
// Add inTransition check here
if (remainingLeaves === 0 && !self.inTransition) {
self.inTransition = true;
self.showSeasonComplete();
LK.setTimeout(function () {
self.inTransition = false;
game.seasonManager.setActiveSeason(game.seasonManager.SEASONS.WINTER);
}, 3000);
} else if (game.gameTimer && game.gameTimer.timeRemaining <= 0) {
// Time ran out before all leaves were cleared
var gameOverText = new Text2("GAME OVER - Not all leaves cleared!", {
size: 120,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2;
game.addChild(gameOverText);
tween(gameOverText, {
alpha: 0
}, {
duration: 1000,
delay: 1500,
onFinish: function onFinish() {
gameOverText.destroy();
LK.showGameOver();
}
});
}
};
self.updateWinter = function () {
// Check warmth meter status
if (garden.warmthMeter) {
if (garden.warmthMeter.warmth <= 0) {
// Game over condition
var gameOverText = new Text2("GAME OVER - Froze solid!", {
size: 120,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2;
game.addChild(gameOverText);
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
} else if (game.gameTimer && game.gameTimer.timeRemaining <= 0 && !self.transitioningToSpring && !self.inTransition) {
self.inTransition = true;
self.transitioningToSpring = true;
self.showSeasonComplete();
if (game.scoreDisplay && game.scoreDisplay.background) {
game.scoreDisplay.background.resetFromWinter();
}
// Clear snowmen properly
if (garden.winterSnowmen) {
garden.winterSnowmen.children.forEach(function (snowman) {
tween(snowman.scale, {
x: 0,
y: 0
}, {
duration: 500,
onFinish: function onFinish() {
garden.winterSnowmen.removeChild(snowman);
}
});
});
// Remove the container itself after animation
LK.setTimeout(function () {
garden.removeChild(garden.winterSnowmen);
garden.winterSnowmen = null;
}, 600);
}
// Clear pattern system and particles
if (garden.patternSystem) {
// Clear existing particles with fade animation
garden.patternSystem.particles.forEach(function (particle) {
tween(particle, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 500,
onFinish: function onFinish() {
particle.destroy();
}
});
});
// Clear the pattern system
LK.setTimeout(function () {
garden.patternSystem.particles = [];
game.removeChild(garden.patternSystem);
garden.patternSystem = null;
}, 600);
}
// Remove snow overlay properly
if (game.children[0] instanceof GardenBackground) {
var soilLayer = game.children[0].soilLayer;
soilLayer.children.forEach(function (child) {
if (child !== game.children[0].gardenSoil) {
tween(child, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
soilLayer.removeChild(child);
}
});
}
});
}
// Remove warmth meter
if (garden.warmthMeter) {
tween(garden.warmthMeter, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(garden.warmthMeter);
garden.warmthMeter = null;
}
});
}
// After cleanup animations, transition to spring
LK.setTimeout(function () {
self.inTransition = false;
self.transitioningToSpring = false;
self.yearNumber++;
game.seasonManager.setActiveSeason(game.seasonManager.SEASONS.SPRING);
}, 3000);
}
}
};
return self;
});
var Snowman = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('Snowman', {
anchorX: 0.5,
anchorY: 0.5
});
self.danceTimer = 0;
self.baseRotation = (Math.random() - 0.5) * 0.1;
self.rotation = self.baseRotation;
self.update = function () {
self.danceTimer += 0.05;
// Add the sin wave to the current position instead of overwriting it
self.y += Math.sin(self.danceTimer) * 0.5; // Reduced amount and just add/subtract from current y
self.rotation = self.baseRotation + Math.sin(self.danceTimer * 0.7) * 0.1;
var scalePulse = 1 + Math.sin(self.danceTimer * 0.5) * 0.05;
self.scale.set(scalePulse);
};
return self;
});
var SourceFlower = Container.expand(function (color) {
var self = Container.call(this);
// Store flower color
self.color = color;
self.isSourceFlower = true; // Flag to identify source flowers
// Map color to asset name
var assetMap = {
'red': 'RedFlower',
'blue': 'BlueFlower',
'yellow': 'YellowFlower'
};
// Create flower sprite
var flowerGraphics = self.attachAsset(assetMap[self.color], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
// Source flowers always have pollen
self.hasActivePollen = true;
self.fairyParticles = [];
self.FAIRY_COUNT = 3;
// Initialize fairy particles
for (var i = 0; i < self.FAIRY_COUNT; i++) {
var fairy = new PollenParticle().init('fairy');
fairy.scale.set(0.3 + Math.random() * 0.2);
fairy.x += (Math.random() - 0.5) * 60;
fairy.y += (Math.random() - 0.5) * 60;
fairy.rotation = Math.random() * Math.PI * 2;
fairy.rotationSpeed = (Math.random() - 0.5) * 0.2;
self.addChild(fairy);
self.fairyParticles.push(fairy);
}
// Gentle animation
self.update = function () {
var scaleFactor = 1.5 + Math.sin(LK.ticks * 0.05) * 0.1; // Adjusted for 1.5x size and increased animation amplitude
flowerGraphics.scale.x = scaleFactor;
flowerGraphics.scale.y = scaleFactor;
flowerGraphics.rotation = Math.sin(LK.ticks * 0.05) * 0.1; // Increased rotation amplitude for larger size
// Update fairy particles
self.fairyParticles.forEach(function (fairy) {
if (fairy && fairy.update) {
fairy.update();
}
});
};
// Override collection behavior - source flowers regenerate pollen immediately
self.pollenCollected = false;
self.resetPollen = function () {
self.hasActivePollen = true;
self.pollenCollected = false;
};
self.collectPollen = function () {
// Reset immediately to allow continuous collection
self.hasActivePollen = true;
self.pollenCollected = false;
};
return self;
});
var TransitionParticle = Container.expand(function (assetName) {
var self = Container.call(this);
var sprite = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = Math.random() * 2048;
self.y = -50;
self.vx = (Math.random() - 0.5) * 5;
self.vy = 3 + Math.random() * 2;
self.rotationSpeed = (Math.random() - 0.5) * 0.1;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
self.rotation += self.rotationSpeed;
// Remove if off screen
if (self.y > 2732 + 50) {
self.destroy();
}
};
return self;
});
var TutorialManager = Container.expand(function () {
var self = Container.call(this);
self.targetParticles = [];
// Tutorial states
self.state = {
movement: {
completed: false,
targetPoints: [{
x: 2048 / 4,
y: 2732 / 4,
collected: false
}, {
x: 2048 * 3 / 4,
y: 2732 / 4,
collected: false
}, {
x: 2048 / 4,
y: 2732 * 3 / 4,
collected: false
}, {
x: 2048 * 3 / 4,
y: 2732 * 3 / 4,
collected: false
}]
},
pollenCollection: {
completed: false,
started: false
},
transitPollination: {
completed: false,
started: false
},
dragPollination: {
completed: false,
started: false
},
hybrid: {
completed: false,
started: false
}
};
// Instructions text
self.instructions = {
movement: "Visit all four glowing points!\nTap anywhere to fly there.\nYou can also hold on the bee and drag.",
sourceFlowers: "These big flowers provide pollen!\nFly near one to collect its pollen.",
pollinationTransit: "Great! Now tap a bud to pollinate it precisely.\nThe bee will fly straight there and\n only pollinate once it arrives!",
pollinationDrag: "Perfect! You can also drag the bee through buds!\nCareful though as the bee will pollinate\n or collect anything it touches in this mode.",
hybrid: "Time to mix colors!\nTry Red + Blue = Purple\nBlue + Yellow = Green\nRed + Yellow = Orange"
};
// Create target particles
self.createTargetParticles = function () {
self.targetParticles.forEach(function (p) {
if (p.parent) {
p.parent.removeChild(p);
}
});
self.targetParticles = [];
self.state.movement.targetPoints.forEach(function (point, index) {
if (!point.collected) {
for (var i = 0; i < 6; i++) {
var particle = new PatternParticle();
particle.x = point.x;
particle.y = point.y;
particle.startAngle = i / 6 * Math.PI * 2;
particle.pointIndex = index;
particle.orbitRadius = 40;
particle.orbitSpeed = 0.02;
particle.update = function () {
if (this.active) {
var time = LK.ticks * this.orbitSpeed;
this.x = point.x + Math.cos(time + this.startAngle) * this.orbitRadius;
this.y = point.y + Math.sin(time + this.startAngle) * this.orbitRadius;
this.rotation = time;
this.alpha = 0.8 + Math.sin(LK.ticks * this.twinkleSpeed + this.twinkleOffset) * 0.2;
}
};
game.addChild(particle);
self.targetParticles.push(particle);
}
}
});
};
self.checkParticleCollisions = function (beeX, beeY) {
var anyCollected = false;
self.state.movement.targetPoints.forEach(function (point, index) {
if (!point.collected) {
var dx = beeX - point.x;
var dy = beeY - point.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 50) {
point.collected = true;
anyCollected = true;
self.targetParticles.filter(function (p) {
return p.pointIndex === index;
}).forEach(function (particle) {
tween(particle, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 500,
onFinish: function onFinish() {
if (particle.parent) {
particle.parent.removeChild(particle);
}
}
});
});
for (var i = 0; i < 8; i++) {
var burstParticle = new PollenParticle().init('star');
burstParticle.x = point.x;
burstParticle.y = point.y;
game.addChild(burstParticle);
}
}
}
});
if (anyCollected && self.state.movement.targetPoints.every(function (p) {
return p.collected;
})) {
self.state.movement.completed = true;
self.addSourceFlowers();
}
};
self.showInstruction = function (key) {
if (self.currentText) {
self.currentText.parent.destroy();
}
var textBg = new Container();
self.currentText = new Text2(self.instructions[key], {
size: 80,
fill: 0xFFFFFF,
align: 'center'
});
self.currentText.anchor.set(0.5, 0.5); // Changed from (0.5, 0) to (0.5, 0.5)
self.currentText.x = 0; // Changed from 2048/2 to 0
self.currentText.y = 0; // Changed from 50 to 0
textBg.addChild(self.currentText);
textBg.x = 2048 / 2;
textBg.y = 200; // Adjusted position for better placement
game.addChild(textBg);
};
self.addSourceFlowers = function () {
garden.sourceFlowers = new Container();
garden.addChild(garden.sourceFlowers);
var centerX = garden.cols * garden.cellSize / 2;
var blueFlower = new SourceFlower('blue');
blueFlower.x = centerX;
blueFlower.y = garden.rows * garden.cellSize + garden.cellSize * 1.5 - 0.02 * 2732;
garden.sourceFlowers.addChild(blueFlower);
var redFlower = new SourceFlower('red');
redFlower.x = garden.cellSize / 2 - 0.015 * 2048;
redFlower.y = garden.rows * garden.cellSize + garden.cellSize * 1.5 - 0.02 * 2732;
garden.sourceFlowers.addChild(redFlower);
var yellowFlower = new SourceFlower('yellow');
yellowFlower.x = garden.cols * garden.cellSize - garden.cellSize / 2 + 0.01 * 2048;
yellowFlower.y = garden.rows * garden.cellSize + garden.cellSize * 1.5 - 0.02 * 2732;
garden.sourceFlowers.addChild(yellowFlower);
self.showInstruction('sourceFlowers');
self.state.pollenCollection.started = true;
};
self.addBuds = function () {
// Clear existing buds from the grid
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
var cell = garden.grid[row][col];
if (cell && (cell.isBud || cell.isFlower && !cell.isSourceFlower)) {
garden.removeChild(cell);
garden.grid[row][col] = null;
}
}
}
var positions = [[3, 3], [4, 3], [3, 4], [4, 4]];
positions.forEach(function (pos) {
var bud = new Bud();
var worldPos = garden.gridToWorld(pos[0], pos[1]);
bud.x = worldPos.x - 400 + garden.cellSize;
bud.y = worldPos.y - 400 - 50;
garden.grid[pos[1]][pos[0]] = bud;
garden.addChild(bud);
});
};
self.checkPollenCollection = function () {
if (bee.currentPollen > 0 && !self.state.pollenCollection.completed) {
self.state.pollenCollection.completed = true;
self.state.transitPollination.started = true;
self.showInstruction('pollinationTransit');
self.addBuds();
}
};
self.checkPollination = function () {
if (!self.state.transitPollination.completed) {
// Just check if a flower exists to complete first pollination phase
if (self.hasAnyFlowers()) {
self.state.transitPollination.completed = true;
self.state.dragPollination.started = true;
self.showInstruction('pollinationDrag');
// Clear and reset buds
self.addBuds();
}
} else if (self.state.dragPollination.started && !self.state.dragPollination.completed && bee.isMoving && self.hasAnyFlowers()) {
self.state.dragPollination.completed = true;
self.state.hybrid.started = true;
self.showInstruction('hybrid');
}
};
self.hasAnyFlowers = function () {
for (var row = 0; row < garden.rows; row++) {
for (var col = 0; col < garden.cols; col++) {
var cell = garden.grid[row][col];
if (cell && cell.isFlower && !cell.isSourceFlower) {
// Added !cell.isSourceFlower check
return true;
}
}
}
return false;
};
self.checkHybridCompletion = function () {
if (!self.state.hybrid.completed) {
var hasHybrid = garden.grid.some(function (row) {
return row.some(function (cell) {
return cell && cell.isFlower && ['purple', 'green', 'orange'].includes(cell.color);
});
});
if (hasHybrid) {
self.completeTutorial();
}
}
return false;
};
self.completeTutorial = function () {
self.state.hybrid.completed = true;
// Clear bee's pollen state
bee.currentPollen = 0;
bee.currentColor = null;
if (bee.pollenTrail) {
bee.pollenTrail.active = false;
bee.pollenTrail.points = [];
}
var completionText = new Text2("Tutorial Complete!", {
size: 120,
fill: 0x00FF00
});
completionText.anchor.set(0.5);
completionText.x = 2048 / 2;
completionText.y = 2732 / 2;
game.addChild(completionText);
LK.setTimeout(function () {
tween(game, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
game.alpha = 1;
titleScreen.alpha = 0;
game.addChild(titleScreen);
tween(titleScreen, {
alpha: 1
}, {
duration: 500
});
game.tutorial = null; // Remove tutorial flag before transitioning
}
});
}, 2000);
};
return self;
});
var WarmthMeter = Container.expand(function () {
var self = Container.call(this);
// Create background bar
var background = LK.getAsset('marker', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 0.5,
tint: 0x333333
});
self.addChild(background);
// Create fill bar - using same anchor as background
var fill = LK.getAsset('marker', {
anchorX: 0.5,
anchorY: 0.5,
scaleY: 0.4
});
fill.x = 0; // Center align with background
self.fillBar = fill;
self.addChild(fill);
// Add "Warmth Meter" text
var label = new Text2("Warmth Meter", {
size: 60,
fill: 0xFFFFFF
});
label.anchor.set(0.5);
label.y = 50;
self.addChild(label);
self.warmth = 100;
self.active = false;
self.update = function () {
if (!self.active) {
return;
}
// Start with full width and adjust scale from center
var fullWidth = 8;
var currentWidth = fullWidth * (self.warmth / 100);
self.fillBar.scale.x = currentWidth;
// Update color based on warmth level
var r = Math.min(255, Math.max(0, self.warmth * 2.55));
var b = Math.min(255, Math.max(0, (100 - self.warmth) * 2.55));
self.fillBar.tint = r << 16 | 0 << 8 | b;
// Calculate base decay rate
var baseDecay = 0.1;
// Scale decay with year if in seasons mode
if (game.seasonManager) {
baseDecay += (game.seasonManager.yearNumber - 1) * 0.025; // Add 50% more decay per year
}
// Decrease warmth over time with scaled decay
self.warmth = Math.max(0, self.warmth - baseDecay);
};
// Add back the warmth method
self.addWarmth = function (amount) {
self.warmth = Math.min(100, self.warmth + amount);
};
return self;
});
var WinterPatternSystem = Container.expand(function () {
var self = Container.call(this);
self.patterns = [
// Infinity symbol
function (centerX, centerY) {
var points = [];
for (var t = 0; t < Math.PI * 2; t += 0.1) {
var x = centerX + Math.cos(t) * 800 / (1 + Math.sin(t) * Math.sin(t));
var y = centerY + Math.sin(t) * Math.cos(t) * 600;
points.push({
x: x,
y: y
});
}
return points;
}, function (centerX, centerY) {
var points = [];
// Simple dome semicircle
for (var t = -Math.PI; t <= 0; t += 0.1) {
var x = centerX + Math.cos(t) * 600;
var y = centerY + Math.sin(t) * 600;
points.push({
x: x,
y: y
});
}
// Base line connecting the dome bottom
for (var i = 0; i <= 20; i++) {
var progress = i / 20;
points.push({
x: centerX - 600 + 1200 * progress,
// from -600 to +600
y: centerY
});
}
// Longer straight handle (460px instead of 400px)
for (var i = 0; i <= 23; i++) {
points.push({
x: centerX,
y: centerY + i * 20
});
}
// More graceful curved end
for (var t = 0; t <= Math.PI / 2; t += 0.1) {
var x = centerX - Math.sin(t) * 150;
var y = centerY + 460 + Math.cos(t) * 150 - 150;
points.push({
x: x,
y: y
});
}
return points;
},
// Star pattern
function (centerX, centerY) {
var points = [];
var numPoints = 5;
var outerRadius = 800;
var innerRadius = 400;
centerY += 200; // Move just the star down 200 pixels// Get the points of the star
var corners = [];
for (var i = 0; i < numPoints * 2; i++) {
var radius = i % 2 === 0 ? outerRadius : innerRadius;
var angle = i * Math.PI / numPoints - Math.PI / 2; // Start at top
corners.push({
x: centerX + Math.cos(angle) * radius,
y: centerY + Math.sin(angle) * radius
});
}
// Add first point again to close the shape
corners.push(corners[0]);
// Create particles between each pair of corners
for (var i = 0; i < corners.length - 1; i++) {
var start = corners[i];
var end = corners[i + 1];
var particleCount = 10; // Adjust for density
for (var j = 0; j <= particleCount; j++) {
var t = j / particleCount;
points.push({
x: start.x + (end.x - start.x) * t,
y: start.y + (end.y - start.y) * t
});
}
}
return points;
},
// Spiral pattern
function (centerX, centerY) {
var points = [];
var radius = 50; // Starting radius
var maxRadius = 800; // Maximum radius
var totalRotation = Math.PI * 6; // 3 full rotations
var angleStep = 0.2; // Smaller step for more particles
centerY += 200; // Move just the star down 200 pixels
for (var angle = 0; angle < totalRotation; angle += angleStep) {
// Gradually increase radius as we rotate
var currentRadius = radius + angle / totalRotation * maxRadius;
points.push({
x: centerX + Math.cos(angle) * currentRadius,
y: centerY + Math.sin(angle) * currentRadius
});
}
return points;
},
// W shape (with continuous line particles)
function (centerX, centerY) {
var points = [];
var corners = [{
x: centerX - 800,
y: centerY - 400
}, {
x: centerX - 400,
y: centerY + 400
}, {
x: centerX,
y: centerY - 200
}, {
x: centerX + 400,
y: centerY + 400
}, {
x: centerX + 800,
y: centerY - 400
}];
// Create particles between each pair of corners
for (var i = 0; i < corners.length - 1; i++) {
var start = corners[i];
var end = corners[i + 1];
var particleCount = 16; // Adjust this number for particle density
for (var j = 0; j <= particleCount; j++) {
var t = j / particleCount;
points.push({
x: start.x + (end.x - start.x) * t,
y: start.y + (end.y - start.y) * t
});
}
}
return points;
},
// Four circles
function (centerX, centerY) {
var points = [];
var offsets = [{
x: -600,
y: -500
}, {
x: 600,
y: -500
}, {
x: -600,
y: 600
}, {
x: 600,
y: 600
}];
offsets.forEach(function (offset) {
for (var t = 0; t < Math.PI * 2; t += 0.3) {
points.push({
x: centerX + offset.x + Math.cos(t) * 250,
y: centerY + offset.y + Math.sin(t) * 250
});
}
});
return points;
}];
self.currentPattern = null;
self.particles = [];
self.createPattern = function () {
self.particles.forEach(function (p) {
return p.destroy();
});
self.particles = [];
var pattern = self.patterns[Math.floor(Math.random() * self.patterns.length)];
var points = pattern(2048 / 2, 2732 / 2 - 200);
points.forEach(function (point) {
var particle = new PatternParticle();
particle.x = point.x;
particle.y = point.y;
self.addChild(particle);
self.particles.push(particle);
});
};
self.update = function () {
if (self.particles.length > 0 && self.particles.every(function (p) {
return !p.active;
})) {
self.createPattern();
if (garden.warmthMeter) {
garden.warmthMeter.addWarmth(20);
}
}
self.particles.forEach(function (particle) {
if (particle.update) {
particle.update();
}
});
};
self.checkBeeCollision = function (bee) {
self.particles.forEach(function (particle) {
if (particle.active) {
var dx = bee.x - particle.x;
var dy = bee.y - particle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 75) {
particle.active = false;
// Create and animate points text
var pointText = new Text2("+10", {
size: 80,
fill: 0xFFFF00
});
pointText.anchor.set(0.5);
pointText.x = particle.x;
pointText.y = particle.y;
game.addChild(pointText);
// Animate points text
tween(pointText, {
y: pointText.y - 50,
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
pointText.destroy();
if (game.scoreManager) {
game.scoreManager.addScore(10);
}
}
});
// Particle fade out animation
tween(particle, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 500,
onFinish: function onFinish() {
if (garden.warmthMeter) {
garden.warmthMeter.addWarmth(2);
}
}
});
}
}
});
};
return self;
});
// Score display class
var ScoreDisplay = Text2.expand(function () {
var self = Text2.call(this, '0', {
size: 150,
fill: 0xFFFFFF
});
// Keep track of our background
self.background = null;
self.setBackground = function (background) {
self.background = background;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 //Init game with black background
});
/****
* Game Code
****/
// Declare bee variable in the global scope
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
function _classCallCheck(a, n) {
if (!(a instanceof n)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(e, r) {
for (var t = 0; t < r.length; t++) {
var o = r[t];
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
}
}
function _createClass(e, r, t) {
return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
writable: !1
}), e;
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == _typeof(i) ? i : i + "";
}
function _toPrimitive(t, r) {
if ("object" != _typeof(t) || !t) {
return t;
}
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof(i)) {
return i;
}
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _callSuper(t, o, e) {
return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
}
function _possibleConstructorReturn(t, e) {
if (e && ("object" == _typeof(e) || "function" == typeof e)) {
return e;
}
if (void 0 !== e) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(t);
}
function _assertThisInitialized(e) {
if (void 0 === e) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return e;
}
function _isNativeReflectConstruct() {
try {
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
} catch (t) {}
return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {
return !!t;
})();
}
function _getPrototypeOf(t) {
return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
return t.__proto__ || Object.getPrototypeOf(t);
}, _getPrototypeOf(t);
}
function _inherits(t, e) {
if ("function" != typeof e && null !== e) {
throw new TypeError("Super expression must either be null or a function");
}
t.prototype = Object.create(e && e.prototype, {
constructor: {
value: t,
writable: !0,
configurable: !0
}
}), Object.defineProperty(t, "prototype", {
writable: !1
}), e && _setPrototypeOf(t, e);
}
function _setPrototypeOf(t, e) {
return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
return t.__proto__ = e, t;
}, _setPrototypeOf(t, e);
}
var BasicFlower = /*#__PURE__*/function (_Container) {
function BasicFlower(color) {
var _this3;
_classCallCheck(this, BasicFlower);
_this3 = _callSuper(this, BasicFlower);
_this3.color = color || 'red';
_this3.assetMap = {
'red': 'RedFlower',
'blue': 'BlueFlower',
'yellow': 'YellowFlower',
'purple': 'PurpleFlower',
'green': 'GreenFlower',
'orange': 'OrangeFlower',
'rainbow': 'RainbowFlower'
};
_this3.budGraphics = _this3.attachAsset('Bud', {
anchorX: 0.5,
anchorY: 0.5
});
_this3.flowerGraphics = _this3.attachAsset(_this3.assetMap[_this3.color], {
anchorX: 0.5,
anchorY: 0.5
});
_this3.hasActivePollen = false;
_this3.fairyParticles = [];
_this3.FAIRY_COUNT = 3;
_this3.pollenCollected = true;
return _this3;
}
_inherits(BasicFlower, _Container);
return _createClass(BasicFlower, [{
key: "update",
value: function update() {
var scaleFactor = 1 + Math.sin(LK.ticks * 0.1) * 0.05;
this.flowerGraphics.scale.x = scaleFactor;
this.flowerGraphics.scale.y = scaleFactor;
this.flowerGraphics.rotation = Math.sin(LK.ticks * 0.1) * 0.05;
}
}, {
key: "bloom",
value: function bloom() {
var _this4 = this;
this.scale.set(0.3, 0.3);
tween(this.scale, {
x: 1,
y: 1
}, {
duration: 1000,
onFinish: function onFinish() {
_this4.hasActivePollen = true;
_this4.pollenCollected = false;
_this4.checkGridPosition();
}
});
LK.setTimeout(function () {
if (game.seasonManager && game.seasonManager.currentSeason === game.seasonManager.SEASONS.SPRING) {
game.seasonManager.updateFlowerCounts();
}
}, 1000);
this.createPollenBurst(this.x, this.y);
}
}, {
key: "checkGridPosition",
value: function checkGridPosition() {
var foundGridPos = false;
var gridX = 0;
var gridY = 0;
for (var y = 0; y < garden.rows; y++) {
for (var x = 0; x < garden.cols; x++) {
if (garden.grid[y][x] === this) {
gridX = x;
gridY = y;
foundGridPos = true;
break;
}
}
if (foundGridPos) {
break;
}
}
if (foundGridPos && game.flowerMatcher && !(game.seasonManager && game.seasonManager.currentSeason === game.seasonManager.SEASONS.SPRING && game.seasonManager.springFinaleStarted)) {
LK.setTimeout(function () {
game.flowerMatcher.checkForMatches(garden, gridX, gridY);
}, 100);
}
}
}, {
key: "createPollenBurst",
value: function createPollenBurst(x, y) {
var colorTints = {
'red': 0xFF0000,
'blue': 0x0000FF,
'yellow': 0xFFFF00,
'purple': 0x800080,
'green': 0x00FF00,
'orange': 0xFFA500,
'rainbow': [0xFF0000, 0x0000FF, 0xFFFF00]
};
for (var i = 0; i < 12; i++) {
var particle = new PollenParticle().init('burst');
var angle = i / 12 * Math.PI * 2;
particle.x = x;
particle.y = y;
particle.vx = Math.cos(angle) * 3;
particle.vy = Math.sin(angle) * 3;
if (this.color === 'rainbow') {
var rainbowColors = colorTints[this.color];
particle.tint = rainbowColors[Math.floor(Math.random() * rainbowColors.length)];
} else {
particle.tint = colorTints[this.color];
}
if (this.parent) {
this.parent.addChild(particle);
}
}
}
}, {
key: "removeFairyParticles",
value: function removeFairyParticles() {
var _this5 = this;
this.fairyParticles.forEach(function (fairy) {
_this5.removeChild(fairy);
});
this.fairyParticles = [];
}
}]);
}(Container);
function _toConsumableArray3(r) {
return _arrayWithoutHoles3(r) || _iterableToArray3(r) || _unsupportedIterableToArray13(r) || _nonIterableSpread3();
}
function _nonIterableSpread3() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _iterableToArray3(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) {
return Array.from(r);
}
}
function _arrayWithoutHoles3(r) {
if (Array.isArray(r)) {
return _arrayLikeToArray13(r);
}
}
function _createForOfIteratorHelper7(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray13(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n7 = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n7 >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n7++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _slicedToArray11(r, e) {
return _arrayWithHoles11(r) || _iterableToArrayLimit11(r, e) || _unsupportedIterableToArray13(r, e) || _nonIterableRest11();
}
function _nonIterableRest11() {
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 _unsupportedIterableToArray13(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray13(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) ? _arrayLikeToArray13(r, a) : void 0;
}
}
function _arrayLikeToArray13(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 _iterableToArrayLimit11(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 _arrayWithHoles11(r) {
if (Array.isArray(r)) {
return r;
}
}
var bee;
// Initialize oldPollen to track changes in currentPollen
var oldPollen = 0;
// Initialize score manager
var flowerPoints = 100; // Define flowerPoints variable with a default value
function _toConsumableArray2(r) {
return _arrayWithoutHoles2(r) || _iterableToArray2(r) || _unsupportedIterableToArray12(r) || _nonIterableSpread2();
}
function _nonIterableSpread2() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray12(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray12(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) ? _arrayLikeToArray12(r, a) : void 0;
}
}
function _iterableToArray2(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) {
return Array.from(r);
}
}
function _arrayWithoutHoles2(r) {
if (Array.isArray(r)) {
return _arrayLikeToArray12(r);
}
}
function _arrayLikeToArray12(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 _toConsumableArray(r) {
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray11(r) || _nonIterableSpread();
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray11(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray11(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) ? _arrayLikeToArray11(r, a) : void 0;
}
}
function _iterableToArray(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) {
return Array.from(r);
}
}
function _arrayWithoutHoles(r) {
if (Array.isArray(r)) {
return _arrayLikeToArray11(r);
}
}
function _arrayLikeToArray11(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 _slicedToArray10(r, e) {
return _arrayWithHoles10(r) || _iterableToArrayLimit10(r, e) || _unsupportedIterableToArray10(r, e) || _nonIterableRest10();
}
function _nonIterableRest10() {
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 _unsupportedIterableToArray10(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray10(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) ? _arrayLikeToArray10(r, a) : void 0;
}
}
function _arrayLikeToArray10(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 _iterableToArrayLimit10(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 _arrayWithHoles10(r) {
if (Array.isArray(r)) {
return r;
}
}
function _slicedToArray9(r, e) {
return _arrayWithHoles9(r) || _iterableToArrayLimit9(r, e) || _unsupportedIterableToArray9(r, e) || _nonIterableRest9();
}
function _nonIterableRest9() {
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 _unsupportedIterableToArray9(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray9(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) ? _arrayLikeToArray9(r, a) : void 0;
}
}
function _arrayLikeToArray9(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 _iterableToArrayLimit9(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 _arrayWithHoles9(r) {
if (Array.isArray(r)) {
return r;
}
}
function _slicedToArray8(r, e) {
return _arrayWithHoles8(r) || _iterableToArrayLimit8(r, e) || _unsupportedIterableToArray8(r, e) || _nonIterableRest8();
}
function _nonIterableRest8() {
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 _unsupportedIterableToArray8(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray8(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) ? _arrayLikeToArray8(r, a) : void 0;
}
}
function _arrayLikeToArray8(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 _iterableToArrayLimit8(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 _arrayWithHoles8(r) {
if (Array.isArray(r)) {
return r;
}
}
function _slicedToArray7(r, e) {
return _arrayWithHoles7(r) || _iterableToArrayLimit7(r, e) || _unsupportedIterableToArray7(r, e) || _nonIterableRest7();
}
function _nonIterableRest7() {
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 _iterableToArrayLimit7(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 _arrayWithHoles7(r) {
if (Array.isArray(r)) {
return r;
}
}
function _createForOfIteratorHelper6(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray7(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n6 = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n6 >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n6++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _unsupportedIterableToArray7(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray7(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) ? _arrayLikeToArray7(r, a) : void 0;
}
}
function _arrayLikeToArray7(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 _slicedToArray6(r, e) {
return _arrayWithHoles6(r) || _iterableToArrayLimit6(r, e) || _unsupportedIterableToArray6(r, e) || _nonIterableRest6();
}
function _nonIterableRest6() {
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 _iterableToArrayLimit6(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 _arrayWithHoles6(r) {
if (Array.isArray(r)) {
return r;
}
}
function _createForOfIteratorHelper5(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray6(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n5 = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n5 >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n5++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _unsupportedIterableToArray6(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray6(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) ? _arrayLikeToArray6(r, a) : void 0;
}
}
function _arrayLikeToArray6(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 _slicedToArray5(r, e) {
return _arrayWithHoles5(r) || _iterableToArrayLimit5(r, e) || _unsupportedIterableToArray5(r, e) || _nonIterableRest5();
}
function _nonIterableRest5() {
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 _iterableToArrayLimit5(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 _arrayWithHoles5(r) {
if (Array.isArray(r)) {
return r;
}
}
function _createForOfIteratorHelper4(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray5(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n4 = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n4 >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n4++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _unsupportedIterableToArray5(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray5(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) ? _arrayLikeToArray5(r, a) : void 0;
}
}
function _arrayLikeToArray5(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 _slicedToArray4(r, e) {
return _arrayWithHoles4(r) || _iterableToArrayLimit4(r, e) || _unsupportedIterableToArray4(r, e) || _nonIterableRest4();
}
function _nonIterableRest4() {
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 _unsupportedIterableToArray4(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray4(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) ? _arrayLikeToArray4(r, a) : void 0;
}
}
function _arrayLikeToArray4(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 _iterableToArrayLimit4(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 _arrayWithHoles4(r) {
if (Array.isArray(r)) {
return r;
}
}
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 _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 _createForOfIteratorHelper3(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray3(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n3 = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n3 >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n3++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
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 _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 _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 _createForOfIteratorHelper2(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray2(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n2 = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n2 >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n2++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
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 _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 _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;
}
}
function _createForOfIteratorHelper(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
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;
}
var flowerManager = new FlowerManager();
var titleScreen = new Container();
// In the title screen setup, replace the existing background setup with:
var titleBG = new Container();
titleScreen.addChild(titleBG);
// Create duplicated sets of backgrounds to allow seamless scrolling
var backgrounds = [LK.getAsset('SpringBackground', {
anchorX: 0,
anchorY: 0.5
}), LK.getAsset('SummerBackground', {
anchorX: 0,
anchorY: 0.5
}), LK.getAsset('FallBackground', {
anchorX: 0,
anchorY: 0.5
}), LK.getAsset('WinterBackground', {
anchorX: 0,
anchorY: 0.5
}),
// Duplicate first one to create seamless loop
LK.getAsset('SpringBackground', {
anchorX: 0,
anchorY: 0.5
})];
// Position backgrounds, centering spring initially
backgrounds.forEach(function (bg, index) {
bg.x = 2048 * index;
bg.y = 2732 / 2;
titleBG.addChild(bg);
});
// Start with spring centered
titleBG.x = -1024 + 2048 / 2; // Negative half width to center spring
titleBG.scrollSpeed = 2;
titleScreen.update = function () {
titleBG.x -= titleBG.scrollSpeed;
// When we've scrolled one full sequence (4 backgrounds)
if (titleBG.x <= -2048 * 4 + 1024) {
titleBG.x = -1024 + 2048 / 2; // Reset to starting position
}
};
// Keep logo and buttons on top
var logo = LK.getAsset('logo', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 0.06 * 2732 // Move up by 6% of the screen height
});
titleScreen.addChild(logo);
var playButton = LK.getAsset('playButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 325,
y: 2732 / 2 + 1050
});
titleScreen.addChild(playButton);
var tutorialButton = LK.getAsset('tutorialButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 325,
y: 2732 / 2 + 1050
});
titleScreen.addChild(tutorialButton);
function createModeButtons() {
var arcadeButton = LK.getAsset('ArcadeButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 500,
y: 2732 / 2 + 1050,
alpha: 0,
interactive: false,
visible: false
});
var seasonsButton = LK.getAsset('SeasonsButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 500,
y: 2732 / 2 + 1050,
alpha: 0,
interactive: false,
visible: false
});
var backButton = LK.getAsset('BackButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 1250,
alpha: 0,
interactive: false,
visible: false
});
// Assign down handlers immediately
arcadeButton.down = function (x, y, obj) {
tween(obj, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
onFinish: function onFinish() {
tween(titleScreen, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(titleScreen);
initializeGame('arcade');
}
});
}
});
};
seasonsButton.down = function (x, y, obj) {
tween(obj, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
onFinish: function onFinish() {
tween(titleScreen, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(titleScreen);
initializeGame('seasons');
}
});
}
});
};
backButton.down = function (x, y, obj) {
tween(obj, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
tween(arcadeButton, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
arcadeButton.interactive = false;
arcadeButton.visible = false;
}
});
tween(seasonsButton, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
seasonsButton.interactive = false;
seasonsButton.visible = false;
}
});
tween(backButton, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
backButton.interactive = false;
backButton.visible = false;
}
});
LK.setTimeout(function () {
tween(playButton, {
scaleX: 1,
scaleY: 1,
alpha: 1,
y: 2732 / 2 + 1050
}, {
duration: 300
});
tween(tutorialButton, {
scaleX: 1,
scaleY: 1,
alpha: 1,
y: 2732 / 2 + 1050
}, {
duration: 300
});
}, 150);
};
return {
arcadeButton: arcadeButton,
seasonsButton: seasonsButton,
backButton: backButton
};
}
// Keep logo and buttons on top
titleScreen.setChildIndex(logo, titleScreen.children.length - 1);
titleScreen.setChildIndex(playButton, titleScreen.children.length - 1);
titleScreen.setChildIndex(tutorialButton, titleScreen.children.length - 1);
game.addChild(titleScreen);
titleScreen.modeButtons = createModeButtons();
titleScreen.addChild(titleScreen.modeButtons.arcadeButton);
titleScreen.addChild(titleScreen.modeButtons.seasonsButton);
titleScreen.addChild(titleScreen.modeButtons.backButton);
playButton.down = function (x, y, obj) {
// Button press animation
tween(playButton.scale, {
x: 0.9,
y: 0.9
}, {
duration: 100
});
tween(tutorialButton.scale, {
x: 0.9,
y: 0.9
}, {
duration: 100
});
// Fade out main buttons
LK.setTimeout(function () {
tween(playButton, {
alpha: 0,
y: playButton.y - 50
}, {
duration: 300
});
tween(tutorialButton, {
alpha: 0,
y: tutorialButton.y - 50
}, {
duration: 300
});
titleScreen.modeButtons.arcadeButton.visible = true;
titleScreen.modeButtons.seasonsButton.visible = true;
titleScreen.modeButtons.backButton.visible = true;
titleScreen.modeButtons.arcadeButton.interactive = true;
titleScreen.modeButtons.seasonsButton.interactive = true;
titleScreen.modeButtons.backButton.interactive = true; // Fade in mode buttons
tween(titleScreen.modeButtons.arcadeButton, {
alpha: 1
}, {
duration: 300
});
tween(titleScreen.modeButtons.seasonsButton, {
alpha: 1
}, {
duration: 300
});
tween(titleScreen.modeButtons.backButton, {
alpha: 1
}, {
duration: 300
});
}, 150);
};
function initializeTutorial() {
// Setup basic game elements
var gardenBackground = new GardenBackground();
game.addChild(gardenBackground);
garden = new Garden();
garden.init();
game.addChild(garden);
var background = new MenuBackground();
game.addChild(background);
// Create bee
bee = new Bee();
bee.x = 2048 / 2;
bee.y = 2732 / 2;
game.addChild(bee);
// Initialize tutorial manager
var tutorial = new TutorialManager();
game.tutorial = tutorial;
game.addChild(tutorial);
// Create initial target particles
tutorial.createTargetParticles();
// Show first instruction
LK.setTimeout(function () {
tutorial.showInstruction('movement');
}, 100);
// Touch handlers
game.down = function (x, y, obj) {
var touchPos = game.toLocal({
x: x,
y: y
}, LK.stage);
var dx = touchPos.x - bee.x;
var dy = touchPos.y - bee.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
bee.state = 'free';
bee.isMoving = true;
bee.targetX = touchPos.x;
bee.targetY = touchPos.y;
} else {
bee.state = 'transit';
bee.targetX = touchPos.x;
bee.targetY = touchPos.y;
}
};
game.move = function (x, y, obj) {
if (bee.isMoving) {
bee.targetX = x;
bee.targetY = y;
}
};
game.up = function (x, y, obj) {
bee.isMoving = false;
};
// Main update loop
game.update = function () {
// Update bee
if (bee && bee.update) {
bee.update();
}
// Update garden
if (garden) {
garden.update();
}
// Update and check target particles
if (!tutorial.state.movement.completed) {
tutorial.targetParticles.forEach(function (particle) {
if (particle.update) {
particle.update();
}
});
tutorial.checkParticleCollisions(bee.x, bee.y);
}
// Tutorial state progression
if (tutorial.state.transitPollination.started || tutorial.state.dragPollination.started) {
tutorial.checkPollination();
} else if (tutorial.state.pollenCollection.started) {
tutorial.checkPollenCollection();
}
// Always check hybrid completion after drag pollination is completed
if (tutorial.state.dragPollination.completed) {
tutorial.checkHybridCompletion();
}
};
}
function initializeGame(mode) {
var initialTouchTime = 0;
var holdTimer = 0; // Initialize holdTimer variable
var HOLD_THRESHOLD = 30; // Half second at 60fps
var gardenBackground = new GardenBackground();
game.addChild(gardenBackground);
gardenBackground.alpha = 0;
tween(gardenBackground, {
alpha: 1
}, {
duration: 500
});
garden = new Garden();
garden.init();
game.addChild(garden);
var flowerManager = new FlowerManager();
// Initialize score manager
game.scoreManager = new ScoreManager();
game.addChild(game.scoreManager);
game.flowerMatcher = new FlowerMatcher();
game.addChild(game.flowerMatcher);
var pollenTrail = new PollenTrail();
game.addChild(pollenTrail);
var background = new MenuBackground();
game.addChild(background);
// Create bee
bee = new Bee();
bee.x = -bee.width; // Start off screen to the left
bee.y = 2732 / 2; // Center vertically
game.addChild(bee);
// Animate bee flying to the center of the screen
tween(bee, {
x: 2048 / 2
}, {
duration: 2000,
easing: tween.easeInOut
});
// Ensure pollen particles are rendered on top by adding them last
game.setChildIndex(pollenTrail, game.children.length - 1);
// Initialize bud spawner
garden.budSpawner = new BudSpawner();
garden.budSpawner.init(garden);
game.addChild(garden.budSpawner);
// Touch handlers
game.down = function (x, y, obj) {
function showDebugText(message, color) {
var debugText = new Text2(message, {
size: 120,
fill: color
});
// Start with no anchor adjustment
debugText.anchor.set(1, 0);
// Try positioning at 0,0 first just to see where it appears
debugText.x = 400;
debugText.y = 400;
LK.gui.top.addChild(debugText);
tween(debugText, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
LK.gui.top.removeChild(debugText);
}
});
}
// Debug zones same as before
//if (x > 824 && x < 1224 && y < 200) {
// showDebugText("SPRING MODE", 0x00FF00);
// game.seasonManager.setActiveSeason(game.seasonManager.SEASONS.SPRING);
// return;
//if (x > 1848 && y < 200) {
// showDebugText("SUMMER MODE", 0xFFFF00);
// game.seasonManager.setActiveSeason(game.seasonManager.SEASONS.SUMMER);
// return;
//if (x < 200 && y > 2532) {
// showDebugText("FALL MODE", 0xFF6600);
// game.seasonManager.setActiveSeason(game.seasonManager.SEASONS.FALL);
// return;
//if (x > 1848 && y > 2532) {
// showDebugText("WINTER MODE", 0x00FFFF);
// game.seasonManager.setActiveSeason(game.seasonManager.SEASONS.WINTER);
// return;
// Convert touch position to world space
var touchPos = game.toLocal({
x: x,
y: y
}, LK.stage);
// Check if touch is on bee
var dx = touchPos.x - bee.x;
var dy = touchPos.y - bee.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bee.isHolding = false;
initialTouchTime = LK.ticks;
if (distance < 100) {
// Increased from 50 to 100
// Adjust radius as needed
bee.state = 'free';
bee.isMoving = true;
// Set initial target to current position to prevent jumping
bee.targetX = bee.x;
bee.targetY = bee.y;
// Then update target to the current touch position
bee.targetX = touchPos.x;
bee.targetY = touchPos.y;
} else {
bee.state = 'waiting'; // New state
}
// (allows holding through transit)
if (!bee.isMoving) {
bee.isHolding = false;
}
};
game.move = function (x, y, obj) {
if (bee.isMoving) {
bee.targetX = x;
bee.targetY = y - 200;
}
};
game.up = function (x, y, obj) {
var touchPos = game.toLocal({
x: x,
y: y
}, LK.stage);
// If we were waiting to determine hold vs tap
if (bee.state === 'waiting') {
// Check if it was held long enough
bee.isHolding = LK.ticks - initialTouchTime >= HOLD_THRESHOLD;
// Now send bee to location
bee.state = 'transit';
bee.targetX = touchPos.x;
bee.targetY = touchPos.y;
}
bee.isMoving = false;
};
// Initialize score display
var scoreDisplay = new ScoreDisplay();
scoreDisplay.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreDisplay);
scoreDisplay.setBackground(background);
game.scoreDisplay = scoreDisplay;
// Add the main update loop
game.update = function () {
// Update spawning system
if (game.budSpawner) {
game.budSpawner.update();
}
// Update trail system
if (pollenTrail) {
pollenTrail.update();
}
// Update garden elements
if (garden) {
garden.update();
// Update all flowers and buds in the grid
for (var i = 0; i < garden.rows; i++) {
for (var j = 0; j < garden.cols; j++) {
var gridItem = garden.grid[i][j];
if (gridItem && gridItem.update) {
gridItem.update();
}
}
}
}
// Update all children that have update methods
for (var i = 0; i < game.children.length; i++) {
var child = game.children[i];
if (child && child.update) {
child.update();
}
}
// Update bee
if (bee && bee.update) {
bee.update();
if (garden.patternSystem && bee) {
garden.patternSystem.checkBeeCollision(bee);
}
}
if (game.seasonManager) {
game.seasonManager.update();
}
};
if (mode === 'arcade') {
// Initialize storage if not exists
if (storage.bestScore === undefined) {
storage.bestScore = 0;
}
var bestScoreDisplay = new Text2("Best: " + storage.bestScore, {
size: 80,
fill: 0xFFFFFF,
alpha: 0 // Start invisible like the background
});
bestScoreDisplay.anchor.set(0, 0);
bestScoreDisplay.x = 100;
bestScoreDisplay.y = 250;
game.bestScoreDisplay = bestScoreDisplay;
game.addChild(bestScoreDisplay);
var levelDisplay = new Text2("Level 1", {
size: 80,
fill: 0xFFFFFF
});
levelDisplay.anchor.set(0.5, 0);
levelDisplay.x = 2048 - 220; // Position on far right
levelDisplay.y = 250; // Same height as score
game.levelDisplay = levelDisplay;
game.addChild(levelDisplay);
game.currentLevel = 1;
// Fade in with the background
tween(bestScoreDisplay, {
alpha: 1
}, {
duration: 500
});
if (game.children[0] instanceof GardenBackground) {
var arcadeBackground = LK.getAsset('ArcadeBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.02,
scaleY: 1.02,
x: 2048 / 2,
y: 2732 / 2
});
game.children[0].bgLayer.removeChild(game.children[0].seasonalBackground);
game.children[0].bgLayer.addChild(arcadeBackground);
game.children[0].seasonalBackground = arcadeBackground;
}
} else if (mode === 'seasons') {
game.seasonManager = new SeasonManager();
game.seasonManager.init();
game.seasonManager.setActiveSeason(game.seasonManager.SEASONS.SPRING);
}
}
;
tutorialButton.down = function (x, y, obj) {
tween(titleScreen, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(titleScreen);
initializeTutorial();
}
});
};
// Removed duplicate playPollenPatternAnimation method ===================================================================
--- original.js
+++ change.js
@@ -898,13 +898,15 @@
anchorX: 0.5,
anchorY: 0.5
});
self.background.tint = 0x333333;
- // Create fill hexagon
+ // Create fill hexagon - adjust anchor to bottom
self.fill = meterContainer.attachAsset('HoneyComb', {
anchorX: 0.5,
- anchorY: 0.5
+ anchorY: 1 // Anchor to bottom
});
+ // Move the fill up by half height to align with background
+ self.fill.y = self.background.height / 2;
// Set colors
var colorMap = {
red: 0xFF0000,
blue: 0x0000FF,
@@ -1368,8 +1370,46 @@
checkForLeafClearing(matches);
matches.forEach(function (match) {
// Removed call to undefined method checkAndSpawnSideEffects
});
+ // Add meter fill from matches
+ if (garden.meters) {
+ // Calculate fill amounts for each color
+ matches.forEach(function (match) {
+ var color = match.flower.color;
+ // Primary colors give full amount
+ if (color === 'red' && garden.meters.red) {
+ garden.meters.red.addFill(15);
+ } else if (color === 'blue' && garden.meters.blue) {
+ garden.meters.blue.addFill(15);
+ } else if (color === 'yellow' && garden.meters.yellow) {
+ garden.meters.yellow.addFill(15);
+ }
+ // Hybrid colors give half to each component
+ else if (color === 'purple') {
+ if (garden.meters.red) {
+ garden.meters.red.addFill(7.5);
+ }
+ if (garden.meters.blue) {
+ garden.meters.blue.addFill(7.5);
+ }
+ } else if (color === 'green') {
+ if (garden.meters.blue) {
+ garden.meters.blue.addFill(7.5);
+ }
+ if (garden.meters.yellow) {
+ garden.meters.yellow.addFill(7.5);
+ }
+ } else if (color === 'orange') {
+ if (garden.meters.red) {
+ garden.meters.red.addFill(7.5);
+ }
+ if (garden.meters.yellow) {
+ garden.meters.yellow.addFill(7.5);
+ }
+ }
+ });
+ }
matches.forEach(function (match, index) {
// First animate all the match clears with proper sequencing
LK.setTimeout(function () {
tween(match.flower.scale, {
@@ -1856,21 +1896,21 @@
// Create and position meters
if (redFlower) {
self.meters.red = new ColorMeter('red');
self.meters.red.x = redFlower.x;
- self.meters.red.y = redFlower.y + 150;
+ self.meters.red.y = redFlower.y + 225;
self.addChild(self.meters.red);
}
if (blueFlower) {
self.meters.blue = new ColorMeter('blue');
self.meters.blue.x = blueFlower.x;
- self.meters.blue.y = blueFlower.y + 150;
+ self.meters.blue.y = blueFlower.y + 225;
self.addChild(self.meters.blue);
}
if (yellowFlower) {
self.meters.yellow = new ColorMeter('yellow');
self.meters.yellow.x = yellowFlower.x;
- self.meters.yellow.y = yellowFlower.y + 150;
+ self.meters.yellow.y = yellowFlower.y + 225;
self.addChild(self.meters.yellow);
}
// Center the grid on screen
self.x = (2048 - self.cols * self.cellSize) / 2;
@@ -1917,8 +1957,15 @@
}
}
// Then check for autoblooming
self.checkForAutoBloom();
+ if (self.meters) {
+ Object.values(self.meters).forEach(function (meter) {
+ if (meter && meter.update) {
+ meter.update();
+ }
+ });
+ }
};
});
var GardenBackground = Container.expand(function () {
var self = Container.call(this);
A background image for a puzzle video game depicting the season of summer. Cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A background image for a puzzle video game depicting the season of fall. Cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A background image for a puzzle video game depicting the season of winter. Cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Multiple stylized texts with phrases that include “Hurry!” “Time’s up!” Cartoon style.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Create a SVG text design in bold cartoon style: "SPRING" in chunky rounded letters with floral accents and vines. Use spring pastels.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Create an SVG text design for "SUMMER" in bold cartoon style with chunky rounded letters. Add sun rays and small flower details in warm, vibrant colors.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Create an SVG text design for "FALL" in bold cartoon style with chunky rounded letters. Add small falling leaves and acorn accents in warm autumn colors.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Create an SVG text design for "WINTER" in bold cartoon style with chunky rounded letters. Add small snowflake accents and icy details in cool, frosty blues and white.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Create a SVG text design in bold cartoon style: “Bloom the garden" in chunky rounded letters with floral accents and vines. Use spring pastels.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Create an SVG text design for "Match the blooms" in bold cartoon style with chunky rounded letters. Add sun rays and small flower details in warm, vibrant colors.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Create an SVG text design for "Match to clear leaves" in bold cartoon style with chunky rounded letters. Add small falling leaves and acorn accents in warm autumn colors.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Create an SVG text design for "DANCE TO STAY WARM" in bold cartoon style with chunky rounded letters. Add small snowflake accents and icy details in cool, frosty blues and white.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Create a SVG text design in bold cartoon style: "SEASON COMPLETE!" in chunky rounded letters with stars around it . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.