User prompt
Let the bombs explode in the air and kill the animals
User prompt
Make the bombs a little bigger and spawn more
User prompt
Spawn bombs in different places at different times
User prompt
spawn more bombs in the game
User prompt
add unicorn to game
User prompt
spawn "bomb"
User prompt
Add the "bomb" asset to the game
User prompt
create asset "bomb"
User prompt
Get the kill counter in the bottom left
User prompt
Lower the kill counter a bit more
User prompt
lower the kill counter
User prompt
turn kill counter down a bit
User prompt
When there is Kill Counter 5, there should be more Spiders When it becomes kill counter 11, the game becomes much faster and more difficult.
User prompt
Animals speed up when you pass Kill Counter 7 , and let the lions roam far away from us
User prompt
More spiders to come when kill counter passes 11
User prompt
When Kill Counter 8 is reached, animals should speed up a bit. and more
User prompt
lower the kill counter a bit
User prompt
lower the kill counter a bit
User prompt
add kill counter
User prompt
Turrets come with a 25% chance
User prompt
delete the friends button
User prompt
Turrets come every 11 seconds, stop for 5 seconds and then go away
User prompt
When you click on friend, a "turret" will come from the assets. Nothing else will come
User prompt
Make the upgrade $200
User prompt
When you press friend, "turret" will appear every 9 seconds.
/**** * 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) } self.asset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.direction = Math.random() < 0.5 ? 1 : -1; 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; }); // 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 ****/ // Turret asset // Music // Sounds // Bullets // Guns // Animals // Game state variables var animals = []; var bullets = []; var caughtAnimals = []; var money = 0; var gunLevel = 0; // 0: basic, 1: rapid, 2: sniper var gunTypes = ['basic', 'rapid', 'sniper']; var gunPrices = [0, 1000, 600]; var gunNames = ['Basic Gun', 'Rapid Gun', 'Sniper Gun']; var gun; // 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 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; // Add Friend button var skinBtn = new Text2('Friend ($100)', { size: 70, fill: 0x00BFFF }); skinBtn.anchor.set(0.5, 0.5); LK.gui.bottom.addChild(skinBtn); skinBtn.y = -40; skinBtn.alpha = 1; // Track if skin is bought var skinBought = false; // Friend button event skinBtn.down = function (x, y, obj) { if (skinBought) return; if (money < 100) return; money -= 100; skinBought = true; skinBtn.setText('Owned'); skinBtn.alpha = 0.5; // Spawn mini gun friend spawnMiniGunFriend(); updateUI(); }; // Mini gun friend logic var miniGunFriend = null; var miniGunFriendActiveTicks = 0; // Turret spawn timer variables var turretSpawnInterval = 540; // 9 seconds at 60 FPS var turretSpawnTicks = 0; var turrets = []; function spawnMiniGunFriend() { if (miniGunFriend) { // Already active, reset timer miniGunFriendActiveTicks = 0; return; } miniGunFriend = new Gun(); miniGunFriend.init('rapid'); // Change appearance: add a hat and tint the gun for visual distinction if (!miniGunFriend.hat) { var hat = LK.getAsset('hat', { anchorX: 0.5, anchorY: 1 }); hat.x = miniGunFriend.asset.width * 0.5; hat.y = -miniGunFriend.asset.height * 0.45; miniGunFriend.addChild(hat); miniGunFriend.hat = hat; } // Tint the gun asset to blue for distinction miniGunFriend.asset.tint = 0x00BFFF; miniGunFriend.scaleX = 0.7; miniGunFriend.scaleY = 0.7; miniGunFriend.x = gun.x + 320; miniGunFriend.y = gun.y - 320; game.addChild(miniGunFriend); miniGunFriendActiveTicks = 0; // Reset turret spawn timer turretSpawnTicks = 0; } // Helper: spawn animal function spawnAnimal() { // 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 (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); 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; } // Update skinBtn UI if (typeof skinBtn !== "undefined") { if (skinBought) { skinBtn.setText('Owned'); skinBtn.alpha = 0.5; } else { skinBtn.setText('Friend ($100)'); skinBtn.alpha = money >= 100 ? 1 : 0.5; } } } // 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; // If skin is bought, re-apply hat if (skinBought && gun.asset) { if (!gun.hat) { var hat = LK.getAsset('hat', { anchorX: 0.5, anchorY: 1 }); hat.x = gun.asset.width * 0.5; hat.y = -gun.asset.height * 0.45; gun.addChild(hat); gun.hat = hat; } } 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); // Animate animal fade out 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; } } } // Mini gun friend logic if (miniGunFriend) { miniGunFriendActiveTicks++; // Find all animals within 600px var targets = []; for (var i = 0; i < animals.length; i++) { var a = animals[i]; if (a.caught) continue; var dx = a.x - miniGunFriend.x; var dy = a.y - miniGunFriend.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 600) { targets.push(a); } } // Spray bullets every 6 ticks (10 times per second) if (LK.ticks % 6 === 0 && targets.length > 0) { // Pick up to 3 closest targets targets.sort(function (a, b) { var da = Math.sqrt((a.x - miniGunFriend.x) * (a.x - miniGunFriend.x) + (a.y - miniGunFriend.y) * (a.y - miniGunFriend.y)); var db = Math.sqrt((b.x - miniGunFriend.x) * (b.x - miniGunFriend.x) + (b.y - miniGunFriend.y) * (b.y - miniGunFriend.y)); return da - db; }); for (var t = 0; t < Math.min(3, targets.length); t++) { var target = targets[t]; var bullet = new Bullet(); bullet.init('rapid'); bullet.x = miniGunFriend.x + miniGunFriend.asset.width * 0.9; bullet.y = miniGunFriend.y; var dx = target.x - bullet.x; var dy = target.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); // Play shoot sound LK.getSound('shoot').play(); } } // Remove after 5 seconds (300 ticks) if (miniGunFriendActiveTicks > 300) { miniGunFriend.destroy(); miniGunFriend = null; } // Turret spawn logic turretSpawnTicks++; if (turretSpawnTicks >= turretSpawnInterval) { turretSpawnTicks = 0; // Spawn a turret near the center, but offset to avoid overlap 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); turrets.push(turret); } } // Update turrets for (var i = turrets.length - 1; i >= 0; i--) { var turret = turrets[i]; if (typeof turret.update === "function") { turret.update(); } } 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)
}
self.asset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = Math.random() < 0.5 ? 1 : -1;
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;
});
// 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
****/
// Turret asset
// Music
// Sounds
// Bullets
// Guns
// Animals
// Game state variables
var animals = [];
var bullets = [];
var caughtAnimals = [];
var money = 0;
var gunLevel = 0; // 0: basic, 1: rapid, 2: sniper
var gunTypes = ['basic', 'rapid', 'sniper'];
var gunPrices = [0, 1000, 600];
var gunNames = ['Basic Gun', 'Rapid Gun', 'Sniper Gun'];
var gun;
// 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 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;
// Add Friend button
var skinBtn = new Text2('Friend ($100)', {
size: 70,
fill: 0x00BFFF
});
skinBtn.anchor.set(0.5, 0.5);
LK.gui.bottom.addChild(skinBtn);
skinBtn.y = -40;
skinBtn.alpha = 1;
// Track if skin is bought
var skinBought = false;
// Friend button event
skinBtn.down = function (x, y, obj) {
if (skinBought) return;
if (money < 100) return;
money -= 100;
skinBought = true;
skinBtn.setText('Owned');
skinBtn.alpha = 0.5;
// Spawn mini gun friend
spawnMiniGunFriend();
updateUI();
};
// Mini gun friend logic
var miniGunFriend = null;
var miniGunFriendActiveTicks = 0;
// Turret spawn timer variables
var turretSpawnInterval = 540; // 9 seconds at 60 FPS
var turretSpawnTicks = 0;
var turrets = [];
function spawnMiniGunFriend() {
if (miniGunFriend) {
// Already active, reset timer
miniGunFriendActiveTicks = 0;
return;
}
miniGunFriend = new Gun();
miniGunFriend.init('rapid');
// Change appearance: add a hat and tint the gun for visual distinction
if (!miniGunFriend.hat) {
var hat = LK.getAsset('hat', {
anchorX: 0.5,
anchorY: 1
});
hat.x = miniGunFriend.asset.width * 0.5;
hat.y = -miniGunFriend.asset.height * 0.45;
miniGunFriend.addChild(hat);
miniGunFriend.hat = hat;
}
// Tint the gun asset to blue for distinction
miniGunFriend.asset.tint = 0x00BFFF;
miniGunFriend.scaleX = 0.7;
miniGunFriend.scaleY = 0.7;
miniGunFriend.x = gun.x + 320;
miniGunFriend.y = gun.y - 320;
game.addChild(miniGunFriend);
miniGunFriendActiveTicks = 0;
// Reset turret spawn timer
turretSpawnTicks = 0;
}
// Helper: spawn animal
function spawnAnimal() {
// 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 (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);
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;
}
// Update skinBtn UI
if (typeof skinBtn !== "undefined") {
if (skinBought) {
skinBtn.setText('Owned');
skinBtn.alpha = 0.5;
} else {
skinBtn.setText('Friend ($100)');
skinBtn.alpha = money >= 100 ? 1 : 0.5;
}
}
}
// 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;
// If skin is bought, re-apply hat
if (skinBought && gun.asset) {
if (!gun.hat) {
var hat = LK.getAsset('hat', {
anchorX: 0.5,
anchorY: 1
});
hat.x = gun.asset.width * 0.5;
hat.y = -gun.asset.height * 0.45;
gun.addChild(hat);
gun.hat = hat;
}
}
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);
// Animate animal fade out
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;
}
}
}
// Mini gun friend logic
if (miniGunFriend) {
miniGunFriendActiveTicks++;
// Find all animals within 600px
var targets = [];
for (var i = 0; i < animals.length; i++) {
var a = animals[i];
if (a.caught) continue;
var dx = a.x - miniGunFriend.x;
var dy = a.y - miniGunFriend.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 600) {
targets.push(a);
}
}
// Spray bullets every 6 ticks (10 times per second)
if (LK.ticks % 6 === 0 && targets.length > 0) {
// Pick up to 3 closest targets
targets.sort(function (a, b) {
var da = Math.sqrt((a.x - miniGunFriend.x) * (a.x - miniGunFriend.x) + (a.y - miniGunFriend.y) * (a.y - miniGunFriend.y));
var db = Math.sqrt((b.x - miniGunFriend.x) * (b.x - miniGunFriend.x) + (b.y - miniGunFriend.y) * (b.y - miniGunFriend.y));
return da - db;
});
for (var t = 0; t < Math.min(3, targets.length); t++) {
var target = targets[t];
var bullet = new Bullet();
bullet.init('rapid');
bullet.x = miniGunFriend.x + miniGunFriend.asset.width * 0.9;
bullet.y = miniGunFriend.y;
var dx = target.x - bullet.x;
var dy = target.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);
// Play shoot sound
LK.getSound('shoot').play();
}
}
// Remove after 5 seconds (300 ticks)
if (miniGunFriendActiveTicks > 300) {
miniGunFriend.destroy();
miniGunFriend = null;
}
// Turret spawn logic
turretSpawnTicks++;
if (turretSpawnTicks >= turretSpawnInterval) {
turretSpawnTicks = 0;
// Spawn a turret near the center, but offset to avoid overlap
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);
turrets.push(turret);
}
}
// Update turrets
for (var i = turrets.length - 1; i >= 0; i--) {
var turret = turrets[i];
if (typeof turret.update === "function") {
turret.update();
}
}
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