/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Base = Container.expand(function (type) { var self = Container.call(this); self.type = type; // 'dog' or 'cat' self.health = 100; self.maxHealth = 100; self.isDestroyed = false; var baseGraphics = self.attachAsset(type === 'dog' ? 'dogBase' : 'catBase', { anchorX: 0.5, anchorY: 0.5 }); self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0 && !self.isDestroyed) { self.destroy(); } }; self.destroy = function () { self.isDestroyed = true; // If dog base is destroyed, stop boss music, play death sound, and kill superstronggoldendogform if (self.type === 'dog') { LK.stopMusic(); // Only play death sound if superstronggoldendogform is actually spawned if (superstrongBosses.length > 0) { LK.getSound('Superstronggoldendogformdies').play(); } // Make cats back up toward cat base so people can see the superstronggoldendogformdie for (var i = cats.length - 1; i >= 0; i--) { var cat = cats[i]; // Calculate direction toward cat base var dx = catBaseObj.x - cat.x; var dy = catBaseObj.y - cat.y; var distance = Math.sqrt(dx * dx + dy * dy); // Move cats partway toward cat base (about 300 pixels closer) var moveDistance = Math.min(300, distance * 0.7); var targetX = cat.x + dx / distance * moveDistance; var targetY = cat.y + dy / distance * moveDistance; tween(cat, { x: targetX, y: targetY }, { duration: 1000, easing: tween.easeOut }); } // Kill any existing Superstronggoldendogform bosses for (var i = 0; i < superstrongBosses.length; i++) { var boss = superstrongBosses[i]; if (boss && !boss.isDying) { // Change to death sprite boss.attachAsset('Superstronggoldendogformdie', { anchorX: 0.5, anchorY: 0.5, scaleX: 6.0, scaleY: 6.0 }); // Make boss disappear after short delay tween(boss, { alpha: 0 }, { duration: 2000, onFinish: function onFinish() { // Remove health elements if (boss.healthBar) { boss.healthBar.destroy(); } if (boss.healthBarBack) { boss.healthBarBack.destroy(); } if (boss.healthText) { boss.healthText.destroy(); } boss.destroy(); // Remove from array var bossIndex = superstrongBosses.indexOf(boss); if (bossIndex > -1) { superstrongBosses.splice(bossIndex, 1); } } }); } } } // Fade out animation tween(self, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { if (self.type === 'dog') { gameState = 'catsWin'; showMessage('Cats Win!'); } else { gameState = 'dogsWin'; showMessage('Dogs Win!'); } } }); }; return self; }); var Cat = Container.expand(function (isLambo) { var self = Container.call(this); self.isLambo = isLambo || false; self.health = 50; self.speed = self.isLambo ? 3 : 1.5; self.target = null; self.lastAttackTime = 0; self.lastMoveTime = 0; var catGraphics = self.attachAsset(self.isLambo ? 'lamboCat' : 'normalCat', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // Lambo cats have movement cooldown if (self.isLambo && LK.ticks - self.lastMoveTime < 120) { return; } // Normal cats no longer spawn irongolemhelper automatically // First check for nearby iron golems to avoid var avoidanceForceX = 0; var avoidanceForceY = 0; var avoidanceRadius = 150; // Distance to start avoiding iron golems for (var i = 0; i < ironGolems.length; i++) { var golem = ironGolems[i]; var dx = golem.x - self.x; var dy = golem.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // If within avoidance radius, add avoidance force if (distance < avoidanceRadius && distance > 0) { var avoidanceStrength = (avoidanceRadius - distance) / avoidanceRadius; avoidanceForceX -= dx / distance * avoidanceStrength * 3; avoidanceForceY -= dy / distance * avoidanceStrength * 3; } } // Move towards nearest dog or dog base, but only if not avoiding iron golems var nearestTarget = null; var nearestDistance = Infinity; // Only look for dogs to attack, not iron golems for (var i = 0; i < dogs.length; i++) { var dog = dogs[i]; var dx = dog.x - self.x; var dy = dog.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = dog; } } var moveX = 0; var moveY = 0; if (nearestTarget) { // Move towards nearest dog var dx = nearestTarget.x - self.x; var dy = nearestTarget.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { moveX = dx / distance * self.speed; moveY = dy / distance * self.speed; } // Attack if close enough if (distance < 50 && LK.ticks - self.lastAttackTime > 60) { self.attack(nearestTarget); self.lastAttackTime = LK.ticks; } } else if (dogBaseObj && !dogBaseObj.isDestroyed) { // Move towards dog base if no dogs present var dx = dogBaseObj.x - self.x; var dy = dogBaseObj.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 50) { moveX = dx / distance * self.speed; moveY = dy / distance * self.speed; } else if (LK.ticks - self.lastAttackTime > 60) { // Attack the base dogBaseObj.takeDamage(5); self.lastAttackTime = LK.ticks; LK.getSound('battle').play(); } } // Apply movement with avoidance force if (moveX !== 0 || moveY !== 0 || avoidanceForceX !== 0 || avoidanceForceY !== 0) { self.x += moveX + avoidanceForceX; self.y += moveY + avoidanceForceY; if (self.isLambo) { self.lastMoveTime = LK.ticks; } } }; self.attack = function (target) { if (target.takeDamageFromCat) { // Attacking an iron golem or boss // 10% chance to accidentally hit the irongolemhelper if (Math.random() < 0.1 && target.killCat) { // IronGolemHelper kills the cat target.killCat(self); return; } target.takeDamageFromCat(); } else { // Attacking a dog if (self.isLambo) { // Lambo cats can kill any dog self.killDog(target); } else { // Check for group attack on golden dogs if (target.isGolden) { var nearbyCats = self.countNearbyCats(); if (nearbyCats >= 9) { self.killDog(target); } } else { target.takeDamage(8); // Cats deal 8 damage to dogs } } } LK.getSound('battle').play(); }; self.countNearbyCats = function () { var count = 0; for (var i = 0; i < cats.length; i++) { var cat = cats[i]; var dx = cat.x - self.x; var dy = cat.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 100) { count++; } } return count; }; self.killDog = function (dog) { if (dog.isDying) return; // Don't kill if dog is already dying // Check if dog is also trying to kill this cat at the same time var simultaneousKill = false; if (dog.target === self || dog.lastAttackTime === LK.ticks) { simultaneousKill = true; } if (simultaneousKill) { // Both are killing each other - apply survival chances var catSurvives = Math.random() < 0.15; // 15% chance cat survives var dogSurvives = Math.random() < 0.18; // 18% chance dog survives if (catSurvives && !dogSurvives) { // Only cat survives var dogIndex = dogs.indexOf(dog); if (dogIndex > -1) { dogs.splice(dogIndex, 1); dog.die(); } } else if (dogSurvives && !catSurvives) { // Only dog survives self.die(); } else if (!catSurvives && !dogSurvives) { // Both die var dogIndex = dogs.indexOf(dog); if (dogIndex > -1) { dogs.splice(dogIndex, 1); dog.die(); } self.die(); } // If both survive, neither dies } else { // Cat kills dog, then cat dies too var dogIndex = dogs.indexOf(dog); if (dogIndex > -1) { dogs.splice(dogIndex, 1); dog.die(); } // Cat dies after killing the dog self.die(); } }; self.killCat = function (cat) { if (cat.isDying) return; // Don't kill if cat is already dying // Cats don't die when killing other cats - do nothing }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.die(); } }; self.die = function (fromFallDamage) { if (self.isDying) return; // Prevent multiple death calls self.isDying = true; // Never lose money when cats die - keep it permanently moneyText.setText(playerMoney + '¢'); var catIndex = cats.indexOf(self); if (catIndex > -1) { cats.splice(catIndex, 1); } // Store original position for underground state self.originalY = self.y; // First turn red, then wait 0.63 seconds, then sink underground tween(self, { tint: 0xff0000 }, { duration: 630, onFinish: function onFinish() { // Stop being red and go underground tween(self, { tint: 0xFFFFFF, y: self.y + 500, scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, onFinish: function onFinish() { self.isUnderground = true; } }); } }); // Don't allow movement underground self.update = function () { // Do nothing - can't move when underground }; }; self.down = function (x, y, obj) { if (self.isUnderground) { // Fly into the sky tween(self, { y: self.y - 800, rotation: Math.PI * 2 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Explode effect (flash red briefly) tween(self, { tint: 0xff0000, scaleX: self.scaleX * 2, scaleY: self.scaleY * 2, alpha: 0.5 }, { duration: 200, onFinish: function onFinish() { // Drop random coin (1¢, 50¢, or 100¢) var coinValues = [1, 50, 100]; var randomValue = coinValues[Math.floor(Math.random() * coinValues.length)]; var coin = new SmallRandomCoin(randomValue); coin.x = self.x; coin.y = self.y; droppedCoins.push(coin); game.addChild(coin); LK.getSound('coinCollect').play(); self.destroy(); } }); } }); } }; return self; }); var Cloud = Container.expand(function () { var self = Container.call(this); self.speed = 2; // Move left at 2 pixels per frame var cloudGraphics = self.attachAsset('Cloud', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.update = function () { // Move left continuously self.x -= self.speed; // Remove cloud if it goes off the left side of screen if (self.x < -100) { var cloudIndex = clouds.indexOf(self); if (cloudIndex > -1) { clouds.splice(cloudIndex, 1); } self.destroy(); } }; return self; }); var Coin = Container.expand(function () { var self = Container.call(this); self.value = 50; self.canAttack = false; // Coins cannot attack cats or dogs var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 6, scaleY: 6 }); self.down = function (x, y, obj) { // Collect coin based on its value var coinValue = self.value; if (self.value === 100) { // 100¢ coin has chance for extra 20¢ if (Math.random() < 0.2) { // 20% chance for extra coinValue += 20; } } playerMoney += coinValue; moneyText.setText(playerMoney + '¢'); var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } LK.getSound('coinCollect').play(); self.destroy(); }; return self; }); var Cuteuwudog = Container.expand(function () { var self = Container.call(this); self.health = 1; self.speed = 2.5; self.target = null; self.lastAttackTime = 0; var dogGraphics = self.attachAsset('Cuteuwudog', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.0, scaleY: 3.0 }); self.update = function () { // Move towards nearest cat or cat base var nearestTarget = null; var nearestDistance = Infinity; // Check cats for (var i = 0; i < cats.length; i++) { var cat = cats[i]; var dx = cat.x - self.x; var dy = cat.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = cat; } } if (nearestTarget) { // Move towards nearest cat var dx = nearestTarget.x - self.x; var dy = nearestTarget.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Attack if close enough if (distance < 50 && LK.ticks - self.lastAttackTime > 60) { self.attack(nearestTarget); self.lastAttackTime = LK.ticks; } } else if (catBaseObj && !catBaseObj.isDestroyed) { // Move towards cat base if no cats present var dx = catBaseObj.x - self.x; var dy = catBaseObj.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 50) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } else if (LK.ticks - self.lastAttackTime > 60) { // Attack the base catBaseObj.takeDamage(5); self.lastAttackTime = LK.ticks; LK.getSound('battle').play(); } } }; self.attack = function (target) { // Cuteuwudog instantly kills cats self.killCat(target); LK.getSound('battle').play(); }; self.killCat = function (cat) { if (cat.isDying) return; var catIndex = cats.indexOf(cat); if (catIndex > -1) { cats.splice(catIndex, 1); cat.die(); } // Cuteuwudog dies after killing the cat self.die(); }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.die(); } }; self.die = function () { if (self.isDying) return; self.isDying = true; // Drop coins when dying self.dropCoins(); var dogIndex = cuteuwudogs.indexOf(self); if (dogIndex > -1) { cuteuwudogs.splice(dogIndex, 1); } // Store original position for underground state self.originalY = self.y; // First turn red, then wait 0.63 seconds, then sink underground tween(self, { tint: 0xff0000 }, { duration: 630, onFinish: function onFinish() { // Stop being red and go underground tween(self, { tint: 0xFFFFFF, y: self.y + 500, scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, onFinish: function onFinish() { self.isUnderground = true; } }); } }); // Don't allow movement underground self.update = function () { // Do nothing - can't move when underground }; }; self.dropCoins = function () { // Drop single coin - similar to regular dogs var coin = new Coin(); coin.x = self.x + (Math.random() - 0.5) * 100; coin.y = self.y + (Math.random() - 0.5) * 100; if (Math.random() < 0.05) { coin.value = 100; } else { coin.value = 50; } droppedCoins.push(coin); game.addChild(coin); }; self.down = function (x, y, obj) { if (self.isUnderground) { // Fly into the sky tween(self, { y: self.y - 800, rotation: Math.PI * 2 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Explode effect (flash red briefly) tween(self, { tint: 0xff0000, scaleX: self.scaleX * 2, scaleY: self.scaleY * 2, alpha: 0.5 }, { duration: 200, onFinish: function onFinish() { // Drop random coin (1¢, 50¢, or 100¢) var coinValues = [1, 50, 100]; var randomValue = coinValues[Math.floor(Math.random() * coinValues.length)]; var coin = new SmallRandomCoin(randomValue); coin.x = self.x; coin.y = self.y; droppedCoins.push(coin); game.addChild(coin); LK.getSound('coinCollect').play(); self.destroy(); } }); } }); } }; return self; }); var Dog = Container.expand(function (isGolden) { var self = Container.call(this); self.isGolden = isGolden || false; self.health = 54; self.speed = 2; self.target = null; self.lastAttackTime = 0; var dogGraphics = self.attachAsset(self.isGolden ? 'goldenDog' : 'normalDog', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // Move towards nearest cat, iron golem, or cat base var nearestTarget = null; var nearestDistance = Infinity; // Check cats for (var i = 0; i < cats.length; i++) { var cat = cats[i]; var dx = cat.x - self.x; var dy = cat.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = cat; } } // Check iron golems for (var i = 0; i < ironGolems.length; i++) { var golem = ironGolems[i]; var dx = golem.x - self.x; var dy = golem.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = golem; } } var nearestCat = nearestTarget; if (nearestCat) { // Move towards nearest cat var dx = nearestCat.x - self.x; var dy = nearestCat.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Attack if close enough if (distance < 50 && LK.ticks - self.lastAttackTime > 60) { self.attack(nearestCat); self.lastAttackTime = LK.ticks; } } else if (catBaseObj && !catBaseObj.isDestroyed) { // Move towards cat base if no cats present var dx = catBaseObj.x - self.x; var dy = catBaseObj.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 50) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } else if (LK.ticks - self.lastAttackTime > 60) { // Attack the base catBaseObj.takeDamage(5); self.lastAttackTime = LK.ticks; LK.getSound('battle').play(); } } }; self.attack = function (target) { if (target.takeDamageFromDog) { // Attacking an iron golem or boss target.takeDamageFromDog(self); } else { // Attacking a cat if (self.isGolden) { // Golden dogs deal 10 damage to cats if (target.takeDamage) { target.takeDamage(10); } else { self.killCat(target); } } else { // Dogs deal 8 damage to cats target.takeDamage(8); } } LK.getSound('battle').play(); }; self.killCat = function (cat) { if (cat.isDying) return; // Don't kill if cat is already dying // Check if cat is also trying to kill this dog at the same time var simultaneousKill = false; if (cat.target === self || cat.lastAttackTime === LK.ticks) { simultaneousKill = true; } if (simultaneousKill) { // Both are killing each other - apply survival chances var catSurvives = Math.random() < 0.15; // 15% chance cat survives var dogSurvives = Math.random() < 0.18; // 18% chance dog survives if (catSurvives && !dogSurvives) { // Only cat survives self.die(); } else if (dogSurvives && !catSurvives) { // Only dog survives var catIndex = cats.indexOf(cat); if (catIndex > -1) { cats.splice(catIndex, 1); cat.die(); } } else if (!catSurvives && !dogSurvives) { // Both die var catIndex = cats.indexOf(cat); if (catIndex > -1) { cats.splice(catIndex, 1); cat.die(); } self.die(); } // If both survive, neither dies } else { // Dog kills cat, then dog dies too var catIndex = cats.indexOf(cat); if (catIndex > -1) { cats.splice(catIndex, 1); cat.die(); } // Dog dies after killing the cat self.die(); } }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.die(); } }; self.die = function () { if (self.isDying) return; // Prevent multiple death calls self.isDying = true; // All dogs drop coins when they die self.dropCoins(); var dogIndex = dogs.indexOf(self); if (dogIndex > -1) { dogs.splice(dogIndex, 1); } // Store original position for underground state self.originalY = self.y; // First turn red, then wait 0.63 seconds, then sink underground tween(self, { tint: 0xff0000 }, { duration: 630, onFinish: function onFinish() { // Stop being red and go underground tween(self, { tint: 0xFFFFFF, y: self.y + 500, scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, onFinish: function onFinish() { self.isUnderground = true; } }); } }); // Don't allow movement underground self.update = function () { // Do nothing - can't move when underground }; }; self.dropCoins = function () { // Drop single coin - 5% chance for 100¢ coin, otherwise 50¢ var coin = new Coin(); coin.x = self.x + (Math.random() - 0.5) * 100; coin.y = self.y + (Math.random() - 0.5) * 100; // 5% chance for 100¢ coin if (Math.random() < 0.05) { coin.value = 100; } else { coin.value = 50; } droppedCoins.push(coin); game.addChild(coin); }; self.down = function (x, y, obj) { if (self.isUnderground) { // Fly into the sky tween(self, { y: self.y - 800, rotation: Math.PI * 2 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Explode effect (flash red briefly) tween(self, { tint: 0xff0000, scaleX: self.scaleX * 2, scaleY: self.scaleY * 2, alpha: 0.5 }, { duration: 200, onFinish: function onFinish() { // Drop random coin (1¢, 50¢, or 100¢) var coinValues = [1, 50, 100]; var randomValue = coinValues[Math.floor(Math.random() * coinValues.length)]; var coin = new SmallRandomCoin(randomValue); coin.x = self.x; coin.y = self.y; droppedCoins.push(coin); game.addChild(coin); LK.getSound('coinCollect').play(); self.destroy(); } }); } }); } }; return self; }); // Game code is already saved and preserved var DogwithTophat = Container.expand(function () { var self = Container.call(this); self.health = 1; self.speed = 2; self.target = null; self.lastAttackTime = 0; var dogGraphics = self.attachAsset('Dogwothtophat', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.2, scaleY: 3.0 }); self.update = function () { // Move towards nearest cat or cat base var nearestTarget = null; var nearestDistance = Infinity; // Check cats for (var i = 0; i < cats.length; i++) { var cat = cats[i]; var dx = cat.x - self.x; var dy = cat.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = cat; } } if (nearestTarget) { // Move towards nearest cat var dx = nearestTarget.x - self.x; var dy = nearestTarget.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Attack if close enough if (distance < 50 && LK.ticks - self.lastAttackTime > 60) { self.attack(nearestTarget); self.lastAttackTime = LK.ticks; } } else if (catBaseObj && !catBaseObj.isDestroyed) { // Move towards cat base if no cats present var dx = catBaseObj.x - self.x; var dy = catBaseObj.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 50) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } else if (LK.ticks - self.lastAttackTime > 60) { // Attack the base catBaseObj.takeDamage(5); self.lastAttackTime = LK.ticks; LK.getSound('battle').play(); } } }; self.attack = function (target) { if (target.takeDamage) { // Deal 6 damage to target target.takeDamage(6); } else { // DogwithTophat kills cats like normal dogs self.killCat(target); } LK.getSound('battle').play(); }; self.killCat = function (cat) { if (cat.isDying) return; var catIndex = cats.indexOf(cat); if (catIndex > -1) { cats.splice(catIndex, 1); cat.die(); } // DogwithTophat dies after killing the cat self.die(); }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.die(); } }; self.die = function () { if (self.isDying) return; self.isDying = true; // Drop coins when dying self.dropCoins(); var dogIndex = dogs.indexOf(self); if (dogIndex > -1) { dogs.splice(dogIndex, 1); } // Store original position for underground state self.originalY = self.y; // First turn red, then wait 0.63 seconds, then sink underground tween(self, { tint: 0xff0000 }, { duration: 630, onFinish: function onFinish() { // Stop being red and go underground tween(self, { tint: 0xFFFFFF, y: self.y + 500, scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, onFinish: function onFinish() { self.isUnderground = true; } }); } }); // Don't allow movement underground self.update = function () { // Do nothing - can't move when underground }; }; self.dropCoins = function () { // Drop single coin var coin = new Coin(); coin.x = self.x + (Math.random() - 0.5) * 100; coin.y = self.y + (Math.random() - 0.5) * 100; if (Math.random() < 0.05) { coin.value = 100; } else { coin.value = 50; } droppedCoins.push(coin); game.addChild(coin); }; self.down = function (x, y, obj) { if (self.isUnderground) { // Fly into the sky tween(self, { y: self.y - 800, rotation: Math.PI * 2 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Explode effect (flash red briefly) tween(self, { tint: 0xff0000, scaleX: self.scaleX * 2, scaleY: self.scaleY * 2, alpha: 0.5 }, { duration: 200, onFinish: function onFinish() { // Drop random coin (1¢, 50¢, or 100¢) var coinValues = [1, 50, 100]; var randomValue = coinValues[Math.floor(Math.random() * coinValues.length)]; var coin = new SmallRandomCoin(randomValue); coin.x = self.x; coin.y = self.y; droppedCoins.push(coin); game.addChild(coin); LK.getSound('coinCollect').play(); self.destroy(); } }); } }); } }; return self; }); var IronGolemBoss = Container.expand(function () { var self = Container.call(this); self.health = 293; self.maxHealth = 293; self.speed = 1.5; self.target = null; self.lastAttackTime = 0; self.lastComfortCheck = 0; self.comfortThreshold = 3; // Gets uncomfortable with 3+ cats nearby var bossGraphics = self.attachAsset('Irongolemboss', { anchorX: 0.5, anchorY: 0.5, scaleX: 5.5, scaleY: 5.5 }); self.update = function () { // Check comfort level every 60 ticks (1 second) if (LK.ticks - self.lastComfortCheck > 60) { self.checkComfortLevel(); self.lastComfortCheck = LK.ticks; } // Move towards nearest dog or dog base var nearestTarget = null; var nearestDistance = Infinity; // Check superstronggoldendogform bosses first for (var i = 0; i < superstrongBosses.length; i++) { var boss = superstrongBosses[i]; var dx = boss.x - self.x; var dy = boss.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = boss; } } // Check dogs if no boss found if (!nearestTarget) { for (var i = 0; i < dogs.length; i++) { var dog = dogs[i]; var dx = dog.x - self.x; var dy = dog.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = dog; } } } if (nearestTarget) { // Move towards nearest target var dx = nearestTarget.x - self.x; var dy = nearestTarget.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Attack if close enough if (distance < 70 && LK.ticks - self.lastAttackTime > 60) { self.attack(nearestTarget); self.lastAttackTime = LK.ticks; } } else if (dogBaseObj && !dogBaseObj.isDestroyed) { // Move towards dog base if no targets present var dx = dogBaseObj.x - self.x; var dy = dogBaseObj.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 70) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } else if (LK.ticks - self.lastAttackTime > 60) { // Attack the base dogBaseObj.takeDamage(590); self.lastAttackTime = LK.ticks; LK.getSound('battle').play(); } } }; self.attack = function (target) { // Check if attacking superstronggoldendogform var isSuperstrongBoss = superstrongBosses.indexOf(target) > -1; if (isSuperstrongBoss) { // Deal 590 damage and slightly throw into sky target.health -= 590; // Throw superstronggoldendogform slightly into sky (1 inch = ~25 pixels) tween(target, { y: target.y - 25 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Fall back down tween(target, { y: target.y + 25 }, { duration: 300, easing: tween.easeIn }); } }); // Check if superstronggoldendogform dies (takes 5 hits to kill) if (target.health <= 0) { // Play death sound LK.getSound('Superstronggoldendogformdies').play(); // Change to death sprite target.attachAsset('Superstronggoldendogformdie', { anchorX: 0.5, anchorY: 0.5, scaleX: 6.0, scaleY: 6.0 }); // Make boss disappear after delay tween(target, { alpha: 0 }, { duration: 2000, onFinish: function onFinish() { // Remove health elements if (target.healthBar) { target.healthBar.destroy(); } if (target.healthBarBack) { target.healthBarBack.destroy(); } if (target.healthText) { target.healthText.destroy(); } target.destroy(); // Remove from array var bossIndex = superstrongBosses.indexOf(target); if (bossIndex > -1) { superstrongBosses.splice(bossIndex, 1); } } }); } } else { // Attacking dogs - throw them off screen self.throwOffScreen(target); } LK.getSound('battle').play(); }; self.throwOffScreen = function (target) { // Throw target off screen var throwDirection = Math.random() < 0.5 ? -1 : 1; // Left or right var offScreenX = throwDirection > 0 ? 2148 : -100; // Off screen position tween(target, { x: offScreenX, y: target.y - 300, rotation: Math.PI * 2 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Remove from appropriate array and destroy var dogIndex = dogs.indexOf(target); if (dogIndex > -1) { dogs.splice(dogIndex, 1); } var cuteIndex = cuteuwudogs.indexOf(target); if (cuteIndex > -1) { cuteuwudogs.splice(cuteIndex, 1); } target.destroy(); } }); }; self.checkComfortLevel = function () { // Count nearby cats within 200 pixel radius var nearbyCats = []; for (var i = 0; i < cats.length; i++) { var cat = cats[i]; var dx = cat.x - self.x; var dy = cat.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { nearbyCats.push(cat); } } // If too many cats nearby, get uncomfortable and throw them out if (nearbyCats.length >= self.comfortThreshold) { var catsToThrow = Math.min(3, nearbyCats.length); // Throw up to 3 cats for (var j = 0; j < catsToThrow; j++) { var victimCat = nearbyCats[j]; self.throwOffScreen(victimCat); } } }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.die(); } }; self.die = function () { var bossIndex = ironGolemBosses.indexOf(self); if (bossIndex > -1) { ironGolemBosses.splice(bossIndex, 1); } // Stop iron golem boss music when boss dies LK.stopMusic(); // Turn red then disappear tween(self, { tint: 0xff0000 }, { duration: 500, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var IronGolemHelper = Container.expand(function () { var self = Container.call(this); self.health = 103; self.maxHealth = 103; self.speed = 1; self.target = null; self.lastAttackTime = 0; self.hitsTakenFromCats = 0; self.hitsTakenFromDogs = 0; self.lastComfortCheck = 0; self.comfortThreshold = 5; // Gets uncomfortable with 5+ cats nearby var golemGraphics = self.attachAsset('Irongolemhelper', { anchorX: 0.5, anchorY: 0.5, scaleX: 4.0, scaleY: 4.0 }); self.update = function () { // Check comfort level every 60 ticks (1 second) if (LK.ticks - self.lastComfortCheck > 60) { self.checkComfortLevel(); self.lastComfortCheck = LK.ticks; } // Move towards nearest dog or dog base var nearestDog = null; var nearestDistance = Infinity; for (var i = 0; i < dogs.length; i++) { var dog = dogs[i]; var dx = dog.x - self.x; var dy = dog.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestDog = dog; } } if (nearestDog) { // Move towards nearest dog var dx = nearestDog.x - self.x; var dy = nearestDog.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Attack if close enough if (distance < 50 && LK.ticks - self.lastAttackTime > 60) { self.attack(nearestDog); self.lastAttackTime = LK.ticks; } } else if (dogBaseObj && !dogBaseObj.isDestroyed) { // Move towards dog base if no dogs present var dx = dogBaseObj.x - self.x; var dy = dogBaseObj.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 50) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } else if (LK.ticks - self.lastAttackTime > 60) { // Attack the base dogBaseObj.takeDamage(5); self.lastAttackTime = LK.ticks; LK.getSound('battle').play(); } } }; self.attack = function (target) { if (target.takeDamageFromIronGolem) { // Attacking Superstronggoldendogform target.takeDamageFromIronGolem(self); } else if (target.takeDamage) { // Deal 45 damage to targets that can take damage target.takeDamage(45); } else { // Attacking a dog - instantly kill self.killDog(target); } LK.getSound('battle').play(); }; self.killDog = function (dog) { if (dog.isDying) return; // Don't kill if dog is already dying var dogIndex = dogs.indexOf(dog); if (dogIndex > -1) { dogs.splice(dogIndex, 1); dog.die(); } }; self.takeDamageFromCat = function () { self.health -= 8; // 8 damage per cat hit self.hitsTakenFromCats++; if (self.health <= 0) { self.die(); } }; self.takeDamageFromDog = function () { self.health -= 8; // 8 damage per dog hit self.hitsTakenFromDogs++; if (self.health <= 0) { self.die(); } }; self.killCat = function (cat) { if (cat.isDying) return; // Don't kill if cat is already dying var catIndex = cats.indexOf(cat); if (catIndex > -1) { cats.splice(catIndex, 1); cat.die(); } }; self.checkComfortLevel = function () { // Count nearby cats within 200 pixel radius var nearbyCats = []; for (var i = 0; i < cats.length; i++) { var cat = cats[i]; var dx = cat.x - self.x; var dy = cat.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { nearbyCats.push(cat); } } // If too many cats nearby, get uncomfortable and fling some if (nearbyCats.length >= self.comfortThreshold) { var catsToFling = Math.min(2, nearbyCats.length); // Fling up to 2 cats for (var j = 0; j < catsToFling; j++) { var victimCat = nearbyCats[j]; self.flingCat(victimCat); } } }; self.flingCat = function (cat) { // Store original position for fall back var originalY = cat.y; var flingHeight = -2000; // Fling SOOOOOOOOO high (2000 pixels up) var flingDirection = (Math.random() - 0.5) * 600; // Random horizontal fling // 25% chance to die immediately from iron golem fling if (Math.random() < 0.25) { cat.die(true); return; } // Fling cat up and sideways tween(cat, { x: cat.x + flingDirection, y: cat.y + flingHeight }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { // Stay in the air for 222ms before falling LK.setTimeout(function () { // Fall back down tween(cat, { y: originalY }, { duration: 1200, easing: tween.easeIn, onFinish: function onFinish() { // 25% chance to die from fall damage if (Math.random() < 0.25) { cat.die(true); } } }); }, 222); } }); }; self.die = function () { var golemIndex = ironGolems.indexOf(self); if (golemIndex > -1) { ironGolems.splice(golemIndex, 1); } // Turn red then disappear tween(self, { tint: 0xff0000 }, { duration: 500, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var IronIngot = Container.expand(function () { var self = Container.call(this); self.value = 34; var ingotGraphics = self.attachAsset('Ironingot', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.down = function (x, y, obj) { playerMoney += self.value; // Use the ingot's value (default 34, or 90 when dropped by boss) moneyText.setText(playerMoney + '¢'); var ingotIndex = droppedIngots.indexOf(self); if (ingotIndex > -1) { droppedIngots.splice(ingotIndex, 1); } LK.getSound('coinCollect').play(); self.destroy(); }; return self; }); var Small100Coin = Container.expand(function () { var self = Container.call(this); self.value = 100; self.fallSpeed = 3; var coinGraphics = self.attachAsset('100coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, // Small size scaleY: 1 }); self.update = function () { // Fall down self.y += self.fallSpeed; // Remove if fallen off screen if (self.y > 2732 + 50) { var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } self.destroy(); } }; self.down = function (x, y, obj) { playerMoney += 100; moneyText.setText(playerMoney + '¢'); var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } LK.getSound('coinCollect').play(); self.destroy(); }; return self; }); var Small50Coin = Container.expand(function () { var self = Container.call(this); self.value = 50; self.fallSpeed = 3; var coinGraphics = self.attachAsset('50coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, // Small size scaleY: 1 }); self.update = function () { // Fall down self.y += self.fallSpeed; // Remove if fallen off screen if (self.y > 2732 + 50) { var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } self.destroy(); } }; self.down = function (x, y, obj) { playerMoney += 50; moneyText.setText(playerMoney + '¢'); var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } LK.getSound('coinCollect').play(); self.destroy(); }; return self; }); var SmallRandomCoin = Container.expand(function (value) { var self = Container.call(this); self.value = value || 1; // Default to 1¢ self.fallSpeed = 3; // Choose appropriate asset based on value var assetId = '1coin'; if (value === 50) assetId = '50coin'; if (value === 100) assetId = '100coin'; var coinGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.update = function () { // Fall down until hitting grass level self.y += self.fallSpeed; // Stop falling when reaching grass level (around y = 2400) if (self.y >= 2400) { self.y = 2400; // Land on grass self.fallSpeed = 0; // Stop falling } // Remove if fallen off screen if (self.y > 2732 + 50) { var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } self.destroy(); } }; self.down = function (x, y, obj) { playerMoney += self.value; moneyText.setText(playerMoney + '¢'); var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } LK.getSound('coinCollect').play(); self.destroy(); }; return self; }); var Special100Coin = Container.expand(function () { var self = Container.call(this); self.value = 100; self.canAttack = false; var coinGraphics = self.attachAsset('100coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); self.down = function (x, y, obj) { playerMoney += 100; moneyText.setText(playerMoney + '¢'); var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } LK.getSound('coinCollect').play(); self.destroy(); }; return self; }); var Special1Coin = Container.expand(function () { var self = Container.call(this); self.value = 1; self.canAttack = false; var coinGraphics = self.attachAsset('1coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); self.down = function (x, y, obj) { playerMoney += 1; moneyText.setText(playerMoney + '¢'); var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } LK.getSound('coinCollect').play(); self.destroy(); }; return self; }); var Special3000Coin = Container.expand(function () { var self = Container.call(this); self.value = 3000; self.canAttack = false; var coinGraphics = self.attachAsset('3000coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 4, scaleY: 4 }); self.down = function (x, y, obj) { playerMoney += 3000; moneyText.setText(playerMoney + '¢'); var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } LK.getSound('coinCollect').play(); self.destroy(); }; return self; }); var Special50Coin = Container.expand(function () { var self = Container.call(this); self.value = 50; self.canAttack = false; var coinGraphics = self.attachAsset('50coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); self.down = function (x, y, obj) { playerMoney += 50; moneyText.setText(playerMoney + '¢'); var coinIndex = droppedCoins.indexOf(self); if (coinIndex > -1) { droppedCoins.splice(coinIndex, 1); } LK.getSound('coinCollect').play(); self.destroy(); }; return self; }); var Superstronggoldendogform = Container.expand(function () { var self = Container.call(this); self.health = 202; self.maxHealth = 202; self.speed = 1.5; self.target = null; self.lastAttackTime = 0; self.hitsTakenFromCats = 0; self.hitsTakenFromDogs = 0; self.isDying = false; self.attackCount = 0; // Track how many times it's been attacked self.spawnGoldenDogsThreshold = 200; // Spawn golden dogs after 200 attacks var bossGraphics = self.attachAsset('Superstronggoldendogform', { anchorX: 0.5, anchorY: 0.5, scaleX: 6.0, // Slightly bigger than irongolemhelper (4.0) scaleY: 6.0 }); // Create health bar background self.healthBarBack = LK.getAsset('Healthbarback', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.2, scaleY: 1.7, alpha: 0 }); // Create health bar that follows the boss self.healthBar = LK.getAsset('Superstronggoldendogformhealth', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.0, scaleY: 1.5 }); // Create health text showing 399 self.healthText = new Text2('399', { size: 40, fill: 0xFFFFFF }); self.healthText.anchor.set(0.5, 0.5); self.update = function () { // Update health bar background position self.healthBarBack.x = self.x; self.healthBarBack.y = self.y - 200; // Update health bar position to follow boss self.healthBar.x = self.x; self.healthBar.y = self.y - 200; // Position above the boss // Update health bar visibility based on health percentage var healthPercent = self.health / self.maxHealth; self.healthBar.alpha = 0.7 + healthPercent * 0.3; // Fade as health decreases // Update health text position and value self.healthText.x = self.x; self.healthText.y = self.y - 280; // Position above health bar self.healthText.setText(Math.max(0, self.health).toString()); // Move towards nearest cat or cat base var nearestTarget = null; var nearestDistance = Infinity; // Check cats for (var i = 0; i < cats.length; i++) { var cat = cats[i]; var dx = cat.x - self.x; var dy = cat.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = cat; } } if (nearestTarget) { // Move towards nearest cat var dx = nearestTarget.x - self.x; var dy = nearestTarget.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Attack if close enough if (distance < 80 && LK.ticks - self.lastAttackTime > 30) { self.attack(nearestTarget); self.lastAttackTime = LK.ticks; } } else if (catBaseObj && !catBaseObj.isDestroyed) { // Move towards cat base if no cats present var dx = catBaseObj.x - self.x; var dy = catBaseObj.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 80) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } else if (LK.ticks - self.lastAttackTime > 30) { // Attack the base catBaseObj.takeDamage(1000); self.lastAttackTime = LK.ticks; LK.getSound('battle').play(); } } }; self.attack = function (target) { // Find nearest target within large radius for mind power var nearestTarget = null; var nearestDistance = Infinity; // Check all cats for (var i = 0; i < cats.length; i++) { var cat = cats[i]; var dx = cat.x - self.x; var dy = cat.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = cat; } } // Check all iron golems for (var i = 0; i < ironGolems.length; i++) { var golem = ironGolems[i]; var dx = golem.x - self.x; var dy = golem.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = golem; } } // Use mind power to drag the nearest target (can be far away) if (nearestTarget) { self.mindPowerDrag(nearestTarget); } else { // Fallback to original target if no other targets found self.mindPowerDrag(target); } LK.getSound('battle').play(); }; self.mindPowerDrag = function (target) { // Check if target is an irongolemhelper var isIronGolem = ironGolems.indexOf(target) > -1; // Animate target being dragged into the ground with mind power // Target can be dragged from any distance tween(target, { y: target.y + 500, scaleX: target.scaleX * 0.3, scaleY: target.scaleY * 0.1 }, { duration: 2000, easing: tween.easeIn, onFinish: function onFinish() { // Special handling for irongolemhelper if (isIronGolem) { // Drop ironingot worth 90¢ var ironingot = new IronIngot(); ironingot.value = 90; // Override default value ironingot.x = target.x; ironingot.y = target.originalY || target.y - 500; droppedIngots.push(ironingot); game.addChild(ironingot); // Remove from ironGolems array var golemIndex = ironGolems.indexOf(target); if (golemIndex > -1) { ironGolems.splice(golemIndex, 1); } target.destroy(); } else { // After dragging, apply damage or kill for other targets if (target.takeDamage) { target.takeDamage(1000); } else if (target.die) { // Remove from appropriate array and kill if (cats.indexOf(target) > -1) { cats.splice(cats.indexOf(target), 1); } else if (dogs.indexOf(target) > -1) { dogs.splice(dogs.indexOf(target), 1); } target.die(); } } } }); }; self.takeDamageFromCat = function () { // Check if cats can defeat the boss var canDefeat = false; if (cats.length >= 30) { // 30 or more cats can instantly defeat the boss canDefeat = true; } else if (cats.length >= 20) { // 20 cats or more can defeat canDefeat = true; } else if (cats.length >= 10 && ironGolems.length >= 2) { // 10+ cats with 2+ iron golems can defeat canDefeat = true; } else if (cats.length >= 10) { // 10+ cats can instantly defeat the boss when it's strong canDefeat = true; } else if (cats.length >= 5 && ironGolems.length >= 2) { // 5+ cats with 2+ iron golems can defeat canDefeat = true; } else if (cats.length >= 3 && ironGolems.length >= 1) { // 3+ cats with 1+ iron golem can defeat canDefeat = true; } if (canDefeat) { self.health = 0; self.die(); return; } self.health -= 8; self.hitsTakenFromCats++; self.attackCount++; // Check if tired of getting attacked (spawn golden dogs) if (self.attackCount >= self.spawnGoldenDogsThreshold) { self.spawnGoldenDogs(); self.attackCount = 0; // Reset counter } if (self.health <= 0) { self.die(); } }; self.takeDamageFromIronGolem = function (ironGolem) { // Check if irongolem is at 3 health for special animation if (ironGolem && ironGolem.hitsTakenFromCats + ironGolem.hitsTakenFromDogs >= 20) { // Special grab, toss, and step animation var originalY = ironGolem.y; // Grab and toss in the air tween(ironGolem, { y: ironGolem.y - 300, rotation: Math.PI * 2 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Fall back down tween(ironGolem, { y: originalY, rotation: 0 }, { duration: 800, easing: tween.easeIn, onFinish: function onFinish() { // Superstronggoldendogform steps on irongolemhelper tween(ironGolem, { scaleX: ironGolem.scaleX * 0.3, scaleY: ironGolem.scaleY * 0.1, alpha: 0.5 }, { duration: 500, onFinish: function onFinish() { // Drop ironingot var ironingot = new IronIngot(); ironingot.x = ironGolem.x; ironingot.y = ironGolem.y; droppedIngots.push(ironingot); game.addChild(ironingot); // Remove irongolem var golemIndex = ironGolems.indexOf(ironGolem); if (golemIndex > -1) { ironGolems.splice(golemIndex, 1); } ironGolem.destroy(); } }); } }); } }); } else { var damage = 45; // 45 damage from iron golem self.health -= damage; self.attackCount++; // Check if tired of getting attacked (spawn golden dogs) if (self.attackCount >= self.spawnGoldenDogsThreshold) { self.spawnGoldenDogs(); self.attackCount = 0; // Reset counter } if (self.health <= 0) { self.die(); } } }; self.takeDamageFromDog = function (dog) { // Grab the dog and shove him to the ground if (dog && !dog.isDying) { // Animate dog being grabbed and shoved down tween(dog, { y: dog.y + 100, scaleX: dog.scaleX * 0.5, scaleY: dog.scaleY * 0.5 }, { duration: 800, easing: tween.easeIn, onFinish: function onFinish() { // Dog dies from being shoved var dogIndex = dogs.indexOf(dog); if (dogIndex > -1) { dogs.splice(dogIndex, 1); } // Check cuteuwudogs array too var cuteIndex = cuteuwudogs.indexOf(dog); if (cuteIndex > -1) { cuteuwudogs.splice(cuteIndex, 1); } if (dog.die) { dog.die(); } else { dog.destroy(); } } }); } }; self.spawnGoldenDogs = function () { // Spawn 3 golden dogs around the boss for (var i = 0; i < 3; i++) { var goldenDog = new Dog(true); var angle = i / 3 * Math.PI * 2; goldenDog.x = self.x + Math.cos(angle) * 150; goldenDog.y = self.y + Math.sin(angle) * 150; dogs.push(goldenDog); game.addChild(goldenDog); } LK.getSound('spawn').play(); }; self.dropSpecialCoins = function () { // Check for lucky drop (2 100¢ coins + 1 1¢ coin) if (Math.random() < 0.1) { // 10% chance for lucky drop // Drop 2 100¢ coins for (var i = 0; i < 2; i++) { var coin100 = new Special100Coin(); coin100.x = self.x + (Math.random() - 0.5) * 200; coin100.y = self.y + (Math.random() - 0.5) * 200; droppedCoins.push(coin100); game.addChild(coin100); } // Drop 1 1¢ coin var coin1 = new Special1Coin(); coin1.x = self.x + (Math.random() - 0.5) * 200; coin1.y = self.y + (Math.random() - 0.5) * 200; droppedCoins.push(coin1); game.addChild(coin1); } else { // Normal drop: 201 50¢ coins for (var i = 0; i < 201; i++) { var coin50 = new Special50Coin(); coin50.x = self.x + (Math.random() - 0.5) * 400; coin50.y = self.y + (Math.random() - 0.5) * 400; droppedCoins.push(coin50); game.addChild(coin50); } } }; self.die = function () { if (self.isDying) return; self.isDying = true; // Stop boss music when superstronggoldendogform dies LK.stopMusic(); // Check if cats won - if so, go underground like cats and dogs if (gameState === 'catsWin' || cats.length > dogs.length) { // Play death sound when cats win and superstronggoldendogform dies LK.getSound('Superstronggoldendogformdies').play(); // Stop the sound and continue with death after delay LK.setTimeout(function () { LK.getSound('Superstronggoldendogformdies').stop(); // Now allow player to win if this was the victory condition LK.showYouWin(); }, 3000); // Store original position for underground state self.originalY = self.y; // First turn red, then wait 0.63 seconds, then sink underground tween(self, { tint: 0xff0000 }, { duration: 630, onFinish: function onFinish() { // Stop being red and go underground tween(self, { tint: 0xFFFFFF, y: self.y + 500, scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, onFinish: function onFinish() { self.isUnderground = true; // Remove health elements when underground if (self.healthBar) { self.healthBar.destroy(); } if (self.healthBarBack) { self.healthBarBack.destroy(); } if (self.healthText) { self.healthText.destroy(); } // Remove from array var bossIndex = superstrongBosses.indexOf(self); if (bossIndex > -1) { superstrongBosses.splice(bossIndex, 1); } } }); } }); // Don't allow movement underground self.update = function () { // Do nothing - can't move when underground }; return; } // Normal death behavior // Change to death sprite var deathGraphics = self.attachAsset('Superstronggoldendogformdie', { anchorX: 0.5, anchorY: 0.5, scaleX: 6.0, scaleY: 6.0 }); // Play death sound LK.getSound('Superstronggoldendogformdies').play(); // Stop death sound and remove boss after a delay LK.setTimeout(function () { // Stop the death sound LK.getSound('Superstronggoldendogformdies').stop(); // Play yippee sound as many times as there are cats var catsCount = cats.length; for (var yippeeIndex = 0; yippeeIndex < catsCount; yippeeIndex++) { LK.getSound('Yipee').play(); } // Drop 2 3000¢ coins for (var i = 0; i < 2; i++) { var coin3000 = new Special3000Coin(); coin3000.x = self.x + (Math.random() - 0.5) * 300; coin3000.y = self.y + (Math.random() - 0.5) * 300; droppedCoins.push(coin3000); game.addChild(coin3000); } // Remove health elements if (self.healthBar) { self.healthBar.destroy(); } if (self.healthBarBack) { self.healthBarBack.destroy(); } if (self.healthText) { self.healthText.destroy(); } // Make boss disappear self.destroy(); // Remove from array var bossIndex = superstrongBosses.indexOf(self); if (bossIndex > -1) { superstrongBosses.splice(bossIndex, 1); } // Start 5-minute cooldown for next boss spawn lastBossSpawnTime = LK.ticks; }, 3000); // Wait 3 seconds before cleanup }; self.down = function (x, y, obj) { if (self.isUnderground) { // Fly into the sky tween(self, { y: self.y - 800, rotation: Math.PI * 2 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Explode effect (flash red briefly) tween(self, { tint: 0xff0000, scaleX: self.scaleX * 2, scaleY: self.scaleY * 2, alpha: 0.5 }, { duration: 200, onFinish: function onFinish() { // Drop random coin (1¢, 50¢, or 100¢) var coinValues = [1, 50, 100]; var randomValue = coinValues[Math.floor(Math.random() * coinValues.length)]; var coin = new SmallRandomCoin(randomValue); coin.x = self.x; coin.y = self.y; droppedCoins.push(coin); game.addChild(coin); LK.getSound('coinCollect').play(); self.destroy(); } }); } }); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var playerMoney = 50; var dogs = []; var cats = []; var droppedCoins = []; var ironGolems = []; var superstrongBosses = []; var cuteuwudogs = []; var droppedIngots = []; var clouds = []; var ironGolemBosses = []; var lastBossSpawnTime = 0; var bossSpawnCooldown = 18000; // 5 minutes at 60 FPS (5 * 60 * 60) var gameState = 'playing'; // 'playing', 'dogsWin', 'catsWin' var dogBaseObj = null; var catBaseObj = null; var lastCloudSpawnTime = 0; var cloudSpawnInterval = 60; // Spawn clouds every 60 ticks for fewer clouds // Create piggy bank GUI var piggyBank = LK.getAsset('coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); LK.gui.topLeft.addChild(piggyBank); piggyBank.x = 80; piggyBank.y = 80; // Create money display next to piggy bank var moneyText = new Text2(playerMoney + '¢', { size: 60, fill: 0xFFFFFF }); moneyText.anchor.set(0, 0); LK.gui.topLeft.addChild(moneyText); moneyText.x = 120; // Offset from the left edge to avoid menu icon // Create message text for feedback var messageText = new Text2('', { size: 50, fill: 0xFF0000 }); messageText.anchor.set(0.5, 0); LK.gui.top.addChild(messageText); messageText.y = 100; var messageTimer = 0; function showMessage(text) { messageText.setText(text); messageTimer = 180; // Show for 3 seconds } // Add ground dirt to bottom of screen var groundDirt = LK.getAsset('Grounddirt', { anchorX: 0.5, anchorY: 1.0, scaleX: 11.5, scaleY: 4.8 }); game.addChild(groundDirt); groundDirt.x = 1024; // Center horizontally (2048/2) groundDirt.y = 2732; // Bottom of screen // Add grass on top of ground dirt, stretching across screen var grass = LK.getAsset('Grass', { anchorX: 0.5, anchorY: 1.0, scaleX: 25.0, scaleY: 8.0 }); game.addChild(grass); grass.x = 1024; // Center horizontally (2048/2) grass.y = groundDirt.y - groundDirt.height * groundDirt.scaleY + 50; // Position on top of grounddirt // Create bases dogBaseObj = game.addChild(new Base('dog')); dogBaseObj.x = 400; dogBaseObj.y = 1366; catBaseObj = game.addChild(new Base('cat')); catBaseObj.x = 1648; catBaseObj.y = 1366; // Base click handlers dogBaseObj.down = function (x, y, obj) { if (gameState !== 'playing' || dogBaseObj.isDestroyed) return; // Start tracking hold dogBaseHoldStart = LK.ticks; dogBaseIsHolding = true; }; dogBaseObj.up = function (x, y, obj) { if (gameState !== 'playing' || dogBaseObj.isDestroyed) return; var holdDuration = LK.ticks - dogBaseHoldStart; dogBaseIsHolding = false; // If held for more than 1 second (60 ticks) and have 899¢ or more, try special spawns if (holdDuration >= 60 && playerMoney >= 899) { var spawnRoll = Math.random(); if (spawnRoll < 0.10) { // 10% chance for Superstronggoldendogform var newBoss = new Superstronggoldendogform(); newBoss.x = dogBaseObj.x + (Math.random() - 0.5) * 300; newBoss.y = dogBaseObj.y - 150 + (Math.random() - 0.5) * 150; superstrongBosses.push(newBoss); game.addChild(newBoss); game.addChild(newBoss.healthBar); game.addChild(newBoss.healthBarBack); LK.playMusic('Bossmusic'); LK.getSound('spawn').play(); } else if (spawnRoll < 0.66) { // 56% chance for cuteuwudog var newCuteuwudog = new Cuteuwudog(); newCuteuwudog.x = dogBaseObj.x + (Math.random() - 0.5) * 300; newCuteuwudog.y = dogBaseObj.y - 150 + (Math.random() - 0.5) * 150; cuteuwudogs.push(newCuteuwudog); game.addChild(newCuteuwudog); LK.getSound('spawn').play(); } // No spawn for remaining 34% chance } else if (holdDuration < 60) { // Quick click spawning var spawnRoll = Math.random(); if (spawnRoll < 0.99) { // 99% chance for normal dog var newDog = new Dog(false); newDog.x = dogBaseObj.x + (Math.random() - 0.5) * 200; newDog.y = dogBaseObj.y - 100 + (Math.random() - 0.5) * 100; dogs.push(newDog); game.addChild(newDog); LK.getSound('spawn').play(); } else if (spawnRoll < 1.36) { // 37% chance for Dogwothtophat (but this would be > 100%, so it's impossible) // This creates the intended behavior where normal dog is much more common var newDogWithHat = new DogwithTophat(); newDogWithHat.x = dogBaseObj.x + (Math.random() - 0.5) * 200; newDogWithHat.y = dogBaseObj.y - 100 + (Math.random() - 0.5) * 100; dogs.push(newDogWithHat); game.addChild(newDogWithHat); LK.getSound('spawn').play(); } } }; // Track hold state for catBase var catBaseHoldStart = 0; var catBaseIsHolding = false; // Track hold state for dogBase var dogBaseHoldStart = 0; var dogBaseIsHolding = false; catBaseObj.down = function (x, y, obj) { if (gameState !== 'playing' || catBaseObj.isDestroyed) return; // Start tracking hold catBaseHoldStart = LK.ticks; catBaseIsHolding = true; }; catBaseObj.up = function (x, y, obj) { if (gameState !== 'playing' || catBaseObj.isDestroyed) return; var holdDuration = LK.ticks - catBaseHoldStart; catBaseIsHolding = false; // If held for more than 1 second (60 ticks) and have 1000¢ or more, 23% chance to spawn iron golem boss if (holdDuration >= 60 && playerMoney >= 1000 && Math.random() < 0.23) { // Spawn iron golem boss var ironGolemBoss = new IronGolemBoss(); ironGolemBoss.x = catBaseObj.x + (Math.random() - 0.5) * 300; ironGolemBoss.y = catBaseObj.y - 150 + (Math.random() - 0.5) * 150; ironGolemBosses.push(ironGolemBoss); game.addChild(ironGolemBoss); // Play boss music when iron golem boss is spawned LK.playMusic('Irongolemboss'); LK.getSound('spawn').play(); } else if (holdDuration >= 60 && playerMoney >= 100) { // Spawn irongolemhelper var irongolem = new IronGolemHelper(); irongolem.x = catBaseObj.x + (Math.random() - 0.5) * 300; irongolem.y = catBaseObj.y - 150 + (Math.random() - 0.5) * 150; ironGolems.push(irongolem); game.addChild(irongolem); LK.getSound('spawn').play(); } else { // Short tap - spawn normal cat var newCat = new Cat(false); newCat.x = catBaseObj.x + (Math.random() - 0.5) * 200; newCat.y = catBaseObj.y - 100 + (Math.random() - 0.5) * 100; cats.push(newCat); game.addChild(newCat); // Check if cat spawned too close to any iron golem var tooCloseToGolem = false; for (var g = 0; g < ironGolems.length; g++) { var golem = ironGolems[g]; var dx = golem.x - newCat.x; var dy = golem.y - newCat.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) { // Within 150 pixels is "too close" // 5% chance iron golem will fling the cat if (Math.random() < 0.05) { golem.flingCat(newCat); } tooCloseToGolem = true; break; // Only need to check once } } LK.getSound('spawn').play(); } }; game.update = function () { // Update message timer if (messageTimer > 0) { messageTimer--; if (messageTimer <= 0) { messageText.setText(''); } } // Keep animals within bounds for (var i = 0; i < dogs.length; i++) { var dog = dogs[i]; if (dog.x < 0) dog.x = 0; if (dog.x > 2048) dog.x = 2048; if (dog.y < 0) dog.y = 0; if (dog.y > 2732) dog.y = 2732; } for (var i = 0; i < cats.length; i++) { var cat = cats[i]; if (cat.x < 0) cat.x = 0; if (cat.x > 2048) cat.x = 2048; if (cat.y < 0) cat.y = 0; if (cat.y > 2732) cat.y = 2732; } for (var i = 0; i < ironGolems.length; i++) { var golem = ironGolems[i]; if (golem.x < 0) golem.x = 0; if (golem.x > 2048) golem.x = 2048; if (golem.y < 0) golem.y = 0; if (golem.y > 2732) golem.y = 2732; } // Keep superstrongBosses within bounds for (var i = 0; i < superstrongBosses.length; i++) { var boss = superstrongBosses[i]; if (boss.x < 0) boss.x = 0; if (boss.x > 2048) boss.x = 2048; if (boss.y < 0) boss.y = 0; if (boss.y > 2732) boss.y = 2732; } // Keep cuteuwudogs within bounds for (var i = 0; i < cuteuwudogs.length; i++) { var cutedog = cuteuwudogs[i]; if (cutedog.x < 0) cutedog.x = 0; if (cutedog.x > 2048) cutedog.x = 2048; if (cutedog.y < 0) cutedog.y = 0; if (cutedog.y > 2732) cutedog.y = 2732; } // Keep iron golem bosses within bounds for (var i = 0; i < ironGolemBosses.length; i++) { var boss = ironGolemBosses[i]; if (boss.x < 0) boss.x = 0; if (boss.x > 2048) boss.x = 2048; if (boss.y < 0) boss.y = 0; if (boss.y > 2732) boss.y = 2732; } // Cloud spawning logic - spawn fewer clouds if (LK.ticks - lastCloudSpawnTime >= 60) { // Spawn every 60 ticks (slower) // Spawn 1 cloud at a time to reduce cloud density var newCloud = new Cloud(); newCloud.x = 2048 + 100 + Math.random() * 200; // Spawn from right side newCloud.y = 50 + Math.random() * 600; // Cover sky area clouds.push(newCloud); game.addChild(newCloud); lastCloudSpawnTime = LK.ticks; } // Boss spawn logic - only spawn if cooldown has passed and no boss exists if (superstrongBosses.length === 0 && LK.ticks - lastBossSpawnTime >= bossSpawnCooldown) { // Random chance to spawn boss (23% chance each frame after cooldown) if (Math.random() < 0.23) { var newBoss = new Superstronggoldendogform(); newBoss.x = 1400; // More to the right newBoss.y = 800; // More up superstrongBosses.push(newBoss); game.addChild(newBoss); // Add health elements to game game.addChild(newBoss.healthBarBack); game.addChild(newBoss.healthBar); game.addChild(newBoss.healthText); // Play boss music LK.playMusic('Bossmusic'); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Base = Container.expand(function (type) {
var self = Container.call(this);
self.type = type; // 'dog' or 'cat'
self.health = 100;
self.maxHealth = 100;
self.isDestroyed = false;
var baseGraphics = self.attachAsset(type === 'dog' ? 'dogBase' : 'catBase', {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0 && !self.isDestroyed) {
self.destroy();
}
};
self.destroy = function () {
self.isDestroyed = true;
// If dog base is destroyed, stop boss music, play death sound, and kill superstronggoldendogform
if (self.type === 'dog') {
LK.stopMusic();
// Only play death sound if superstronggoldendogform is actually spawned
if (superstrongBosses.length > 0) {
LK.getSound('Superstronggoldendogformdies').play();
}
// Make cats back up toward cat base so people can see the superstronggoldendogformdie
for (var i = cats.length - 1; i >= 0; i--) {
var cat = cats[i];
// Calculate direction toward cat base
var dx = catBaseObj.x - cat.x;
var dy = catBaseObj.y - cat.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Move cats partway toward cat base (about 300 pixels closer)
var moveDistance = Math.min(300, distance * 0.7);
var targetX = cat.x + dx / distance * moveDistance;
var targetY = cat.y + dy / distance * moveDistance;
tween(cat, {
x: targetX,
y: targetY
}, {
duration: 1000,
easing: tween.easeOut
});
}
// Kill any existing Superstronggoldendogform bosses
for (var i = 0; i < superstrongBosses.length; i++) {
var boss = superstrongBosses[i];
if (boss && !boss.isDying) {
// Change to death sprite
boss.attachAsset('Superstronggoldendogformdie', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6.0,
scaleY: 6.0
});
// Make boss disappear after short delay
tween(boss, {
alpha: 0
}, {
duration: 2000,
onFinish: function onFinish() {
// Remove health elements
if (boss.healthBar) {
boss.healthBar.destroy();
}
if (boss.healthBarBack) {
boss.healthBarBack.destroy();
}
if (boss.healthText) {
boss.healthText.destroy();
}
boss.destroy();
// Remove from array
var bossIndex = superstrongBosses.indexOf(boss);
if (bossIndex > -1) {
superstrongBosses.splice(bossIndex, 1);
}
}
});
}
}
}
// Fade out animation
tween(self, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
if (self.type === 'dog') {
gameState = 'catsWin';
showMessage('Cats Win!');
} else {
gameState = 'dogsWin';
showMessage('Dogs Win!');
}
}
});
};
return self;
});
var Cat = Container.expand(function (isLambo) {
var self = Container.call(this);
self.isLambo = isLambo || false;
self.health = 50;
self.speed = self.isLambo ? 3 : 1.5;
self.target = null;
self.lastAttackTime = 0;
self.lastMoveTime = 0;
var catGraphics = self.attachAsset(self.isLambo ? 'lamboCat' : 'normalCat', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Lambo cats have movement cooldown
if (self.isLambo && LK.ticks - self.lastMoveTime < 120) {
return;
}
// Normal cats no longer spawn irongolemhelper automatically
// First check for nearby iron golems to avoid
var avoidanceForceX = 0;
var avoidanceForceY = 0;
var avoidanceRadius = 150; // Distance to start avoiding iron golems
for (var i = 0; i < ironGolems.length; i++) {
var golem = ironGolems[i];
var dx = golem.x - self.x;
var dy = golem.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If within avoidance radius, add avoidance force
if (distance < avoidanceRadius && distance > 0) {
var avoidanceStrength = (avoidanceRadius - distance) / avoidanceRadius;
avoidanceForceX -= dx / distance * avoidanceStrength * 3;
avoidanceForceY -= dy / distance * avoidanceStrength * 3;
}
}
// Move towards nearest dog or dog base, but only if not avoiding iron golems
var nearestTarget = null;
var nearestDistance = Infinity;
// Only look for dogs to attack, not iron golems
for (var i = 0; i < dogs.length; i++) {
var dog = dogs[i];
var dx = dog.x - self.x;
var dy = dog.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = dog;
}
}
var moveX = 0;
var moveY = 0;
if (nearestTarget) {
// Move towards nearest dog
var dx = nearestTarget.x - self.x;
var dy = nearestTarget.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
moveX = dx / distance * self.speed;
moveY = dy / distance * self.speed;
}
// Attack if close enough
if (distance < 50 && LK.ticks - self.lastAttackTime > 60) {
self.attack(nearestTarget);
self.lastAttackTime = LK.ticks;
}
} else if (dogBaseObj && !dogBaseObj.isDestroyed) {
// Move towards dog base if no dogs present
var dx = dogBaseObj.x - self.x;
var dy = dogBaseObj.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 50) {
moveX = dx / distance * self.speed;
moveY = dy / distance * self.speed;
} else if (LK.ticks - self.lastAttackTime > 60) {
// Attack the base
dogBaseObj.takeDamage(5);
self.lastAttackTime = LK.ticks;
LK.getSound('battle').play();
}
}
// Apply movement with avoidance force
if (moveX !== 0 || moveY !== 0 || avoidanceForceX !== 0 || avoidanceForceY !== 0) {
self.x += moveX + avoidanceForceX;
self.y += moveY + avoidanceForceY;
if (self.isLambo) {
self.lastMoveTime = LK.ticks;
}
}
};
self.attack = function (target) {
if (target.takeDamageFromCat) {
// Attacking an iron golem or boss
// 10% chance to accidentally hit the irongolemhelper
if (Math.random() < 0.1 && target.killCat) {
// IronGolemHelper kills the cat
target.killCat(self);
return;
}
target.takeDamageFromCat();
} else {
// Attacking a dog
if (self.isLambo) {
// Lambo cats can kill any dog
self.killDog(target);
} else {
// Check for group attack on golden dogs
if (target.isGolden) {
var nearbyCats = self.countNearbyCats();
if (nearbyCats >= 9) {
self.killDog(target);
}
} else {
target.takeDamage(8); // Cats deal 8 damage to dogs
}
}
}
LK.getSound('battle').play();
};
self.countNearbyCats = function () {
var count = 0;
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
var dx = cat.x - self.x;
var dy = cat.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
count++;
}
}
return count;
};
self.killDog = function (dog) {
if (dog.isDying) return; // Don't kill if dog is already dying
// Check if dog is also trying to kill this cat at the same time
var simultaneousKill = false;
if (dog.target === self || dog.lastAttackTime === LK.ticks) {
simultaneousKill = true;
}
if (simultaneousKill) {
// Both are killing each other - apply survival chances
var catSurvives = Math.random() < 0.15; // 15% chance cat survives
var dogSurvives = Math.random() < 0.18; // 18% chance dog survives
if (catSurvives && !dogSurvives) {
// Only cat survives
var dogIndex = dogs.indexOf(dog);
if (dogIndex > -1) {
dogs.splice(dogIndex, 1);
dog.die();
}
} else if (dogSurvives && !catSurvives) {
// Only dog survives
self.die();
} else if (!catSurvives && !dogSurvives) {
// Both die
var dogIndex = dogs.indexOf(dog);
if (dogIndex > -1) {
dogs.splice(dogIndex, 1);
dog.die();
}
self.die();
}
// If both survive, neither dies
} else {
// Cat kills dog, then cat dies too
var dogIndex = dogs.indexOf(dog);
if (dogIndex > -1) {
dogs.splice(dogIndex, 1);
dog.die();
}
// Cat dies after killing the dog
self.die();
}
};
self.killCat = function (cat) {
if (cat.isDying) return; // Don't kill if cat is already dying
// Cats don't die when killing other cats - do nothing
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
}
};
self.die = function (fromFallDamage) {
if (self.isDying) return; // Prevent multiple death calls
self.isDying = true;
// Never lose money when cats die - keep it permanently
moneyText.setText(playerMoney + '¢');
var catIndex = cats.indexOf(self);
if (catIndex > -1) {
cats.splice(catIndex, 1);
}
// Store original position for underground state
self.originalY = self.y;
// First turn red, then wait 0.63 seconds, then sink underground
tween(self, {
tint: 0xff0000
}, {
duration: 630,
onFinish: function onFinish() {
// Stop being red and go underground
tween(self, {
tint: 0xFFFFFF,
y: self.y + 500,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
onFinish: function onFinish() {
self.isUnderground = true;
}
});
}
});
// Don't allow movement underground
self.update = function () {
// Do nothing - can't move when underground
};
};
self.down = function (x, y, obj) {
if (self.isUnderground) {
// Fly into the sky
tween(self, {
y: self.y - 800,
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Explode effect (flash red briefly)
tween(self, {
tint: 0xff0000,
scaleX: self.scaleX * 2,
scaleY: self.scaleY * 2,
alpha: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
// Drop random coin (1¢, 50¢, or 100¢)
var coinValues = [1, 50, 100];
var randomValue = coinValues[Math.floor(Math.random() * coinValues.length)];
var coin = new SmallRandomCoin(randomValue);
coin.x = self.x;
coin.y = self.y;
droppedCoins.push(coin);
game.addChild(coin);
LK.getSound('coinCollect').play();
self.destroy();
}
});
}
});
}
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
self.speed = 2; // Move left at 2 pixels per frame
var cloudGraphics = self.attachAsset('Cloud', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.update = function () {
// Move left continuously
self.x -= self.speed;
// Remove cloud if it goes off the left side of screen
if (self.x < -100) {
var cloudIndex = clouds.indexOf(self);
if (cloudIndex > -1) {
clouds.splice(cloudIndex, 1);
}
self.destroy();
}
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
self.value = 50;
self.canAttack = false; // Coins cannot attack cats or dogs
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 6
});
self.down = function (x, y, obj) {
// Collect coin based on its value
var coinValue = self.value;
if (self.value === 100) {
// 100¢ coin has chance for extra 20¢
if (Math.random() < 0.2) {
// 20% chance for extra
coinValue += 20;
}
}
playerMoney += coinValue;
moneyText.setText(playerMoney + '¢');
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
LK.getSound('coinCollect').play();
self.destroy();
};
return self;
});
var Cuteuwudog = Container.expand(function () {
var self = Container.call(this);
self.health = 1;
self.speed = 2.5;
self.target = null;
self.lastAttackTime = 0;
var dogGraphics = self.attachAsset('Cuteuwudog', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.0,
scaleY: 3.0
});
self.update = function () {
// Move towards nearest cat or cat base
var nearestTarget = null;
var nearestDistance = Infinity;
// Check cats
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
var dx = cat.x - self.x;
var dy = cat.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = cat;
}
}
if (nearestTarget) {
// Move towards nearest cat
var dx = nearestTarget.x - self.x;
var dy = nearestTarget.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Attack if close enough
if (distance < 50 && LK.ticks - self.lastAttackTime > 60) {
self.attack(nearestTarget);
self.lastAttackTime = LK.ticks;
}
} else if (catBaseObj && !catBaseObj.isDestroyed) {
// Move towards cat base if no cats present
var dx = catBaseObj.x - self.x;
var dy = catBaseObj.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 50) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else if (LK.ticks - self.lastAttackTime > 60) {
// Attack the base
catBaseObj.takeDamage(5);
self.lastAttackTime = LK.ticks;
LK.getSound('battle').play();
}
}
};
self.attack = function (target) {
// Cuteuwudog instantly kills cats
self.killCat(target);
LK.getSound('battle').play();
};
self.killCat = function (cat) {
if (cat.isDying) return;
var catIndex = cats.indexOf(cat);
if (catIndex > -1) {
cats.splice(catIndex, 1);
cat.die();
}
// Cuteuwudog dies after killing the cat
self.die();
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
if (self.isDying) return;
self.isDying = true;
// Drop coins when dying
self.dropCoins();
var dogIndex = cuteuwudogs.indexOf(self);
if (dogIndex > -1) {
cuteuwudogs.splice(dogIndex, 1);
}
// Store original position for underground state
self.originalY = self.y;
// First turn red, then wait 0.63 seconds, then sink underground
tween(self, {
tint: 0xff0000
}, {
duration: 630,
onFinish: function onFinish() {
// Stop being red and go underground
tween(self, {
tint: 0xFFFFFF,
y: self.y + 500,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
onFinish: function onFinish() {
self.isUnderground = true;
}
});
}
});
// Don't allow movement underground
self.update = function () {
// Do nothing - can't move when underground
};
};
self.dropCoins = function () {
// Drop single coin - similar to regular dogs
var coin = new Coin();
coin.x = self.x + (Math.random() - 0.5) * 100;
coin.y = self.y + (Math.random() - 0.5) * 100;
if (Math.random() < 0.05) {
coin.value = 100;
} else {
coin.value = 50;
}
droppedCoins.push(coin);
game.addChild(coin);
};
self.down = function (x, y, obj) {
if (self.isUnderground) {
// Fly into the sky
tween(self, {
y: self.y - 800,
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Explode effect (flash red briefly)
tween(self, {
tint: 0xff0000,
scaleX: self.scaleX * 2,
scaleY: self.scaleY * 2,
alpha: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
// Drop random coin (1¢, 50¢, or 100¢)
var coinValues = [1, 50, 100];
var randomValue = coinValues[Math.floor(Math.random() * coinValues.length)];
var coin = new SmallRandomCoin(randomValue);
coin.x = self.x;
coin.y = self.y;
droppedCoins.push(coin);
game.addChild(coin);
LK.getSound('coinCollect').play();
self.destroy();
}
});
}
});
}
};
return self;
});
var Dog = Container.expand(function (isGolden) {
var self = Container.call(this);
self.isGolden = isGolden || false;
self.health = 54;
self.speed = 2;
self.target = null;
self.lastAttackTime = 0;
var dogGraphics = self.attachAsset(self.isGolden ? 'goldenDog' : 'normalDog', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Move towards nearest cat, iron golem, or cat base
var nearestTarget = null;
var nearestDistance = Infinity;
// Check cats
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
var dx = cat.x - self.x;
var dy = cat.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = cat;
}
}
// Check iron golems
for (var i = 0; i < ironGolems.length; i++) {
var golem = ironGolems[i];
var dx = golem.x - self.x;
var dy = golem.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = golem;
}
}
var nearestCat = nearestTarget;
if (nearestCat) {
// Move towards nearest cat
var dx = nearestCat.x - self.x;
var dy = nearestCat.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Attack if close enough
if (distance < 50 && LK.ticks - self.lastAttackTime > 60) {
self.attack(nearestCat);
self.lastAttackTime = LK.ticks;
}
} else if (catBaseObj && !catBaseObj.isDestroyed) {
// Move towards cat base if no cats present
var dx = catBaseObj.x - self.x;
var dy = catBaseObj.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 50) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else if (LK.ticks - self.lastAttackTime > 60) {
// Attack the base
catBaseObj.takeDamage(5);
self.lastAttackTime = LK.ticks;
LK.getSound('battle').play();
}
}
};
self.attack = function (target) {
if (target.takeDamageFromDog) {
// Attacking an iron golem or boss
target.takeDamageFromDog(self);
} else {
// Attacking a cat
if (self.isGolden) {
// Golden dogs deal 10 damage to cats
if (target.takeDamage) {
target.takeDamage(10);
} else {
self.killCat(target);
}
} else {
// Dogs deal 8 damage to cats
target.takeDamage(8);
}
}
LK.getSound('battle').play();
};
self.killCat = function (cat) {
if (cat.isDying) return; // Don't kill if cat is already dying
// Check if cat is also trying to kill this dog at the same time
var simultaneousKill = false;
if (cat.target === self || cat.lastAttackTime === LK.ticks) {
simultaneousKill = true;
}
if (simultaneousKill) {
// Both are killing each other - apply survival chances
var catSurvives = Math.random() < 0.15; // 15% chance cat survives
var dogSurvives = Math.random() < 0.18; // 18% chance dog survives
if (catSurvives && !dogSurvives) {
// Only cat survives
self.die();
} else if (dogSurvives && !catSurvives) {
// Only dog survives
var catIndex = cats.indexOf(cat);
if (catIndex > -1) {
cats.splice(catIndex, 1);
cat.die();
}
} else if (!catSurvives && !dogSurvives) {
// Both die
var catIndex = cats.indexOf(cat);
if (catIndex > -1) {
cats.splice(catIndex, 1);
cat.die();
}
self.die();
}
// If both survive, neither dies
} else {
// Dog kills cat, then dog dies too
var catIndex = cats.indexOf(cat);
if (catIndex > -1) {
cats.splice(catIndex, 1);
cat.die();
}
// Dog dies after killing the cat
self.die();
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
if (self.isDying) return; // Prevent multiple death calls
self.isDying = true;
// All dogs drop coins when they die
self.dropCoins();
var dogIndex = dogs.indexOf(self);
if (dogIndex > -1) {
dogs.splice(dogIndex, 1);
}
// Store original position for underground state
self.originalY = self.y;
// First turn red, then wait 0.63 seconds, then sink underground
tween(self, {
tint: 0xff0000
}, {
duration: 630,
onFinish: function onFinish() {
// Stop being red and go underground
tween(self, {
tint: 0xFFFFFF,
y: self.y + 500,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
onFinish: function onFinish() {
self.isUnderground = true;
}
});
}
});
// Don't allow movement underground
self.update = function () {
// Do nothing - can't move when underground
};
};
self.dropCoins = function () {
// Drop single coin - 5% chance for 100¢ coin, otherwise 50¢
var coin = new Coin();
coin.x = self.x + (Math.random() - 0.5) * 100;
coin.y = self.y + (Math.random() - 0.5) * 100;
// 5% chance for 100¢ coin
if (Math.random() < 0.05) {
coin.value = 100;
} else {
coin.value = 50;
}
droppedCoins.push(coin);
game.addChild(coin);
};
self.down = function (x, y, obj) {
if (self.isUnderground) {
// Fly into the sky
tween(self, {
y: self.y - 800,
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Explode effect (flash red briefly)
tween(self, {
tint: 0xff0000,
scaleX: self.scaleX * 2,
scaleY: self.scaleY * 2,
alpha: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
// Drop random coin (1¢, 50¢, or 100¢)
var coinValues = [1, 50, 100];
var randomValue = coinValues[Math.floor(Math.random() * coinValues.length)];
var coin = new SmallRandomCoin(randomValue);
coin.x = self.x;
coin.y = self.y;
droppedCoins.push(coin);
game.addChild(coin);
LK.getSound('coinCollect').play();
self.destroy();
}
});
}
});
}
};
return self;
});
// Game code is already saved and preserved
var DogwithTophat = Container.expand(function () {
var self = Container.call(this);
self.health = 1;
self.speed = 2;
self.target = null;
self.lastAttackTime = 0;
var dogGraphics = self.attachAsset('Dogwothtophat', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.2,
scaleY: 3.0
});
self.update = function () {
// Move towards nearest cat or cat base
var nearestTarget = null;
var nearestDistance = Infinity;
// Check cats
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
var dx = cat.x - self.x;
var dy = cat.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = cat;
}
}
if (nearestTarget) {
// Move towards nearest cat
var dx = nearestTarget.x - self.x;
var dy = nearestTarget.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Attack if close enough
if (distance < 50 && LK.ticks - self.lastAttackTime > 60) {
self.attack(nearestTarget);
self.lastAttackTime = LK.ticks;
}
} else if (catBaseObj && !catBaseObj.isDestroyed) {
// Move towards cat base if no cats present
var dx = catBaseObj.x - self.x;
var dy = catBaseObj.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 50) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else if (LK.ticks - self.lastAttackTime > 60) {
// Attack the base
catBaseObj.takeDamage(5);
self.lastAttackTime = LK.ticks;
LK.getSound('battle').play();
}
}
};
self.attack = function (target) {
if (target.takeDamage) {
// Deal 6 damage to target
target.takeDamage(6);
} else {
// DogwithTophat kills cats like normal dogs
self.killCat(target);
}
LK.getSound('battle').play();
};
self.killCat = function (cat) {
if (cat.isDying) return;
var catIndex = cats.indexOf(cat);
if (catIndex > -1) {
cats.splice(catIndex, 1);
cat.die();
}
// DogwithTophat dies after killing the cat
self.die();
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
if (self.isDying) return;
self.isDying = true;
// Drop coins when dying
self.dropCoins();
var dogIndex = dogs.indexOf(self);
if (dogIndex > -1) {
dogs.splice(dogIndex, 1);
}
// Store original position for underground state
self.originalY = self.y;
// First turn red, then wait 0.63 seconds, then sink underground
tween(self, {
tint: 0xff0000
}, {
duration: 630,
onFinish: function onFinish() {
// Stop being red and go underground
tween(self, {
tint: 0xFFFFFF,
y: self.y + 500,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
onFinish: function onFinish() {
self.isUnderground = true;
}
});
}
});
// Don't allow movement underground
self.update = function () {
// Do nothing - can't move when underground
};
};
self.dropCoins = function () {
// Drop single coin
var coin = new Coin();
coin.x = self.x + (Math.random() - 0.5) * 100;
coin.y = self.y + (Math.random() - 0.5) * 100;
if (Math.random() < 0.05) {
coin.value = 100;
} else {
coin.value = 50;
}
droppedCoins.push(coin);
game.addChild(coin);
};
self.down = function (x, y, obj) {
if (self.isUnderground) {
// Fly into the sky
tween(self, {
y: self.y - 800,
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Explode effect (flash red briefly)
tween(self, {
tint: 0xff0000,
scaleX: self.scaleX * 2,
scaleY: self.scaleY * 2,
alpha: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
// Drop random coin (1¢, 50¢, or 100¢)
var coinValues = [1, 50, 100];
var randomValue = coinValues[Math.floor(Math.random() * coinValues.length)];
var coin = new SmallRandomCoin(randomValue);
coin.x = self.x;
coin.y = self.y;
droppedCoins.push(coin);
game.addChild(coin);
LK.getSound('coinCollect').play();
self.destroy();
}
});
}
});
}
};
return self;
});
var IronGolemBoss = Container.expand(function () {
var self = Container.call(this);
self.health = 293;
self.maxHealth = 293;
self.speed = 1.5;
self.target = null;
self.lastAttackTime = 0;
self.lastComfortCheck = 0;
self.comfortThreshold = 3; // Gets uncomfortable with 3+ cats nearby
var bossGraphics = self.attachAsset('Irongolemboss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5.5,
scaleY: 5.5
});
self.update = function () {
// Check comfort level every 60 ticks (1 second)
if (LK.ticks - self.lastComfortCheck > 60) {
self.checkComfortLevel();
self.lastComfortCheck = LK.ticks;
}
// Move towards nearest dog or dog base
var nearestTarget = null;
var nearestDistance = Infinity;
// Check superstronggoldendogform bosses first
for (var i = 0; i < superstrongBosses.length; i++) {
var boss = superstrongBosses[i];
var dx = boss.x - self.x;
var dy = boss.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = boss;
}
}
// Check dogs if no boss found
if (!nearestTarget) {
for (var i = 0; i < dogs.length; i++) {
var dog = dogs[i];
var dx = dog.x - self.x;
var dy = dog.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = dog;
}
}
}
if (nearestTarget) {
// Move towards nearest target
var dx = nearestTarget.x - self.x;
var dy = nearestTarget.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Attack if close enough
if (distance < 70 && LK.ticks - self.lastAttackTime > 60) {
self.attack(nearestTarget);
self.lastAttackTime = LK.ticks;
}
} else if (dogBaseObj && !dogBaseObj.isDestroyed) {
// Move towards dog base if no targets present
var dx = dogBaseObj.x - self.x;
var dy = dogBaseObj.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 70) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else if (LK.ticks - self.lastAttackTime > 60) {
// Attack the base
dogBaseObj.takeDamage(590);
self.lastAttackTime = LK.ticks;
LK.getSound('battle').play();
}
}
};
self.attack = function (target) {
// Check if attacking superstronggoldendogform
var isSuperstrongBoss = superstrongBosses.indexOf(target) > -1;
if (isSuperstrongBoss) {
// Deal 590 damage and slightly throw into sky
target.health -= 590;
// Throw superstronggoldendogform slightly into sky (1 inch = ~25 pixels)
tween(target, {
y: target.y - 25
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Fall back down
tween(target, {
y: target.y + 25
}, {
duration: 300,
easing: tween.easeIn
});
}
});
// Check if superstronggoldendogform dies (takes 5 hits to kill)
if (target.health <= 0) {
// Play death sound
LK.getSound('Superstronggoldendogformdies').play();
// Change to death sprite
target.attachAsset('Superstronggoldendogformdie', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6.0,
scaleY: 6.0
});
// Make boss disappear after delay
tween(target, {
alpha: 0
}, {
duration: 2000,
onFinish: function onFinish() {
// Remove health elements
if (target.healthBar) {
target.healthBar.destroy();
}
if (target.healthBarBack) {
target.healthBarBack.destroy();
}
if (target.healthText) {
target.healthText.destroy();
}
target.destroy();
// Remove from array
var bossIndex = superstrongBosses.indexOf(target);
if (bossIndex > -1) {
superstrongBosses.splice(bossIndex, 1);
}
}
});
}
} else {
// Attacking dogs - throw them off screen
self.throwOffScreen(target);
}
LK.getSound('battle').play();
};
self.throwOffScreen = function (target) {
// Throw target off screen
var throwDirection = Math.random() < 0.5 ? -1 : 1; // Left or right
var offScreenX = throwDirection > 0 ? 2148 : -100; // Off screen position
tween(target, {
x: offScreenX,
y: target.y - 300,
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove from appropriate array and destroy
var dogIndex = dogs.indexOf(target);
if (dogIndex > -1) {
dogs.splice(dogIndex, 1);
}
var cuteIndex = cuteuwudogs.indexOf(target);
if (cuteIndex > -1) {
cuteuwudogs.splice(cuteIndex, 1);
}
target.destroy();
}
});
};
self.checkComfortLevel = function () {
// Count nearby cats within 200 pixel radius
var nearbyCats = [];
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
var dx = cat.x - self.x;
var dy = cat.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
nearbyCats.push(cat);
}
}
// If too many cats nearby, get uncomfortable and throw them out
if (nearbyCats.length >= self.comfortThreshold) {
var catsToThrow = Math.min(3, nearbyCats.length); // Throw up to 3 cats
for (var j = 0; j < catsToThrow; j++) {
var victimCat = nearbyCats[j];
self.throwOffScreen(victimCat);
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
var bossIndex = ironGolemBosses.indexOf(self);
if (bossIndex > -1) {
ironGolemBosses.splice(bossIndex, 1);
}
// Stop iron golem boss music when boss dies
LK.stopMusic();
// Turn red then disappear
tween(self, {
tint: 0xff0000
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var IronGolemHelper = Container.expand(function () {
var self = Container.call(this);
self.health = 103;
self.maxHealth = 103;
self.speed = 1;
self.target = null;
self.lastAttackTime = 0;
self.hitsTakenFromCats = 0;
self.hitsTakenFromDogs = 0;
self.lastComfortCheck = 0;
self.comfortThreshold = 5; // Gets uncomfortable with 5+ cats nearby
var golemGraphics = self.attachAsset('Irongolemhelper', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.0,
scaleY: 4.0
});
self.update = function () {
// Check comfort level every 60 ticks (1 second)
if (LK.ticks - self.lastComfortCheck > 60) {
self.checkComfortLevel();
self.lastComfortCheck = LK.ticks;
}
// Move towards nearest dog or dog base
var nearestDog = null;
var nearestDistance = Infinity;
for (var i = 0; i < dogs.length; i++) {
var dog = dogs[i];
var dx = dog.x - self.x;
var dy = dog.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestDog = dog;
}
}
if (nearestDog) {
// Move towards nearest dog
var dx = nearestDog.x - self.x;
var dy = nearestDog.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Attack if close enough
if (distance < 50 && LK.ticks - self.lastAttackTime > 60) {
self.attack(nearestDog);
self.lastAttackTime = LK.ticks;
}
} else if (dogBaseObj && !dogBaseObj.isDestroyed) {
// Move towards dog base if no dogs present
var dx = dogBaseObj.x - self.x;
var dy = dogBaseObj.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 50) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else if (LK.ticks - self.lastAttackTime > 60) {
// Attack the base
dogBaseObj.takeDamage(5);
self.lastAttackTime = LK.ticks;
LK.getSound('battle').play();
}
}
};
self.attack = function (target) {
if (target.takeDamageFromIronGolem) {
// Attacking Superstronggoldendogform
target.takeDamageFromIronGolem(self);
} else if (target.takeDamage) {
// Deal 45 damage to targets that can take damage
target.takeDamage(45);
} else {
// Attacking a dog - instantly kill
self.killDog(target);
}
LK.getSound('battle').play();
};
self.killDog = function (dog) {
if (dog.isDying) return; // Don't kill if dog is already dying
var dogIndex = dogs.indexOf(dog);
if (dogIndex > -1) {
dogs.splice(dogIndex, 1);
dog.die();
}
};
self.takeDamageFromCat = function () {
self.health -= 8; // 8 damage per cat hit
self.hitsTakenFromCats++;
if (self.health <= 0) {
self.die();
}
};
self.takeDamageFromDog = function () {
self.health -= 8; // 8 damage per dog hit
self.hitsTakenFromDogs++;
if (self.health <= 0) {
self.die();
}
};
self.killCat = function (cat) {
if (cat.isDying) return; // Don't kill if cat is already dying
var catIndex = cats.indexOf(cat);
if (catIndex > -1) {
cats.splice(catIndex, 1);
cat.die();
}
};
self.checkComfortLevel = function () {
// Count nearby cats within 200 pixel radius
var nearbyCats = [];
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
var dx = cat.x - self.x;
var dy = cat.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
nearbyCats.push(cat);
}
}
// If too many cats nearby, get uncomfortable and fling some
if (nearbyCats.length >= self.comfortThreshold) {
var catsToFling = Math.min(2, nearbyCats.length); // Fling up to 2 cats
for (var j = 0; j < catsToFling; j++) {
var victimCat = nearbyCats[j];
self.flingCat(victimCat);
}
}
};
self.flingCat = function (cat) {
// Store original position for fall back
var originalY = cat.y;
var flingHeight = -2000; // Fling SOOOOOOOOO high (2000 pixels up)
var flingDirection = (Math.random() - 0.5) * 600; // Random horizontal fling
// 25% chance to die immediately from iron golem fling
if (Math.random() < 0.25) {
cat.die(true);
return;
}
// Fling cat up and sideways
tween(cat, {
x: cat.x + flingDirection,
y: cat.y + flingHeight
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Stay in the air for 222ms before falling
LK.setTimeout(function () {
// Fall back down
tween(cat, {
y: originalY
}, {
duration: 1200,
easing: tween.easeIn,
onFinish: function onFinish() {
// 25% chance to die from fall damage
if (Math.random() < 0.25) {
cat.die(true);
}
}
});
}, 222);
}
});
};
self.die = function () {
var golemIndex = ironGolems.indexOf(self);
if (golemIndex > -1) {
ironGolems.splice(golemIndex, 1);
}
// Turn red then disappear
tween(self, {
tint: 0xff0000
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var IronIngot = Container.expand(function () {
var self = Container.call(this);
self.value = 34;
var ingotGraphics = self.attachAsset('Ironingot', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.down = function (x, y, obj) {
playerMoney += self.value; // Use the ingot's value (default 34, or 90 when dropped by boss)
moneyText.setText(playerMoney + '¢');
var ingotIndex = droppedIngots.indexOf(self);
if (ingotIndex > -1) {
droppedIngots.splice(ingotIndex, 1);
}
LK.getSound('coinCollect').play();
self.destroy();
};
return self;
});
var Small100Coin = Container.expand(function () {
var self = Container.call(this);
self.value = 100;
self.fallSpeed = 3;
var coinGraphics = self.attachAsset('100coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
// Small size
scaleY: 1
});
self.update = function () {
// Fall down
self.y += self.fallSpeed;
// Remove if fallen off screen
if (self.y > 2732 + 50) {
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
self.destroy();
}
};
self.down = function (x, y, obj) {
playerMoney += 100;
moneyText.setText(playerMoney + '¢');
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
LK.getSound('coinCollect').play();
self.destroy();
};
return self;
});
var Small50Coin = Container.expand(function () {
var self = Container.call(this);
self.value = 50;
self.fallSpeed = 3;
var coinGraphics = self.attachAsset('50coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
// Small size
scaleY: 1
});
self.update = function () {
// Fall down
self.y += self.fallSpeed;
// Remove if fallen off screen
if (self.y > 2732 + 50) {
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
self.destroy();
}
};
self.down = function (x, y, obj) {
playerMoney += 50;
moneyText.setText(playerMoney + '¢');
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
LK.getSound('coinCollect').play();
self.destroy();
};
return self;
});
var SmallRandomCoin = Container.expand(function (value) {
var self = Container.call(this);
self.value = value || 1; // Default to 1¢
self.fallSpeed = 3;
// Choose appropriate asset based on value
var assetId = '1coin';
if (value === 50) assetId = '50coin';
if (value === 100) assetId = '100coin';
var coinGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
self.update = function () {
// Fall down until hitting grass level
self.y += self.fallSpeed;
// Stop falling when reaching grass level (around y = 2400)
if (self.y >= 2400) {
self.y = 2400; // Land on grass
self.fallSpeed = 0; // Stop falling
}
// Remove if fallen off screen
if (self.y > 2732 + 50) {
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
self.destroy();
}
};
self.down = function (x, y, obj) {
playerMoney += self.value;
moneyText.setText(playerMoney + '¢');
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
LK.getSound('coinCollect').play();
self.destroy();
};
return self;
});
var Special100Coin = Container.expand(function () {
var self = Container.call(this);
self.value = 100;
self.canAttack = false;
var coinGraphics = self.attachAsset('100coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
self.down = function (x, y, obj) {
playerMoney += 100;
moneyText.setText(playerMoney + '¢');
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
LK.getSound('coinCollect').play();
self.destroy();
};
return self;
});
var Special1Coin = Container.expand(function () {
var self = Container.call(this);
self.value = 1;
self.canAttack = false;
var coinGraphics = self.attachAsset('1coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
self.down = function (x, y, obj) {
playerMoney += 1;
moneyText.setText(playerMoney + '¢');
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
LK.getSound('coinCollect').play();
self.destroy();
};
return self;
});
var Special3000Coin = Container.expand(function () {
var self = Container.call(this);
self.value = 3000;
self.canAttack = false;
var coinGraphics = self.attachAsset('3000coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
self.down = function (x, y, obj) {
playerMoney += 3000;
moneyText.setText(playerMoney + '¢');
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
LK.getSound('coinCollect').play();
self.destroy();
};
return self;
});
var Special50Coin = Container.expand(function () {
var self = Container.call(this);
self.value = 50;
self.canAttack = false;
var coinGraphics = self.attachAsset('50coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
self.down = function (x, y, obj) {
playerMoney += 50;
moneyText.setText(playerMoney + '¢');
var coinIndex = droppedCoins.indexOf(self);
if (coinIndex > -1) {
droppedCoins.splice(coinIndex, 1);
}
LK.getSound('coinCollect').play();
self.destroy();
};
return self;
});
var Superstronggoldendogform = Container.expand(function () {
var self = Container.call(this);
self.health = 202;
self.maxHealth = 202;
self.speed = 1.5;
self.target = null;
self.lastAttackTime = 0;
self.hitsTakenFromCats = 0;
self.hitsTakenFromDogs = 0;
self.isDying = false;
self.attackCount = 0; // Track how many times it's been attacked
self.spawnGoldenDogsThreshold = 200; // Spawn golden dogs after 200 attacks
var bossGraphics = self.attachAsset('Superstronggoldendogform', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6.0,
// Slightly bigger than irongolemhelper (4.0)
scaleY: 6.0
});
// Create health bar background
self.healthBarBack = LK.getAsset('Healthbarback', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.2,
scaleY: 1.7,
alpha: 0
});
// Create health bar that follows the boss
self.healthBar = LK.getAsset('Superstronggoldendogformhealth', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.0,
scaleY: 1.5
});
// Create health text showing 399
self.healthText = new Text2('399', {
size: 40,
fill: 0xFFFFFF
});
self.healthText.anchor.set(0.5, 0.5);
self.update = function () {
// Update health bar background position
self.healthBarBack.x = self.x;
self.healthBarBack.y = self.y - 200;
// Update health bar position to follow boss
self.healthBar.x = self.x;
self.healthBar.y = self.y - 200; // Position above the boss
// Update health bar visibility based on health percentage
var healthPercent = self.health / self.maxHealth;
self.healthBar.alpha = 0.7 + healthPercent * 0.3; // Fade as health decreases
// Update health text position and value
self.healthText.x = self.x;
self.healthText.y = self.y - 280; // Position above health bar
self.healthText.setText(Math.max(0, self.health).toString());
// Move towards nearest cat or cat base
var nearestTarget = null;
var nearestDistance = Infinity;
// Check cats
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
var dx = cat.x - self.x;
var dy = cat.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = cat;
}
}
if (nearestTarget) {
// Move towards nearest cat
var dx = nearestTarget.x - self.x;
var dy = nearestTarget.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Attack if close enough
if (distance < 80 && LK.ticks - self.lastAttackTime > 30) {
self.attack(nearestTarget);
self.lastAttackTime = LK.ticks;
}
} else if (catBaseObj && !catBaseObj.isDestroyed) {
// Move towards cat base if no cats present
var dx = catBaseObj.x - self.x;
var dy = catBaseObj.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 80) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else if (LK.ticks - self.lastAttackTime > 30) {
// Attack the base
catBaseObj.takeDamage(1000);
self.lastAttackTime = LK.ticks;
LK.getSound('battle').play();
}
}
};
self.attack = function (target) {
// Find nearest target within large radius for mind power
var nearestTarget = null;
var nearestDistance = Infinity;
// Check all cats
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
var dx = cat.x - self.x;
var dy = cat.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = cat;
}
}
// Check all iron golems
for (var i = 0; i < ironGolems.length; i++) {
var golem = ironGolems[i];
var dx = golem.x - self.x;
var dy = golem.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestTarget = golem;
}
}
// Use mind power to drag the nearest target (can be far away)
if (nearestTarget) {
self.mindPowerDrag(nearestTarget);
} else {
// Fallback to original target if no other targets found
self.mindPowerDrag(target);
}
LK.getSound('battle').play();
};
self.mindPowerDrag = function (target) {
// Check if target is an irongolemhelper
var isIronGolem = ironGolems.indexOf(target) > -1;
// Animate target being dragged into the ground with mind power
// Target can be dragged from any distance
tween(target, {
y: target.y + 500,
scaleX: target.scaleX * 0.3,
scaleY: target.scaleY * 0.1
}, {
duration: 2000,
easing: tween.easeIn,
onFinish: function onFinish() {
// Special handling for irongolemhelper
if (isIronGolem) {
// Drop ironingot worth 90¢
var ironingot = new IronIngot();
ironingot.value = 90; // Override default value
ironingot.x = target.x;
ironingot.y = target.originalY || target.y - 500;
droppedIngots.push(ironingot);
game.addChild(ironingot);
// Remove from ironGolems array
var golemIndex = ironGolems.indexOf(target);
if (golemIndex > -1) {
ironGolems.splice(golemIndex, 1);
}
target.destroy();
} else {
// After dragging, apply damage or kill for other targets
if (target.takeDamage) {
target.takeDamage(1000);
} else if (target.die) {
// Remove from appropriate array and kill
if (cats.indexOf(target) > -1) {
cats.splice(cats.indexOf(target), 1);
} else if (dogs.indexOf(target) > -1) {
dogs.splice(dogs.indexOf(target), 1);
}
target.die();
}
}
}
});
};
self.takeDamageFromCat = function () {
// Check if cats can defeat the boss
var canDefeat = false;
if (cats.length >= 30) {
// 30 or more cats can instantly defeat the boss
canDefeat = true;
} else if (cats.length >= 20) {
// 20 cats or more can defeat
canDefeat = true;
} else if (cats.length >= 10 && ironGolems.length >= 2) {
// 10+ cats with 2+ iron golems can defeat
canDefeat = true;
} else if (cats.length >= 10) {
// 10+ cats can instantly defeat the boss when it's strong
canDefeat = true;
} else if (cats.length >= 5 && ironGolems.length >= 2) {
// 5+ cats with 2+ iron golems can defeat
canDefeat = true;
} else if (cats.length >= 3 && ironGolems.length >= 1) {
// 3+ cats with 1+ iron golem can defeat
canDefeat = true;
}
if (canDefeat) {
self.health = 0;
self.die();
return;
}
self.health -= 8;
self.hitsTakenFromCats++;
self.attackCount++;
// Check if tired of getting attacked (spawn golden dogs)
if (self.attackCount >= self.spawnGoldenDogsThreshold) {
self.spawnGoldenDogs();
self.attackCount = 0; // Reset counter
}
if (self.health <= 0) {
self.die();
}
};
self.takeDamageFromIronGolem = function (ironGolem) {
// Check if irongolem is at 3 health for special animation
if (ironGolem && ironGolem.hitsTakenFromCats + ironGolem.hitsTakenFromDogs >= 20) {
// Special grab, toss, and step animation
var originalY = ironGolem.y;
// Grab and toss in the air
tween(ironGolem, {
y: ironGolem.y - 300,
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Fall back down
tween(ironGolem, {
y: originalY,
rotation: 0
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
// Superstronggoldendogform steps on irongolemhelper
tween(ironGolem, {
scaleX: ironGolem.scaleX * 0.3,
scaleY: ironGolem.scaleY * 0.1,
alpha: 0.5
}, {
duration: 500,
onFinish: function onFinish() {
// Drop ironingot
var ironingot = new IronIngot();
ironingot.x = ironGolem.x;
ironingot.y = ironGolem.y;
droppedIngots.push(ironingot);
game.addChild(ironingot);
// Remove irongolem
var golemIndex = ironGolems.indexOf(ironGolem);
if (golemIndex > -1) {
ironGolems.splice(golemIndex, 1);
}
ironGolem.destroy();
}
});
}
});
}
});
} else {
var damage = 45; // 45 damage from iron golem
self.health -= damage;
self.attackCount++;
// Check if tired of getting attacked (spawn golden dogs)
if (self.attackCount >= self.spawnGoldenDogsThreshold) {
self.spawnGoldenDogs();
self.attackCount = 0; // Reset counter
}
if (self.health <= 0) {
self.die();
}
}
};
self.takeDamageFromDog = function (dog) {
// Grab the dog and shove him to the ground
if (dog && !dog.isDying) {
// Animate dog being grabbed and shoved down
tween(dog, {
y: dog.y + 100,
scaleX: dog.scaleX * 0.5,
scaleY: dog.scaleY * 0.5
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
// Dog dies from being shoved
var dogIndex = dogs.indexOf(dog);
if (dogIndex > -1) {
dogs.splice(dogIndex, 1);
}
// Check cuteuwudogs array too
var cuteIndex = cuteuwudogs.indexOf(dog);
if (cuteIndex > -1) {
cuteuwudogs.splice(cuteIndex, 1);
}
if (dog.die) {
dog.die();
} else {
dog.destroy();
}
}
});
}
};
self.spawnGoldenDogs = function () {
// Spawn 3 golden dogs around the boss
for (var i = 0; i < 3; i++) {
var goldenDog = new Dog(true);
var angle = i / 3 * Math.PI * 2;
goldenDog.x = self.x + Math.cos(angle) * 150;
goldenDog.y = self.y + Math.sin(angle) * 150;
dogs.push(goldenDog);
game.addChild(goldenDog);
}
LK.getSound('spawn').play();
};
self.dropSpecialCoins = function () {
// Check for lucky drop (2 100¢ coins + 1 1¢ coin)
if (Math.random() < 0.1) {
// 10% chance for lucky drop
// Drop 2 100¢ coins
for (var i = 0; i < 2; i++) {
var coin100 = new Special100Coin();
coin100.x = self.x + (Math.random() - 0.5) * 200;
coin100.y = self.y + (Math.random() - 0.5) * 200;
droppedCoins.push(coin100);
game.addChild(coin100);
}
// Drop 1 1¢ coin
var coin1 = new Special1Coin();
coin1.x = self.x + (Math.random() - 0.5) * 200;
coin1.y = self.y + (Math.random() - 0.5) * 200;
droppedCoins.push(coin1);
game.addChild(coin1);
} else {
// Normal drop: 201 50¢ coins
for (var i = 0; i < 201; i++) {
var coin50 = new Special50Coin();
coin50.x = self.x + (Math.random() - 0.5) * 400;
coin50.y = self.y + (Math.random() - 0.5) * 400;
droppedCoins.push(coin50);
game.addChild(coin50);
}
}
};
self.die = function () {
if (self.isDying) return;
self.isDying = true;
// Stop boss music when superstronggoldendogform dies
LK.stopMusic();
// Check if cats won - if so, go underground like cats and dogs
if (gameState === 'catsWin' || cats.length > dogs.length) {
// Play death sound when cats win and superstronggoldendogform dies
LK.getSound('Superstronggoldendogformdies').play();
// Stop the sound and continue with death after delay
LK.setTimeout(function () {
LK.getSound('Superstronggoldendogformdies').stop();
// Now allow player to win if this was the victory condition
LK.showYouWin();
}, 3000);
// Store original position for underground state
self.originalY = self.y;
// First turn red, then wait 0.63 seconds, then sink underground
tween(self, {
tint: 0xff0000
}, {
duration: 630,
onFinish: function onFinish() {
// Stop being red and go underground
tween(self, {
tint: 0xFFFFFF,
y: self.y + 500,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
onFinish: function onFinish() {
self.isUnderground = true;
// Remove health elements when underground
if (self.healthBar) {
self.healthBar.destroy();
}
if (self.healthBarBack) {
self.healthBarBack.destroy();
}
if (self.healthText) {
self.healthText.destroy();
}
// Remove from array
var bossIndex = superstrongBosses.indexOf(self);
if (bossIndex > -1) {
superstrongBosses.splice(bossIndex, 1);
}
}
});
}
});
// Don't allow movement underground
self.update = function () {
// Do nothing - can't move when underground
};
return;
}
// Normal death behavior
// Change to death sprite
var deathGraphics = self.attachAsset('Superstronggoldendogformdie', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6.0,
scaleY: 6.0
});
// Play death sound
LK.getSound('Superstronggoldendogformdies').play();
// Stop death sound and remove boss after a delay
LK.setTimeout(function () {
// Stop the death sound
LK.getSound('Superstronggoldendogformdies').stop();
// Play yippee sound as many times as there are cats
var catsCount = cats.length;
for (var yippeeIndex = 0; yippeeIndex < catsCount; yippeeIndex++) {
LK.getSound('Yipee').play();
}
// Drop 2 3000¢ coins
for (var i = 0; i < 2; i++) {
var coin3000 = new Special3000Coin();
coin3000.x = self.x + (Math.random() - 0.5) * 300;
coin3000.y = self.y + (Math.random() - 0.5) * 300;
droppedCoins.push(coin3000);
game.addChild(coin3000);
}
// Remove health elements
if (self.healthBar) {
self.healthBar.destroy();
}
if (self.healthBarBack) {
self.healthBarBack.destroy();
}
if (self.healthText) {
self.healthText.destroy();
}
// Make boss disappear
self.destroy();
// Remove from array
var bossIndex = superstrongBosses.indexOf(self);
if (bossIndex > -1) {
superstrongBosses.splice(bossIndex, 1);
}
// Start 5-minute cooldown for next boss spawn
lastBossSpawnTime = LK.ticks;
}, 3000); // Wait 3 seconds before cleanup
};
self.down = function (x, y, obj) {
if (self.isUnderground) {
// Fly into the sky
tween(self, {
y: self.y - 800,
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Explode effect (flash red briefly)
tween(self, {
tint: 0xff0000,
scaleX: self.scaleX * 2,
scaleY: self.scaleY * 2,
alpha: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
// Drop random coin (1¢, 50¢, or 100¢)
var coinValues = [1, 50, 100];
var randomValue = coinValues[Math.floor(Math.random() * coinValues.length)];
var coin = new SmallRandomCoin(randomValue);
coin.x = self.x;
coin.y = self.y;
droppedCoins.push(coin);
game.addChild(coin);
LK.getSound('coinCollect').play();
self.destroy();
}
});
}
});
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var playerMoney = 50;
var dogs = [];
var cats = [];
var droppedCoins = [];
var ironGolems = [];
var superstrongBosses = [];
var cuteuwudogs = [];
var droppedIngots = [];
var clouds = [];
var ironGolemBosses = [];
var lastBossSpawnTime = 0;
var bossSpawnCooldown = 18000; // 5 minutes at 60 FPS (5 * 60 * 60)
var gameState = 'playing'; // 'playing', 'dogsWin', 'catsWin'
var dogBaseObj = null;
var catBaseObj = null;
var lastCloudSpawnTime = 0;
var cloudSpawnInterval = 60; // Spawn clouds every 60 ticks for fewer clouds
// Create piggy bank GUI
var piggyBank = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
LK.gui.topLeft.addChild(piggyBank);
piggyBank.x = 80;
piggyBank.y = 80;
// Create money display next to piggy bank
var moneyText = new Text2(playerMoney + '¢', {
size: 60,
fill: 0xFFFFFF
});
moneyText.anchor.set(0, 0);
LK.gui.topLeft.addChild(moneyText);
moneyText.x = 120; // Offset from the left edge to avoid menu icon
// Create message text for feedback
var messageText = new Text2('', {
size: 50,
fill: 0xFF0000
});
messageText.anchor.set(0.5, 0);
LK.gui.top.addChild(messageText);
messageText.y = 100;
var messageTimer = 0;
function showMessage(text) {
messageText.setText(text);
messageTimer = 180; // Show for 3 seconds
}
// Add ground dirt to bottom of screen
var groundDirt = LK.getAsset('Grounddirt', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 11.5,
scaleY: 4.8
});
game.addChild(groundDirt);
groundDirt.x = 1024; // Center horizontally (2048/2)
groundDirt.y = 2732; // Bottom of screen
// Add grass on top of ground dirt, stretching across screen
var grass = LK.getAsset('Grass', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 25.0,
scaleY: 8.0
});
game.addChild(grass);
grass.x = 1024; // Center horizontally (2048/2)
grass.y = groundDirt.y - groundDirt.height * groundDirt.scaleY + 50; // Position on top of grounddirt
// Create bases
dogBaseObj = game.addChild(new Base('dog'));
dogBaseObj.x = 400;
dogBaseObj.y = 1366;
catBaseObj = game.addChild(new Base('cat'));
catBaseObj.x = 1648;
catBaseObj.y = 1366;
// Base click handlers
dogBaseObj.down = function (x, y, obj) {
if (gameState !== 'playing' || dogBaseObj.isDestroyed) return;
// Start tracking hold
dogBaseHoldStart = LK.ticks;
dogBaseIsHolding = true;
};
dogBaseObj.up = function (x, y, obj) {
if (gameState !== 'playing' || dogBaseObj.isDestroyed) return;
var holdDuration = LK.ticks - dogBaseHoldStart;
dogBaseIsHolding = false;
// If held for more than 1 second (60 ticks) and have 899¢ or more, try special spawns
if (holdDuration >= 60 && playerMoney >= 899) {
var spawnRoll = Math.random();
if (spawnRoll < 0.10) {
// 10% chance for Superstronggoldendogform
var newBoss = new Superstronggoldendogform();
newBoss.x = dogBaseObj.x + (Math.random() - 0.5) * 300;
newBoss.y = dogBaseObj.y - 150 + (Math.random() - 0.5) * 150;
superstrongBosses.push(newBoss);
game.addChild(newBoss);
game.addChild(newBoss.healthBar);
game.addChild(newBoss.healthBarBack);
LK.playMusic('Bossmusic');
LK.getSound('spawn').play();
} else if (spawnRoll < 0.66) {
// 56% chance for cuteuwudog
var newCuteuwudog = new Cuteuwudog();
newCuteuwudog.x = dogBaseObj.x + (Math.random() - 0.5) * 300;
newCuteuwudog.y = dogBaseObj.y - 150 + (Math.random() - 0.5) * 150;
cuteuwudogs.push(newCuteuwudog);
game.addChild(newCuteuwudog);
LK.getSound('spawn').play();
}
// No spawn for remaining 34% chance
} else if (holdDuration < 60) {
// Quick click spawning
var spawnRoll = Math.random();
if (spawnRoll < 0.99) {
// 99% chance for normal dog
var newDog = new Dog(false);
newDog.x = dogBaseObj.x + (Math.random() - 0.5) * 200;
newDog.y = dogBaseObj.y - 100 + (Math.random() - 0.5) * 100;
dogs.push(newDog);
game.addChild(newDog);
LK.getSound('spawn').play();
} else if (spawnRoll < 1.36) {
// 37% chance for Dogwothtophat (but this would be > 100%, so it's impossible)
// This creates the intended behavior where normal dog is much more common
var newDogWithHat = new DogwithTophat();
newDogWithHat.x = dogBaseObj.x + (Math.random() - 0.5) * 200;
newDogWithHat.y = dogBaseObj.y - 100 + (Math.random() - 0.5) * 100;
dogs.push(newDogWithHat);
game.addChild(newDogWithHat);
LK.getSound('spawn').play();
}
}
};
// Track hold state for catBase
var catBaseHoldStart = 0;
var catBaseIsHolding = false;
// Track hold state for dogBase
var dogBaseHoldStart = 0;
var dogBaseIsHolding = false;
catBaseObj.down = function (x, y, obj) {
if (gameState !== 'playing' || catBaseObj.isDestroyed) return;
// Start tracking hold
catBaseHoldStart = LK.ticks;
catBaseIsHolding = true;
};
catBaseObj.up = function (x, y, obj) {
if (gameState !== 'playing' || catBaseObj.isDestroyed) return;
var holdDuration = LK.ticks - catBaseHoldStart;
catBaseIsHolding = false;
// If held for more than 1 second (60 ticks) and have 1000¢ or more, 23% chance to spawn iron golem boss
if (holdDuration >= 60 && playerMoney >= 1000 && Math.random() < 0.23) {
// Spawn iron golem boss
var ironGolemBoss = new IronGolemBoss();
ironGolemBoss.x = catBaseObj.x + (Math.random() - 0.5) * 300;
ironGolemBoss.y = catBaseObj.y - 150 + (Math.random() - 0.5) * 150;
ironGolemBosses.push(ironGolemBoss);
game.addChild(ironGolemBoss);
// Play boss music when iron golem boss is spawned
LK.playMusic('Irongolemboss');
LK.getSound('spawn').play();
} else if (holdDuration >= 60 && playerMoney >= 100) {
// Spawn irongolemhelper
var irongolem = new IronGolemHelper();
irongolem.x = catBaseObj.x + (Math.random() - 0.5) * 300;
irongolem.y = catBaseObj.y - 150 + (Math.random() - 0.5) * 150;
ironGolems.push(irongolem);
game.addChild(irongolem);
LK.getSound('spawn').play();
} else {
// Short tap - spawn normal cat
var newCat = new Cat(false);
newCat.x = catBaseObj.x + (Math.random() - 0.5) * 200;
newCat.y = catBaseObj.y - 100 + (Math.random() - 0.5) * 100;
cats.push(newCat);
game.addChild(newCat);
// Check if cat spawned too close to any iron golem
var tooCloseToGolem = false;
for (var g = 0; g < ironGolems.length; g++) {
var golem = ironGolems[g];
var dx = golem.x - newCat.x;
var dy = golem.y - newCat.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 150) {
// Within 150 pixels is "too close"
// 5% chance iron golem will fling the cat
if (Math.random() < 0.05) {
golem.flingCat(newCat);
}
tooCloseToGolem = true;
break; // Only need to check once
}
}
LK.getSound('spawn').play();
}
};
game.update = function () {
// Update message timer
if (messageTimer > 0) {
messageTimer--;
if (messageTimer <= 0) {
messageText.setText('');
}
}
// Keep animals within bounds
for (var i = 0; i < dogs.length; i++) {
var dog = dogs[i];
if (dog.x < 0) dog.x = 0;
if (dog.x > 2048) dog.x = 2048;
if (dog.y < 0) dog.y = 0;
if (dog.y > 2732) dog.y = 2732;
}
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
if (cat.x < 0) cat.x = 0;
if (cat.x > 2048) cat.x = 2048;
if (cat.y < 0) cat.y = 0;
if (cat.y > 2732) cat.y = 2732;
}
for (var i = 0; i < ironGolems.length; i++) {
var golem = ironGolems[i];
if (golem.x < 0) golem.x = 0;
if (golem.x > 2048) golem.x = 2048;
if (golem.y < 0) golem.y = 0;
if (golem.y > 2732) golem.y = 2732;
}
// Keep superstrongBosses within bounds
for (var i = 0; i < superstrongBosses.length; i++) {
var boss = superstrongBosses[i];
if (boss.x < 0) boss.x = 0;
if (boss.x > 2048) boss.x = 2048;
if (boss.y < 0) boss.y = 0;
if (boss.y > 2732) boss.y = 2732;
}
// Keep cuteuwudogs within bounds
for (var i = 0; i < cuteuwudogs.length; i++) {
var cutedog = cuteuwudogs[i];
if (cutedog.x < 0) cutedog.x = 0;
if (cutedog.x > 2048) cutedog.x = 2048;
if (cutedog.y < 0) cutedog.y = 0;
if (cutedog.y > 2732) cutedog.y = 2732;
}
// Keep iron golem bosses within bounds
for (var i = 0; i < ironGolemBosses.length; i++) {
var boss = ironGolemBosses[i];
if (boss.x < 0) boss.x = 0;
if (boss.x > 2048) boss.x = 2048;
if (boss.y < 0) boss.y = 0;
if (boss.y > 2732) boss.y = 2732;
}
// Cloud spawning logic - spawn fewer clouds
if (LK.ticks - lastCloudSpawnTime >= 60) {
// Spawn every 60 ticks (slower)
// Spawn 1 cloud at a time to reduce cloud density
var newCloud = new Cloud();
newCloud.x = 2048 + 100 + Math.random() * 200; // Spawn from right side
newCloud.y = 50 + Math.random() * 600; // Cover sky area
clouds.push(newCloud);
game.addChild(newCloud);
lastCloudSpawnTime = LK.ticks;
}
// Boss spawn logic - only spawn if cooldown has passed and no boss exists
if (superstrongBosses.length === 0 && LK.ticks - lastBossSpawnTime >= bossSpawnCooldown) {
// Random chance to spawn boss (23% chance each frame after cooldown)
if (Math.random() < 0.23) {
var newBoss = new Superstronggoldendogform();
newBoss.x = 1400; // More to the right
newBoss.y = 800; // More up
superstrongBosses.push(newBoss);
game.addChild(newBoss);
// Add health elements to game
game.addChild(newBoss.healthBarBack);
game.addChild(newBoss.healthBar);
game.addChild(newBoss.healthText);
// Play boss music
LK.playMusic('Bossmusic');
}
}
};
A white dog with black spots on him and one ear black and one ear blue. Make it a sitting dog with a heart grey hole in the middle of the body and make it SOOOO cute with big cute eyes with shines in them and make the dog facing right. Kinda 3d. Some Shadows.
A golden shining coin with the words “dogs vs cats coin” at the top and the coin says “50¢” . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Minecraft iron golem facing left with a pink flower on his forehead. Full body. 2d. Cool.
Golden dog with blue eyes that is SOO BUFF that he looks so cool and he scares everyone away. full body. Facing right. 2d.
Make a green health bar with words under it golden shiny letters saying “Superstronggoldendogform” and golden words on top saying “399HP”. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A golden shining coin with the words “dogs vs cats coin” at the top and the coin says “100¢” . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Brown dog with a blue top hat. 🎩. In-Game asset. High contrast. No shadows. 2d.
Super buff Golden dog with a hand up laying falling in lava holding his hand out for help. full body. Facing right. 2d.
Make a white dog SOOOOOO CUTE. In-Game asset. 2d. High contrast. No shadows
A golden shining coin with the words “dogs vs cats coin” at the top and the coin says “1¢” . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
No background Minecraft iron ingot
Dirt square
Line of grass. In-Game asset. 2d. High contrast. No shadows
Cloud. In-Game asset. 2d. High contrast. No shadows
A golden shining coin with the words “dogs vs cats coin” at the top and the coin says “3000¢” with a dark yellow line under. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A super buff iron golem with super big muscles and that has a Minecraft iron sword in his hand.. In-Game asset. 2d. High contrast. No shadows