/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BigCactus = Container.expand(function () { var self = Container.call(this); var cactusGraphics = self.attachAsset('kaktus2', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.health = 2; self.direction = { x: 0, y: 0 }; self.lastIntersectingSheriff = false; self.update = function () { // Recalculate direction to always track sheriff's current position var dx = sheriff.x - self.x; var dy = sheriff.y - self.y; var distance = calculateDistance(self.x, self.y, sheriff.x, sheriff.y); if (distance > 0) { self.direction.x = dx / distance; self.direction.y = dy / distance; } self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; // Check collision with sheriff var currentIntersecting = self.intersects(sheriff); if (!self.lastIntersectingSheriff && currentIntersecting) { sheriff.takeDamage(2); // Deal 2 damage self.destroy(); var index = bigCacti.indexOf(self); if (index > -1) { bigCacti.splice(index, 1); } } self.lastIntersectingSheriff = currentIntersecting; }; self.takeDamage = function () { self.health--; if (self.health <= 0) { self.destroy(); var index = bigCacti.indexOf(self); if (index > -1) { bigCacti.splice(index, 1); } // Add gold LK.setScore(LK.getScore() + 20); scoreText.setText('Gold: ' + LK.getScore()); } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.direction = { x: 0, y: 0 }; self.lastY = 0; self.lastX = 0; self.update = function () { self.lastX = self.x; self.lastY = self.y; self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; }; return self; }); var Cactus = Container.expand(function () { var self = Container.call(this); var cactusGraphics = self.attachAsset('cactus', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.direction = { x: 0, y: 0 }; self.lastIntersectingSheriff = false; self.update = function () { // Recalculate direction to always track sheriff's current position var dx = sheriff.x - self.x; var dy = sheriff.y - self.y; var distance = calculateDistance(self.x, self.y, sheriff.x, sheriff.y); if (distance > 0) { self.direction.x = dx / distance; self.direction.y = dy / distance; } self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; // Check collision with sheriff var currentIntersecting = self.intersects(sheriff); if (!self.lastIntersectingSheriff && currentIntersecting) { sheriff.takeDamage(); self.destroy(); var index = cacti.indexOf(self); if (index > -1) { cacti.splice(index, 1); } } self.lastIntersectingSheriff = currentIntersecting; }; return self; }); var GoldenStar = Container.expand(function () { var self = Container.call(this); var starGraphics = self.attachAsset('goldenStar', { anchorX: 0.5, anchorY: 0.5 }); self.lastIntersectingSheriff = false; self.update = function () { // Rotate the star starGraphics.rotation += 0.1; // Check collision with sheriff var currentIntersecting = self.intersects(sheriff); if (!self.lastIntersectingSheriff && currentIntersecting) { sheriff.activateInvincibility(); self.destroy(); var index = goldenStars.indexOf(self); if (index > -1) { goldenStars.splice(index, 1); } } self.lastIntersectingSheriff = currentIntersecting; }; return self; }); var Sheriff = Container.expand(function () { var self = Container.call(this); var sheriffGraphics = self.attachAsset('sheriff', { anchorX: 0.5, anchorY: 0.5 }); self.health = 10; self.invincible = false; self.invincibilityEndTime = 0; self.rapidFire = false; self.rapidFireEndTime = 0; self.update = function () { // Check if invincibility expired if (self.invincible && LK.ticks > self.invincibilityEndTime) { self.invincible = false; sheriffGraphics.tint = 0xFFFFFF; // Reset tint } // Check if rapid fire expired if (self.rapidFire && LK.ticks > self.rapidFireEndTime) { self.rapidFire = false; } // Flash effect when invincible if (self.invincible) { var flashValue = Math.sin(LK.ticks * 0.3) > 0 ? 0xFFD700 : 0xFFFFFF; sheriffGraphics.tint = flashValue; } }; self.takeDamage = function (damage) { if (!self.invincible) { damage = damage || 1; // Default to 1 damage if not specified self.health -= damage; LK.getSound('hit').play(); // Flash red briefly sheriffGraphics.tint = 0xFF0000; LK.setTimeout(function () { if (!self.invincible) { sheriffGraphics.tint = 0xFFFFFF; } }, 200); if (self.health <= 0) { LK.showGameOver(); } } }; self.activateInvincibility = function () { self.invincible = true; self.invincibilityEndTime = LK.ticks + 600; // 10 seconds at 60fps LK.getSound('powerup').play(); }; self.activateRapidFire = function () { self.rapidFire = true; self.rapidFireEndTime = LK.ticks + 600; // 10 seconds at 60fps LK.getSound('powerup').play(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xDEB887 }); /**** * Game Code ****/ var sheriff = game.addChild(new Sheriff()); sheriff.x = 1024; sheriff.y = 1366; var cacti = []; var bullets = []; var goldenStars = []; var bigCacti = []; var waveNumber = 1; var cactusSpawnRate = 120; // frames between spawns var cactusSpeed = 2; var dragNode = null; var lastShootTime = 0; var shootInterval = 60; // 60 frames = 1 second at 60fps // UI Elements var healthText = new Text2('Health: 10', { size: 60, fill: 0xFF0000 }); healthText.anchor.set(0, 0); healthText.y = 80; // Move health text down to make room for upgrade button LK.gui.topRight.addChild(healthText); // Upgrade button and counter var upgradeButton = new Container(); var buttonBg = upgradeButton.attachAsset('button', { width: 150, height: 60, color: 0x0000FF, shape: 'box', anchorX: 1, anchorY: 0 }); LK.gui.topRight.addChild(upgradeButton); var upgradeCounter = new Text2('0', { size: 50, fill: 0x0000FF }); upgradeCounter.anchor.set(1, 0); upgradeCounter.x = -160; // Position to the left of the button LK.gui.topRight.addChild(upgradeCounter); var upgradeLevel = 0; var upgradeCost = 10; var scoreText = new Text2('Gold: 0', { size: 60, fill: 0xFFD700 }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var invincibilityText = new Text2('', { size: 50, fill: 0xFFD700 }); invincibilityText.anchor.set(0.5, 0); invincibilityText.y = 80; LK.gui.top.addChild(invincibilityText); var rapidFireText = new Text2('', { size: 50, fill: 0xFF8C00 }); rapidFireText.anchor.set(0.5, 0); rapidFireText.y = 140; LK.gui.top.addChild(rapidFireText); var waveText = new Text2('Wave: 1', { size: 50, fill: 0xFFFFFF }); waveText.anchor.set(0, 0); LK.gui.topLeft.addChild(waveText); waveText.x = 120; // Offset to avoid menu icon function spawnCactus() { var cactus = new Cactus(); var side = Math.floor(Math.random() * 4); switch (side) { case 0: // Top cactus.x = Math.random() * 2048; cactus.y = -30; break; case 1: // Right cactus.x = 2078; cactus.y = Math.random() * 2732; break; case 2: // Bottom cactus.x = Math.random() * 2048; cactus.y = 2762; break; case 3: // Left cactus.x = -30; cactus.y = Math.random() * 2732; break; } var direction = calculateDirection(cactus.x, cactus.y, sheriff.x, sheriff.y); cactus.direction.x = direction.x; cactus.direction.y = direction.y; cactus.speed = cactusSpeed; cacti.push(cactus); game.addChild(cactus); } function spawnBigCactus() { var bigCactus = new BigCactus(); var side = Math.floor(Math.random() * 4); switch (side) { case 0: // Top bigCactus.x = Math.random() * 2048; bigCactus.y = -30; break; case 1: // Right bigCactus.x = 2078; bigCactus.y = Math.random() * 2732; break; case 2: // Bottom bigCactus.x = Math.random() * 2048; bigCactus.y = 2762; break; case 3: // Left bigCactus.x = -30; bigCactus.y = Math.random() * 2732; break; } var direction = calculateDirection(bigCactus.x, bigCactus.y, sheriff.x, sheriff.y); bigCactus.direction.x = direction.x; bigCactus.direction.y = direction.y; bigCactus.speed = cactusSpeed; bigCacti.push(bigCactus); game.addChild(bigCactus); } function spawnGoldenStar() { var star = new GoldenStar(); star.x = Math.random() * 1800 + 124; // Keep away from edges star.y = Math.random() * 2400 + 166; goldenStars.push(star); game.addChild(star); } function calculateDistance(x1, y1, x2, y2) { var dx = x2 - x1; var dy = y2 - y1; return Math.sqrt(dx * dx + dy * dy); } function calculateDirection(fromX, fromY, toX, toY) { var dx = toX - fromX; var dy = toY - fromY; var distance = calculateDistance(fromX, fromY, toX, toY); return { x: distance > 0 ? dx / distance : 0, y: distance > 0 ? dy / distance : 0 }; } function shootBullet(targetX, targetY) { var bullet = new Bullet(); bullet.x = sheriff.x; bullet.y = sheriff.y; // Find the nearest cactus (including big cacti) var nearestCactus = null; var nearestDistance = Infinity; for (var i = 0; i < cacti.length; i++) { var cactus = cacti[i]; var distance = calculateDistance(sheriff.x, sheriff.y, cactus.x, cactus.y); if (distance < nearestDistance) { nearestDistance = distance; nearestCactus = cactus; } } // Also check big cacti for (var i = 0; i < bigCacti.length; i++) { var bigCactus = bigCacti[i]; var distance = calculateDistance(sheriff.x, sheriff.y, bigCactus.x, bigCactus.y); if (distance < nearestDistance) { nearestDistance = distance; nearestCactus = bigCactus; } } // If there's a nearest cactus, aim at it, otherwise use touch direction var direction; if (nearestCactus) { direction = calculateDirection(sheriff.x, sheriff.y, nearestCactus.x, nearestCactus.y); } else { direction = calculateDirection(sheriff.x, sheriff.y, targetX, targetY); } bullet.direction.x = direction.x; bullet.direction.y = direction.y; bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); } // Upgrade button click handler upgradeButton.down = function (x, y, obj) { if (LK.getScore() >= upgradeCost) { // Deduct gold LK.setScore(LK.getScore() - upgradeCost); scoreText.setText('Gold: ' + LK.getScore()); // Increase shooting speed by reducing interval by 10 frames (10/60 = ~167ms) shootInterval = Math.max(10, shootInterval - 10); // Minimum 10 frames between shots // Increment upgrade level and counter upgradeLevel++; upgradeCounter.setText(upgradeLevel.toString()); // Increase cost for next upgrade upgradeCost += 10; } }; game.down = function (x, y, obj) { dragNode = sheriff; sheriff.x = x; sheriff.y = y; }; game.move = function (x, y, obj) { if (dragNode) { dragNode.x = x; dragNode.y = y; } }; game.up = function (x, y, obj) { dragNode = null; }; game.update = function () { // Automatic shooting - rapid fire shoots every 30 frames (0.5 seconds), normal shoots every 60 frames (1 second) var currentShootInterval = sheriff.rapidFire ? 30 : shootInterval; if (LK.ticks - lastShootTime >= currentShootInterval) { shootBullet(sheriff.x, sheriff.y); lastShootTime = LK.ticks; } // Spawn cacti - spawn multiple based on wave number if (LK.ticks % cactusSpawnRate === 0) { var cactusesToSpawn = Math.min(waveNumber, 5); // Cap at 5 cacti per spawn for (var c = 0; c < cactusesToSpawn; c++) { spawnCactus(); } } // Spawn big cacti starting from wave 3 - spawn multiple based on wave number if (waveNumber >= 3 && LK.ticks % (cactusSpawnRate * 3) === 0) { var bigCactiToSpawn = Math.min(waveNumber - 2, 3); // Start from wave 3, cap at 3 big cacti per spawn for (var bc = 0; bc < bigCactiToSpawn; bc++) { spawnBigCactus(); } } // Spawn golden stars (5% chance every 3 seconds) if (LK.ticks % 180 === 0 && Math.random() < 0.05) { spawnGoldenStar(); } // Update wave progression var newWave = Math.floor(LK.ticks / 1800) + 1; // New wave every 30 seconds if (newWave > waveNumber) { waveNumber = newWave; cactusSpawnRate = Math.max(30, cactusSpawnRate - 10); // Increase spawn rate cactusSpeed = Math.min(5, cactusSpeed + 0.3); // Increase speed waveText.setText('Wave: ' + waveNumber); } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; // Check bullet-cactus collisions for (var j = cacti.length - 1; j >= 0; j--) { var cactus = cacti[j]; if (bullet.intersects(cactus)) { // Destroy cactus and bullet cactus.destroy(); cacti.splice(j, 1); bullet.destroy(); bullets.splice(i, 1); // Add gold LK.setScore(LK.getScore() + 10); scoreText.setText('Gold: ' + LK.getScore()); break; } } // Check bullet-big cactus collisions for (var j = bigCacti.length - 1; j >= 0; j--) { var bigCactus = bigCacti[j]; if (bullet.intersects(bigCactus)) { // Damage big cactus and destroy bullet bigCactus.takeDamage(); bullet.destroy(); bullets.splice(i, 1); break; } } } // Remove bullets that go off screen for (var k = bullets.length - 1; k >= 0; k--) { var bullet = bullets[k]; if (bullet.x < -100 || bullet.x > 2148 || bullet.y < -100 || bullet.y > 2832) { bullet.destroy(); bullets.splice(k, 1); } } // Remove cacti that go too far off screen for (var k = cacti.length - 1; k >= 0; k--) { var cactus = cacti[k]; if (cactus.x < -100 || cactus.x > 2148 || cactus.y < -100 || cactus.y > 2832) { cactus.destroy(); cacti.splice(k, 1); } } // Remove big cacti that go too far off screen for (var k = bigCacti.length - 1; k >= 0; k--) { var bigCactus = bigCacti[k]; if (bigCactus.x < -100 || bigCactus.x > 2148 || bigCactus.y < -100 || bigCactus.y > 2832) { bigCactus.destroy(); bigCacti.splice(k, 1); } } // Update UI healthText.setText('Health: ' + sheriff.health); // Update invincibility timer display if (sheriff.invincible) { var timeLeft = Math.ceil((sheriff.invincibilityEndTime - LK.ticks) / 60); invincibilityText.setText('Invincible: ' + timeLeft + 's'); } else { invincibilityText.setText(''); } // Update rapid fire timer display if (sheriff.rapidFire) { var timeLeft = Math.ceil((sheriff.rapidFireEndTime - LK.ticks) / 60); rapidFireText.setText('Rapid Fire: ' + timeLeft + 's'); } else { rapidFireText.setText(''); } }; // Goal already implemented: BigCactus.takeDamage() method already awards 20 gold when kaktus2 is destroyed
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BigCactus = Container.expand(function () {
var self = Container.call(this);
var cactusGraphics = self.attachAsset('kaktus2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.health = 2;
self.direction = {
x: 0,
y: 0
};
self.lastIntersectingSheriff = false;
self.update = function () {
// Recalculate direction to always track sheriff's current position
var dx = sheriff.x - self.x;
var dy = sheriff.y - self.y;
var distance = calculateDistance(self.x, self.y, sheriff.x, sheriff.y);
if (distance > 0) {
self.direction.x = dx / distance;
self.direction.y = dy / distance;
}
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
// Check collision with sheriff
var currentIntersecting = self.intersects(sheriff);
if (!self.lastIntersectingSheriff && currentIntersecting) {
sheriff.takeDamage(2); // Deal 2 damage
self.destroy();
var index = bigCacti.indexOf(self);
if (index > -1) {
bigCacti.splice(index, 1);
}
}
self.lastIntersectingSheriff = currentIntersecting;
};
self.takeDamage = function () {
self.health--;
if (self.health <= 0) {
self.destroy();
var index = bigCacti.indexOf(self);
if (index > -1) {
bigCacti.splice(index, 1);
}
// Add gold
LK.setScore(LK.getScore() + 20);
scoreText.setText('Gold: ' + LK.getScore());
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.direction = {
x: 0,
y: 0
};
self.lastY = 0;
self.lastX = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
};
return self;
});
var Cactus = Container.expand(function () {
var self = Container.call(this);
var cactusGraphics = self.attachAsset('cactus', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.direction = {
x: 0,
y: 0
};
self.lastIntersectingSheriff = false;
self.update = function () {
// Recalculate direction to always track sheriff's current position
var dx = sheriff.x - self.x;
var dy = sheriff.y - self.y;
var distance = calculateDistance(self.x, self.y, sheriff.x, sheriff.y);
if (distance > 0) {
self.direction.x = dx / distance;
self.direction.y = dy / distance;
}
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
// Check collision with sheriff
var currentIntersecting = self.intersects(sheriff);
if (!self.lastIntersectingSheriff && currentIntersecting) {
sheriff.takeDamage();
self.destroy();
var index = cacti.indexOf(self);
if (index > -1) {
cacti.splice(index, 1);
}
}
self.lastIntersectingSheriff = currentIntersecting;
};
return self;
});
var GoldenStar = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('goldenStar', {
anchorX: 0.5,
anchorY: 0.5
});
self.lastIntersectingSheriff = false;
self.update = function () {
// Rotate the star
starGraphics.rotation += 0.1;
// Check collision with sheriff
var currentIntersecting = self.intersects(sheriff);
if (!self.lastIntersectingSheriff && currentIntersecting) {
sheriff.activateInvincibility();
self.destroy();
var index = goldenStars.indexOf(self);
if (index > -1) {
goldenStars.splice(index, 1);
}
}
self.lastIntersectingSheriff = currentIntersecting;
};
return self;
});
var Sheriff = Container.expand(function () {
var self = Container.call(this);
var sheriffGraphics = self.attachAsset('sheriff', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 10;
self.invincible = false;
self.invincibilityEndTime = 0;
self.rapidFire = false;
self.rapidFireEndTime = 0;
self.update = function () {
// Check if invincibility expired
if (self.invincible && LK.ticks > self.invincibilityEndTime) {
self.invincible = false;
sheriffGraphics.tint = 0xFFFFFF; // Reset tint
}
// Check if rapid fire expired
if (self.rapidFire && LK.ticks > self.rapidFireEndTime) {
self.rapidFire = false;
}
// Flash effect when invincible
if (self.invincible) {
var flashValue = Math.sin(LK.ticks * 0.3) > 0 ? 0xFFD700 : 0xFFFFFF;
sheriffGraphics.tint = flashValue;
}
};
self.takeDamage = function (damage) {
if (!self.invincible) {
damage = damage || 1; // Default to 1 damage if not specified
self.health -= damage;
LK.getSound('hit').play();
// Flash red briefly
sheriffGraphics.tint = 0xFF0000;
LK.setTimeout(function () {
if (!self.invincible) {
sheriffGraphics.tint = 0xFFFFFF;
}
}, 200);
if (self.health <= 0) {
LK.showGameOver();
}
}
};
self.activateInvincibility = function () {
self.invincible = true;
self.invincibilityEndTime = LK.ticks + 600; // 10 seconds at 60fps
LK.getSound('powerup').play();
};
self.activateRapidFire = function () {
self.rapidFire = true;
self.rapidFireEndTime = LK.ticks + 600; // 10 seconds at 60fps
LK.getSound('powerup').play();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xDEB887
});
/****
* Game Code
****/
var sheriff = game.addChild(new Sheriff());
sheriff.x = 1024;
sheriff.y = 1366;
var cacti = [];
var bullets = [];
var goldenStars = [];
var bigCacti = [];
var waveNumber = 1;
var cactusSpawnRate = 120; // frames between spawns
var cactusSpeed = 2;
var dragNode = null;
var lastShootTime = 0;
var shootInterval = 60; // 60 frames = 1 second at 60fps
// UI Elements
var healthText = new Text2('Health: 10', {
size: 60,
fill: 0xFF0000
});
healthText.anchor.set(0, 0);
healthText.y = 80; // Move health text down to make room for upgrade button
LK.gui.topRight.addChild(healthText);
// Upgrade button and counter
var upgradeButton = new Container();
var buttonBg = upgradeButton.attachAsset('button', {
width: 150,
height: 60,
color: 0x0000FF,
shape: 'box',
anchorX: 1,
anchorY: 0
});
LK.gui.topRight.addChild(upgradeButton);
var upgradeCounter = new Text2('0', {
size: 50,
fill: 0x0000FF
});
upgradeCounter.anchor.set(1, 0);
upgradeCounter.x = -160; // Position to the left of the button
LK.gui.topRight.addChild(upgradeCounter);
var upgradeLevel = 0;
var upgradeCost = 10;
var scoreText = new Text2('Gold: 0', {
size: 60,
fill: 0xFFD700
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var invincibilityText = new Text2('', {
size: 50,
fill: 0xFFD700
});
invincibilityText.anchor.set(0.5, 0);
invincibilityText.y = 80;
LK.gui.top.addChild(invincibilityText);
var rapidFireText = new Text2('', {
size: 50,
fill: 0xFF8C00
});
rapidFireText.anchor.set(0.5, 0);
rapidFireText.y = 140;
LK.gui.top.addChild(rapidFireText);
var waveText = new Text2('Wave: 1', {
size: 50,
fill: 0xFFFFFF
});
waveText.anchor.set(0, 0);
LK.gui.topLeft.addChild(waveText);
waveText.x = 120; // Offset to avoid menu icon
function spawnCactus() {
var cactus = new Cactus();
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
cactus.x = Math.random() * 2048;
cactus.y = -30;
break;
case 1:
// Right
cactus.x = 2078;
cactus.y = Math.random() * 2732;
break;
case 2:
// Bottom
cactus.x = Math.random() * 2048;
cactus.y = 2762;
break;
case 3:
// Left
cactus.x = -30;
cactus.y = Math.random() * 2732;
break;
}
var direction = calculateDirection(cactus.x, cactus.y, sheriff.x, sheriff.y);
cactus.direction.x = direction.x;
cactus.direction.y = direction.y;
cactus.speed = cactusSpeed;
cacti.push(cactus);
game.addChild(cactus);
}
function spawnBigCactus() {
var bigCactus = new BigCactus();
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
bigCactus.x = Math.random() * 2048;
bigCactus.y = -30;
break;
case 1:
// Right
bigCactus.x = 2078;
bigCactus.y = Math.random() * 2732;
break;
case 2:
// Bottom
bigCactus.x = Math.random() * 2048;
bigCactus.y = 2762;
break;
case 3:
// Left
bigCactus.x = -30;
bigCactus.y = Math.random() * 2732;
break;
}
var direction = calculateDirection(bigCactus.x, bigCactus.y, sheriff.x, sheriff.y);
bigCactus.direction.x = direction.x;
bigCactus.direction.y = direction.y;
bigCactus.speed = cactusSpeed;
bigCacti.push(bigCactus);
game.addChild(bigCactus);
}
function spawnGoldenStar() {
var star = new GoldenStar();
star.x = Math.random() * 1800 + 124; // Keep away from edges
star.y = Math.random() * 2400 + 166;
goldenStars.push(star);
game.addChild(star);
}
function calculateDistance(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
function calculateDirection(fromX, fromY, toX, toY) {
var dx = toX - fromX;
var dy = toY - fromY;
var distance = calculateDistance(fromX, fromY, toX, toY);
return {
x: distance > 0 ? dx / distance : 0,
y: distance > 0 ? dy / distance : 0
};
}
function shootBullet(targetX, targetY) {
var bullet = new Bullet();
bullet.x = sheriff.x;
bullet.y = sheriff.y;
// Find the nearest cactus (including big cacti)
var nearestCactus = null;
var nearestDistance = Infinity;
for (var i = 0; i < cacti.length; i++) {
var cactus = cacti[i];
var distance = calculateDistance(sheriff.x, sheriff.y, cactus.x, cactus.y);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestCactus = cactus;
}
}
// Also check big cacti
for (var i = 0; i < bigCacti.length; i++) {
var bigCactus = bigCacti[i];
var distance = calculateDistance(sheriff.x, sheriff.y, bigCactus.x, bigCactus.y);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestCactus = bigCactus;
}
}
// If there's a nearest cactus, aim at it, otherwise use touch direction
var direction;
if (nearestCactus) {
direction = calculateDirection(sheriff.x, sheriff.y, nearestCactus.x, nearestCactus.y);
} else {
direction = calculateDirection(sheriff.x, sheriff.y, targetX, targetY);
}
bullet.direction.x = direction.x;
bullet.direction.y = direction.y;
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
}
// Upgrade button click handler
upgradeButton.down = function (x, y, obj) {
if (LK.getScore() >= upgradeCost) {
// Deduct gold
LK.setScore(LK.getScore() - upgradeCost);
scoreText.setText('Gold: ' + LK.getScore());
// Increase shooting speed by reducing interval by 10 frames (10/60 = ~167ms)
shootInterval = Math.max(10, shootInterval - 10); // Minimum 10 frames between shots
// Increment upgrade level and counter
upgradeLevel++;
upgradeCounter.setText(upgradeLevel.toString());
// Increase cost for next upgrade
upgradeCost += 10;
}
};
game.down = function (x, y, obj) {
dragNode = sheriff;
sheriff.x = x;
sheriff.y = y;
};
game.move = function (x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.update = function () {
// Automatic shooting - rapid fire shoots every 30 frames (0.5 seconds), normal shoots every 60 frames (1 second)
var currentShootInterval = sheriff.rapidFire ? 30 : shootInterval;
if (LK.ticks - lastShootTime >= currentShootInterval) {
shootBullet(sheriff.x, sheriff.y);
lastShootTime = LK.ticks;
}
// Spawn cacti - spawn multiple based on wave number
if (LK.ticks % cactusSpawnRate === 0) {
var cactusesToSpawn = Math.min(waveNumber, 5); // Cap at 5 cacti per spawn
for (var c = 0; c < cactusesToSpawn; c++) {
spawnCactus();
}
}
// Spawn big cacti starting from wave 3 - spawn multiple based on wave number
if (waveNumber >= 3 && LK.ticks % (cactusSpawnRate * 3) === 0) {
var bigCactiToSpawn = Math.min(waveNumber - 2, 3); // Start from wave 3, cap at 3 big cacti per spawn
for (var bc = 0; bc < bigCactiToSpawn; bc++) {
spawnBigCactus();
}
}
// Spawn golden stars (5% chance every 3 seconds)
if (LK.ticks % 180 === 0 && Math.random() < 0.05) {
spawnGoldenStar();
}
// Update wave progression
var newWave = Math.floor(LK.ticks / 1800) + 1; // New wave every 30 seconds
if (newWave > waveNumber) {
waveNumber = newWave;
cactusSpawnRate = Math.max(30, cactusSpawnRate - 10); // Increase spawn rate
cactusSpeed = Math.min(5, cactusSpeed + 0.3); // Increase speed
waveText.setText('Wave: ' + waveNumber);
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Check bullet-cactus collisions
for (var j = cacti.length - 1; j >= 0; j--) {
var cactus = cacti[j];
if (bullet.intersects(cactus)) {
// Destroy cactus and bullet
cactus.destroy();
cacti.splice(j, 1);
bullet.destroy();
bullets.splice(i, 1);
// Add gold
LK.setScore(LK.getScore() + 10);
scoreText.setText('Gold: ' + LK.getScore());
break;
}
}
// Check bullet-big cactus collisions
for (var j = bigCacti.length - 1; j >= 0; j--) {
var bigCactus = bigCacti[j];
if (bullet.intersects(bigCactus)) {
// Damage big cactus and destroy bullet
bigCactus.takeDamage();
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
}
// Remove bullets that go off screen
for (var k = bullets.length - 1; k >= 0; k--) {
var bullet = bullets[k];
if (bullet.x < -100 || bullet.x > 2148 || bullet.y < -100 || bullet.y > 2832) {
bullet.destroy();
bullets.splice(k, 1);
}
}
// Remove cacti that go too far off screen
for (var k = cacti.length - 1; k >= 0; k--) {
var cactus = cacti[k];
if (cactus.x < -100 || cactus.x > 2148 || cactus.y < -100 || cactus.y > 2832) {
cactus.destroy();
cacti.splice(k, 1);
}
}
// Remove big cacti that go too far off screen
for (var k = bigCacti.length - 1; k >= 0; k--) {
var bigCactus = bigCacti[k];
if (bigCactus.x < -100 || bigCactus.x > 2148 || bigCactus.y < -100 || bigCactus.y > 2832) {
bigCactus.destroy();
bigCacti.splice(k, 1);
}
}
// Update UI
healthText.setText('Health: ' + sheriff.health);
// Update invincibility timer display
if (sheriff.invincible) {
var timeLeft = Math.ceil((sheriff.invincibilityEndTime - LK.ticks) / 60);
invincibilityText.setText('Invincible: ' + timeLeft + 's');
} else {
invincibilityText.setText('');
}
// Update rapid fire timer display
if (sheriff.rapidFire) {
var timeLeft = Math.ceil((sheriff.rapidFireEndTime - LK.ticks) / 60);
rapidFireText.setText('Rapid Fire: ' + timeLeft + 's');
} else {
rapidFireText.setText('');
}
};
// Goal already implemented: BigCactus.takeDamage() method already awards 20 gold when kaktus2 is destroyed
göğsünde bir şerif yıldızı olan silahlı bir stickman. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
kafalarında kaktüs çiçeği olan 2 kaktüs . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
üçlarında topçuk olan gökkuşağı bir yıldız. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
altın renginde mermi. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
büyük bir kaktüs. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
üzerinde SPEED UP yazan bir buton. In-Game asset. 2d. High contrast. No shadows