/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
playerResources: 0,
totalKills: 0
});
/****
* Classes
****/
// Base class
var Base = Container.expand(function () {
var self = Container.call(this);
var baseGraphics = self.attachAsset('playerBase', {
anchorX: 0.5,
anchorY: 1
});
var healthBar = self.addChild(new HealthBar());
healthBar.y = -180;
self.maxHealth = 200;
self.health = 200;
self.color = 0x4169E1;
self.takeDamage = function (dmg) {
self.health -= dmg;
healthBar.setHealth(self.health, self.maxHealth);
};
self.setColor = function (color) {
self.color = color;
baseGraphics.tint = color;
};
return self;
});
// Bullet class for gunner cat
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('background', {
width: 15,
height: 15,
color: 0xFFFF00,
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 3;
self.speed = 8;
self.direction = -1;
self.lifetime = 300; // 5 seconds at 60 FPS
self.update = function () {
self.x += self.speed * self.direction;
self.lifetime--;
};
return self;
});
// Cat Unit Base Class
var CatUnit = Container.expand(function () {
var self = Container.call(this);
var catGraphics = self.attachAsset('catNormal', {
anchorX: 0.5,
anchorY: 0.5
});
var healthBar = self.addChild(new HealthBar());
healthBar.y = -50;
self.maxHealth = 30;
self.health = 30;
self.damage = 5;
self.speed = 2;
self.direction = -1; // -1 for left, 1 for right
self.gravity = 0.3;
self.velocityY = 0;
self.onGround = false;
self.groundLevel = 2732 - 100 - 40;
self.lastX = self.x;
self.takeDamage = function (dmg) {
self.health -= dmg;
healthBar.setHealth(self.health, self.maxHealth);
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
self.update = function () {
self.lastX = self.x;
// Apply gravity
if (self.y < self.groundLevel) {
self.velocityY += self.gravity;
self.y += self.velocityY;
} else {
self.y = self.groundLevel;
self.velocityY = 0;
self.onGround = true;
}
// Move horizontally
self.x += self.speed * self.direction;
};
return self;
});
// Titan Cat
var CatTitan = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catTitan', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 17;
self.health = 17;
self.damage = 7;
self.speed = 2;
self.cost = 55;
return self;
});
// Tank Cat
var CatTank = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catDefense', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 60;
self.health = 60;
self.damage = 3;
self.speed = 1;
self.cost = 25;
return self;
});
// Normal Cat
var CatNormal = CatUnit.expand(function () {
var self = CatUnit.call(this);
var catGraphics = LK.getAsset('catNormal', {
anchorX: 0.5,
anchorY: 0.5
});
self.attachAsset('catNormal', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 30;
self.health = 30;
self.damage = 5;
self.speed = 2;
self.cost = 15;
return self;
});
// Milk Cat
var CatMilk = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catMilk', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 70;
self.health = 70;
self.damage = 3;
self.speed = 2.5; // 25% faster than normal cat (2 * 1.25)
self.cost = 25;
return self;
});
// Healer Cat
var CatHealer = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catNormal', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 35;
self.health = 35;
self.damage = 2;
self.speed = 1.7; // 19% slower than normal cat (2 * 0.81)
self.cost = 25;
self.healRadius = 150;
self.healAmount = 2;
self.healCooldown = 0;
self.healInterval = 30; // Heal every 30 frames (0.5 seconds at 60 FPS)
var originalUpdate = self.update;
self.update = function () {
originalUpdate.call(self);
self.healCooldown--;
};
self.healNearby = function (allies) {
if (self.healCooldown <= 0) {
for (var i = 0; i < allies.length; i++) {
var ally = allies[i];
if (ally === self) continue;
var dx = ally.x - self.x;
var dy = ally.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.healRadius) {
ally.health = Math.min(ally.maxHealth, ally.health + self.healAmount);
if (ally.healthBar) {
ally.healthBar.setHealth(ally.health, ally.maxHealth);
}
}
}
self.healCooldown = self.healInterval;
}
};
return self;
});
// Gunner Cat
var CatGunner = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catGunner', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 15;
self.health = 15;
self.damage = 3;
self.speed = 1.4; // 30% slower (2 * 0.7) = 1.4
self.cost = 45;
self.shootCooldown = 0;
self.shootInterval = 60; // Shoot every 60 frames (1 second at 60 FPS)
self.bulletDamage = 3;
self.shootRange = 400;
self.projectileCount = 0; // Track projectiles for meteorite
self.isShooting = false; // Track if currently shooting
var originalUpdate = self.update;
self.update = function () {
// Only move if not shooting
if (!self.isShooting) {
originalUpdate.call(self);
}
self.shootCooldown--;
// Reset shooting state if cooldown finished
if (self.shootCooldown <= 0) {
self.isShooting = false;
}
};
self.findTarget = function (enemies) {
var closest = null;
var closestDist = self.shootRange;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < closestDist) {
closestDist = distance;
closest = enemy;
}
}
return closest;
};
self.shoot = function (target) {
if (self.shootCooldown <= 0 && target) {
self.shootCooldown = self.shootInterval;
self.isShooting = true; // Stop moving while shooting
self.projectileCount++; // Increment projectile count
return true;
}
return false;
};
return self;
});
// Axe Cat
var CatAxe = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catAxe', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 40;
self.health = 40;
self.damage = 10;
self.speed = 1.5;
self.cost = 55;
return self;
});
// Enemy Unit Base Class
var EnemyUnit = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
var healthBar = self.addChild(new HealthBar());
healthBar.y = -50;
self.maxHealth = 25;
self.health = 25;
self.damage = 4;
self.speed = 1.5;
self.direction = 1; // 1 for right
self.gravity = 0.3;
self.velocityY = 0;
self.onGround = false;
self.groundLevel = 2732 - 100 - 40;
self.lastX = self.x;
self.takeDamage = function (dmg) {
self.health -= dmg;
healthBar.setHealth(self.health, self.maxHealth);
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
self.update = function () {
self.lastX = self.x;
// Apply gravity
if (self.y < self.groundLevel) {
self.velocityY += self.gravity;
self.y += self.velocityY;
} else {
self.y = self.groundLevel;
self.velocityY = 0;
self.onGround = true;
}
// Move horizontally
self.x += self.speed * self.direction;
};
return self;
});
// Snake Enemy
var Snake = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
self.attachAsset('snake', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 35;
self.health = 35;
self.damage = 8;
self.speed = 1;
return self;
});
// Pig Enemy
var Pig = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
self.attachAsset('pig', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 50;
self.health = 50;
self.damage = 6;
self.speed = 0.8;
return self;
});
//{dog_potato6}
// Penguin Enemy
var Penguin = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 12;
self.health = 12;
self.damage = 3.5;
self.speed = 1.65; // 10% faster (1.5 * 1.1)
return self;
});
// Mammoth Enemy
var Mammoth = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 20;
self.health = 20;
self.damage = 7;
self.speed = 1.2;
return self;
});
// Dog Potato Nose Enemy
var DogPotatoNose = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
//{dog_potato1}
self.attachAsset('dog', {
anchorX: 0.5,
//{dog_potato2}
anchorY: 0.5 //{dog_potato3}
}); //{dog_potato4}
self.maxHealth = 1;
self.health = 1;
self.damage = 1;
self.speed = 1.1; // 26% slower (1.5 * 0.74)
self.shootRange = 100; // Short range attack
return self; //{dog_potato5}
});
// Dog Enemy
var Dog = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 25;
self.health = 25;
self.damage = 4;
self.speed = 1.5;
return self;
});
// Health Bar class
var HealthBar = Container.expand(function () {
var self = Container.call(this);
var maxHealth = 100;
var currentHealth = 100;
var background = LK.getAsset('background', {
width: 40,
height: 8,
color: 0x000000
});
var healthFill = LK.getAsset('healthFill', {
width: 40,
height: 8,
color: 0x00FF00
});
self.addChild(background);
self.addChild(healthFill);
self.setHealth = function (health, max) {
maxHealth = max;
currentHealth = health;
var percent = Math.max(0, currentHealth / maxHealth);
healthFill.width = 40 * percent;
if (percent > 0.5) {
healthFill.tint = 0x00FF00;
} else if (percent > 0.25) {
healthFill.tint = 0xFFFF00;
} else {
healthFill.tint = 0xFF0000;
}
};
return self;
});
// Laser class for boss attacks
var Laser = Container.expand(function () {
var self = Container.call(this);
var laserGraphics = self.attachAsset('background', {
width: 20,
height: 300,
color: 0xFF0000
});
self.damage = 4;
self.speed = 10;
self.direction = 1;
self.lifetime = 100; // Short lived
self.impacted = false;
self.update = function () {
self.x += self.speed * self.direction;
self.lifetime--;
};
return self;
});
// Meteorite class for gunner special attack
var Meteorite = Container.expand(function () {
var self = Container.call(this);
//{meteor_new1}
var meteorGraphics = self.attachAsset('background', {
width: 40,
//{meteor_new2}
height: 40,
//{meteor_new3}
color: 0xFF8C00 //{meteor_new4}
}); //{meteor_new5}
self.damage = 5; //{meteor_new6}
self.speed = 6; //{meteor_new7}
self.direction = -1; //{meteor_new8}
self.lifetime = 500; // 8+ seconds at 60 FPS//{meteor_new9}
self.impacted = false; // Track if already impacted//{meteor_new10}
self.explosionRadius = 200; // Area of effect radius//{meteor_new11}
self.update = function () {
//{meteor_new12}
self.x += self.speed * self.direction; //{meteor_new13}
self.lifetime--; //{meteor_new14}
}; //{meteor_new15}
return self; //{meteor_new16}
});
//{meteor_new17}
// Robot Dog Boss
var RobotDog = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
var healthBar = self.addChild(new HealthBar());
healthBar.y = -50;
self.maxHealth = 1;
self.health = 1;
self.damage = 0; // Boss doesn't deal damage on contact
self.speed = 0; // Boss doesn't move
self.x = 100; // Fixed position at enemy base
self.y = 2732 - 100 - 40; // Ground level
self.laserDamage = 4;
self.laserCooldown = 0;
self.laserInterval = 60; // Fire every 60 frames
self.laserSpamCooldown = 0; // Anti-spam cooldown of 1 second
self.takeDamage = function (dmg) {
self.health -= dmg;
healthBar.setHealth(self.health, self.maxHealth);
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
self.update = function () {
self.laserCooldown--;
self.laserSpamCooldown--;
};
return self;
});
//{meteor_new17}
// Shop Button
var ShopButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('shopButton', {
anchorX: 0.5,
anchorY: 0.5
});
var label = self.addChild(new Text2('SHOP', {
size: 24,
fill: 0x000000
}));
label.anchor.set(0.5, 0.5);
self.cost = 0;
self.unitType = 'normal';
self.down = function (x, y, obj) {
// Handle button press
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Sounds
// UI Elements
// Ground
// Bases
// Enemies
// Cats
// Add ground
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 1
}));
ground.x = 0;
ground.y = 2732;
// Create bases
var playerBase = game.addChild(new Base());
playerBase.x = 2048 - 100;
playerBase.y = 2732 - 100;
playerBase.setColor(0x4169E1);
var enemyBase = game.addChild(new Base());
enemyBase.x = 100;
enemyBase.y = 2732 - 100;
enemyBase.setColor(0xDC143C);
// Arrays for units
var catUnits = [];
var enemyUnits = [];
// Game state
var playerResources = storage.playerResources || 50;
var enemyResources = 50;
var gameOver = false;
var passiveMoneyPerTick = 0.016666; // 1 money per millisecond at 60 FPS
var accumulatedMoney = 0;
var totalMoneyEarned = 0;
var lastMammothSpawn = 0;
// UI - Resources display
var resourceText = new Text2('Resources: ' + Math.floor(playerResources), {
size: 60,
fill: 0x000000
});
resourceText.anchor.set(0.5, 0);
LK.gui.top.addChild(resourceText);
// Shop buttons - positioned at center of game (not GUI)
var normalCatButton = new Container();
normalCatButton.x = 1024 - 300;
normalCatButton.y = 400;
var normalButtonGraphics = normalCatButton.attachAsset('catNormal', {
anchorX: 0.5,
anchorY: 0.5
});
var normalCostText = normalCatButton.addChild(new Text2('15', {
size: 24,
fill: 0xFFFFFF
}));
normalCostText.anchor.set(0.5, 0.5);
normalCostText.y = 40;
normalCatButton.interactive = true;
normalCatButton.down = function (x, y, obj) {
if (playerResources >= 15) {
var newCat = game.addChild(new CatNormal());
newCat.x = playerBase.x - 100;
newCat.y = playerBase.y - 100;
newCat.direction = -1;
catUnits.push(newCat);
playerResources -= 15;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
LK.getSound('spawn').play();
}
};
normalCatButton.buttonMode = true;
game.addChild(normalCatButton);
var tankCatButton = new Container();
tankCatButton.x = 1024;
tankCatButton.y = 400;
var tankButtonGraphics = tankCatButton.attachAsset('catTank', {
anchorX: 0.5,
anchorY: 0.5
});
var tankCostText = tankCatButton.addChild(new Text2('25', {
size: 24,
fill: 0xFFFFFF
}));
tankCostText.anchor.set(0.5, 0.5);
tankCostText.y = 50;
tankCatButton.interactive = true;
tankCatButton.down = function (x, y, obj) {
if (playerResources >= 25) {
var newCat = game.addChild(new CatTank());
newCat.x = playerBase.x - 100;
newCat.y = playerBase.y - 100;
newCat.direction = -1;
catUnits.push(newCat);
playerResources -= 25;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
LK.getSound('spawn').play();
}
};
tankCatButton.buttonMode = true;
game.addChild(tankCatButton);
var milkCatButton = new Container();
milkCatButton.x = 1024 - 150;
milkCatButton.y = 400;
var milkButtonGraphics = milkCatButton.attachAsset('catMilk', {
anchorX: 0.5,
//{milk_btn1}
anchorY: 0.5 //{milk_btn2}
}); //{milk_btn3}
var milkCostText = milkCatButton.addChild(new Text2('25', {
size: 24,
//{milk_btn4}
fill: 0xFFFFFF //{milk_btn5}
})); //{milk_btn6}
milkCostText.anchor.set(0.5, 0.5);
milkCostText.y = 40;
milkCatButton.interactive = true;
milkCatButton.down = function (x, y, obj) {
if (playerResources >= 25) {
var newCat = game.addChild(new CatMilk());
newCat.x = playerBase.x - 100; //{milk_btn7}
newCat.y = playerBase.y - 100; //{milk_btn8}
newCat.direction = -1; //{milk_btn9}
catUnits.push(newCat); //{milk_btn10}
playerResources -= 25;
storage.playerResources = playerResources; //{milk_btn11}
resourceText.setText('Resources: ' + Math.floor(playerResources)); //{milk_btn12}
LK.getSound('spawn').play(); //{milk_btn13}
} //{milk_btn14}
}; //{milk_btn15}
milkCatButton.buttonMode = true;
game.addChild(milkCatButton);
var axeCatButton = new Container();
axeCatButton.x = 1024 + 300;
axeCatButton.y = 400;
var axeButtonGraphics = axeCatButton.attachAsset('catAxe', {
anchorX: 0.5,
anchorY: 0.5
});
var axeCostText = axeCatButton.addChild(new Text2('55', {
size: 24,
fill: 0xFFFFFF
}));
axeCostText.anchor.set(0.5, 0.5);
axeCostText.y = 45;
axeCatButton.interactive = true;
axeCatButton.down = function (x, y, obj) {
if (playerResources >= 55) {
var newCat = game.addChild(new CatAxe());
newCat.x = playerBase.x - 100;
newCat.y = playerBase.y - 100;
newCat.direction = -1;
catUnits.push(newCat);
playerResources -= 55;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
LK.getSound('spawn').play();
}
};
axeCatButton.buttonMode = true;
game.addChild(axeCatButton);
// Healer Cat Button
var healerCatButton = new Container();
healerCatButton.x = 1024 + 150;
healerCatButton.y = 400;
var healerButtonGraphics = healerCatButton.attachAsset('catNormal', {
anchorX: 0.5,
//{healer_btn1}
anchorY: 0.5 //{healer_btn2}
}); //{healer_btn3}
var healerCostText = healerCatButton.addChild(new Text2('25', {
size: 24,
//{healer_btn4}
fill: 0xFFFFFF //{healer_btn5}
})); //{healer_btn6}
healerCostText.anchor.set(0.5, 0.5);
healerCostText.y = 40;
healerCatButton.interactive = true;
healerCatButton.down = function (x, y, obj) {
if (playerResources >= 25) {
var newCat = game.addChild(new CatHealer());
newCat.x = playerBase.x - 100; //{healer_btn7}
newCat.y = playerBase.y - 100; //{healer_btn8}
newCat.direction = -1; //{healer_btn9}
catUnits.push(newCat); //{healer_btn10}
playerResources -= 25;
storage.playerResources = playerResources; //{healer_btn11}
resourceText.setText('Resources: ' + Math.floor(playerResources)); //{healer_btn12}
LK.getSound('spawn').play(); //{healer_btn13}
} //{healer_btn14}
}; //{healer_btn15}
healerCatButton.buttonMode = true;
game.addChild(healerCatButton);
// Gunner Cat Button
var gunnerCatButton = new Container();
gunnerCatButton.x = 1024 + 450;
gunnerCatButton.y = 400;
var gunnerButtonGraphics = gunnerCatButton.attachAsset('catNormal', {
anchorX: 0.5,
//{gunner_btn1}
anchorY: 0.5 //{gunner_btn2}
}); //{gunner_btn3}
var gunnerCostText = gunnerCatButton.addChild(new Text2('45', {
size: 24,
//{gunner_btn4}
fill: 0xFFFFFF //{gunner_btn5}
})); //{gunner_btn6}
gunnerCostText.anchor.set(0.5, 0.5);
gunnerCostText.y = 40;
gunnerCatButton.interactive = true;
gunnerCatButton.down = function (x, y, obj) {
if (playerResources >= 45) {
var newCat = game.addChild(new CatGunner());
newCat.x = playerBase.x - 100; //{gunner_btn7}
newCat.y = playerBase.y - 100; //{gunner_btn8}
newCat.direction = -1; //{gunner_btn9}
catUnits.push(newCat); //{gunner_btn10}
playerResources -= 45;
storage.playerResources = playerResources; //{gunner_btn11}
resourceText.setText('Resources: ' + Math.floor(playerResources)); //{gunner_btn12}
LK.getSound('spawn').play(); //{gunner_btn13}
} //{gunner_btn14}
}; //{gunner_btn15}
gunnerCatButton.buttonMode = true;
game.addChild(gunnerCatButton);
// Titan Cat Button
var titanCatButton = new Container();
titanCatButton.x = 1024 - 450;
titanCatButton.y = 400;
var titanButtonGraphics = titanCatButton.attachAsset('catTitan', {
anchorX: 0.5,
anchorY: 0.5
});
var titanCostText = titanCatButton.addChild(new Text2('55', {
size: 24,
fill: 0xFFFFFF
}));
titanCostText.anchor.set(0.5, 0.5);
titanCostText.y = 50;
titanCatButton.interactive = true;
titanCatButton.down = function (x, y, obj) {
if (playerResources >= 55) {
var newCat = game.addChild(new CatTitan());
newCat.x = playerBase.x - 100;
newCat.y = playerBase.y - 100;
newCat.direction = -1;
catUnits.push(newCat);
playerResources -= 55;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
LK.getSound('spawn').play();
}
};
titanCatButton.buttonMode = true;
game.addChild(titanCatButton);
// Enemy spawn timer
var mammothSpawnCounter = 0;
var mammothEventTimer = LK.setInterval(function () {
if (gameOver) return;
// Spawn mammoth at enemy base to attack player base
var eventMammoth = game.addChild(new Mammoth());
eventMammoth.x = enemyBase.x + 100;
eventMammoth.y = enemyBase.y - 100;
eventMammoth.direction = 1;
enemyUnits.push(eventMammoth);
LK.getSound('spawn').play();
}, 20000);
var enemySpawnTimer = LK.setInterval(function () {
if (gameOver) return;
if (enemyResources >= 10) {
var randomValue = Math.random();
var newEnemy;
if (randomValue < 0.65) {
newEnemy = new Dog();
enemyResources -= 10;
} else if (randomValue < 0.88) {
newEnemy = new Snake();
enemyResources -= 15;
} else if (randomValue < 0.93) {
newEnemy = new Penguin();
enemyResources -= 12;
} else if (randomValue < 0.98) {
newEnemy = new Pig();
enemyResources -= 20;
} else {
newEnemy = new Mammoth();
enemyResources -= 25;
}
newEnemy = game.addChild(newEnemy);
newEnemy.x = enemyBase.x + 100;
newEnemy.y = enemyBase.y - 100;
newEnemy.direction = 1;
enemyUnits.push(newEnemy);
LK.getSound('spawn').play();
}
}, 2000);
// Main game update
game.update = function () {
if (gameOver) return;
// Passive money generation - 1 money per millisecond
accumulatedMoney += passiveMoneyPerTick;
if (accumulatedMoney >= 1) {
var moneyGained = Math.floor(accumulatedMoney);
playerResources += moneyGained;
totalMoneyEarned += moneyGained;
accumulatedMoney -= moneyGained;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
// Spawn mammoth every 120 coins earned
if (totalMoneyEarned - lastMammothSpawn >= 120) {
var mammoth = game.addChild(new Mammoth());
mammoth.x = enemyBase.x + 100;
mammoth.y = enemyBase.y - 100;
mammoth.direction = 1;
enemyUnits.push(mammoth);
LK.getSound('spawn').play();
lastMammothSpawn = totalMoneyEarned;
// Disable all current cats for 5 seconds
for (var k = 0; k < catUnits.length; k++) {
var affectedCat = catUnits[k];
affectedCat.originalHealth = affectedCat.health;
affectedCat.originalDamage = affectedCat.damage;
affectedCat.health = 1;
affectedCat.damage = 0;
affectedCat.mammothDisabledTime = 300; // 5 seconds at 60 FPS
if (affectedCat.healthBar) {
affectedCat.healthBar.setHealth(1, affectedCat.maxHealth);
}
}
}
}
// Enemy resource regeneration
enemyResources += 0.0333; // ~2 per second at 60 FPS
// Update all cat units
for (var i = catUnits.length - 1; i >= 0; i--) {
var cat = catUnits[i];
cat.update();
// Handle mammoth disable timer
if (cat.mammothDisabledTime !== undefined) {
cat.mammothDisabledTime--;
if (cat.mammothDisabledTime <= 0) {
cat.health = cat.originalHealth;
cat.damage = cat.originalDamage;
if (cat.healthBar) {
cat.healthBar.setHealth(cat.health, cat.maxHealth);
}
delete cat.mammothDisabledTime;
delete cat.originalHealth;
delete cat.originalDamage;
}
}
// Remove if off-screen
if (cat.x < -100 || cat.x > 2048 + 100 || cat.y > 2732 + 100) {
cat.destroy();
catUnits.splice(i, 1);
continue;
}
// Handle healer cat special ability
if (cat instanceof CatHealer) {
//{update_healer1}
cat.healNearby(catUnits);
} //{update_healer2}
// Handle gunner cat special ability
if (cat instanceof CatGunner) {
//{update_gunner1}
var target = cat.findTarget(enemyUnits);
if (cat.shoot(target)) {
var bullet = game.addChild(new Bullet());
bullet.x = cat.x;
bullet.y = cat.y;
bullet.direction = cat.direction;
bullet.damage = cat.bulletDamage;
// Every 2nd projectile, 90% chance to spawn meteorite
if (cat.projectileCount % 2 === 0 && Math.random() < 0.9) {
var meteorite = game.addChild(new Meteorite());
meteorite.x = cat.x;
meteorite.y = cat.y;
meteorite.direction = cat.direction;
}
}
} //{update_gunner2}
// Check collision with enemy base
if (cat.intersects(enemyBase)) {
enemyBase.takeDamage(cat.damage);
if (enemyBase.health <= 0) {
gameOver = false; // Not game over yet, boss spawns
// Spawn RobotDog boss
var boss = game.addChild(new RobotDog());
enemyUnits.push(boss);
LK.getSound('spawn').play();
}
}
}
// Update all enemy units
for (var i = enemyUnits.length - 1; i >= 0; i--) {
var enemy = enemyUnits[i];
enemy.update();
// Remove if off-screen
if (enemy.x < -100 || enemy.x > 2048 + 100 || enemy.y > 2732 + 100) {
enemy.destroy();
enemyUnits.splice(i, 1);
continue;
}
// Handle RobotDog boss laser attack
if (enemy instanceof RobotDog) {
enemy.laserCooldown--;
enemy.laserSpamCooldown--;
if (enemy.laserCooldown <= 0 && enemy.laserSpamCooldown <= 0) {
enemy.laserCooldown = enemy.laserInterval;
enemy.laserSpamCooldown = 60; // 1 second anti-spam cooldown
// Fire laser at random cat
if (catUnits.length > 0) {
var randomCat = catUnits[Math.floor(Math.random() * catUnits.length)];
var laser = game.addChild(new Laser());
laser.x = enemy.x;
laser.y = enemy.y;
laser.direction = randomCat.x > enemy.x ? 1 : -1;
}
}
}
// Check collision with player base
if (enemy.intersects(playerBase)) {
playerBase.takeDamage(enemy.damage);
if (playerBase.health <= 0) {
gameOver = true;
LK.showGameOver();
}
}
}
// Update bullets, meteorites and lasers
var bullets = [];
var meteorites = [];
var lasers = [];
for (var i = game.children.length - 1; i >= 0; i--) {
var child = game.children[i];
if (child instanceof Bullet) {
//{bullet_update1}
bullets.push(child);
} else if (child instanceof Meteorite) {
meteorites.push(child);
} else if (child instanceof Laser) {
lasers.push(child);
}
} //{bullet_update2}
// Update lasers
for (var i = lasers.length - 1; i >= 0; i--) {
var laser = lasers[i];
laser.update();
// Remove if off-screen or expired
if (laser.x < -100 || laser.x > 2048 + 100 || laser.lifetime <= 0) {
laser.destroy();
lasers.splice(i, 1);
continue;
}
// Check collision with cats
for (var j = catUnits.length - 1; j >= 0; j--) {
var cat = catUnits[j];
if (laser.intersects(cat)) {
// CatTitan is immune to lasers
if (cat instanceof CatTitan) {
break;
}
LK.getSound('hit').play();
var catDied = cat.takeDamage(laser.damage);
laser.destroy();
lasers.splice(i, 1);
if (catDied) {
catUnits.splice(j, 1);
}
break;
}
}
}
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Remove if off-screen or expired
if (bullet.x < -100 || bullet.x > 2048 + 100 || bullet.lifetime <= 0) {
//{bullet_update3}
bullet.destroy();
continue;
} //{bullet_update4}
// Check collision with enemies
for (var j = enemyUnits.length - 1; j >= 0; j--) {
//{bullet_update5}
var enemy = enemyUnits[j];
if (bullet.intersects(enemy)) {
LK.getSound('hit').play();
var enemyDied = enemy.takeDamage(bullet.damage);
bullet.destroy();
if (enemyDied) {
var reward = 15;
if (enemy instanceof Penguin) {
reward = 35;
} else if (enemy instanceof Mammoth) {
reward = 50;
}
playerResources += reward;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
enemyUnits.splice(j, 1);
}
break;
}
} //{bullet_update6}
} //{bullet_update7}
// Update meteorites
for (var i = meteorites.length - 1; i >= 0; i--) {
var meteorite = meteorites[i];
meteorite.update();
// Remove if off-screen or expired
if (meteorite.x < -100 || meteorite.x > 2048 + 100 || meteorite.lifetime <= 0) {
meteorite.destroy();
meteorites.splice(i, 1);
continue;
}
// Check collision with enemies and deal area damage
for (var j = enemyUnits.length - 1; j >= 0; j--) {
var enemy = enemyUnits[j];
var dx = enemy.x - meteorite.x;
var dy = enemy.y - meteorite.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= meteorite.explosionRadius) {
if (!meteorite.impacted) {
LK.getSound('hit').play();
meteorite.impacted = true;
// Deal damage to all enemies in radius
for (var k = enemyUnits.length - 1; k >= 0; k--) {
var targetEnemy = enemyUnits[k];
var tdx = targetEnemy.x - meteorite.x;
var tdy = targetEnemy.y - meteorite.y;
var tdistance = Math.sqrt(tdx * tdx + tdy * tdy);
if (tdistance <= meteorite.explosionRadius) {
var enemyDied = targetEnemy.takeDamage(meteorite.damage);
if (enemyDied) {
var reward = 15;
if (targetEnemy instanceof Penguin) {
reward = 35;
} else if (targetEnemy instanceof Mammoth) {
reward = 50;
}
playerResources += reward;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
enemyUnits.splice(k, 1);
}
}
}
meteorite.destroy();
meteorites.splice(i, 1);
break;
}
}
}
}
// Collision detection between cats and enemies
for (var i = 0; i < catUnits.length; i++) {
var cat = catUnits[i];
for (var j = enemyUnits.length - 1; j >= 0; j--) {
var enemy = enemyUnits[j];
if (cat.intersects(enemy)) {
LK.getSound('hit').play();
var enemyDied = enemy.takeDamage(cat.damage);
var catDied = cat.takeDamage(enemy.damage);
if (enemyDied) {
var reward = 15;
if (enemy instanceof Penguin) {
reward = 35;
} else if (enemy instanceof Mammoth) {
reward = 50;
}
playerResources += reward;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
// Check if boss was defeated
if (enemy instanceof RobotDog) {
gameOver = true;
LK.showYouWin();
}
enemyUnits.splice(j, 1);
}
if (catDied) {
catUnits.splice(i, 1);
i--;
break;
}
}
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
playerResources: 0,
totalKills: 0
});
/****
* Classes
****/
// Base class
var Base = Container.expand(function () {
var self = Container.call(this);
var baseGraphics = self.attachAsset('playerBase', {
anchorX: 0.5,
anchorY: 1
});
var healthBar = self.addChild(new HealthBar());
healthBar.y = -180;
self.maxHealth = 200;
self.health = 200;
self.color = 0x4169E1;
self.takeDamage = function (dmg) {
self.health -= dmg;
healthBar.setHealth(self.health, self.maxHealth);
};
self.setColor = function (color) {
self.color = color;
baseGraphics.tint = color;
};
return self;
});
// Bullet class for gunner cat
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('background', {
width: 15,
height: 15,
color: 0xFFFF00,
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 3;
self.speed = 8;
self.direction = -1;
self.lifetime = 300; // 5 seconds at 60 FPS
self.update = function () {
self.x += self.speed * self.direction;
self.lifetime--;
};
return self;
});
// Cat Unit Base Class
var CatUnit = Container.expand(function () {
var self = Container.call(this);
var catGraphics = self.attachAsset('catNormal', {
anchorX: 0.5,
anchorY: 0.5
});
var healthBar = self.addChild(new HealthBar());
healthBar.y = -50;
self.maxHealth = 30;
self.health = 30;
self.damage = 5;
self.speed = 2;
self.direction = -1; // -1 for left, 1 for right
self.gravity = 0.3;
self.velocityY = 0;
self.onGround = false;
self.groundLevel = 2732 - 100 - 40;
self.lastX = self.x;
self.takeDamage = function (dmg) {
self.health -= dmg;
healthBar.setHealth(self.health, self.maxHealth);
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
self.update = function () {
self.lastX = self.x;
// Apply gravity
if (self.y < self.groundLevel) {
self.velocityY += self.gravity;
self.y += self.velocityY;
} else {
self.y = self.groundLevel;
self.velocityY = 0;
self.onGround = true;
}
// Move horizontally
self.x += self.speed * self.direction;
};
return self;
});
// Titan Cat
var CatTitan = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catTitan', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 17;
self.health = 17;
self.damage = 7;
self.speed = 2;
self.cost = 55;
return self;
});
// Tank Cat
var CatTank = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catDefense', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 60;
self.health = 60;
self.damage = 3;
self.speed = 1;
self.cost = 25;
return self;
});
// Normal Cat
var CatNormal = CatUnit.expand(function () {
var self = CatUnit.call(this);
var catGraphics = LK.getAsset('catNormal', {
anchorX: 0.5,
anchorY: 0.5
});
self.attachAsset('catNormal', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 30;
self.health = 30;
self.damage = 5;
self.speed = 2;
self.cost = 15;
return self;
});
// Milk Cat
var CatMilk = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catMilk', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 70;
self.health = 70;
self.damage = 3;
self.speed = 2.5; // 25% faster than normal cat (2 * 1.25)
self.cost = 25;
return self;
});
// Healer Cat
var CatHealer = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catNormal', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 35;
self.health = 35;
self.damage = 2;
self.speed = 1.7; // 19% slower than normal cat (2 * 0.81)
self.cost = 25;
self.healRadius = 150;
self.healAmount = 2;
self.healCooldown = 0;
self.healInterval = 30; // Heal every 30 frames (0.5 seconds at 60 FPS)
var originalUpdate = self.update;
self.update = function () {
originalUpdate.call(self);
self.healCooldown--;
};
self.healNearby = function (allies) {
if (self.healCooldown <= 0) {
for (var i = 0; i < allies.length; i++) {
var ally = allies[i];
if (ally === self) continue;
var dx = ally.x - self.x;
var dy = ally.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.healRadius) {
ally.health = Math.min(ally.maxHealth, ally.health + self.healAmount);
if (ally.healthBar) {
ally.healthBar.setHealth(ally.health, ally.maxHealth);
}
}
}
self.healCooldown = self.healInterval;
}
};
return self;
});
// Gunner Cat
var CatGunner = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catGunner', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 15;
self.health = 15;
self.damage = 3;
self.speed = 1.4; // 30% slower (2 * 0.7) = 1.4
self.cost = 45;
self.shootCooldown = 0;
self.shootInterval = 60; // Shoot every 60 frames (1 second at 60 FPS)
self.bulletDamage = 3;
self.shootRange = 400;
self.projectileCount = 0; // Track projectiles for meteorite
self.isShooting = false; // Track if currently shooting
var originalUpdate = self.update;
self.update = function () {
// Only move if not shooting
if (!self.isShooting) {
originalUpdate.call(self);
}
self.shootCooldown--;
// Reset shooting state if cooldown finished
if (self.shootCooldown <= 0) {
self.isShooting = false;
}
};
self.findTarget = function (enemies) {
var closest = null;
var closestDist = self.shootRange;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < closestDist) {
closestDist = distance;
closest = enemy;
}
}
return closest;
};
self.shoot = function (target) {
if (self.shootCooldown <= 0 && target) {
self.shootCooldown = self.shootInterval;
self.isShooting = true; // Stop moving while shooting
self.projectileCount++; // Increment projectile count
return true;
}
return false;
};
return self;
});
// Axe Cat
var CatAxe = CatUnit.expand(function () {
var self = CatUnit.call(this);
self.attachAsset('catAxe', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 40;
self.health = 40;
self.damage = 10;
self.speed = 1.5;
self.cost = 55;
return self;
});
// Enemy Unit Base Class
var EnemyUnit = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
var healthBar = self.addChild(new HealthBar());
healthBar.y = -50;
self.maxHealth = 25;
self.health = 25;
self.damage = 4;
self.speed = 1.5;
self.direction = 1; // 1 for right
self.gravity = 0.3;
self.velocityY = 0;
self.onGround = false;
self.groundLevel = 2732 - 100 - 40;
self.lastX = self.x;
self.takeDamage = function (dmg) {
self.health -= dmg;
healthBar.setHealth(self.health, self.maxHealth);
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
self.update = function () {
self.lastX = self.x;
// Apply gravity
if (self.y < self.groundLevel) {
self.velocityY += self.gravity;
self.y += self.velocityY;
} else {
self.y = self.groundLevel;
self.velocityY = 0;
self.onGround = true;
}
// Move horizontally
self.x += self.speed * self.direction;
};
return self;
});
// Snake Enemy
var Snake = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
self.attachAsset('snake', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 35;
self.health = 35;
self.damage = 8;
self.speed = 1;
return self;
});
// Pig Enemy
var Pig = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
self.attachAsset('pig', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 50;
self.health = 50;
self.damage = 6;
self.speed = 0.8;
return self;
});
//{dog_potato6}
// Penguin Enemy
var Penguin = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 12;
self.health = 12;
self.damage = 3.5;
self.speed = 1.65; // 10% faster (1.5 * 1.1)
return self;
});
// Mammoth Enemy
var Mammoth = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 20;
self.health = 20;
self.damage = 7;
self.speed = 1.2;
return self;
});
// Dog Potato Nose Enemy
var DogPotatoNose = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
//{dog_potato1}
self.attachAsset('dog', {
anchorX: 0.5,
//{dog_potato2}
anchorY: 0.5 //{dog_potato3}
}); //{dog_potato4}
self.maxHealth = 1;
self.health = 1;
self.damage = 1;
self.speed = 1.1; // 26% slower (1.5 * 0.74)
self.shootRange = 100; // Short range attack
return self; //{dog_potato5}
});
// Dog Enemy
var Dog = EnemyUnit.expand(function () {
var self = EnemyUnit.call(this);
self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 25;
self.health = 25;
self.damage = 4;
self.speed = 1.5;
return self;
});
// Health Bar class
var HealthBar = Container.expand(function () {
var self = Container.call(this);
var maxHealth = 100;
var currentHealth = 100;
var background = LK.getAsset('background', {
width: 40,
height: 8,
color: 0x000000
});
var healthFill = LK.getAsset('healthFill', {
width: 40,
height: 8,
color: 0x00FF00
});
self.addChild(background);
self.addChild(healthFill);
self.setHealth = function (health, max) {
maxHealth = max;
currentHealth = health;
var percent = Math.max(0, currentHealth / maxHealth);
healthFill.width = 40 * percent;
if (percent > 0.5) {
healthFill.tint = 0x00FF00;
} else if (percent > 0.25) {
healthFill.tint = 0xFFFF00;
} else {
healthFill.tint = 0xFF0000;
}
};
return self;
});
// Laser class for boss attacks
var Laser = Container.expand(function () {
var self = Container.call(this);
var laserGraphics = self.attachAsset('background', {
width: 20,
height: 300,
color: 0xFF0000
});
self.damage = 4;
self.speed = 10;
self.direction = 1;
self.lifetime = 100; // Short lived
self.impacted = false;
self.update = function () {
self.x += self.speed * self.direction;
self.lifetime--;
};
return self;
});
// Meteorite class for gunner special attack
var Meteorite = Container.expand(function () {
var self = Container.call(this);
//{meteor_new1}
var meteorGraphics = self.attachAsset('background', {
width: 40,
//{meteor_new2}
height: 40,
//{meteor_new3}
color: 0xFF8C00 //{meteor_new4}
}); //{meteor_new5}
self.damage = 5; //{meteor_new6}
self.speed = 6; //{meteor_new7}
self.direction = -1; //{meteor_new8}
self.lifetime = 500; // 8+ seconds at 60 FPS//{meteor_new9}
self.impacted = false; // Track if already impacted//{meteor_new10}
self.explosionRadius = 200; // Area of effect radius//{meteor_new11}
self.update = function () {
//{meteor_new12}
self.x += self.speed * self.direction; //{meteor_new13}
self.lifetime--; //{meteor_new14}
}; //{meteor_new15}
return self; //{meteor_new16}
});
//{meteor_new17}
// Robot Dog Boss
var RobotDog = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
var healthBar = self.addChild(new HealthBar());
healthBar.y = -50;
self.maxHealth = 1;
self.health = 1;
self.damage = 0; // Boss doesn't deal damage on contact
self.speed = 0; // Boss doesn't move
self.x = 100; // Fixed position at enemy base
self.y = 2732 - 100 - 40; // Ground level
self.laserDamage = 4;
self.laserCooldown = 0;
self.laserInterval = 60; // Fire every 60 frames
self.laserSpamCooldown = 0; // Anti-spam cooldown of 1 second
self.takeDamage = function (dmg) {
self.health -= dmg;
healthBar.setHealth(self.health, self.maxHealth);
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
self.update = function () {
self.laserCooldown--;
self.laserSpamCooldown--;
};
return self;
});
//{meteor_new17}
// Shop Button
var ShopButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('shopButton', {
anchorX: 0.5,
anchorY: 0.5
});
var label = self.addChild(new Text2('SHOP', {
size: 24,
fill: 0x000000
}));
label.anchor.set(0.5, 0.5);
self.cost = 0;
self.unitType = 'normal';
self.down = function (x, y, obj) {
// Handle button press
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Sounds
// UI Elements
// Ground
// Bases
// Enemies
// Cats
// Add ground
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 1
}));
ground.x = 0;
ground.y = 2732;
// Create bases
var playerBase = game.addChild(new Base());
playerBase.x = 2048 - 100;
playerBase.y = 2732 - 100;
playerBase.setColor(0x4169E1);
var enemyBase = game.addChild(new Base());
enemyBase.x = 100;
enemyBase.y = 2732 - 100;
enemyBase.setColor(0xDC143C);
// Arrays for units
var catUnits = [];
var enemyUnits = [];
// Game state
var playerResources = storage.playerResources || 50;
var enemyResources = 50;
var gameOver = false;
var passiveMoneyPerTick = 0.016666; // 1 money per millisecond at 60 FPS
var accumulatedMoney = 0;
var totalMoneyEarned = 0;
var lastMammothSpawn = 0;
// UI - Resources display
var resourceText = new Text2('Resources: ' + Math.floor(playerResources), {
size: 60,
fill: 0x000000
});
resourceText.anchor.set(0.5, 0);
LK.gui.top.addChild(resourceText);
// Shop buttons - positioned at center of game (not GUI)
var normalCatButton = new Container();
normalCatButton.x = 1024 - 300;
normalCatButton.y = 400;
var normalButtonGraphics = normalCatButton.attachAsset('catNormal', {
anchorX: 0.5,
anchorY: 0.5
});
var normalCostText = normalCatButton.addChild(new Text2('15', {
size: 24,
fill: 0xFFFFFF
}));
normalCostText.anchor.set(0.5, 0.5);
normalCostText.y = 40;
normalCatButton.interactive = true;
normalCatButton.down = function (x, y, obj) {
if (playerResources >= 15) {
var newCat = game.addChild(new CatNormal());
newCat.x = playerBase.x - 100;
newCat.y = playerBase.y - 100;
newCat.direction = -1;
catUnits.push(newCat);
playerResources -= 15;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
LK.getSound('spawn').play();
}
};
normalCatButton.buttonMode = true;
game.addChild(normalCatButton);
var tankCatButton = new Container();
tankCatButton.x = 1024;
tankCatButton.y = 400;
var tankButtonGraphics = tankCatButton.attachAsset('catTank', {
anchorX: 0.5,
anchorY: 0.5
});
var tankCostText = tankCatButton.addChild(new Text2('25', {
size: 24,
fill: 0xFFFFFF
}));
tankCostText.anchor.set(0.5, 0.5);
tankCostText.y = 50;
tankCatButton.interactive = true;
tankCatButton.down = function (x, y, obj) {
if (playerResources >= 25) {
var newCat = game.addChild(new CatTank());
newCat.x = playerBase.x - 100;
newCat.y = playerBase.y - 100;
newCat.direction = -1;
catUnits.push(newCat);
playerResources -= 25;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
LK.getSound('spawn').play();
}
};
tankCatButton.buttonMode = true;
game.addChild(tankCatButton);
var milkCatButton = new Container();
milkCatButton.x = 1024 - 150;
milkCatButton.y = 400;
var milkButtonGraphics = milkCatButton.attachAsset('catMilk', {
anchorX: 0.5,
//{milk_btn1}
anchorY: 0.5 //{milk_btn2}
}); //{milk_btn3}
var milkCostText = milkCatButton.addChild(new Text2('25', {
size: 24,
//{milk_btn4}
fill: 0xFFFFFF //{milk_btn5}
})); //{milk_btn6}
milkCostText.anchor.set(0.5, 0.5);
milkCostText.y = 40;
milkCatButton.interactive = true;
milkCatButton.down = function (x, y, obj) {
if (playerResources >= 25) {
var newCat = game.addChild(new CatMilk());
newCat.x = playerBase.x - 100; //{milk_btn7}
newCat.y = playerBase.y - 100; //{milk_btn8}
newCat.direction = -1; //{milk_btn9}
catUnits.push(newCat); //{milk_btn10}
playerResources -= 25;
storage.playerResources = playerResources; //{milk_btn11}
resourceText.setText('Resources: ' + Math.floor(playerResources)); //{milk_btn12}
LK.getSound('spawn').play(); //{milk_btn13}
} //{milk_btn14}
}; //{milk_btn15}
milkCatButton.buttonMode = true;
game.addChild(milkCatButton);
var axeCatButton = new Container();
axeCatButton.x = 1024 + 300;
axeCatButton.y = 400;
var axeButtonGraphics = axeCatButton.attachAsset('catAxe', {
anchorX: 0.5,
anchorY: 0.5
});
var axeCostText = axeCatButton.addChild(new Text2('55', {
size: 24,
fill: 0xFFFFFF
}));
axeCostText.anchor.set(0.5, 0.5);
axeCostText.y = 45;
axeCatButton.interactive = true;
axeCatButton.down = function (x, y, obj) {
if (playerResources >= 55) {
var newCat = game.addChild(new CatAxe());
newCat.x = playerBase.x - 100;
newCat.y = playerBase.y - 100;
newCat.direction = -1;
catUnits.push(newCat);
playerResources -= 55;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
LK.getSound('spawn').play();
}
};
axeCatButton.buttonMode = true;
game.addChild(axeCatButton);
// Healer Cat Button
var healerCatButton = new Container();
healerCatButton.x = 1024 + 150;
healerCatButton.y = 400;
var healerButtonGraphics = healerCatButton.attachAsset('catNormal', {
anchorX: 0.5,
//{healer_btn1}
anchorY: 0.5 //{healer_btn2}
}); //{healer_btn3}
var healerCostText = healerCatButton.addChild(new Text2('25', {
size: 24,
//{healer_btn4}
fill: 0xFFFFFF //{healer_btn5}
})); //{healer_btn6}
healerCostText.anchor.set(0.5, 0.5);
healerCostText.y = 40;
healerCatButton.interactive = true;
healerCatButton.down = function (x, y, obj) {
if (playerResources >= 25) {
var newCat = game.addChild(new CatHealer());
newCat.x = playerBase.x - 100; //{healer_btn7}
newCat.y = playerBase.y - 100; //{healer_btn8}
newCat.direction = -1; //{healer_btn9}
catUnits.push(newCat); //{healer_btn10}
playerResources -= 25;
storage.playerResources = playerResources; //{healer_btn11}
resourceText.setText('Resources: ' + Math.floor(playerResources)); //{healer_btn12}
LK.getSound('spawn').play(); //{healer_btn13}
} //{healer_btn14}
}; //{healer_btn15}
healerCatButton.buttonMode = true;
game.addChild(healerCatButton);
// Gunner Cat Button
var gunnerCatButton = new Container();
gunnerCatButton.x = 1024 + 450;
gunnerCatButton.y = 400;
var gunnerButtonGraphics = gunnerCatButton.attachAsset('catNormal', {
anchorX: 0.5,
//{gunner_btn1}
anchorY: 0.5 //{gunner_btn2}
}); //{gunner_btn3}
var gunnerCostText = gunnerCatButton.addChild(new Text2('45', {
size: 24,
//{gunner_btn4}
fill: 0xFFFFFF //{gunner_btn5}
})); //{gunner_btn6}
gunnerCostText.anchor.set(0.5, 0.5);
gunnerCostText.y = 40;
gunnerCatButton.interactive = true;
gunnerCatButton.down = function (x, y, obj) {
if (playerResources >= 45) {
var newCat = game.addChild(new CatGunner());
newCat.x = playerBase.x - 100; //{gunner_btn7}
newCat.y = playerBase.y - 100; //{gunner_btn8}
newCat.direction = -1; //{gunner_btn9}
catUnits.push(newCat); //{gunner_btn10}
playerResources -= 45;
storage.playerResources = playerResources; //{gunner_btn11}
resourceText.setText('Resources: ' + Math.floor(playerResources)); //{gunner_btn12}
LK.getSound('spawn').play(); //{gunner_btn13}
} //{gunner_btn14}
}; //{gunner_btn15}
gunnerCatButton.buttonMode = true;
game.addChild(gunnerCatButton);
// Titan Cat Button
var titanCatButton = new Container();
titanCatButton.x = 1024 - 450;
titanCatButton.y = 400;
var titanButtonGraphics = titanCatButton.attachAsset('catTitan', {
anchorX: 0.5,
anchorY: 0.5
});
var titanCostText = titanCatButton.addChild(new Text2('55', {
size: 24,
fill: 0xFFFFFF
}));
titanCostText.anchor.set(0.5, 0.5);
titanCostText.y = 50;
titanCatButton.interactive = true;
titanCatButton.down = function (x, y, obj) {
if (playerResources >= 55) {
var newCat = game.addChild(new CatTitan());
newCat.x = playerBase.x - 100;
newCat.y = playerBase.y - 100;
newCat.direction = -1;
catUnits.push(newCat);
playerResources -= 55;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
LK.getSound('spawn').play();
}
};
titanCatButton.buttonMode = true;
game.addChild(titanCatButton);
// Enemy spawn timer
var mammothSpawnCounter = 0;
var mammothEventTimer = LK.setInterval(function () {
if (gameOver) return;
// Spawn mammoth at enemy base to attack player base
var eventMammoth = game.addChild(new Mammoth());
eventMammoth.x = enemyBase.x + 100;
eventMammoth.y = enemyBase.y - 100;
eventMammoth.direction = 1;
enemyUnits.push(eventMammoth);
LK.getSound('spawn').play();
}, 20000);
var enemySpawnTimer = LK.setInterval(function () {
if (gameOver) return;
if (enemyResources >= 10) {
var randomValue = Math.random();
var newEnemy;
if (randomValue < 0.65) {
newEnemy = new Dog();
enemyResources -= 10;
} else if (randomValue < 0.88) {
newEnemy = new Snake();
enemyResources -= 15;
} else if (randomValue < 0.93) {
newEnemy = new Penguin();
enemyResources -= 12;
} else if (randomValue < 0.98) {
newEnemy = new Pig();
enemyResources -= 20;
} else {
newEnemy = new Mammoth();
enemyResources -= 25;
}
newEnemy = game.addChild(newEnemy);
newEnemy.x = enemyBase.x + 100;
newEnemy.y = enemyBase.y - 100;
newEnemy.direction = 1;
enemyUnits.push(newEnemy);
LK.getSound('spawn').play();
}
}, 2000);
// Main game update
game.update = function () {
if (gameOver) return;
// Passive money generation - 1 money per millisecond
accumulatedMoney += passiveMoneyPerTick;
if (accumulatedMoney >= 1) {
var moneyGained = Math.floor(accumulatedMoney);
playerResources += moneyGained;
totalMoneyEarned += moneyGained;
accumulatedMoney -= moneyGained;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
// Spawn mammoth every 120 coins earned
if (totalMoneyEarned - lastMammothSpawn >= 120) {
var mammoth = game.addChild(new Mammoth());
mammoth.x = enemyBase.x + 100;
mammoth.y = enemyBase.y - 100;
mammoth.direction = 1;
enemyUnits.push(mammoth);
LK.getSound('spawn').play();
lastMammothSpawn = totalMoneyEarned;
// Disable all current cats for 5 seconds
for (var k = 0; k < catUnits.length; k++) {
var affectedCat = catUnits[k];
affectedCat.originalHealth = affectedCat.health;
affectedCat.originalDamage = affectedCat.damage;
affectedCat.health = 1;
affectedCat.damage = 0;
affectedCat.mammothDisabledTime = 300; // 5 seconds at 60 FPS
if (affectedCat.healthBar) {
affectedCat.healthBar.setHealth(1, affectedCat.maxHealth);
}
}
}
}
// Enemy resource regeneration
enemyResources += 0.0333; // ~2 per second at 60 FPS
// Update all cat units
for (var i = catUnits.length - 1; i >= 0; i--) {
var cat = catUnits[i];
cat.update();
// Handle mammoth disable timer
if (cat.mammothDisabledTime !== undefined) {
cat.mammothDisabledTime--;
if (cat.mammothDisabledTime <= 0) {
cat.health = cat.originalHealth;
cat.damage = cat.originalDamage;
if (cat.healthBar) {
cat.healthBar.setHealth(cat.health, cat.maxHealth);
}
delete cat.mammothDisabledTime;
delete cat.originalHealth;
delete cat.originalDamage;
}
}
// Remove if off-screen
if (cat.x < -100 || cat.x > 2048 + 100 || cat.y > 2732 + 100) {
cat.destroy();
catUnits.splice(i, 1);
continue;
}
// Handle healer cat special ability
if (cat instanceof CatHealer) {
//{update_healer1}
cat.healNearby(catUnits);
} //{update_healer2}
// Handle gunner cat special ability
if (cat instanceof CatGunner) {
//{update_gunner1}
var target = cat.findTarget(enemyUnits);
if (cat.shoot(target)) {
var bullet = game.addChild(new Bullet());
bullet.x = cat.x;
bullet.y = cat.y;
bullet.direction = cat.direction;
bullet.damage = cat.bulletDamage;
// Every 2nd projectile, 90% chance to spawn meteorite
if (cat.projectileCount % 2 === 0 && Math.random() < 0.9) {
var meteorite = game.addChild(new Meteorite());
meteorite.x = cat.x;
meteorite.y = cat.y;
meteorite.direction = cat.direction;
}
}
} //{update_gunner2}
// Check collision with enemy base
if (cat.intersects(enemyBase)) {
enemyBase.takeDamage(cat.damage);
if (enemyBase.health <= 0) {
gameOver = false; // Not game over yet, boss spawns
// Spawn RobotDog boss
var boss = game.addChild(new RobotDog());
enemyUnits.push(boss);
LK.getSound('spawn').play();
}
}
}
// Update all enemy units
for (var i = enemyUnits.length - 1; i >= 0; i--) {
var enemy = enemyUnits[i];
enemy.update();
// Remove if off-screen
if (enemy.x < -100 || enemy.x > 2048 + 100 || enemy.y > 2732 + 100) {
enemy.destroy();
enemyUnits.splice(i, 1);
continue;
}
// Handle RobotDog boss laser attack
if (enemy instanceof RobotDog) {
enemy.laserCooldown--;
enemy.laserSpamCooldown--;
if (enemy.laserCooldown <= 0 && enemy.laserSpamCooldown <= 0) {
enemy.laserCooldown = enemy.laserInterval;
enemy.laserSpamCooldown = 60; // 1 second anti-spam cooldown
// Fire laser at random cat
if (catUnits.length > 0) {
var randomCat = catUnits[Math.floor(Math.random() * catUnits.length)];
var laser = game.addChild(new Laser());
laser.x = enemy.x;
laser.y = enemy.y;
laser.direction = randomCat.x > enemy.x ? 1 : -1;
}
}
}
// Check collision with player base
if (enemy.intersects(playerBase)) {
playerBase.takeDamage(enemy.damage);
if (playerBase.health <= 0) {
gameOver = true;
LK.showGameOver();
}
}
}
// Update bullets, meteorites and lasers
var bullets = [];
var meteorites = [];
var lasers = [];
for (var i = game.children.length - 1; i >= 0; i--) {
var child = game.children[i];
if (child instanceof Bullet) {
//{bullet_update1}
bullets.push(child);
} else if (child instanceof Meteorite) {
meteorites.push(child);
} else if (child instanceof Laser) {
lasers.push(child);
}
} //{bullet_update2}
// Update lasers
for (var i = lasers.length - 1; i >= 0; i--) {
var laser = lasers[i];
laser.update();
// Remove if off-screen or expired
if (laser.x < -100 || laser.x > 2048 + 100 || laser.lifetime <= 0) {
laser.destroy();
lasers.splice(i, 1);
continue;
}
// Check collision with cats
for (var j = catUnits.length - 1; j >= 0; j--) {
var cat = catUnits[j];
if (laser.intersects(cat)) {
// CatTitan is immune to lasers
if (cat instanceof CatTitan) {
break;
}
LK.getSound('hit').play();
var catDied = cat.takeDamage(laser.damage);
laser.destroy();
lasers.splice(i, 1);
if (catDied) {
catUnits.splice(j, 1);
}
break;
}
}
}
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Remove if off-screen or expired
if (bullet.x < -100 || bullet.x > 2048 + 100 || bullet.lifetime <= 0) {
//{bullet_update3}
bullet.destroy();
continue;
} //{bullet_update4}
// Check collision with enemies
for (var j = enemyUnits.length - 1; j >= 0; j--) {
//{bullet_update5}
var enemy = enemyUnits[j];
if (bullet.intersects(enemy)) {
LK.getSound('hit').play();
var enemyDied = enemy.takeDamage(bullet.damage);
bullet.destroy();
if (enemyDied) {
var reward = 15;
if (enemy instanceof Penguin) {
reward = 35;
} else if (enemy instanceof Mammoth) {
reward = 50;
}
playerResources += reward;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
enemyUnits.splice(j, 1);
}
break;
}
} //{bullet_update6}
} //{bullet_update7}
// Update meteorites
for (var i = meteorites.length - 1; i >= 0; i--) {
var meteorite = meteorites[i];
meteorite.update();
// Remove if off-screen or expired
if (meteorite.x < -100 || meteorite.x > 2048 + 100 || meteorite.lifetime <= 0) {
meteorite.destroy();
meteorites.splice(i, 1);
continue;
}
// Check collision with enemies and deal area damage
for (var j = enemyUnits.length - 1; j >= 0; j--) {
var enemy = enemyUnits[j];
var dx = enemy.x - meteorite.x;
var dy = enemy.y - meteorite.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= meteorite.explosionRadius) {
if (!meteorite.impacted) {
LK.getSound('hit').play();
meteorite.impacted = true;
// Deal damage to all enemies in radius
for (var k = enemyUnits.length - 1; k >= 0; k--) {
var targetEnemy = enemyUnits[k];
var tdx = targetEnemy.x - meteorite.x;
var tdy = targetEnemy.y - meteorite.y;
var tdistance = Math.sqrt(tdx * tdx + tdy * tdy);
if (tdistance <= meteorite.explosionRadius) {
var enemyDied = targetEnemy.takeDamage(meteorite.damage);
if (enemyDied) {
var reward = 15;
if (targetEnemy instanceof Penguin) {
reward = 35;
} else if (targetEnemy instanceof Mammoth) {
reward = 50;
}
playerResources += reward;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
enemyUnits.splice(k, 1);
}
}
}
meteorite.destroy();
meteorites.splice(i, 1);
break;
}
}
}
}
// Collision detection between cats and enemies
for (var i = 0; i < catUnits.length; i++) {
var cat = catUnits[i];
for (var j = enemyUnits.length - 1; j >= 0; j--) {
var enemy = enemyUnits[j];
if (cat.intersects(enemy)) {
LK.getSound('hit').play();
var enemyDied = enemy.takeDamage(cat.damage);
var catDied = cat.takeDamage(enemy.damage);
if (enemyDied) {
var reward = 15;
if (enemy instanceof Penguin) {
reward = 35;
} else if (enemy instanceof Mammoth) {
reward = 50;
}
playerResources += reward;
storage.playerResources = playerResources;
resourceText.setText('Resources: ' + Math.floor(playerResources));
// Check if boss was defeated
if (enemy instanceof RobotDog) {
gameOver = true;
LK.showYouWin();
}
enemyUnits.splice(j, 1);
}
if (catDied) {
catUnits.splice(i, 1);
i--;
break;
}
}
}
}
};
Un gato blanco con ojos y boca negra sin cuerpo solo la cabeza circular con sus orejas y sus 4 patitas estilo caricatura. In-Game asset. 2d. High contrast. No shadows
Has que el gato tenga un hacha en una mano
El gato sosteniendo una pistola con municioĚn en una patita
Un gato con forma de vaca con 2 cuernos blanco como su cuerpo pero con un ojos y boca negros estilo caricatura. In-Game asset. 2d. High contrast. No shadows
Un perro blanco con 2 patas y dientes de vampiro con una cola pelula estilo caricatura. In-Game asset. 2d. High contrast. No shadows
Una serpiente blanca con manchas grises con ojos negros estilo caricatura. In-Game asset. 2d. High contrast. No shadows
Un cerdo blanco con cuernos en su nariz con ojos negros estilo caricatura. In-Game asset. 2d. High contrast. No shadows
Hasdo en 2 patas y musculoso