Code edit (2 edits merged)
Please save this source code
User prompt
ensure all objects are initialized, as well s the game itself
Code edit (2 edits merged)
Please save this source code
User prompt
add shapes for all images, etc.
User prompt
ensure all objects are visible, initialized, etc.
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Text is not a constructor' in or related to this line: 'var buttonText = new Text(text, {' Line Number: 771
Code edit (4 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Text is not a constructor' in or related to this line: 'var buttonText = new Text(text, {' Line Number: 771
Code edit (3 edits merged)
Please save this source code
User prompt
continue
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'levelProgressBar is not defined' in or related to this line: 'if (levelProgressBar && typeof levelProgressBar.update === 'function') {' Line Number: 1489
User prompt
Please fix the bug: 'levelProgressBar is not defined' in or related to this line: 'if (levelProgressBar && typeof levelProgressBar.update === 'function') {' Line Number: 1489
User prompt
Please fix the bug: 'levelProgressBar is not defined' in or related to this line: 'if (levelProgressBar && typeof levelProgressBar.update === 'function') {' Line Number: 1489
User prompt
Please fix the bug: 'levelProgressBar is not defined' in or related to this line: 'if (levelProgressBar && typeof levelProgressBar.update === 'function') {' Line Number: 1489
User prompt
Please fix the bug: 'levelProgressBar is not defined' in or related to this line: 'if (levelProgressBar && typeof levelProgressBar.update === 'function') {' Line Number: 1489
User prompt
Please fix the bug: 'levelProgressBar is not defined' in or related to this line: 'if (levelProgressBar && typeof levelProgressBar.update === 'function') {' Line Number: 1489
User prompt
Please fix the bug: 'statsPanel is not defined' in or related to this line: 'if (statsPanel && typeof statsPanel.update === 'function') {' Line Number: 1477
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'checkSpecialEvents is not defined' in or related to this line: 'checkSpecialEvents();' Line Number: 1464
User prompt
Please fix the bug: 'checkSpecialEvents is not defined' in or related to this line: 'checkSpecialEvents();' Line Number: 1460
User prompt
Please fix the bug: 'checkSpecialEvents is not defined' in or related to this line: 'checkSpecialEvents();' Line Number: 1460
User prompt
refactor all font related code.
User prompt
Please fix the bug: 'checkSpecialEvents is not defined' in or related to this line: 'checkSpecialEvents();' Line Number: 1468
/****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var AchievementDisplay = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 4
});
bg.tint = 0x000000;
bg.alpha = 0.7;
var titleText = createGameText("Achievements", {
sizeFactor: 1,
fontWeight: 'bold'
});
titleText.anchor.set(0.5, 0);
titleText.y = -fontSizeBase * 2;
self.addChild(titleText);
var achievementTexts = [];
self.update = function () {
// Clear previous achievement texts
achievementTexts.forEach(function (text) {
self.removeChild(text);
});
achievementTexts = [];
// Add achievement texts
var yPos = -fontSizeBase;
var categories = ['sparklesCollected', 'catsOwned', 'upgradesPurchased', 'catLevels'];
var categoryNames = ['Sparkles', 'Cats', 'Upgrades', 'Cat Levels'];
categories.forEach(function (category, index) {
if (achievements[category]) {
var categoryText = createGameText(categoryNames[index] + ":", {
sizeFactor: 0.8,
fontWeight: 'bold'
});
categoryText.anchor.set(0.5, 0);
categoryText.y = yPos;
self.addChild(categoryText);
achievementTexts.push(categoryText);
yPos += fontSizeBase;
achievements[category].forEach(function (achievement) {
var color = achievement.achieved ? 0x00FF00 : 0xFFFFFF;
var text = achievement.achieved ? "✓ " + achievement.threshold + " (" + achievement.reward + " sparkles)" : "□ " + achievement.threshold + " (" + achievement.reward + " sparkles)";
var achievementText = createGameText(text, {
sizeFactor: 0.7,
fill: color
});
achievementText.anchor.set(0.5, 0);
achievementText.y = yPos;
self.addChild(achievementText);
achievementTexts.push(achievementText);
yPos += fontSizeBase * 0.8;
});
yPos += fontSizeBase * 0.5;
}
});
};
return self;
});
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphics = self.attachAsset('cat', {
anchorX: 0.5,
anchorY: 0.5,
scale: 0.6
});
birdGraphics.tint = 0xFF0000;
self.health = 20;
self.speed = 1 + Math.random();
self.value = 10;
self.update = function () {
if (cats.length > 0) {
var nearestCat = cats[0];
var minDist = 10000;
cats.forEach(function (cat) {
var dist = Math.sqrt(Math.pow(cat.x - self.x, 2) + Math.pow(cat.y - self.y, 2));
if (dist < minDist) {
minDist = dist;
nearestCat = cat;
}
});
var dx = nearestCat.x - self.x;
var dy = nearestCat.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
if (dist < 50) {
self.health -= nearestCat.level;
createSparkleEffect(self.x, self.y, 0xFF0000, 2);
if (self.health <= 0) {
handleEnemyDefeat(self, self.value);
game.removeChild(self);
birds.splice(birds.indexOf(self), 1);
}
}
}
};
return self;
});
var Cat = Container.expand(function () {
var self = Container.call(this);
var catGraphics = self.attachAsset('cat', {
anchorX: 0.5,
anchorY: 0.5,
scale: 0.8
});
self.level = 1;
self.productionRate = 0.5;
self.lastProductionTime = 0;
self.speed = 2;
self.attackPower = 10;
self.attackRange = 150;
self.type = 'cat';
var levelCircle = new Container();
var levelCircleGraphics = levelCircle.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 0.5
});
levelCircleGraphics.tint = 0x000000;
levelCircle.x = 0;
levelCircle.y = -catGraphics.height / 2 - 10;
levelCircle.alpha = 0.7;
self.addChild(levelCircle);
var levelText = createGameText("Lvl " + self.level, {
sizeFactor: 0.8,
anchorX: 0.5,
anchorY: 0.5,
fill: 0xFFFFFF
});
levelCircle.addChild(levelText);
var powerUpIndicator = new Container();
var powerUpGraphics = powerUpIndicator.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 0.4
});
powerUpGraphics.tint = 0xFFFFFF;
powerUpIndicator.x = 0;
powerUpIndicator.y = catGraphics.height / 2 + 5;
powerUpIndicator.alpha = 0;
self.addChild(powerUpIndicator);
self.updateLevel = function (newLevel) {
self.level = newLevel;
updateTextProperties(levelText, {
text: "Lvl " + self.level
});
};
self.upgrade = function () {
self.level++;
self.productionRate *= 1.2;
self.speed *= 1.1;
self.attackPower *= 1.2;
self.attackRange *= 1.05;
self.updateLevel(self.level);
levelCircleGraphics.tint = 0x000000;
var levelUpEffect = new Container();
var levelUpGraphics = levelUpEffect.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 1.5
});
levelUpGraphics.tint = 0xFFFFFF;
levelUpEffect.x = 0;
levelUpEffect.y = -catGraphics.height / 2 - 10;
levelUpEffect.alpha = 1;
self.addChild(levelUpEffect);
var startTime = LK.ticks;
levelUpEffect.update = function () {
var elapsed = (LK.ticks - startTime) / 60;
levelUpEffect.scale.set(1.5 - elapsed * 0.5);
levelUpEffect.alpha = 1 - elapsed;
if (elapsed >= 1) {
self.removeChild(levelUpEffect);
}
};
};
self.applyPowerUp = function (type, duration) {
self.powerUps = self.powerUps || {};
self.powerUps[type] = LK.ticks + duration * 60;
if (type === "speed") {
self.speed *= 2;
powerUpGraphics.tint = 0x00FFFF;
} else if (type === "attack") {
self.attackPower *= 2;
powerUpGraphics.tint = 0xFF0000;
}
powerUpIndicator.alpha = 0.8;
createSparkleEffect(self.x, self.y, powerUpGraphics.tint, 10);
};
self.update = function () {
var currentTime = LK.ticks / 60;
if (currentTime - self.lastProductionTime > 1) {
sparkles += self.productionRate * self.level;
self.lastProductionTime = currentTime;
if (Math.random() < 0.3) {
createSparkleEffect(self.x, self.y);
}
}
self.rotation = Math.sin(LK.ticks / 120) * 0.03;
if (self.powerUps) {
var hasPowerUp = false;
for (var type in self.powerUps) {
if (self.powerUps[type] < LK.ticks) {
if (type === "speed") {
self.speed /= 2;
} else if (type === "attack") {
self.attackPower /= 2;
}
delete self.powerUps[type];
} else {
hasPowerUp = true;
var color = type === "speed" ? 0x00FFFF : 0xFF0000;
if (Math.random() < 0.1) {
createSparkleEffect(self.x, self.y, color, 1);
}
}
}
powerUpIndicator.alpha = hasPowerUp ? 0.8 : 0;
}
};
return self;
});
var CatStatusDisplay = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 2
});
bg.tint = 0x330033;
bg.alpha = 0.7;
var titleText = createGameText("Cat Status", {
sizeFactor: 0.8,
fontWeight: 'bold'
});
titleText.anchor.set(0.5, 0);
titleText.y = -fontSizeBase;
self.addChild(titleText);
var catCountText = createGameText("Cats: 0", {
sizeFactor: 0.7
});
catCountText.anchor.set(0.5, 0);
catCountText.y = 0;
self.addChild(catCountText);
self.update = function () {
if (typeof cats !== 'undefined') {
catCountText.text = "Cats: " + (cats ? cats.length : 0);
}
};
return self;
});
var Garden = Container.expand(function () {
var self = Container.call(this);
var gardenGraphics = self.attachAsset('grass-back', {
anchorX: 0.5,
anchorY: 1,
scale: 1.2
});
self.update = function () {
self.x += Math.sin(LK.ticks / 200) * 0.1;
};
return self;
});
var Kitten = Container.expand(function () {
var self = Container.call(this);
var kittenGraphics = self.attachAsset('cat', {
anchorX: 0.5,
anchorY: 0.5,
scale: 0.6
});
kittenGraphics.tint = 0xFFCC99;
self.level = 1;
self.productionRate = 0.3;
self.lastProductionTime = 0;
self.speed = 3;
self.attackPower = 5;
self.attackRange = 100;
self.type = 'kitten';
var levelCircle = new Container();
var levelCircleGraphics = levelCircle.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 0.4
});
levelCircleGraphics.tint = 0x000000;
levelCircle.x = 0;
levelCircle.y = -kittenGraphics.height / 2 - 8;
levelCircle.alpha = 0.7;
self.addChild(levelCircle);
var levelText = createGameText("Lvl " + self.level, {
sizeFactor: 0.7,
anchorX: 0.5,
anchorY: 0.5,
fill: 0xFFFFFF
});
levelCircle.addChild(levelText);
var powerUpIndicator = new Container();
var powerUpGraphics = powerUpIndicator.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 0.3
});
powerUpGraphics.tint = 0xFFFFFF;
powerUpIndicator.x = 0;
powerUpIndicator.y = kittenGraphics.height / 2 + 4;
powerUpIndicator.alpha = 0;
self.addChild(powerUpIndicator);
self.updateLevel = function (newLevel) {
self.level = newLevel;
updateTextProperties(levelText, {
text: "Lvl " + self.level
});
};
self.upgrade = function () {
self.level++;
self.productionRate *= 1.2;
self.speed *= 1.15;
self.attackPower *= 1.15;
self.attackRange *= 1.03;
self.updateLevel(self.level);
levelCircleGraphics.tint = 0x000000;
var levelUpEffect = new Container();
var levelUpGraphics = levelUpEffect.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 1.2
});
levelUpGraphics.tint = 0xFFFFFF;
levelUpEffect.x = 0;
levelUpEffect.y = -kittenGraphics.height / 2 - 8;
levelUpEffect.alpha = 1;
self.addChild(levelUpEffect);
var startTime = LK.ticks;
levelUpEffect.update = function () {
var elapsed = (LK.ticks - startTime) / 60;
levelUpEffect.scale.set(1.2 - elapsed * 0.4);
levelUpEffect.alpha = 1 - elapsed;
if (elapsed >= 1) {
self.removeChild(levelUpEffect);
}
};
};
self.applyPowerUp = function (type, duration) {
self.powerUps = self.powerUps || {};
self.powerUps[type] = LK.ticks + duration * 60;
if (type === "speed") {
self.speed *= 2;
powerUpGraphics.tint = 0x00FFFF;
} else if (type === "attack") {
self.attackPower *= 2;
powerUpGraphics.tint = 0xFF0000;
}
powerUpIndicator.alpha = 0.8;
createSparkleEffect(self.x, self.y, powerUpGraphics.tint, 8);
};
self.update = function () {
var currentTime = LK.ticks / 60;
if (currentTime - self.lastProductionTime > 1) {
sparkles += self.productionRate * self.level;
self.lastProductionTime = currentTime;
if (Math.random() < 0.3) {
createSparkleEffect(self.x, self.y);
}
}
self.rotation = Math.sin(LK.ticks / 90) * 0.05;
if (self.powerUps) {
var hasPowerUp = false;
for (var type in self.powerUps) {
if (self.powerUps[type] < LK.ticks) {
if (type === "speed") {
self.speed /= 2;
} else if (type === "attack") {
self.attackPower /= 2;
}
delete self.powerUps[type];
} else {
hasPowerUp = true;
var color = type === "speed" ? 0x00FFFF : 0xFF0000;
if (Math.random() < 0.1) {
createSparkleEffect(self.x, self.y, color, 1);
}
}
}
powerUpIndicator.alpha = hasPowerUp ? 0.8 : 0;
}
};
return self;
});
var LevelIndicator = Container.expand(function () {
var self = Container.call(this);
var levelText = createGameText("Level: 1", {
sizeFactor: 0.9
});
levelText.anchor.set(0, 0);
self.addChild(levelText);
var multiplierText = createGameText("Multiplier: x1.0", {
sizeFactor: 0.7
});
multiplierText.anchor.set(0, 0);
multiplierText.y = fontSizeBase;
self.addChild(multiplierText);
self.update = function () {
if (typeof playerLevel !== 'undefined') {
levelText.text = "Level: " + playerLevel;
}
if (typeof levelMultiplier !== 'undefined') {
multiplierText.text = "Multiplier: x" + levelMultiplier.toFixed(1);
}
};
return self;
});
var LevelProgressBar = Container.expand(function () {
var self = Container.call(this);
var bgBar = self.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.1
});
bgBar.tint = 0x333333;
self.addChild(bgBar);
var progressBar = self.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.1
});
progressBar.tint = 0x00FF00;
self.progressBar = progressBar;
self.addChild(progressBar);
var labelText = createGameText("Next Level", {
sizeFactor: 0.7
});
labelText.anchor.set(0.5, 1);
labelText.y = -5;
self.addChild(labelText);
self.update = function () {
var enemiesForNextLevel = playerLevel * 10;
var currentLevelEnemies = enemiesDefeated % enemiesForNextLevel;
var progress = currentLevelEnemies / enemiesForNextLevel;
progressBar.scale.x = progress * 2;
updateTextProperties(labelText, {
text: "Next Level: " + currentLevelEnemies + "/" + enemiesForNextLevel
});
};
return self;
});
var MainGarden = Container.expand(function () {
var self = Container.call(this);
var gardenGraphics = self.attachAsset('grass-front', {
anchorX: 0.5,
anchorY: 0.5,
scale: 1.5
});
self.interactive = true;
self.buttonMode = true;
self.on('pointerdown', function (event) {
sparkles += clickMultiplier;
createSparkleEffect(event.data.global.x, event.data.global.y);
if (Math.random() < 0.2) {
var soundIndex = Math.floor(Math.random() * sounds.length);
LK.getSound(sounds[soundIndex]).play();
}
});
return self;
});
var NotificationArea = Container.expand(function () {
var self = Container.call(this);
var messages = [];
var maxMessages = 3;
self.addMessage = function (message) {
var messageText = createGameText(message, {
sizeFactor: 0.7,
fill: 0xFFFFFF
});
messageText.anchor.set(0, 0);
messageText.alpha = 1;
self.addChild(messageText);
messages.push({
text: messageText,
creationTime: LK.ticks
});
self.repositionMessages();
if (messages.length > maxMessages) {
var oldest = messages.shift();
self.removeChild(oldest.text);
}
};
self.repositionMessages = function () {
for (var i = 0; i < messages.length; i++) {
messages[i].text.y = i * fontSizeBase;
}
};
self.update = function () {
var messagesToRemove = [];
messages.forEach(function (message) {
var age = (LK.ticks - message.creationTime) / 60;
if (age > 5) {
messagesToRemove.push(message);
} else if (age > 3) {
message.text.alpha = 1 - (age - 3) / 2;
}
});
messagesToRemove.forEach(function (message) {
var index = messages.indexOf(message);
if (index !== -1) {
messages.splice(index, 1);
self.removeChild(message.text);
}
});
self.repositionMessages();
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
self.attachAsset('sparkle', {});
self.type = type || (Math.random() < 0.5 ? 'speed' : 'attack');
self.scale.set(1.5, 1.5);
self.tint = self.type === 'speed' ? 0x00FFFF : 0xFF0000;
self.expired = false;
self.lifespan = 10000; // 10 seconds
self.creationTime = Date.now();
self.update = function () {
// Float up and down slightly
self.y += Math.sin(Date.now() / 300) * 0.3;
// Check if expired
if (Date.now() - self.creationTime > self.lifespan) {
self.expired = true;
}
// Check for collision with cats or kittens
cats.forEach(function (cat) {
var dx = cat.x - self.x;
var dy = cat.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 40) {
// Apply power-up effect
if (self.type === 'speed') {
cat.speedBoost = true;
cat.speedBoostEndTime = Date.now() + 10000; // 10 seconds
showNotification("Speed Boost!", "Cat moves faster for 10 seconds");
} else {
cat.attackBoost = true;
cat.attackBoostEndTime = Date.now() + 10000; // 10 seconds
showNotification("Attack Boost!", "Cat attacks stronger for 10 seconds");
}
// Remove power-up
self.expired = true;
}
});
kittens.forEach(function (kitten) {
var dx = kitten.x - self.x;
var dy = kitten.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
// Apply power-up effect
if (self.type === 'speed') {
kitten.speedBoost = true;
kitten.speedBoostEndTime = Date.now() + 15000; // 15 seconds for kittens
showNotification("Speed Boost!", "Kitten moves faster for 15 seconds");
} else {
kitten.attackBoost = true;
kitten.attackBoostEndTime = Date.now() + 15000; // 15 seconds for kittens
showNotification("Attack Boost!", "Kitten attacks stronger for 15 seconds");
}
// Remove power-up
self.expired = true;
}
});
};
return self;
});
var PowerUpIndicator = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 2
});
bg.tint = 0x000033;
bg.alpha = 0.7;
var titleText = createGameText("Power-Ups", {
sizeFactor: 0.8,
fontWeight: 'bold'
});
titleText.anchor.set(0.5, 0);
titleText.y = -fontSizeBase;
self.addChild(titleText);
var powerUpText = createGameText("None Active", {
sizeFactor: 0.7
});
powerUpText.anchor.set(0.5, 0);
powerUpText.y = 0;
self.addChild(powerUpText);
self.update = function () {
if (powerUps && powerUps.length > 0) {
powerUpText.text = powerUps.length + " Active";
} else {
powerUpText.text = "None Active";
}
};
return self;
});
var Sparkle = Container.expand(function () {
var self = Container.call(this);
var sparkleGraphics = self.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 0.5
});
sparkleGraphics.tint = 0xFFFFFF;
self.alpha = 1;
self.visible = false;
self.vx = 0;
self.vy = 0;
self.update = function () {
if (!self.visible) {
return;
}
self.x += self.vx;
self.y += self.vy;
self.vy += 0.05; // Gravity
self.alpha -= 0.01;
if (self.alpha <= 0) {
self.visible = false;
}
};
return self;
});
var SparkleCounter = Container.expand(function () {
var self = Container.call(this);
var counterText = new Text("Sparkles: 0", {
fontFamily: "Arial",
fontSize: fontSizeBase,
fill: 0xFFFFFF
});
counterText.anchor.set(0, 0);
self.addChild(counterText);
var levelText = new Text("Level: 1 (x1.0)", {
fontFamily: "Arial",
fontSize: fontSizeBase * 0.9,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
levelText.y = fontSizeBase * 1.5;
self.addChild(levelText);
self.update = function () {
updateTextProperties(counterText, {
text: "Sparkles: " + Math.floor(sparkles)
});
updateTextProperties(levelText, {
text: "Level: " + playerLevel + " (x" + levelMultiplier.toFixed(1) + ")"
});
};
return self;
});
var StatsPanel = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
scale: 4
});
bg.tint = 0x000000;
bg.alpha = 0.7;
var titleText = createGameText("Game Stats", {
sizeFactor: 1,
fontWeight: 'bold'
});
titleText.anchor.set(0.5, 0);
titleText.y = -fontSizeBase * 2;
self.addChild(titleText);
var enemiesText = createGameText("Enemies Defeated: 0", {
sizeFactor: 0.8
});
enemiesText.anchor.set(0.5, 0);
enemiesText.y = -fontSizeBase;
self.addChild(enemiesText);
var catsText = createGameText("Cats: 0", {
sizeFactor: 0.8
});
catsText.anchor.set(0.5, 0);
catsText.y = 0;
self.addChild(catsText);
var totalSparklesText = createGameText("Total Sparkles: 0", {
sizeFactor: 0.8
});
totalSparklesText.anchor.set(0.5, 0);
totalSparklesText.y = fontSizeBase;
self.addChild(totalSparklesText);
self.update = function () {
if (typeof enemiesDefeated !== 'undefined') {
enemiesText.text = "Enemies Defeated: " + enemiesDefeated;
}
if (typeof cats !== 'undefined') {
catsText.text = "Cats: " + (cats ? cats.length : 0);
}
if (typeof totalSparklesEarned !== 'undefined') {
totalSparklesText.text = "Total Sparkles: " + Math.floor(totalSparklesEarned || 0);
}
};
return self;
});
var UFO = Container.expand(function () {
var self = Container.call(this);
var ufoGraphics = self.attachAsset('cat', {
anchorX: 0.5,
anchorY: 0.5,
scale: 0.7
});
ufoGraphics.tint = 0x00FFFF;
self.health = 40;
self.speed = 0.7 + Math.random() * 0.5;
self.value = 20;
self.update = function () {
self.x += Math.sin(LK.ticks / 30) * self.speed;
self.y += Math.cos(LK.ticks / 20) * self.speed;
cats.forEach(function (cat) {
var dist = Math.sqrt(Math.pow(cat.x - self.x, 2) + Math.pow(cat.y - self.y, 2));
if (dist < 60) {
self.health -= cat.level;
createSparkleEffect(self.x, self.y, 0x00FFFF, 1);
if (self.health <= 0) {
handleEnemyDefeat(self, self.value);
game.removeChild(self);
ufos.splice(ufos.indexOf(self), 1);
}
}
});
};
return self;
});
var UpgradeButton = Container.expand(function (type, text, x, y) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('upgrade-button', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type;
var buttonText = new Text2(text, {
fontFamily: "Arial",
fontSize: fontSizeBase * 1.2,
fill: 0xFFFFFF,
align: 'center'
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = 0;
buttonText.y = 0;
self.addChild(buttonText);
self.x = x;
self.y = y;
self.update = function () {
if (self.type === "clickPower") {
buttonText.text = "Click Power\nCost: " + Math.floor(upgrades.clickPower.cost);
} else if (self.type === "autoCollect") {
buttonText.text = "Auto Collect\nCost: " + Math.floor(upgrades.autoCollect.cost);
} else if (self.type === "buyCat") {
buttonText.text = "Buy Cat\nCost: " + Math.floor(upgrades.catCost);
} else if (self.type === "upgradeCat") {
var upgradeCost = 200 * playerLevel;
buttonText.text = "Upgrade Cat\nCost: " + Math.floor(upgradeCost);
if (cats.length > 0) {
if (sparkles >= upgradeCost) {
self.alpha = 1.0;
} else {
self.alpha = 0.7;
}
} else {
if (self.buttonText) {
self.buttonText.text = "No Cats";
}
self.alpha = 0.5;
}
}
};
self.interactive = true;
self.buttonMode = true;
self.on('pointerdown', function () {
if (self.type === "clickPower" && sparkles >= upgrades.clickPower.cost) {
sparkles -= upgrades.clickPower.cost;
upgrades.clickPower.level++;
clickMultiplier *= 1.2;
upgrades.clickPower.cost *= upgrades.clickPower.multiplier;
LK.getSound('songbird1').play();
} else if (self.type === "autoCollect" && sparkles >= upgrades.autoCollect.cost) {
sparkles -= upgrades.autoCollect.cost;
upgrades.autoCollect.level++;
autoSparkleRate += 0.5;
upgrades.autoCollect.cost *= upgrades.autoCollect.multiplier;
LK.getSound('songbird1').play();
} else if (self.type === "buyCat" && sparkles >= upgrades.catCost) {
sparkles -= upgrades.catCost;
addCat();
upgrades.catCost *= upgrades.catMultiplier;
LK.getSound('wings1').play();
}
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Utility functions
function createGameText(text, options) {
options = options || {};
var sizeFactor = options.sizeFactor || 1;
var fontSize = fontSizeBase * sizeFactor;
var textObj = new Text(text, {
fontFamily: "Arial",
fontSize: fontSize,
fill: options.fill || 0xFFFFFF,
fontWeight: options.fontWeight || 'normal',
align: options.align || 'center'
});
if (options.anchorX !== undefined && options.anchorY !== undefined) {
textObj.anchor.set(options.anchorX, options.anchorY);
}
return textObj;
}
function updateTextProperties(textObj, properties) {
if (!textObj) {
return;
}
if (properties.text !== undefined) {
textObj.text = properties.text;
}
if (properties.fill !== undefined) {
textObj.style.fill = properties.fill;
}
if (properties.fontSize !== undefined) {
textObj.style.fontSize = properties.fontSize;
}
if (properties.fontWeight !== undefined) {
textObj.style.fontWeight = properties.fontWeight;
}
}
function ensureInBounds(element) {
if (!element) {
return;
}
var padding = 10;
if (element.x < padding) {
element.x = padding;
}
if (element.y < padding) {
element.y = padding;
}
if (element.x > game.width - padding) {
element.x = game.width - padding;
}
if (element.y > game.height - padding) {
element.y = game.height - padding;
}
}
var gameStorage = {
save: function save(key, data) {
try {
storage.set(key, JSON.stringify(data));
return true;
} catch (e) {
console.error("Error saving data:", e);
return false;
}
},
load: function load(key) {
try {
var data = storage.get(key);
return data ? JSON.parse(data) : null;
} catch (e) {
console.error("Error loading data:", e);
return null;
}
},
clear: function clear(key) {
try {
storage.remove(key);
return true;
} catch (e) {
console.error("Error clearing data:", e);
return false;
}
}
};
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 ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function (r) {
return Object.getOwnPropertyDescriptor(e, r).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
_defineProperty(e, r, t[r]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
});
}
return e;
}
function _defineProperty(e, r, t) {
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: !0,
configurable: !0,
writable: !0
}) : e[r] = t, 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);
}
var startButton = game.addChild(new UpgradeButton("start", "Start", 2048 - 150, 2732 - 100));
startButton.on('pointerdown', function () {
sparkles = 0;
totalSparklesEarned = 0;
playerLevel = 1;
levelMultiplier = 1;
cats = [];
kittens = [];
birds = [];
ufos = [];
enemiesDefeated = 0;
powerUps = [];
totalUpgradesPurchased = 0;
addCat();
addKitten();
game.update = function () {
updateGameElements();
updateGameMechanics();
updateUIElements();
};
function updateGameElements() {
cats.forEach(function (cat) {
if (cat && typeof cat.update === 'function') {
cat.update();
}
});
if (birds && Array.isArray(birds)) {
birds.forEach(function (bird) {
if (bird && typeof bird.update === 'function') {
bird.update();
}
});
}
if (ufos && Array.isArray(ufos)) {
ufos.forEach(function (ufo) {
if (ufo && typeof ufo.update === 'function') {
ufo.update();
}
});
}
if (powerUps && Array.isArray(powerUps)) {
powerUps.forEach(function (powerUp) {
if (powerUp && typeof powerUp.update === 'function') {
powerUp.update();
}
});
}
if (Math.random() < 0.01 * (1 + playerLevel * 0.1)) {
var bird = new Bird();
bird.x = 2048 + 100;
bird.y = 1500 + Math.random() * 800;
game.addChild(bird);
birds.push(bird);
}
if (playerLevel % 5 === 0 && Math.random() < 0.005) {
var ufo = new UFO();
ufo.x = 2048 + 100;
ufo.y = 1200 + Math.random() * 1000;
game.addChild(ufo);
ufos.push(ufo);
}
if (Math.random() < 0.002 * (1 + playerLevel * 0.05)) {
spawnPowerUp();
}
}
function updateGameMechanics() {
sparkles += autoSparkleRate * levelMultiplier / 60;
totalSparklesEarned += autoSparkleRate * levelMultiplier / 60;
checkAchievements();
checkLevelUp();
catDefenseSystem();
}
function updateUIElements() {
if (sparkleCounter && typeof sparkleCounter.update === 'function') {
sparkleCounter.update();
}
if (levelIndicator && typeof levelIndicator.update === 'function') {
levelIndicator.update();
}
if (ensureInBounds) {
[statsPanel, powerUpIndicator, catStatusDisplay, notificationArea, levelProgressBar].forEach(function (element) {
if (element) {
ensureInBounds(element);
}
});
}
[clickUpgrade, autoUpgrade, catUpgrade, autoClickUpgrade, catSpeedUpgrade, catPowerUpgrade].forEach(function (button) {
if (button && typeof button.update === 'function') {
button.update();
}
});
}
function checkSpecialEvents() {
// Placeholder for special event logic
// Add logic here to handle any special events in the game
console.log("Checking for special events...");
}
});
var fontSizeBase = 24; // Define a base font size
var sparkles = 0;
var totalSparklesEarned = 0;
var sparkleRate = 1;
var autoSparkleRate = 0;
var clickMultiplier = 1;
var cats = [];
var kittens = [];
var birds = [];
var ufos = [];
var powerUps = [];
var enemiesDefeated = 0;
var playerLevel = 1;
var levelMultiplier = 1;
var lastSaveTime = Date.now();
var lastPlayTime = Date.now();
var totalUpgradesPurchased = 0;
var tutorialStep = 0;
var tutorialComplete = false;
var sounds = ['breeze1', 'chime1', 'chitter', 'cricket1', 'frog1', 'laser1', 'songbird1', 'teslacoil', 'ufo1', 'wings1'];
var upgrades = {
clickPower: {
level: 1,
cost: 10,
multiplier: 1.5
},
autoCollect: {
level: 0,
cost: 50,
multiplier: 2
},
catCost: 100,
catMultiplier: 1.8
};
var sparklePool = [];
var maxSparkles = 50;
var sparkleCounter = null;
var levelIndicator = null;
var levelProgressBar = null;
var statsPanel = null;
var powerUpIndicator = null;
var catStatusDisplay = null;
var notificationArea = null;
var achievementDisplay = null;
// Utility functions
function handleEnemyDefeat(enemy, value) {
// Increment enemy defeat counter
enemiesDefeated++;
// Add sparkles based on enemy value and level multiplier
sparkles += value * levelMultiplier;
totalSparklesEarned += value * levelMultiplier;
// Create sparkle effect at enemy position
if (enemy && enemy.x !== undefined && enemy.y !== undefined) {
var color = enemy.type === 'ufo' ? 0x00FFFF : 0xFF0000;
createSparkleEffect(enemy.x, enemy.y, color, 10);
}
// Check if we've defeated enough enemies for a level up
var enemiesForNextLevel = playerLevel * 10;
var currentLevelEnemies = enemiesDefeated % enemiesForNextLevel;
if (currentLevelEnemies >= enemiesForNextLevel) {
playerLevel++;
levelMultiplier = 1 + (playerLevel - 1) * 0.1;
showAchievement("Level Up!", "You reached level " + playerLevel, playerLevel * 50);
sparkles += playerLevel * 50;
totalSparklesEarned += playerLevel * 50;
// Play level up sound
if (LK.getSound('chime1')) {
LK.getSound('chime1').play();
}
}
}
function showNotification(title, message) {
if (notificationArea) {
notificationArea.addMessage(title + ": " + message);
}
}
function catDefenseSystem() {
// Check for cats attacking birds
cats.forEach(function (cat) {
birds.forEach(function (bird) {
var dx = bird.x - cat.x;
var dy = bird.y - cat.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < cat.attackRange) {
// Cat is in range to attack
bird.health -= cat.attackPower / 60; // Divide by 60 for per-frame damage
if (Math.random() < 0.05) {
createSparkleEffect(bird.x, bird.y, 0xFF0000, 1);
}
if (bird.health <= 0) {
handleEnemyDefeat(bird, bird.value);
game.removeChild(bird);
birds.splice(birds.indexOf(bird), 1);
}
}
});
// Check for cats attacking UFOs
ufos.forEach(function (ufo) {
var dx = ufo.x - cat.x;
var dy = ufo.y - cat.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < cat.attackRange) {
// Cat is in range to attack
ufo.health -= cat.attackPower / 60; // Divide by 60 for per-frame damage
if (Math.random() < 0.05) {
createSparkleEffect(ufo.x, ufo.y, 0x00FFFF, 1);
}
if (ufo.health <= 0) {
handleEnemyDefeat(ufo, ufo.value);
game.removeChild(ufo);
ufos.splice(ufos.indexOf(ufo), 1);
}
}
});
});
// Also check for kittens attacking
kittens.forEach(function (kitten) {
birds.forEach(function (bird) {
var dx = bird.x - kitten.x;
var dy = bird.y - kitten.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < kitten.attackRange) {
// Kitten is in range to attack
bird.health -= kitten.attackPower / 60; // Divide by 60 for per-frame damage
if (Math.random() < 0.05) {
createSparkleEffect(bird.x, bird.y, 0xFF9900, 1);
}
if (bird.health <= 0) {
handleEnemyDefeat(bird, bird.value);
game.removeChild(bird);
birds.splice(birds.indexOf(bird), 1);
}
}
});
});
}
var clickUpgrade = null;
var autoUpgrade = null;
var catUpgrade = null;
var autoClickUpgrade = null;
var catSpeedUpgrade = null;
var catPowerUpgrade = null;
var achievements = {
sparklesCollected: [{
threshold: 100,
reward: 50,
achieved: false
}, {
threshold: 1000,
reward: 200,
achieved: false
}, {
threshold: 10000,
reward: 500,
achieved: false
}, {
threshold: 100000,
reward: 2000,
achieved: false
}, {
threshold: 1000000,
reward: 10000,
achieved: false
}],
catsOwned: [{
threshold: 1,
reward: 50,
achieved: false
}, {
threshold: 5,
reward: 200,
achieved: false
}, {
threshold: 10,
reward: 500,
achieved: false
}, {
threshold: 25,
reward: 2000,
achieved: false
}, {
threshold: 50,
reward: 10000,
achieved: false
}],
upgradesPurchased: [{
threshold: 5,
reward: 100,
achieved: false
}, {
threshold: 15,
reward: 300,
achieved: false
}, {
threshold: 30,
reward: 1000,
achieved: false
}, {
threshold: 50,
reward: 3000,
achieved: false
}, {
threshold: 100,
reward: 15000,
achieved: false
}],
catLevels: [{
threshold: 10,
reward: 200,
achieved: false
}, {
threshold: 25,
reward: 500,
achieved: false
}, {
threshold: 50,
reward: 1500,
achieved: false
}, {
threshold: 100,
reward: 5000,
achieved: false
}, {
threshold: 250,
reward: 20000,
achieved: false
}]
};
function saveGame() {
var gameData = {
sparkles: sparkles,
totalSparklesEarned: totalSparklesEarned,
sparkleRate: sparkleRate,
autoSparkleRate: autoSparkleRate,
clickMultiplier: clickMultiplier,
playerLevel: playerLevel,
levelMultiplier: levelMultiplier,
enemiesDefeated: enemiesDefeated,
lastSaveTime: Date.now()
};
gameStorage.save('catDefenderSave', gameData);
}
function loadGame() {
var gameState = gameStorage.load('cosmicCatGarden');
if (gameState) {
sparkles = gameState.sparkles || 0;
totalSparklesEarned = gameState.totalSparklesEarned || 0;
sparkleRate = gameState.sparkleRate || 1;
autoSparkleRate = gameState.autoSparkleRate || 0;
clickMultiplier = gameState.clickMultiplier || 1;
playerLevel = gameState.playerLevel || 1;
levelMultiplier = gameState.levelMultiplier || 1;
achievements = gameState.achievements || achievements;
totalUpgradesPurchased = gameState.totalUpgradesPurchased || 0;
tutorialComplete = gameState.tutorialComplete || false;
tutorialStep = gameState.tutorialStep || 0;
upgrades = gameState.upgrades || upgrades;
var currentTime = Date.now();
var offlineTime = (currentTime - gameState.lastSaveTime) / 1000;
var offlineSparkles = 0;
if (offlineTime > 0 && gameState.cats && gameState.cats.length > 0) {
var totalCatProduction = gameState.cats.reduce(function (total, cat) {
return total + cat.productionRate * cat.level;
}, 0);
offlineSparkles = totalCatProduction * offlineTime;
offlineSparkles += gameState.autoSparkleRate * offlineTime;
offlineSparkles *= gameState.levelMultiplier;
sparkles += offlineSparkles;
totalSparklesEarned += offlineSparkles;
showOfflineEarnings(offlineSparkles, offlineTime);
}
if (gameState.cats && gameState.cats.length > 0) {
cats.forEach(function (cat) {
game.removeChild(cat);
});
cats = [];
gameState.cats.forEach(function (catData) {
var cat = addCat(catData.x, catData.y);
cat.level = catData.level || 1;
cat.productionRate = catData.productionRate || 0.5;
});
}
return true;
}
return false;
}
function resetGame() {
gameStorage.clear('cosmicCatGarden');
sparkles = 0;
totalSparklesEarned = 0;
sparkleRate = 1;
autoSparkleRate = 0;
clickMultiplier = 1;
playerLevel = 1;
levelMultiplier = 1;
cats.forEach(function (cat) {
game.removeChild(cat);
});
cats = [];
birds.forEach(function (bird) {
game.removeChild(bird);
});
birds = [];
ufos.forEach(function (ufo) {
game.removeChild(ufo);
});
ufos = [];
achievements = [];
totalUpgradesPurchased = 0;
tutorialComplete = false;
upgrades = [];
addCat();
return true;
}
var lastAutoSaveTime = Date.now();
var saveIndicator = null;
function createSaveIndicator() {
if (!saveIndicator) {
saveIndicator = new Container();
var saveText = createGameText("Saving...", {
sizeFactor: 0.7,
fill: 0xFFFFFF,
align: 'right'
});
saveText.anchor.set(1, 0);
saveIndicator.addChild(saveText);
saveIndicator.alpha = 0;
saveIndicator.x = 1024 - 20;
saveIndicator.y = 20;
game.addChild(saveIndicator);
}
return saveIndicator;
}
function checkAutoSave() {
var currentTime = Date.now();
if (currentTime - lastAutoSaveTime > 30000) {
var indicator = createSaveIndicator();
indicator.alpha = 1;
saveGame();
lastAutoSaveTime = currentTime;
setTimeout(function () {
var fadeInterval = setInterval(function () {
indicator.alpha -= 0.05;
if (indicator.alpha <= 0) {
clearInterval(fadeInterval);
}
}, 50);
}, 1000);
}
}
function showOfflineEarnings(amount, time) {
var notification = new Container();
// Create background
notification.attachAsset('achievement-notification', {});
// Create title text
var titleText = new Text("Welcome Back!", {
fontFamily: "Arial",
fontSize: fontSizeBase,
fill: 0xFFFFFF,
fontWeight: 'bold'
});
titleText.anchor.set(0.5, 0);
titleText.y = 10;
// Create message text
var messageText = new Text("You earned " + Math.floor(amount) + " sparkles\nwhile away for " + Math.floor(time / 60) + " minutes", {
fontFamily: "Arial",
fontSize: fontSizeBase * 0.8,
fill: 0xFFFFFF,
align: 'center'
});
messageText.anchor.set(0.5, 0);
messageText.y = 35;
// Add elements to notification
notification.addChild(titleText);
notification.addChild(messageText);
// Position notification
notification.x = 2048 / 2;
notification.y = 2732 / 2;
notification.alpha = 0;
game.addChild(notification);
// Set up fade in/out animation
var startTime = LK.ticks;
notification.update = function () {
var elapsed = (LK.ticks - startTime) / 60;
if (elapsed < 1) {
notification.alpha = elapsed;
} else if (elapsed < 5) {
notification.alpha = 1;
} else if (elapsed < 6) {
notification.alpha = 6 - elapsed;
} else {
game.removeChild(notification);
}
};
}
function showAchievement(title, description, reward) {
var notification = new Container();
// Create background
var achievementBg = notification.attachAsset('achievement-notification', {});
// Create title text
var titleText = new Text("Achievement: " + title, {
fontFamily: "Arial",
fontSize: fontSizeBase,
fill: 0xFFFFFF,
fontWeight: 'bold'
});
titleText.anchor.set(0.5, 0);
titleText.y = 10;
notification.addChild(titleText);
// Create message text
var messageText = new Text(description + "\nReward: " + reward + " sparkles", {
fontFamily: "Arial",
fontSize: fontSizeBase * 0.8,
fill: 0xFFFFFF,
align: 'center'
});
messageText.anchor.set(0.5, 0);
messageText.y = fontSizeBase * 2;
notification.addChild(messageText);
// Position notification
notification.x = 2048 / 2;
notification.y = 2732 / 2 - achievementBg.height / 2;
game.addChild(notification);
// Play achievement sound
if (LK.getSound('chime1')) {
LK.getSound('chime1').play();
}
// Set up fade in/out animation
var startTime = LK.ticks;
notification.update = function () {
var elapsed = (LK.ticks - startTime) / 60;
if (elapsed < 1) {
notification.alpha = elapsed;
} else if (elapsed < 5) {
notification.alpha = 1;
} else if (elapsed < 6) {
notification.alpha = 6 - elapsed;
} else {
game.removeChild(notification);
}
};
}
function checkAchievements() {
if (typeof achievements !== 'undefined' && achievements) {
if (achievements.sparklesCollected) {
achievements.sparklesCollected.forEach(function (achievement) {
if (!achievement.achieved && totalSparklesEarned >= achievement.threshold) {
achievement.achieved = true;
sparkles += achievement.reward;
totalSparklesEarned += achievement.reward;
showAchievement("Sparkle Collector", "Collected " + achievement.threshold + " sparkles", achievement.reward);
}
});
}
if (achievements.catsOwned) {
achievements.catsOwned.forEach(function (achievement) {
if (!achievement.achieved && cats.length >= achievement.threshold) {
achievement.achieved = true;
sparkles += achievement.reward;
totalSparklesEarned += achievement.reward;
showAchievement("Cat Collector", "Owned " + achievement.threshold + " cats", achievement.reward);
}
});
}
}
}
function checkLevelUp() {
var newLevel = Math.floor(Math.log(totalSparklesEarned / 100 + 1) / Math.log(1.5)) + 1;
if (newLevel > playerLevel) {
// Store previous level for potential use
playerLevel = newLevel;
levelMultiplier = 1 + (playerLevel - 1) * 0.1;
showAchievement("Level Up!", "You reached level " + playerLevel, playerLevel * 50);
sparkles += playerLevel * 50;
totalSparklesEarned += playerLevel * 50;
if (LK.getSound('chime1')) {
LK.getSound('chime1').play();
}
}
}
function initSparklePool() {
for (var i = 0; i < maxSparkles; i++) {
var sparkle = new Sparkle();
sparkle.visible = false;
sparklePool.push(sparkle);
game.addChild(sparkle);
}
}
function initializeGame() {
console.log("Initializing game...");
sparkles = 0;
totalSparklesEarned = 0;
sparkleRate = 1;
autoSparkleRate = 0;
clickMultiplier = 1;
playerLevel = 1;
levelMultiplier = 1;
enemiesDefeated = 0;
totalUpgradesPurchased = 0;
tutorialComplete = false;
clearGameObjects();
initSparklePool();
addCat();
addKitten();
setupUI();
if (LK.getMusic('bgm1')) {
LK.getMusic('bgm1').play({
loop: true,
volume: 0.5
});
}
game.update = function () {
updateGameElements();
updateGameMechanics();
updateUIElements();
if (Date.now() - lastSaveTime > 30000) {
saveGame();
lastSaveTime = Date.now();
}
};
console.log("Game initialized successfully");
}
function clearGameObjects() {
cats.forEach(function (cat) {
if (cat && game.children.includes(cat)) {
game.removeChild(cat);
}
});
cats = [];
kittens.forEach(function (kitten) {
if (kitten && game.children.includes(kitten)) {
game.removeChild(kitten);
}
});
kittens = [];
birds.forEach(function (bird) {
if (bird && game.children.includes(bird)) {
game.removeChild(bird);
}
});
birds = [];
ufos.forEach(function (ufo) {
if (ufo && game.children.includes(ufo)) {
game.removeChild(ufo);
}
});
ufos = [];
powerUps.forEach(function (powerUp) {
if (powerUp && game.children.includes(powerUp)) {
game.removeChild(powerUp);
}
});
powerUps = [];
}
function setupUI() {
// Create UI elements if they don't exist
if (!sparkleCounter) {
sparkleCounter = game.addChild(new SparkleCounter());
sparkleCounter.x = 1024 - 150;
sparkleCounter.y = 30;
}
if (!levelIndicator) {
levelIndicator = game.addChild(new LevelIndicator());
levelIndicator.x = 1024 - 150;
levelIndicator.y = 80;
}
if (!levelProgressBar) {
levelProgressBar = game.addChild(new LevelProgressBar());
levelProgressBar.x = 1024 - 150;
levelProgressBar.y = 130;
}
if (!statsPanel) {
statsPanel = game.addChild(new StatsPanel());
statsPanel.x = 1024;
statsPanel.y = 200;
}
if (!powerUpIndicator) {
powerUpIndicator = game.addChild(new PowerUpIndicator());
powerUpIndicator.x = 1024 - 150;
powerUpIndicator.y = 250;
}
if (!catStatusDisplay) {
catStatusDisplay = game.addChild(new CatStatusDisplay());
catStatusDisplay.x = 1024 - 150;
catStatusDisplay.y = 350;
}
if (!notificationArea) {
notificationArea = game.addChild(new NotificationArea());
notificationArea.x = 20;
notificationArea.y = 550;
}
// Add achievement display
if (!achievementDisplay) {
achievementDisplay = game.addChild(new AchievementDisplay());
achievementDisplay.x = 150;
achievementDisplay.y = 200;
achievementDisplay.visible = false; // Hidden by default, show on button click
}
// Update all UI elements
updateUIElements();
}
function updateGameElements() {
// Update cats
cats.forEach(function (cat) {
if (cat && typeof cat.update === 'function') {
cat.update();
}
});
// Update kittens
kittens.forEach(function (kitten) {
if (kitten && typeof kitten.update === 'function') {
kitten.update();
}
});
// Update birds
for (var i = birds.length - 1; i >= 0; i--) {
var bird = birds[i];
if (bird && typeof bird.update === 'function') {
bird.update();
}
if (bird && bird.markedForRemoval) {
game.removeChild(bird);
birds.splice(i, 1);
}
}
// Update UFOs
for (var i = ufos.length - 1; i >= 0; i--) {
var ufo = ufos[i];
if (ufo && typeof ufo.update === 'function') {
ufo.update();
}
if (ufo && ufo.markedForRemoval) {
game.removeChild(ufo);
ufos.splice(i, 1);
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (powerUp && typeof powerUp.update === 'function') {
powerUp.update();
}
if (powerUp && powerUp.markedForRemoval) {
game.removeChild(powerUp);
powerUps.splice(i, 1);
}
}
// Update sparkles
for (var i = 0; i < sparklePool.length; i++) {
var sparkle = sparklePool[i];
if (sparkle && sparkle.visible && typeof sparkle.update === 'function') {
sparkle.update();
}
}
// Spawn new birds based on level
if (Math.random() < 0.01 * (1 + playerLevel * 0.1)) {
var bird = new Bird();
bird.x = 2048 + 100;
bird.y = 1500 + Math.random() * 800;
game.addChild(bird);
birds.push(bird);
}
// Spawn UFOs every 5 levels
if (playerLevel % 5 === 0 && Math.random() < 0.005) {
var ufo = new UFO();
ufo.x = 2048 + 100;
ufo.y = 1200 + Math.random() * 1000;
game.addChild(ufo);
ufos.push(ufo);
}
// Spawn power-ups occasionally
if (Math.random() < 0.002 * (1 + playerLevel * 0.05)) {
spawnPowerUp();
}
// Run the cat defense system
catDefenseSystem();
}
function addCat(x, y) {
if (x === undefined || y === undefined) {
x = Math.random() * (2048 - 200) + 100;
y = Math.random() * (2732 - 200) + 100;
}
if (sparkles >= upgrades.catCost) {
sparkles -= upgrades.catCost;
var cat = new Cat();
cat.x = x;
cat.y = y;
cats.push(cat);
game.addChild(cat);
upgrades.catCost = Math.floor(upgrades.catCost * upgrades.catMultiplier);
checkAchievements();
showNotification("New Cat", "A new cat has joined your garden!");
return cat;
} else {
showNotification("Not Enough Sparkles", "You need " + Math.floor(upgrades.catCost) + " sparkles to buy a cat.");
return false;
}
}
function addKitten(x, y) {
if (x === undefined || y === undefined) {
x = Math.random() * (2048 - 200) + 100;
y = Math.random() * (2732 - 200) + 100;
}
var kittenCost = 30; // Base cost for a kitten
if (sparkles >= kittenCost) {
sparkles -= kittenCost;
var kitten = new Kitten();
kitten.x = x;
kitten.y = y;
kittens.push(kitten);
game.addChild(kitten);
checkAchievements();
showNotification("New Kitten", "A new kitten has joined your garden!");
return kitten;
} else {
showNotification("Not Enough Sparkles", "You need " + kittenCost + " sparkles to buy a kitten.");
return false;
}
}
function spawnBird() {
var bird = new Bird();
bird.x = 2048 + 100;
bird.y = 1500 + Math.random() * 800;
birds.push(bird);
game.addChild(bird);
return bird;
}
function spawnUFO() {
if (playerLevel % 5 === 0 && ufos.length < 3) {
var ufo = new UFO();
ufo.x = 2048 + 100;
ufo.y = 1200 + Math.random() * 1000;
ufos.push(ufo);
game.addChild(ufo);
return ufo;
}
return null;
}
function spawnPowerUp() {
if (Math.random() < 0.05 * (1 + playerLevel * 0.02)) {
var type = Math.random() < 0.5 ? 'speed' : 'attack';
var powerUp = new PowerUp(type);
powerUp.x = Math.random() * (2048 - 200) + 100;
powerUp.y = Math.random() * (2732 - 200) + 100;
powerUps.push(powerUp);
game.addChild(powerUp);
return powerUp;
}
return null;
}
function createSparkleEffect(x, y, color, count) {
color = color || 0xFFFFFF;
count = count || 5;
for (var c = 0; c < count; c++) {
// Get a sparkle from the pool or create a new one
var sparkle = null;
for (var i = 0; i < sparklePool.length; i++) {
if (!sparklePool[i].visible) {
sparkle = sparklePool[i];
break;
}
}
if (!sparkle) {
if (sparklePool.length < maxSparkles) {
sparkle = new Sparkle();
sparklePool.push(sparkle);
game.addChild(sparkle);
} else {
// Reuse the oldest sparkle
sparkle = sparklePool[0];
sparklePool.push(sparklePool.shift());
}
}
// Set up the sparkle
sparkle.x = x + (Math.random() - 0.5) * 20;
sparkle.y = y + (Math.random() - 0.5) * 20;
sparkle.vx = (Math.random() - 0.5) * 3;
sparkle.vy = (Math.random() - 0.5) * 3 - 2; // Bias upward
sparkle.alpha = 1;
sparkle.visible = true;
sparkle.children[0].tint = color;
// Play a sound occasionally
if (c === 0 && Math.random() < 0.2 && sounds.length > 0) {
var soundIndex = Math.floor(Math.random() * sounds.length);
LK.getSound(sounds[soundIndex]).play();
}
}
}
function updateGameMechanics() {
// Auto-collect sparkles based on rate
sparkles += autoSparkleRate * levelMultiplier / 60;
totalSparklesEarned += autoSparkleRate * levelMultiplier / 60;
// Spawn enemies based on level
if (Math.random() < 0.01 * (1 + playerLevel * 0.05)) {
spawnBird();
}
// Spawn UFOs every 5 levels
if (playerLevel % 5 === 0 && Math.random() < 0.005) {
spawnUFO();
}
// Spawn power-ups
if (Math.random() < 0.001 * (1 + playerLevel * 0.02)) {
spawnPowerUp();
}
// Check achievements
checkAchievements();
}
function updateUIElements() {
// Update sparkle counter
if (sparkleCounter) {
sparkleCounter.text = "Sparkles: " + Math.floor(sparkles);
}
// Update level indicator
if (levelIndicator) {
levelIndicator.text = "Level: " + playerLevel;
}
// Update level progress bar
if (levelProgressBar) {
levelProgressBar.scale.x = enemiesDefeated / 10;
}
} ===================================================================
--- original.js
+++ change.js
@@ -5,9 +5,65 @@
/****
* Classes
****/
-// ok
+var AchievementDisplay = Container.expand(function () {
+ var self = Container.call(this);
+ var bg = self.attachAsset('sparkle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scale: 4
+ });
+ bg.tint = 0x000000;
+ bg.alpha = 0.7;
+ var titleText = createGameText("Achievements", {
+ sizeFactor: 1,
+ fontWeight: 'bold'
+ });
+ titleText.anchor.set(0.5, 0);
+ titleText.y = -fontSizeBase * 2;
+ self.addChild(titleText);
+ var achievementTexts = [];
+ self.update = function () {
+ // Clear previous achievement texts
+ achievementTexts.forEach(function (text) {
+ self.removeChild(text);
+ });
+ achievementTexts = [];
+ // Add achievement texts
+ var yPos = -fontSizeBase;
+ var categories = ['sparklesCollected', 'catsOwned', 'upgradesPurchased', 'catLevels'];
+ var categoryNames = ['Sparkles', 'Cats', 'Upgrades', 'Cat Levels'];
+ categories.forEach(function (category, index) {
+ if (achievements[category]) {
+ var categoryText = createGameText(categoryNames[index] + ":", {
+ sizeFactor: 0.8,
+ fontWeight: 'bold'
+ });
+ categoryText.anchor.set(0.5, 0);
+ categoryText.y = yPos;
+ self.addChild(categoryText);
+ achievementTexts.push(categoryText);
+ yPos += fontSizeBase;
+ achievements[category].forEach(function (achievement) {
+ var color = achievement.achieved ? 0x00FF00 : 0xFFFFFF;
+ var text = achievement.achieved ? "✓ " + achievement.threshold + " (" + achievement.reward + " sparkles)" : "□ " + achievement.threshold + " (" + achievement.reward + " sparkles)";
+ var achievementText = createGameText(text, {
+ sizeFactor: 0.7,
+ fill: color
+ });
+ achievementText.anchor.set(0.5, 0);
+ achievementText.y = yPos;
+ self.addChild(achievementText);
+ achievementTexts.push(achievementText);
+ yPos += fontSizeBase * 0.8;
+ });
+ yPos += fontSizeBase * 0.5;
+ }
+ });
+ };
+ return self;
+});
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphics = self.attachAsset('cat', {
anchorX: 0.5,
@@ -553,18 +609,44 @@
}
};
return self;
});
+var Sparkle = Container.expand(function () {
+ var self = Container.call(this);
+ var sparkleGraphics = self.attachAsset('sparkle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scale: 0.5
+ });
+ sparkleGraphics.tint = 0xFFFFFF;
+ self.alpha = 1;
+ self.visible = false;
+ self.vx = 0;
+ self.vy = 0;
+ self.update = function () {
+ if (!self.visible) {
+ return;
+ }
+ self.x += self.vx;
+ self.y += self.vy;
+ self.vy += 0.05; // Gravity
+ self.alpha -= 0.01;
+ if (self.alpha <= 0) {
+ self.visible = false;
+ }
+ };
+ return self;
+});
var SparkleCounter = Container.expand(function () {
var self = Container.call(this);
- var counterText = new Text2("Sparkles: 0", {
+ var counterText = new Text("Sparkles: 0", {
fontFamily: "Arial",
fontSize: fontSizeBase,
fill: 0xFFFFFF
});
counterText.anchor.set(0, 0);
self.addChild(counterText);
- var levelText = new Text2("Level: 1 (x1.0)", {
+ var levelText = new Text("Level: 1 (x1.0)", {
fontFamily: "Arial",
fontSize: fontSizeBase * 0.9,
fill: 0xFFFFFF
});
@@ -734,8 +816,60 @@
/****
* Game Code
****/
+// Utility functions
+function createGameText(text, options) {
+ options = options || {};
+ var sizeFactor = options.sizeFactor || 1;
+ var fontSize = fontSizeBase * sizeFactor;
+ var textObj = new Text(text, {
+ fontFamily: "Arial",
+ fontSize: fontSize,
+ fill: options.fill || 0xFFFFFF,
+ fontWeight: options.fontWeight || 'normal',
+ align: options.align || 'center'
+ });
+ if (options.anchorX !== undefined && options.anchorY !== undefined) {
+ textObj.anchor.set(options.anchorX, options.anchorY);
+ }
+ return textObj;
+}
+function updateTextProperties(textObj, properties) {
+ if (!textObj) {
+ return;
+ }
+ if (properties.text !== undefined) {
+ textObj.text = properties.text;
+ }
+ if (properties.fill !== undefined) {
+ textObj.style.fill = properties.fill;
+ }
+ if (properties.fontSize !== undefined) {
+ textObj.style.fontSize = properties.fontSize;
+ }
+ if (properties.fontWeight !== undefined) {
+ textObj.style.fontWeight = properties.fontWeight;
+ }
+}
+function ensureInBounds(element) {
+ if (!element) {
+ return;
+ }
+ var padding = 10;
+ if (element.x < padding) {
+ element.x = padding;
+ }
+ if (element.y < padding) {
+ element.y = padding;
+ }
+ if (element.x > game.width - padding) {
+ element.x = game.width - padding;
+ }
+ if (element.y > game.height - padding) {
+ element.y = game.height - padding;
+ }
+}
var gameStorage = {
save: function save(key, data) {
try {
storage.set(key, JSON.stringify(data));
@@ -935,8 +1069,9 @@
var lastPlayTime = Date.now();
var totalUpgradesPurchased = 0;
var tutorialStep = 0;
var tutorialComplete = false;
+var sounds = ['breeze1', 'chime1', 'chitter', 'cricket1', 'frog1', 'laser1', 'songbird1', 'teslacoil', 'ufo1', 'wings1'];
var upgrades = {
clickPower: {
level: 1,
cost: 10,
@@ -959,8 +1094,100 @@
var powerUpIndicator = null;
var catStatusDisplay = null;
var notificationArea = null;
var achievementDisplay = null;
+// Utility functions
+function handleEnemyDefeat(enemy, value) {
+ // Increment enemy defeat counter
+ enemiesDefeated++;
+ // Add sparkles based on enemy value and level multiplier
+ sparkles += value * levelMultiplier;
+ totalSparklesEarned += value * levelMultiplier;
+ // Create sparkle effect at enemy position
+ if (enemy && enemy.x !== undefined && enemy.y !== undefined) {
+ var color = enemy.type === 'ufo' ? 0x00FFFF : 0xFF0000;
+ createSparkleEffect(enemy.x, enemy.y, color, 10);
+ }
+ // Check if we've defeated enough enemies for a level up
+ var enemiesForNextLevel = playerLevel * 10;
+ var currentLevelEnemies = enemiesDefeated % enemiesForNextLevel;
+ if (currentLevelEnemies >= enemiesForNextLevel) {
+ playerLevel++;
+ levelMultiplier = 1 + (playerLevel - 1) * 0.1;
+ showAchievement("Level Up!", "You reached level " + playerLevel, playerLevel * 50);
+ sparkles += playerLevel * 50;
+ totalSparklesEarned += playerLevel * 50;
+ // Play level up sound
+ if (LK.getSound('chime1')) {
+ LK.getSound('chime1').play();
+ }
+ }
+}
+function showNotification(title, message) {
+ if (notificationArea) {
+ notificationArea.addMessage(title + ": " + message);
+ }
+}
+function catDefenseSystem() {
+ // Check for cats attacking birds
+ cats.forEach(function (cat) {
+ birds.forEach(function (bird) {
+ var dx = bird.x - cat.x;
+ var dy = bird.y - cat.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < cat.attackRange) {
+ // Cat is in range to attack
+ bird.health -= cat.attackPower / 60; // Divide by 60 for per-frame damage
+ if (Math.random() < 0.05) {
+ createSparkleEffect(bird.x, bird.y, 0xFF0000, 1);
+ }
+ if (bird.health <= 0) {
+ handleEnemyDefeat(bird, bird.value);
+ game.removeChild(bird);
+ birds.splice(birds.indexOf(bird), 1);
+ }
+ }
+ });
+ // Check for cats attacking UFOs
+ ufos.forEach(function (ufo) {
+ var dx = ufo.x - cat.x;
+ var dy = ufo.y - cat.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < cat.attackRange) {
+ // Cat is in range to attack
+ ufo.health -= cat.attackPower / 60; // Divide by 60 for per-frame damage
+ if (Math.random() < 0.05) {
+ createSparkleEffect(ufo.x, ufo.y, 0x00FFFF, 1);
+ }
+ if (ufo.health <= 0) {
+ handleEnemyDefeat(ufo, ufo.value);
+ game.removeChild(ufo);
+ ufos.splice(ufos.indexOf(ufo), 1);
+ }
+ }
+ });
+ });
+ // Also check for kittens attacking
+ kittens.forEach(function (kitten) {
+ birds.forEach(function (bird) {
+ var dx = bird.x - kitten.x;
+ var dy = bird.y - kitten.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < kitten.attackRange) {
+ // Kitten is in range to attack
+ bird.health -= kitten.attackPower / 60; // Divide by 60 for per-frame damage
+ if (Math.random() < 0.05) {
+ createSparkleEffect(bird.x, bird.y, 0xFF9900, 1);
+ }
+ if (bird.health <= 0) {
+ handleEnemyDefeat(bird, bird.value);
+ game.removeChild(bird);
+ birds.splice(birds.indexOf(bird), 1);
+ }
+ }
+ });
+ });
+}
var clickUpgrade = null;
var autoUpgrade = null;
var catUpgrade = null;
var autoClickUpgrade = null;
@@ -1175,31 +1402,37 @@
}
}
function showOfflineEarnings(amount, time) {
var notification = new Container();
- var bg = notification.attachAsset('achievement-notification', {});
- var titleText = new Text2("Welcome Back!", {
+ // Create background
+ notification.attachAsset('achievement-notification', {});
+ // Create title text
+ var titleText = new Text("Welcome Back!", {
fontFamily: "Arial",
fontSize: fontSizeBase,
fill: 0xFFFFFF,
fontWeight: 'bold'
});
titleText.anchor.set(0.5, 0);
titleText.y = 10;
- var messageText = new Text2("You earned " + Math.floor(amount) + " sparkles\nwhile away for " + Math.floor(time / 60) + " minutes", {
+ // Create message text
+ var messageText = new Text("You earned " + Math.floor(amount) + " sparkles\nwhile away for " + Math.floor(time / 60) + " minutes", {
fontFamily: "Arial",
fontSize: fontSizeBase * 0.8,
fill: 0xFFFFFF,
align: 'center'
});
messageText.anchor.set(0.5, 0);
messageText.y = 35;
+ // Add elements to notification
notification.addChild(titleText);
notification.addChild(messageText);
+ // Position notification
notification.x = 2048 / 2;
notification.y = 2732 / 2;
notification.alpha = 0;
game.addChild(notification);
+ // Set up fade in/out animation
var startTime = LK.ticks;
notification.update = function () {
var elapsed = (LK.ticks - startTime) / 60;
if (elapsed < 1) {
@@ -1214,30 +1447,39 @@
};
}
function showAchievement(title, description, reward) {
var notification = new Container();
- var bg = notification.attachAsset('achievement-notification', {});
- var titleText = new Text2("Achievement: " + title, {
+ // Create background
+ var achievementBg = notification.attachAsset('achievement-notification', {});
+ // Create title text
+ var titleText = new Text("Achievement: " + title, {
fontFamily: "Arial",
fontSize: fontSizeBase,
fill: 0xFFFFFF,
fontWeight: 'bold'
});
titleText.anchor.set(0.5, 0);
titleText.y = 10;
notification.addChild(titleText);
- var messageText = new Text2(description + "\nReward: " + reward + " sparkles", {
+ // Create message text
+ var messageText = new Text(description + "\nReward: " + reward + " sparkles", {
fontFamily: "Arial",
fontSize: fontSizeBase * 0.8,
fill: 0xFFFFFF,
align: 'center'
});
messageText.anchor.set(0.5, 0);
messageText.y = fontSizeBase * 2;
notification.addChild(messageText);
- notification.x = 1024 / 2;
- notification.y = 2732 / 2 - bg.height / 2;
+ // Position notification
+ notification.x = 2048 / 2;
+ notification.y = 2732 / 2 - achievementBg.height / 2;
game.addChild(notification);
+ // Play achievement sound
+ if (LK.getSound('chime1')) {
+ LK.getSound('chime1').play();
+ }
+ // Set up fade in/out animation
var startTime = LK.ticks;
notification.update = function () {
var elapsed = (LK.ticks - startTime) / 60;
if (elapsed < 1) {
@@ -1251,29 +1493,35 @@
}
};
}
function checkAchievements() {
- achievements.sparklesCollected.forEach(function (achievement) {
- if (!achievement.achieved && totalSparklesEarned >= achievement.threshold) {
- achievement.achieved = true;
- sparkles += achievement.reward;
- totalSparklesEarned += achievement.reward;
- showAchievement("Sparkle Collector", "Collected " + achievement.threshold + " sparkles", achievement.reward);
+ if (typeof achievements !== 'undefined' && achievements) {
+ if (achievements.sparklesCollected) {
+ achievements.sparklesCollected.forEach(function (achievement) {
+ if (!achievement.achieved && totalSparklesEarned >= achievement.threshold) {
+ achievement.achieved = true;
+ sparkles += achievement.reward;
+ totalSparklesEarned += achievement.reward;
+ showAchievement("Sparkle Collector", "Collected " + achievement.threshold + " sparkles", achievement.reward);
+ }
+ });
}
- });
- achievements.catsOwned.forEach(function (achievement) {
- if (!achievement.achieved && cats.length >= achievement.threshold) {
- achievement.achieved = true;
- sparkles += achievement.reward;
- totalSparklesEarned += achievement.reward;
- showAchievement("Cat Collector", "Owned " + achievement.threshold + " cats", achievement.reward);
+ if (achievements.catsOwned) {
+ achievements.catsOwned.forEach(function (achievement) {
+ if (!achievement.achieved && cats.length >= achievement.threshold) {
+ achievement.achieved = true;
+ sparkles += achievement.reward;
+ totalSparklesEarned += achievement.reward;
+ showAchievement("Cat Collector", "Owned " + achievement.threshold + " cats", achievement.reward);
+ }
+ });
}
- });
+ }
}
function checkLevelUp() {
var newLevel = Math.floor(Math.log(totalSparklesEarned / 100 + 1) / Math.log(1.5)) + 1;
if (newLevel > playerLevel) {
- var oldLevel = playerLevel;
+ // Store previous level for potential use
playerLevel = newLevel;
levelMultiplier = 1 + (playerLevel - 1) * 0.1;
showAchievement("Level Up!", "You reached level " + playerLevel, playerLevel * 50);
sparkles += playerLevel * 50;
@@ -1284,14 +1532,9 @@
}
}
function initSparklePool() {
for (var i = 0; i < maxSparkles; i++) {
- var sparkle = new Container();
- sparkle.attachAsset('sparkle', {
- anchorX: 0.5,
- anchorY: 0.5,
- scale: 0.5
- });
+ var sparkle = new Sparkle();
sparkle.visible = false;
sparklePool.push(sparkle);
game.addChild(sparkle);
}
@@ -1409,18 +1652,21 @@
// Update all UI elements
updateUIElements();
}
function updateGameElements() {
+ // Update cats
cats.forEach(function (cat) {
if (cat && typeof cat.update === 'function') {
cat.update();
}
});
+ // Update kittens
kittens.forEach(function (kitten) {
if (kitten && typeof kitten.update === 'function') {
kitten.update();
}
});
+ // Update birds
for (var i = birds.length - 1; i >= 0; i--) {
var bird = birds[i];
if (bird && typeof bird.update === 'function') {
bird.update();
@@ -1429,8 +1675,9 @@
game.removeChild(bird);
birds.splice(i, 1);
}
}
+ // Update UFOs
for (var i = ufos.length - 1; i >= 0; i--) {
var ufo = ufos[i];
if (ufo && typeof ufo.update === 'function') {
ufo.update();
@@ -1439,8 +1686,9 @@
game.removeChild(ufo);
ufos.splice(i, 1);
}
}
+ // Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (powerUp && typeof powerUp.update === 'function') {
powerUp.update();
@@ -1449,59 +1697,93 @@
game.removeChild(powerUp);
powerUps.splice(i, 1);
}
}
+ // Update sparkles
+ for (var i = 0; i < sparklePool.length; i++) {
+ var sparkle = sparklePool[i];
+ if (sparkle && sparkle.visible && typeof sparkle.update === 'function') {
+ sparkle.update();
+ }
+ }
+ // Spawn new birds based on level
if (Math.random() < 0.01 * (1 + playerLevel * 0.1)) {
var bird = new Bird();
bird.x = 2048 + 100;
bird.y = 1500 + Math.random() * 800;
game.addChild(bird);
birds.push(bird);
}
+ // Spawn UFOs every 5 levels
if (playerLevel % 5 === 0 && Math.random() < 0.005) {
var ufo = new UFO();
ufo.x = 2048 + 100;
ufo.y = 1200 + Math.random() * 1000;
game.addChild(ufo);
ufos.push(ufo);
}
+ // Spawn power-ups occasionally
if (Math.random() < 0.002 * (1 + playerLevel * 0.05)) {
spawnPowerUp();
}
+ // Run the cat defense system
+ catDefenseSystem();
}
-function addCat() {
+function addCat(x, y) {
+ if (x === undefined || y === undefined) {
+ x = Math.random() * (2048 - 200) + 100;
+ y = Math.random() * (2732 - 200) + 100;
+ }
if (sparkles >= upgrades.catCost) {
sparkles -= upgrades.catCost;
- var cat = new Cat(Math.random() * (game.width - 200) + 100, Math.random() * (game.height - 200) + 100, 1);
+ var cat = new Cat();
+ cat.x = x;
+ cat.y = y;
cats.push(cat);
game.addChild(cat);
upgrades.catCost = Math.floor(upgrades.catCost * upgrades.catMultiplier);
checkAchievements();
- return true;
+ showNotification("New Cat", "A new cat has joined your garden!");
+ return cat;
+ } else {
+ showNotification("Not Enough Sparkles", "You need " + Math.floor(upgrades.catCost) + " sparkles to buy a cat.");
+ return false;
}
- return false;
}
-function addKitten() {
- if (sparkles >= 30) {
- // Assuming 30 sparkles cost based on BRIEF.md
- sparkles -= 30;
- var kitten = new Kitten(Math.random() * (game.width - 200) + 100, Math.random() * (game.height - 200) + 100, 1);
+function addKitten(x, y) {
+ if (x === undefined || y === undefined) {
+ x = Math.random() * (2048 - 200) + 100;
+ y = Math.random() * (2732 - 200) + 100;
+ }
+ var kittenCost = 30; // Base cost for a kitten
+ if (sparkles >= kittenCost) {
+ sparkles -= kittenCost;
+ var kitten = new Kitten();
+ kitten.x = x;
+ kitten.y = y;
kittens.push(kitten);
game.addChild(kitten);
checkAchievements();
- return true;
+ showNotification("New Kitten", "A new kitten has joined your garden!");
+ return kitten;
+ } else {
+ showNotification("Not Enough Sparkles", "You need " + kittenCost + " sparkles to buy a kitten.");
+ return false;
}
- return false;
}
function spawnBird() {
- var bird = new Bird(game.width + 50, Math.random() * (game.height - 100) + 50);
+ var bird = new Bird();
+ bird.x = 2048 + 100;
+ bird.y = 1500 + Math.random() * 800;
birds.push(bird);
game.addChild(bird);
return bird;
}
function spawnUFO() {
if (playerLevel % 5 === 0 && ufos.length < 3) {
- var ufo = new UFO(game.width + 100, Math.random() * (game.height - 150) + 75);
+ var ufo = new UFO();
+ ufo.x = 2048 + 100;
+ ufo.y = 1200 + Math.random() * 1000;
ufos.push(ufo);
game.addChild(ufo);
return ufo;
}
@@ -1509,49 +1791,54 @@
}
function spawnPowerUp() {
if (Math.random() < 0.05 * (1 + playerLevel * 0.02)) {
var type = Math.random() < 0.5 ? 'speed' : 'attack';
- var powerUp = new PowerUp(Math.random() * (game.width - 100) + 50, Math.random() * (game.height - 100) + 50, type);
+ var powerUp = new PowerUp(type);
+ powerUp.x = Math.random() * (2048 - 200) + 100;
+ powerUp.y = Math.random() * (2732 - 200) + 100;
powerUps.push(powerUp);
game.addChild(powerUp);
return powerUp;
}
return null;
}
-function createSparkleEffect(x, y) {
- // Get a sparkle from the pool or create a new one
- var sparkle = null;
- for (var i = 0; i < sparklePool.length; i++) {
- if (!sparklePool[i].visible) {
- sparkle = sparklePool[i];
- break;
+function createSparkleEffect(x, y, color, count) {
+ color = color || 0xFFFFFF;
+ count = count || 5;
+ for (var c = 0; c < count; c++) {
+ // Get a sparkle from the pool or create a new one
+ var sparkle = null;
+ for (var i = 0; i < sparklePool.length; i++) {
+ if (!sparklePool[i].visible) {
+ sparkle = sparklePool[i];
+ break;
+ }
}
- }
- if (!sparkle) {
- if (sparklePool.length < maxSparkles) {
- sparkle = new Sparkle();
- sparklePool.push(sparkle);
- game.addChild(sparkle);
- } else {
- // Reuse the oldest sparkle
- sparkle = sparklePool[0];
- sparklePool.push(sparklePool.shift());
+ if (!sparkle) {
+ if (sparklePool.length < maxSparkles) {
+ sparkle = new Sparkle();
+ sparklePool.push(sparkle);
+ game.addChild(sparkle);
+ } else {
+ // Reuse the oldest sparkle
+ sparkle = sparklePool[0];
+ sparklePool.push(sparklePool.shift());
+ }
}
+ // Set up the sparkle
+ sparkle.x = x + (Math.random() - 0.5) * 20;
+ sparkle.y = y + (Math.random() - 0.5) * 20;
+ sparkle.vx = (Math.random() - 0.5) * 3;
+ sparkle.vy = (Math.random() - 0.5) * 3 - 2; // Bias upward
+ sparkle.alpha = 1;
+ sparkle.visible = true;
+ sparkle.children[0].tint = color;
+ // Play a sound occasionally
+ if (c === 0 && Math.random() < 0.2 && sounds.length > 0) {
+ var soundIndex = Math.floor(Math.random() * sounds.length);
+ LK.getSound(sounds[soundIndex]).play();
+ }
}
- // Set up the sparkle
- sparkle.x = x;
- sparkle.y = y;
- sparkle.vx = (Math.random() - 0.5) * 3;
- sparkle.vy = (Math.random() - 0.5) * 3 - 2; // Bias upward
- sparkle.alpha = 1;
- sparkle.visible = true;
- // Animate the sparkle
- var tween = new TWEEN.Tween(sparkle).to({
- alpha: 0,
- y: sparkle.y - 20
- }, 1000).onComplete(function () {
- sparkle.visible = false;
- }).start();
}
function updateGameMechanics() {
// Auto-collect sparkles based on rate
sparkles += autoSparkleRate * levelMultiplier / 60;
an orange and white cat facing away from the camera. the cat is sitting straight up and looking up, ready to pounce. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
remove black box
fluffy translucent cloud. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
bright sun with wincing cartoon face and a black eye. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a goofy ufo. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
red gaming reticle. Minimal. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
sunny day, hilly landscape. there is an alien invasion taking place in the distance. cities burning.
large AUTUMN SHADES tree with sparse bunches of leaves. branches are exposed, but the tree is tough and old.. true-color, realistic, Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
glowing orange sphere. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
sideway view of a fighter jet. . . In-Game 2d asset. transparent background. horizontal. No shadows.
shiny purple and black attack ufo.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows