User prompt
Under the upgrade button, there is a Buy Turret button, it will be $1500 and when we buy it, a turret will appear next to us.
User prompt
Set trex sell value to 146
User prompt
Set unicorn sell value to 126
User prompt
Set unicorn sell value to 85
User prompt
Set lion sell value to $55
User prompt
Set zebra sell value to $35 (%15 $55)
User prompt
Set spider sell value to $10
User prompt
Bird 15$
User prompt
1. Upgrade is now $350 not $200 2.Upgrdae is now $600
User prompt
remove trees from game
User prompt
add a new weapon to assets
User prompt
4. Upgrade 1500 and new weapon
User prompt
When you reach kill counter 4, spawn a tree in a random place.
User prompt
kill counter 34 spiders and birds go
User prompt
Birds increased when kill counter exceeded 16
User prompt
Kill Counter 23: Trees now spawn 3 every 5 seconds
User prompt
Spiders increased when kill counter exceeded 15.
User prompt
After passing Kill Counter 7, all animals became very fast.
User prompt
Kill counter accounts: lion 2 unicorn 4 trex 3.5
User prompt
kill counter accounts: bird 0.5 spider 0.5 Zebra 1
User prompt
Kill counter will only write numbers like 1 2 3 4 5 ...
User prompt
add tree to assets
User prompt
add tree to game, These trees stop for 5 seconds and go away every 6 seconds
User prompt
remove bombs from game
User prompt
Let the bombs hit but not us
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Animal base class var Animal = Container.expand(function () { var self = Container.call(this); self.type = 'animal'; self.value = 0; self.speed = 0; self.caught = false; self.init = function (animalType) { self.animalType = animalType; var assetId; if (animalType === 'trex') { assetId = 'trex'; self.value = 200; self.speed = 2.2 + Math.random() * 0.8; } else if (animalType === 'lion') { assetId = 'lion'; self.value = 50; self.speed = 3.2 + Math.random() * 1.2; } else if (animalType === 'zebra') { assetId = 'zebra'; self.value = 30; self.speed = 3.8 + Math.random() * 1.5; } else if (animalType === 'bird') { assetId = 'bird'; self.value = 10; self.speed = 5.5 + Math.random() * 2.5; } else if (animalType === 'spider') { assetId = 'spider'; self.value = 2; self.speed = 2.2 + Math.random() * 1.2; } else if (animalType === 'stork') { assetId = 'bird'; self.value = 100; self.speed = 4.5 + Math.random() * 1.5; // Tint the stork to make it visually distinct // (LK.getAsset does not support dynamic tint, so we use the same asset for now) } else if (animalType === 'unicorn') { assetId = 'unicorn'; self.value = 500; self.speed = 3.5 + Math.random() * 1.2; } self.asset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.direction = Math.random() < 0.5 ? 1 : -1; if (animalType === 'lion') { // Let lions roam farther away from the player (avoid center) // Top or bottom 1/3 of the screen if (Math.random() < 0.5) { self.y = 500 + Math.random() * 400; // Top band } else { self.y = 1900 + Math.random() * 300; // Bottom band } } else { self.y = 500 + Math.random() * 1700; } if (self.direction === 1) { self.x = -self.asset.width / 2; } else { self.x = 2048 + self.asset.width / 2; self.asset.scaleX = -1; } }; self.update = function () { if (self.caught) return; self.x += self.speed * self.direction; // Remove if off screen if (self.direction === 1 && self.x > 2048 + self.asset.width / 2 || self.direction === -1 && self.x < -self.asset.width / 2) { self.destroy(); var idx = animals.indexOf(self); if (idx !== -1) animals.splice(idx, 1); } }; self.getSellValue = function () { return self.value; }; return self; }); // Bomb class var Bomb = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5 }); // Bomb falls from the top, explodes when reaching the ground or in the air self.speedY = 18 + Math.random() * 6; self.exploded = false; self.update = function () { if (self.exploded) return; if (typeof self.lastY === "undefined") self.lastY = self.y; self.y += self.speedY; // Explode in the air at a random height (simulate air burst) // Pick a random air burst height for each bomb if not set if (typeof self.airBurstY === "undefined") { // Air burst between 900 and 1800 px (roughly upper-middle of screen) self.airBurstY = 900 + Math.random() * 900; } // Explode if reached air burst height or ground (bottom 200px) var shouldExplode = false; if (self.lastY <= self.airBurstY && self.y > self.airBurstY) { shouldExplode = true; } if (self.lastY <= 2732 - 200 && self.y > 2732 - 200) { shouldExplode = true; } if (shouldExplode) { self.exploded = true; // Remove all animals in a 350px radius, but do NOT affect the player (gun) for (var i = animals.length - 1; i >= 0; i--) { var a = animals[i]; if (!a.caught) { var dx = a.x - self.x; var dy = a.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 350) { a.caught = true; caughtAnimals.push(a); killCount += 0.07; tween(a, { alpha: 0 }, { duration: 300, onFinish: function (animal) { return function () { animal.destroy(); var idx = animals.indexOf(animal); if (idx !== -1) animals.splice(idx, 1); }; }(a) }); } } } // Do NOT check or affect the gun/player here, so bombs never harm the player! // Animate bomb fade out and destroy tween(self, { alpha: 0 }, { duration: 400, onFinish: function onFinish() { self.destroy(); } }); } self.lastY = self.y; // Remove if off screen if (self.y > 2832 + 100) { self.destroy(); } }; return self; }); // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); self.speed = 0; self.range = 0; self.gunType = 'basic'; self.init = function (gunType) { self.gunType = gunType; var assetId; if (gunType === 'basic') { assetId = 'bullet_basic'; self.speed = 28; self.range = 1200; } else if (gunType === 'rapid') { assetId = 'bullet_rapid'; self.speed = 36; self.range = 900; } else if (gunType === 'sniper') { assetId = 'bullet_sniper'; self.speed = 44; self.range = 1800; } self.asset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.distance = 0; }; self.update = function () { if (typeof self.dirX === "number" && typeof self.dirY === "number") { self.x += self.speed * self.dirX; self.y += self.speed * self.dirY; self.distance += self.speed; } else { self.x += self.speed; self.distance += self.speed; } if (self.distance > self.range || self.x < -100 || self.x > 2200 || self.y < -100 || self.y > 2832) { self.destroy(); var idx = bullets.indexOf(self); if (idx !== -1) bullets.splice(idx, 1); } }; return self; }); // Gun class var Gun = Container.expand(function () { var self = Container.call(this); self.gunType = 'basic'; self.reloadTime = 0; self.lastShotTick = 0; self.init = function (gunType) { self.gunType = gunType; var assetId; if (gunType === 'basic') { assetId = 'gun_basic'; self.reloadTime = 30; } else if (gunType === 'rapid') { assetId = 'gun_rapid'; self.reloadTime = 12; } else if (gunType === 'sniper') { assetId = 'gun_sniper'; self.reloadTime = 60; } self.asset = self.attachAsset(assetId, { anchorX: 0.1, anchorY: 0.5 }); }; self.canShoot = function () { return LK.ticks - self.lastShotTick >= self.reloadTime; }; self.shoot = function () { self.lastShotTick = LK.ticks; }; return self; }); // Turret class var Turret = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('turret', { anchorX: 0.5, anchorY: 0.5 }); self.fireCooldown = 0; self.update = function () { // Find nearest animal within 700px var closest = null; var minDist = 99999; for (var i = 0; i < animals.length; i++) { var a = animals[i]; if (a.caught) continue; var dx = a.x - self.x; var dy = a.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 700 && dist < minDist) { minDist = dist; closest = a; } } // Fire at nearest animal every 18 ticks (~3.3 shots/sec) if (closest && self.fireCooldown <= 0) { var bullet = new Bullet(); bullet.init('rapid'); bullet.x = self.x + self.asset.width * 0.5; bullet.y = self.y; var dx = closest.x - bullet.x; var dy = closest.y - bullet.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist === 0) dist = 1; bullet.dirX = dx / dist; bullet.dirY = dy / dist; bullet.rotation = Math.atan2(dy, dx); game.addChild(bullet); bullets.push(bullet); LK.getSound('shoot').play(); self.fireCooldown = 18; } if (self.fireCooldown > 0) self.fireCooldown--; }; return self; }); /**** * Initialize Game ****/ // Helper: spawn animal var game = new LK.Game({ backgroundColor: 0x2e5d2c }); /**** * Game Code ****/ // Game state variables // Animals // Guns // Bullets // Sounds // Music // Turret asset var animals = []; var bullets = []; var caughtAnimals = []; var money = 0; var killCount = 0; // Track total kills var gunLevel = 0; // 0: basic, 1: rapid, 2: sniper var gunTypes = ['basic', 'rapid', 'sniper']; var gunPrices = [0, 200, 600]; var gunNames = ['Basic Gun', 'Rapid Gun', 'Sniper Gun']; var gun; var animalsSpedUp = false; // Track if animals have been sped up // UI var moneyTxt = new Text2('$0', { size: 90, fill: 0xFFF700 }); moneyTxt.anchor.set(0.5, 0); LK.gui.top.addChild(moneyTxt); var caughtTxt = new Text2('Bag: 0', { size: 70, fill: 0xFFFFFF }); caughtTxt.anchor.set(0.5, 0); LK.gui.top.addChild(caughtTxt); caughtTxt.y = 110; var killTxt = new Text2('Kills: 0', { size: 70, fill: 0xFF4444 }); killTxt.anchor.set(0, 1); // anchor bottom left LK.gui.bottomLeft.addChild(killTxt); killTxt.x = 0; killTxt.y = 0; var gunTxt = new Text2('Gun: Basic', { size: 60, fill: 0xFFFFFF }); gunTxt.anchor.set(0.5, 0); LK.gui.top.addChild(gunTxt); gunTxt.y = 200; var sellBtn = new Text2('Sell', { size: 70, fill: 0xFF8800 }); sellBtn.anchor.set(0.5, 0.5); LK.gui.bottom.addChild(sellBtn); sellBtn.y = -200; var upgradeBtn = new Text2('Upgrade', { size: 70, fill: 0x00FF00 }); upgradeBtn.anchor.set(0.5, 0.5); LK.gui.bottom.addChild(upgradeBtn); upgradeBtn.y = -120; // Gun gun = new Gun(); gun.init(gunTypes[gunLevel]); game.addChild(gun); // Center the gun horizontally and vertically gun.x = 2048 / 2; gun.y = 2732 / 2; // Friend button removed // Track if skin is bought var skinBought = false; // Turret spawn timer variables var turretSpawnInterval = 660; // 11 seconds at 60 FPS var turretSpawnTicks = 0; var turrets = []; var turretStayDuration = 300; // 5 seconds at 60 FPS function spawnTurret() { var turret = new Turret(); // Place turrets in a circle around the gun, up to 6 turrets var turretCount = turrets.length; var angle = turretCount % 6 * (Math.PI * 2 / 6); var radius = 500; turret.x = gun.x + Math.cos(angle) * radius; turret.y = gun.y + Math.sin(angle) * radius; game.addChild(turret); // Add a timer property to track how long the turret has been alive turret.ticksAlive = 0; turrets.push(turret); // Reset turret spawn timer turretSpawnTicks = 0; } // Helper: spawn animal function spawnAnimal() { // Very rarely, spawn a unicorn if (Math.random() < 0.0015) { var unicorn = new Animal(); unicorn.init('unicorn'); game.addChild(unicorn); animals.push(unicorn); return; } // Very rarely, spawn a stork if (Math.random() < 0.003) { var stork = new Animal(); stork.init('stork'); game.addChild(stork); animals.push(stork); return; } var r = Math.random(); var animalType; // If killCount >= 11, make game much faster and more difficult (lots of spiders, faster animals) if (killCount >= 11) { if (r < 0.01) { // more trex animalType = 'trex'; } else if (r < 0.18) { animalType = 'lion'; } else if (r < 0.38) { animalType = 'zebra'; } else if (r < 0.48) { animalType = 'bird'; } else { // even more spiders animalType = 'spider'; } } else if (killCount >= 5) { // More spiders when killCount >= 5 if (r < 0.005) { animalType = 'trex'; } else if (r < 0.13) { animalType = 'lion'; } else if (r < 0.33) { animalType = 'zebra'; } else if (r < 0.60) { animalType = 'bird'; } else { // more spiders animalType = 'spider'; } } else { if (r < 0.005) { animalType = 'trex'; } else if (r < 0.13) { animalType = 'lion'; } else if (r < 0.33) { animalType = 'zebra'; } else if (r < 0.70) { animalType = 'bird'; } else { animalType = 'spider'; } } var animal = new Animal(); animal.init(animalType); game.addChild(animal); animals.push(animal); } // Helper: update UI function updateUI() { moneyTxt.setText('$' + money); caughtTxt.setText('Bag: ' + caughtAnimals.length); killTxt.setText('Kills: ' + killCount); gunTxt.setText('Gun: ' + gunNames[gunLevel]); if (gunLevel < 2) { upgradeBtn.setText('Upgrade ($' + gunPrices[gunLevel + 1] + ')'); upgradeBtn.alpha = money >= gunPrices[gunLevel + 1] ? 1 : 0.5; } else { upgradeBtn.setText('Maxed'); upgradeBtn.alpha = 0.5; } // Friend button UI removed // Reset animalsSpedUp if game is reset (killCount is 0) if (killCount < 8) { game.animalsSpedUp = false; } // Reset animalsSuperSpedUp if game is reset (killCount is 0) if (killCount < 11) { game.animalsSuperSpedUp = false; } } // Helper: sell animals function sellAnimals() { if (caughtAnimals.length === 0) return; var total = 0; for (var i = 0; i < caughtAnimals.length; i++) { total += caughtAnimals[i].getSellValue(); } money += total; caughtAnimals = []; LK.getSound('sell').play(); updateUI(); } // Helper: upgrade gun function upgradeGun() { if (gunLevel >= 2) return; var price = gunPrices[gunLevel + 1]; if (money < price) return; money -= price; gunLevel++; gun.destroy(); gun = new Gun(); gun.init(gunTypes[gunLevel]); game.addChild(gun); gun.x = 2048 / 2; gun.y = 2732 / 2; // Hat logic removed (Friend button gone) LK.getSound('upgrade').play(); updateUI(); } // UI events upgradeBtn.down = function (x, y, obj) { upgradeGun(); }; sellBtn.down = function (x, y, obj) { LK.getSound('sell').play(); sellAnimals(); }; // Touch to shoot game.down = function (x, y, obj) { // Don't shoot if touch is on GUI (bottom 300px) if (y > 2732 - 300) return; if (!gun.canShoot()) return; var bullet = new Bullet(); bullet.init(gunTypes[gunLevel]); bullet.x = gun.x + gun.asset.width * 0.9; bullet.y = gun.y; game.addChild(bullet); bullets.push(bullet); gun.shoot(); // Animate gun recoil tween(gun, { x: gun.x - 30 }, { duration: 60, easing: tween.cubicOut, onFinish: function onFinish() { tween(gun, { x: 300 }, { duration: 80, easing: tween.cubicIn }); } }); }; // Gun is fixed in the center; no dragging needed game.move = function (x, y, obj) { // No dragging logic }; // Shoot from the center gun position game.down = function (x, y, obj) { // Don't shoot if touch is on GUI (bottom 300px) if (y > 2732 - 300) return; if (!gun.canShoot()) return; var bullet = new Bullet(); bullet.init(gunTypes[gunLevel]); // Always shoot from the center gun position var gunMuzzleX = gun.x + gun.asset.width * 0.9; var gunMuzzleY = gun.y; bullet.x = gunMuzzleX; bullet.y = gunMuzzleY; var dx = x - gunMuzzleX; var dy = y - gunMuzzleY; var dist = Math.sqrt(dx * dx + dy * dy); if (dist === 0) dist = 1; // prevent division by zero bullet.dirX = dx / dist; bullet.dirY = dy / dist; bullet.rotation = Math.atan2(dy, dx); game.addChild(bullet); bullets.push(bullet); gun.shoot(); LK.getSound('shoot').play(); // Animate gun recoil tween(gun, { x: gun.x - 30 }, { duration: 60, easing: tween.cubicOut, onFinish: function onFinish() { tween(gun, { x: 2048 / 2 }, { duration: 80, easing: tween.cubicIn }); } }); }; game.up = function (x, y, obj) { // No dragging logic }; // Main update loop game.update = function () { // Spawn animals if (LK.ticks % 45 === 0 && animals.length < 7) { spawnAnimal(); } // Update animals for (var i = animals.length - 1; i >= 0; i--) { animals[i].update(); } // Update bullets for (var j = bullets.length - 1; j >= 0; j--) { bullets[j].update(); } // Bullet-animal collision for (var b = bullets.length - 1; b >= 0; b--) { var bullet = bullets[b]; for (var a = animals.length - 1; a >= 0; a--) { var animal = animals[a]; if (animal.caught) continue; if (bullet.intersects(animal)) { animal.caught = true; caughtAnimals.push(animal); killCount += 0.07; // Lower the kill counter increment per animal kill even further // Speed up all animals when kill counter passes 7 (only once) if (!game.animalsSpedUp && killCount >= 7) { for (var ai = 0; ai < animals.length; ai++) { if (!animals[ai].caught) { animals[ai].speed *= 1.35; } } game.animalsSpedUp = true; } // Make all animals much faster and more difficult when killCount >= 11 (only once) if (!game.animalsSuperSpedUp && killCount >= 11) { for (var ai = 0; ai < animals.length; ai++) { if (!animals[ai].caught) { animals[ai].speed *= 1.5; } } game.animalsSuperSpedUp = true; } tween(animal, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { animal.destroy(); var idx = animals.indexOf(animal); if (idx !== -1) animals.splice(idx, 1); } }); bullet.destroy(); bullets.splice(b, 1); break; } } } // Turret spawn logic turretSpawnTicks++; if (turretSpawnTicks >= turretSpawnInterval) { if (Math.random() < 0.25) { spawnTurret(); } turretSpawnTicks = 0; } // Update turrets for (var i = turrets.length - 1; i >= 0; i--) { var turret = turrets[i]; if (typeof turret.update === "function") { turret.update(); } // Turret stay/leave logic if (typeof turret.ticksAlive === "number") { turret.ticksAlive++; if (turret.ticksAlive >= turretStayDuration) { // Remove turret from game and array turret.destroy(); turrets.splice(i, 1); } } } // Bomb spawn logic: spawn bombs at different X positions and at different times if (LK.ticks % 240 === 0) { // More frequent and more bombs for (var i = 0; i < 2; i++) { if (Math.random() < 0.7) { // Spawn bomb at a random X (center region) var bomb = new Bomb(); bomb.x = 200 + Math.random() * (2048 - 400); bomb.y = -100; game.addChild(bomb); } if (Math.random() < 0.4) { // Spawn bomb at the far left var bombLeft = new Bomb(); bombLeft.x = 100 + Math.random() * 100; bombLeft.y = -100; game.addChild(bombLeft); } if (Math.random() < 0.4) { // Spawn bomb at the far right var bombRight = new Bomb(); bombRight.x = 2048 - 200 - Math.random() * 100; bombRight.y = -100; game.addChild(bombRight); } } } if (LK.ticks % 420 === 0) { for (var i = 0; i < 2; i++) { if (Math.random() < 0.5) { // Spawn bomb at the exact center var bomb2 = new Bomb(); bomb2.x = 2048 / 2; bomb2.y = -100; game.addChild(bomb2); } if (Math.random() < 0.3) { // Spawn bomb at a random X in the left half var bomb3 = new Bomb(); bomb3.x = 200 + Math.random() * (2048 / 2 - 200); bomb3.y = -100; game.addChild(bomb3); } if (Math.random() < 0.3) { // Spawn bomb at a random X in the right half var bomb4 = new Bomb(); bomb4.x = 2048 / 2 + Math.random() * (2048 / 2 - 200); bomb4.y = -100; game.addChild(bomb4); } } } updateUI(); }; // Play music LK.playMusic('forest_theme', { fade: { start: 0, end: 1, duration: 1200 } });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Animal base class
var Animal = Container.expand(function () {
var self = Container.call(this);
self.type = 'animal';
self.value = 0;
self.speed = 0;
self.caught = false;
self.init = function (animalType) {
self.animalType = animalType;
var assetId;
if (animalType === 'trex') {
assetId = 'trex';
self.value = 200;
self.speed = 2.2 + Math.random() * 0.8;
} else if (animalType === 'lion') {
assetId = 'lion';
self.value = 50;
self.speed = 3.2 + Math.random() * 1.2;
} else if (animalType === 'zebra') {
assetId = 'zebra';
self.value = 30;
self.speed = 3.8 + Math.random() * 1.5;
} else if (animalType === 'bird') {
assetId = 'bird';
self.value = 10;
self.speed = 5.5 + Math.random() * 2.5;
} else if (animalType === 'spider') {
assetId = 'spider';
self.value = 2;
self.speed = 2.2 + Math.random() * 1.2;
} else if (animalType === 'stork') {
assetId = 'bird';
self.value = 100;
self.speed = 4.5 + Math.random() * 1.5;
// Tint the stork to make it visually distinct
// (LK.getAsset does not support dynamic tint, so we use the same asset for now)
} else if (animalType === 'unicorn') {
assetId = 'unicorn';
self.value = 500;
self.speed = 3.5 + Math.random() * 1.2;
}
self.asset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = Math.random() < 0.5 ? 1 : -1;
if (animalType === 'lion') {
// Let lions roam farther away from the player (avoid center)
// Top or bottom 1/3 of the screen
if (Math.random() < 0.5) {
self.y = 500 + Math.random() * 400; // Top band
} else {
self.y = 1900 + Math.random() * 300; // Bottom band
}
} else {
self.y = 500 + Math.random() * 1700;
}
if (self.direction === 1) {
self.x = -self.asset.width / 2;
} else {
self.x = 2048 + self.asset.width / 2;
self.asset.scaleX = -1;
}
};
self.update = function () {
if (self.caught) return;
self.x += self.speed * self.direction;
// Remove if off screen
if (self.direction === 1 && self.x > 2048 + self.asset.width / 2 || self.direction === -1 && self.x < -self.asset.width / 2) {
self.destroy();
var idx = animals.indexOf(self);
if (idx !== -1) animals.splice(idx, 1);
}
};
self.getSellValue = function () {
return self.value;
};
return self;
});
// Bomb class
var Bomb = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('bomb', {
anchorX: 0.5,
anchorY: 0.5
});
// Bomb falls from the top, explodes when reaching the ground or in the air
self.speedY = 18 + Math.random() * 6;
self.exploded = false;
self.update = function () {
if (self.exploded) return;
if (typeof self.lastY === "undefined") self.lastY = self.y;
self.y += self.speedY;
// Explode in the air at a random height (simulate air burst)
// Pick a random air burst height for each bomb if not set
if (typeof self.airBurstY === "undefined") {
// Air burst between 900 and 1800 px (roughly upper-middle of screen)
self.airBurstY = 900 + Math.random() * 900;
}
// Explode if reached air burst height or ground (bottom 200px)
var shouldExplode = false;
if (self.lastY <= self.airBurstY && self.y > self.airBurstY) {
shouldExplode = true;
}
if (self.lastY <= 2732 - 200 && self.y > 2732 - 200) {
shouldExplode = true;
}
if (shouldExplode) {
self.exploded = true;
// Remove all animals in a 350px radius, but do NOT affect the player (gun)
for (var i = animals.length - 1; i >= 0; i--) {
var a = animals[i];
if (!a.caught) {
var dx = a.x - self.x;
var dy = a.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 350) {
a.caught = true;
caughtAnimals.push(a);
killCount += 0.07;
tween(a, {
alpha: 0
}, {
duration: 300,
onFinish: function (animal) {
return function () {
animal.destroy();
var idx = animals.indexOf(animal);
if (idx !== -1) animals.splice(idx, 1);
};
}(a)
});
}
}
}
// Do NOT check or affect the gun/player here, so bombs never harm the player!
// Animate bomb fade out and destroy
tween(self, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
self.destroy();
}
});
}
self.lastY = self.y;
// Remove if off screen
if (self.y > 2832 + 100) {
self.destroy();
}
};
return self;
});
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
self.speed = 0;
self.range = 0;
self.gunType = 'basic';
self.init = function (gunType) {
self.gunType = gunType;
var assetId;
if (gunType === 'basic') {
assetId = 'bullet_basic';
self.speed = 28;
self.range = 1200;
} else if (gunType === 'rapid') {
assetId = 'bullet_rapid';
self.speed = 36;
self.range = 900;
} else if (gunType === 'sniper') {
assetId = 'bullet_sniper';
self.speed = 44;
self.range = 1800;
}
self.asset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.distance = 0;
};
self.update = function () {
if (typeof self.dirX === "number" && typeof self.dirY === "number") {
self.x += self.speed * self.dirX;
self.y += self.speed * self.dirY;
self.distance += self.speed;
} else {
self.x += self.speed;
self.distance += self.speed;
}
if (self.distance > self.range || self.x < -100 || self.x > 2200 || self.y < -100 || self.y > 2832) {
self.destroy();
var idx = bullets.indexOf(self);
if (idx !== -1) bullets.splice(idx, 1);
}
};
return self;
});
// Gun class
var Gun = Container.expand(function () {
var self = Container.call(this);
self.gunType = 'basic';
self.reloadTime = 0;
self.lastShotTick = 0;
self.init = function (gunType) {
self.gunType = gunType;
var assetId;
if (gunType === 'basic') {
assetId = 'gun_basic';
self.reloadTime = 30;
} else if (gunType === 'rapid') {
assetId = 'gun_rapid';
self.reloadTime = 12;
} else if (gunType === 'sniper') {
assetId = 'gun_sniper';
self.reloadTime = 60;
}
self.asset = self.attachAsset(assetId, {
anchorX: 0.1,
anchorY: 0.5
});
};
self.canShoot = function () {
return LK.ticks - self.lastShotTick >= self.reloadTime;
};
self.shoot = function () {
self.lastShotTick = LK.ticks;
};
return self;
});
// Turret class
var Turret = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('turret', {
anchorX: 0.5,
anchorY: 0.5
});
self.fireCooldown = 0;
self.update = function () {
// Find nearest animal within 700px
var closest = null;
var minDist = 99999;
for (var i = 0; i < animals.length; i++) {
var a = animals[i];
if (a.caught) continue;
var dx = a.x - self.x;
var dy = a.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 700 && dist < minDist) {
minDist = dist;
closest = a;
}
}
// Fire at nearest animal every 18 ticks (~3.3 shots/sec)
if (closest && self.fireCooldown <= 0) {
var bullet = new Bullet();
bullet.init('rapid');
bullet.x = self.x + self.asset.width * 0.5;
bullet.y = self.y;
var dx = closest.x - bullet.x;
var dy = closest.y - bullet.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist === 0) dist = 1;
bullet.dirX = dx / dist;
bullet.dirY = dy / dist;
bullet.rotation = Math.atan2(dy, dx);
game.addChild(bullet);
bullets.push(bullet);
LK.getSound('shoot').play();
self.fireCooldown = 18;
}
if (self.fireCooldown > 0) self.fireCooldown--;
};
return self;
});
/****
* Initialize Game
****/
// Helper: spawn animal
var game = new LK.Game({
backgroundColor: 0x2e5d2c
});
/****
* Game Code
****/
// Game state variables
// Animals
// Guns
// Bullets
// Sounds
// Music
// Turret asset
var animals = [];
var bullets = [];
var caughtAnimals = [];
var money = 0;
var killCount = 0; // Track total kills
var gunLevel = 0; // 0: basic, 1: rapid, 2: sniper
var gunTypes = ['basic', 'rapid', 'sniper'];
var gunPrices = [0, 200, 600];
var gunNames = ['Basic Gun', 'Rapid Gun', 'Sniper Gun'];
var gun;
var animalsSpedUp = false; // Track if animals have been sped up
// UI
var moneyTxt = new Text2('$0', {
size: 90,
fill: 0xFFF700
});
moneyTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(moneyTxt);
var caughtTxt = new Text2('Bag: 0', {
size: 70,
fill: 0xFFFFFF
});
caughtTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(caughtTxt);
caughtTxt.y = 110;
var killTxt = new Text2('Kills: 0', {
size: 70,
fill: 0xFF4444
});
killTxt.anchor.set(0, 1); // anchor bottom left
LK.gui.bottomLeft.addChild(killTxt);
killTxt.x = 0;
killTxt.y = 0;
var gunTxt = new Text2('Gun: Basic', {
size: 60,
fill: 0xFFFFFF
});
gunTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(gunTxt);
gunTxt.y = 200;
var sellBtn = new Text2('Sell', {
size: 70,
fill: 0xFF8800
});
sellBtn.anchor.set(0.5, 0.5);
LK.gui.bottom.addChild(sellBtn);
sellBtn.y = -200;
var upgradeBtn = new Text2('Upgrade', {
size: 70,
fill: 0x00FF00
});
upgradeBtn.anchor.set(0.5, 0.5);
LK.gui.bottom.addChild(upgradeBtn);
upgradeBtn.y = -120;
// Gun
gun = new Gun();
gun.init(gunTypes[gunLevel]);
game.addChild(gun);
// Center the gun horizontally and vertically
gun.x = 2048 / 2;
gun.y = 2732 / 2;
// Friend button removed
// Track if skin is bought
var skinBought = false;
// Turret spawn timer variables
var turretSpawnInterval = 660; // 11 seconds at 60 FPS
var turretSpawnTicks = 0;
var turrets = [];
var turretStayDuration = 300; // 5 seconds at 60 FPS
function spawnTurret() {
var turret = new Turret();
// Place turrets in a circle around the gun, up to 6 turrets
var turretCount = turrets.length;
var angle = turretCount % 6 * (Math.PI * 2 / 6);
var radius = 500;
turret.x = gun.x + Math.cos(angle) * radius;
turret.y = gun.y + Math.sin(angle) * radius;
game.addChild(turret);
// Add a timer property to track how long the turret has been alive
turret.ticksAlive = 0;
turrets.push(turret);
// Reset turret spawn timer
turretSpawnTicks = 0;
}
// Helper: spawn animal
function spawnAnimal() {
// Very rarely, spawn a unicorn
if (Math.random() < 0.0015) {
var unicorn = new Animal();
unicorn.init('unicorn');
game.addChild(unicorn);
animals.push(unicorn);
return;
}
// Very rarely, spawn a stork
if (Math.random() < 0.003) {
var stork = new Animal();
stork.init('stork');
game.addChild(stork);
animals.push(stork);
return;
}
var r = Math.random();
var animalType;
// If killCount >= 11, make game much faster and more difficult (lots of spiders, faster animals)
if (killCount >= 11) {
if (r < 0.01) {
// more trex
animalType = 'trex';
} else if (r < 0.18) {
animalType = 'lion';
} else if (r < 0.38) {
animalType = 'zebra';
} else if (r < 0.48) {
animalType = 'bird';
} else {
// even more spiders
animalType = 'spider';
}
} else if (killCount >= 5) {
// More spiders when killCount >= 5
if (r < 0.005) {
animalType = 'trex';
} else if (r < 0.13) {
animalType = 'lion';
} else if (r < 0.33) {
animalType = 'zebra';
} else if (r < 0.60) {
animalType = 'bird';
} else {
// more spiders
animalType = 'spider';
}
} else {
if (r < 0.005) {
animalType = 'trex';
} else if (r < 0.13) {
animalType = 'lion';
} else if (r < 0.33) {
animalType = 'zebra';
} else if (r < 0.70) {
animalType = 'bird';
} else {
animalType = 'spider';
}
}
var animal = new Animal();
animal.init(animalType);
game.addChild(animal);
animals.push(animal);
}
// Helper: update UI
function updateUI() {
moneyTxt.setText('$' + money);
caughtTxt.setText('Bag: ' + caughtAnimals.length);
killTxt.setText('Kills: ' + killCount);
gunTxt.setText('Gun: ' + gunNames[gunLevel]);
if (gunLevel < 2) {
upgradeBtn.setText('Upgrade ($' + gunPrices[gunLevel + 1] + ')');
upgradeBtn.alpha = money >= gunPrices[gunLevel + 1] ? 1 : 0.5;
} else {
upgradeBtn.setText('Maxed');
upgradeBtn.alpha = 0.5;
}
// Friend button UI removed
// Reset animalsSpedUp if game is reset (killCount is 0)
if (killCount < 8) {
game.animalsSpedUp = false;
}
// Reset animalsSuperSpedUp if game is reset (killCount is 0)
if (killCount < 11) {
game.animalsSuperSpedUp = false;
}
}
// Helper: sell animals
function sellAnimals() {
if (caughtAnimals.length === 0) return;
var total = 0;
for (var i = 0; i < caughtAnimals.length; i++) {
total += caughtAnimals[i].getSellValue();
}
money += total;
caughtAnimals = [];
LK.getSound('sell').play();
updateUI();
}
// Helper: upgrade gun
function upgradeGun() {
if (gunLevel >= 2) return;
var price = gunPrices[gunLevel + 1];
if (money < price) return;
money -= price;
gunLevel++;
gun.destroy();
gun = new Gun();
gun.init(gunTypes[gunLevel]);
game.addChild(gun);
gun.x = 2048 / 2;
gun.y = 2732 / 2;
// Hat logic removed (Friend button gone)
LK.getSound('upgrade').play();
updateUI();
}
// UI events
upgradeBtn.down = function (x, y, obj) {
upgradeGun();
};
sellBtn.down = function (x, y, obj) {
LK.getSound('sell').play();
sellAnimals();
};
// Touch to shoot
game.down = function (x, y, obj) {
// Don't shoot if touch is on GUI (bottom 300px)
if (y > 2732 - 300) return;
if (!gun.canShoot()) return;
var bullet = new Bullet();
bullet.init(gunTypes[gunLevel]);
bullet.x = gun.x + gun.asset.width * 0.9;
bullet.y = gun.y;
game.addChild(bullet);
bullets.push(bullet);
gun.shoot();
// Animate gun recoil
tween(gun, {
x: gun.x - 30
}, {
duration: 60,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(gun, {
x: 300
}, {
duration: 80,
easing: tween.cubicIn
});
}
});
};
// Gun is fixed in the center; no dragging needed
game.move = function (x, y, obj) {
// No dragging logic
};
// Shoot from the center gun position
game.down = function (x, y, obj) {
// Don't shoot if touch is on GUI (bottom 300px)
if (y > 2732 - 300) return;
if (!gun.canShoot()) return;
var bullet = new Bullet();
bullet.init(gunTypes[gunLevel]);
// Always shoot from the center gun position
var gunMuzzleX = gun.x + gun.asset.width * 0.9;
var gunMuzzleY = gun.y;
bullet.x = gunMuzzleX;
bullet.y = gunMuzzleY;
var dx = x - gunMuzzleX;
var dy = y - gunMuzzleY;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist === 0) dist = 1; // prevent division by zero
bullet.dirX = dx / dist;
bullet.dirY = dy / dist;
bullet.rotation = Math.atan2(dy, dx);
game.addChild(bullet);
bullets.push(bullet);
gun.shoot();
LK.getSound('shoot').play();
// Animate gun recoil
tween(gun, {
x: gun.x - 30
}, {
duration: 60,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(gun, {
x: 2048 / 2
}, {
duration: 80,
easing: tween.cubicIn
});
}
});
};
game.up = function (x, y, obj) {
// No dragging logic
};
// Main update loop
game.update = function () {
// Spawn animals
if (LK.ticks % 45 === 0 && animals.length < 7) {
spawnAnimal();
}
// Update animals
for (var i = animals.length - 1; i >= 0; i--) {
animals[i].update();
}
// Update bullets
for (var j = bullets.length - 1; j >= 0; j--) {
bullets[j].update();
}
// Bullet-animal collision
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
for (var a = animals.length - 1; a >= 0; a--) {
var animal = animals[a];
if (animal.caught) continue;
if (bullet.intersects(animal)) {
animal.caught = true;
caughtAnimals.push(animal);
killCount += 0.07; // Lower the kill counter increment per animal kill even further
// Speed up all animals when kill counter passes 7 (only once)
if (!game.animalsSpedUp && killCount >= 7) {
for (var ai = 0; ai < animals.length; ai++) {
if (!animals[ai].caught) {
animals[ai].speed *= 1.35;
}
}
game.animalsSpedUp = true;
}
// Make all animals much faster and more difficult when killCount >= 11 (only once)
if (!game.animalsSuperSpedUp && killCount >= 11) {
for (var ai = 0; ai < animals.length; ai++) {
if (!animals[ai].caught) {
animals[ai].speed *= 1.5;
}
}
game.animalsSuperSpedUp = true;
}
tween(animal, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
animal.destroy();
var idx = animals.indexOf(animal);
if (idx !== -1) animals.splice(idx, 1);
}
});
bullet.destroy();
bullets.splice(b, 1);
break;
}
}
}
// Turret spawn logic
turretSpawnTicks++;
if (turretSpawnTicks >= turretSpawnInterval) {
if (Math.random() < 0.25) {
spawnTurret();
}
turretSpawnTicks = 0;
}
// Update turrets
for (var i = turrets.length - 1; i >= 0; i--) {
var turret = turrets[i];
if (typeof turret.update === "function") {
turret.update();
}
// Turret stay/leave logic
if (typeof turret.ticksAlive === "number") {
turret.ticksAlive++;
if (turret.ticksAlive >= turretStayDuration) {
// Remove turret from game and array
turret.destroy();
turrets.splice(i, 1);
}
}
}
// Bomb spawn logic: spawn bombs at different X positions and at different times
if (LK.ticks % 240 === 0) {
// More frequent and more bombs
for (var i = 0; i < 2; i++) {
if (Math.random() < 0.7) {
// Spawn bomb at a random X (center region)
var bomb = new Bomb();
bomb.x = 200 + Math.random() * (2048 - 400);
bomb.y = -100;
game.addChild(bomb);
}
if (Math.random() < 0.4) {
// Spawn bomb at the far left
var bombLeft = new Bomb();
bombLeft.x = 100 + Math.random() * 100;
bombLeft.y = -100;
game.addChild(bombLeft);
}
if (Math.random() < 0.4) {
// Spawn bomb at the far right
var bombRight = new Bomb();
bombRight.x = 2048 - 200 - Math.random() * 100;
bombRight.y = -100;
game.addChild(bombRight);
}
}
}
if (LK.ticks % 420 === 0) {
for (var i = 0; i < 2; i++) {
if (Math.random() < 0.5) {
// Spawn bomb at the exact center
var bomb2 = new Bomb();
bomb2.x = 2048 / 2;
bomb2.y = -100;
game.addChild(bomb2);
}
if (Math.random() < 0.3) {
// Spawn bomb at a random X in the left half
var bomb3 = new Bomb();
bomb3.x = 200 + Math.random() * (2048 / 2 - 200);
bomb3.y = -100;
game.addChild(bomb3);
}
if (Math.random() < 0.3) {
// Spawn bomb at a random X in the right half
var bomb4 = new Bomb();
bomb4.x = 2048 / 2 + Math.random() * (2048 / 2 - 200);
bomb4.y = -100;
game.addChild(bomb4);
}
}
}
updateUI();
};
// Play music
LK.playMusic('forest_theme', {
fade: {
start: 0,
end: 1,
duration: 1200
}
});
Spider pixel. In-Game asset. 2d. High contrast. No shadows
Lion pixel. In-Game asset. 2d. High contrast. No shadows
Zebra pixel. In-Game asset. 2d. High contrast. No shadows
Trex pixel. In-Game asset. 2d. High contrast. No shadows
Bird pixel. In-Game asset. 2d. High contrast. No shadows
person with glock18 in hand pixel. In-Game asset. 2d. High contrast. No shadows
man with sniper
Person with m4a1 in hand
Bullet pixel. In-Game asset. 2d. High contrast. No shadows
Turret pixel. In-Game asset. 2d. High contrast. No shadows
Unicorn pixel. In-Game asset. 2d. High contrast. No shadows
Tree pixel. In-Game asset. 2d. High contrast. No shadows
man with laser gun