User prompt
Move the text to the left and paste it under the playing field so that they do not interfere with each other.
User prompt
Yazıları sağa çek
User prompt
Her seçeneğin arasında küçük bir boşluk olsun. Yazılar birbirine değmesin ve üst üste binmesin
User prompt
make the machines orderly and one under the other and also place the freeze enemies thing under the machine
User prompt
move the machines to the left and put them under each other
User prompt
put the machines under the road but do not let any of them enter the road, if they do not fit write them on the side of the road
User prompt
Yolun başlangic noktasını biraz daha yukarıya taşı ve onun altına makineleri taşı laser gün ile başla
User prompt
Put the freezing enemies thing aside and keep the machines organized so that none of them interfere with each other.
User prompt
Now do it under the top and in order, everything will be in order
User prompt
make as space between machines
User prompt
space between machines and make them tidy
User prompt
move it a little bit up and to the side
User prompt
Make the freeze button visible, when you press it the enemies will freeze for 3 seconds ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add the button I mentioned to the game, it has 1000 money and its name is freeze enemies ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let's have a fire in the game that we can throw at our enemies, when we step on that fire, the health of the enemies will decrease and they will burn, and the price for this will be 700 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
At level nine and ten, there are only 10 enemies.
User prompt
Make the enemy arrival numbers in nine and o 10
User prompt
Nine and ten sizes shortened a little bit
User prompt
Do not let any of the machines stick to each other and leave space between them.
User prompt
Put the machines one under the other somewhere, if there is no space, write them next to each other
User prompt
Add a new 500 machine to the game, the machine should have a fire feature
User prompt
Just make the enemies a little bigger so they aren't huge.
User prompt
Levels nine and ten should be so strong that machines can barely kill them.
User prompt
When you reach level eight, the enemies are very strong.
User prompt
After the sixth level ONLY some enemies will be given speed boost
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BuildSpot = Container.expand(function () {
var self = Container.call(this);
var spotGraphics = self.attachAsset('buildSpot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.isOccupied = false;
self.turret = null;
self.previewRange = null;
self.move = function (x, y, obj) {
if (self.isOccupied) return;
if (!self.previewRange) {
// Create preview range indicator
self.previewRange = self.addChild(LK.getAsset('buildSpot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.15,
tint: selectedTowerType === 'laser' ? 0x4444FF : selectedTowerType === 'missile' ? 0xFF4444 : selectedTowerType === 'fire' ? 0xFF8800 : selectedTowerType === 'fireMachine' ? 0xFF2200 : selectedTowerType === 'fireTrap' ? 0xFF4400 : 0xFFFF00,
scaleX: selectedTowerType === 'laser' ? 3.0 : selectedTowerType === 'missile' ? 3.4 : selectedTowerType === 'fire' ? 3.6 : selectedTowerType === 'fireMachine' ? 5.0 : selectedTowerType === 'fireTrap' ? 1.5 : 4.4,
scaleY: selectedTowerType === 'laser' ? 3.0 : selectedTowerType === 'missile' ? 3.4 : selectedTowerType === 'fire' ? 3.6 : selectedTowerType === 'fireMachine' ? 5.0 : selectedTowerType === 'fireTrap' ? 1.5 : 4.4
}));
}
};
self.up = function (x, y, obj) {
if (self.previewRange) {
self.previewRange.destroy();
self.previewRange = null;
}
};
self.down = function (x, y, obj) {
if (self.isOccupied) return;
if (currency < selectedTowerCost) return;
// Build turret
var turret = new Turret();
turret.x = self.x;
turret.y = self.y;
turret.towerType = selectedTowerType;
turret.cost = selectedTowerCost;
turret.updateTowerProperties(); // Update properties based on tower type
self.turret = turret;
self.isOccupied = true;
currency -= selectedTowerCost;
updateCurrencyDisplay();
turrets.push(turret);
game.addChild(turret);
// Hide build spot
spotGraphics.alpha = 0;
// Flash green when built with tower type color
var flashColor = selectedTowerType === 'laser' ? 0x4444FF : selectedTowerType === 'missile' ? 0xFF4444 : selectedTowerType === 'fire' ? 0xFF8800 : selectedTowerType === 'fireMachine' ? 0xFF2200 : selectedTowerType === 'fireTrap' ? 0xFF4400 : 0xFFFF00;
LK.effects.flashObject(turret, flashColor, 500);
};
return self;
});
var FireTrap = Container.expand(function () {
var self = Container.call(this);
var fireGraphics = self.attachAsset('fireTrap', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
self.damage = 50;
self.burnDuration = 3000; // 3 seconds
self.lastDamage = 0;
self.damageRate = 30; // frames between damage ticks
// Create fire effect animation
tween(fireGraphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(fireGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Restart animation loop
if (self.parent) {
tween(fireGraphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: arguments.callee
});
}
}
});
}
});
self.update = function () {
self.lastDamage += speedMultiplier;
if (self.lastDamage >= self.damageRate) {
// Check for zombies in fire area
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
if (zombie.isDead) continue;
var dx = zombie.x - self.x;
var dy = zombie.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 60) {
// Fire area radius
zombie.takeDamage(self.damage);
// Apply burning effect
if (!zombie.isBurning) {
zombie.isBurning = true;
zombie.burnTimer = 0;
zombie.burnDamage = 25;
// Visual burning effect
tween(zombie.children[0], {
tint: 0xFF4400
}, {
duration: 200,
onFinish: function onFinish() {
tween(zombie.children[0], {
tint: 0xFFFFFF
}, {
duration: 200,
onFinish: function onFinish() {
if (zombie.isBurning && zombie.parent) {
tween(zombie.children[0], {
tint: 0xFF4400
}, {
duration: 200,
onFinish: arguments.callee
});
}
}
});
}
});
}
}
}
self.lastDamage = 0;
}
};
return self;
});
var Turret = Container.expand(function () {
var self = Container.call(this);
var turretGraphics = self.attachAsset('turret', {
anchorX: 0.5,
anchorY: 0.5
});
// Add range indicator (will be updated based on tower type)
self.rangeIndicator = self.addChild(LK.getAsset('buildSpot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.25,
tint: 0x4444FF,
scaleX: 4,
scaleY: 4
}));
// Add cross indicator (hidden by default)
self.crossIndicator = self.addChild(LK.getAsset('cross', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0,
rotation: Math.PI / 4 // 45 degrees to make it look like an X
}));
self.damage = 75;
self.range = 200;
self.fireRate = 15; // frames between shots
self.lastShot = 0;
self.target = null;
self.cost = 50;
self.sellPrice = 25; // 50% of cost back when sold
self.towerType = 'laser'; // Default type
self.upgradeLevel = 1; // Track upgrade level
self.upgradeCost = 50; // Cost to upgrade
self.updateTowerProperties = function () {
var upgradeMultiplier = 1 + (self.upgradeLevel - 1) * 0.5; // 50% increase per level
if (self.towerType === 'laser') {
self.range = 150 * upgradeMultiplier;
self.damage = 75 * upgradeMultiplier;
self.fireRate = Math.max(5, 15 - (self.upgradeLevel - 1) * 2); // Faster fire rate
self.rangeIndicator.tint = 0x4444FF;
self.rangeIndicator.scaleX = 3.0; // Keep visual size constant
self.rangeIndicator.scaleY = 3.0; // Keep visual size constant
self.sellPrice = Math.floor((50 + (self.upgradeLevel - 1) * 50) * 0.5); // 50% of total cost back
self.upgradeCost = 50 * self.upgradeLevel; // Increasing upgrade cost
} else if (self.towerType === 'missile') {
self.range = 170 * upgradeMultiplier;
self.damage = 120 * upgradeMultiplier;
self.fireRate = Math.max(8, 20 - (self.upgradeLevel - 1) * 3);
self.rangeIndicator.tint = 0xFF4444;
self.rangeIndicator.scaleX = 3.4; // Keep visual size constant
self.rangeIndicator.scaleY = 3.4; // Keep visual size constant
self.sellPrice = Math.floor((100 + (self.upgradeLevel - 1) * 100) * 0.5); // 50% of total cost back
self.upgradeCost = 100 * self.upgradeLevel;
} else if (self.towerType === 'fire') {
self.range = 180 * upgradeMultiplier;
self.damage = 90 * upgradeMultiplier;
self.fireRate = Math.max(4, 10 - (self.upgradeLevel - 1) * 2);
self.rangeIndicator.tint = 0xFF8800;
self.rangeIndicator.scaleX = 3.6; // Keep visual size constant
self.rangeIndicator.scaleY = 3.6; // Keep visual size constant
self.sellPrice = Math.floor((200 + (self.upgradeLevel - 1) * 200) * 0.5); // 50% of total cost back
self.upgradeCost = 200 * self.upgradeLevel;
} else if (self.towerType === 'electric') {
self.range = 220 * upgradeMultiplier;
self.damage = 60 * upgradeMultiplier;
self.fireRate = Math.max(6, 12 - (self.upgradeLevel - 1) * 2);
self.rangeIndicator.tint = 0xFFFF00;
self.rangeIndicator.scaleX = 4.4; // Keep visual size constant
self.rangeIndicator.scaleY = 4.4; // Keep visual size constant
self.sellPrice = Math.floor((300 + (self.upgradeLevel - 1) * 300) * 0.5); // 50% of total cost back
self.upgradeCost = 300 * self.upgradeLevel;
} else if (self.towerType === 'fireMachine') {
self.range = 250 * upgradeMultiplier;
self.damage = 200 * upgradeMultiplier;
self.fireRate = Math.max(3, 8 - (self.upgradeLevel - 1) * 2);
self.rangeIndicator.tint = 0xFF2200;
self.rangeIndicator.scaleX = 5.0; // Keep visual size constant
self.rangeIndicator.scaleY = 5.0; // Keep visual size constant
self.sellPrice = Math.floor((500 + (self.upgradeLevel - 1) * 500) * 0.5); // 50% of total cost back
self.upgradeCost = 500 * self.upgradeLevel;
}
};
self.towerType = 'laser'; // Default type
self.findTarget = function () {
var closestZombie = null;
var closestDistance = self.range;
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
if (zombie.isDead) continue;
var dx = zombie.x - self.x;
var dy = zombie.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < closestDistance) {
closestDistance = distance;
closestZombie = zombie;
}
}
return closestZombie;
};
self.shoot = function (target) {
// Direct damage to target without bullets
if (target && !target.isDead) {
target.takeDamage(self.damage);
// Create explosion effect at target location
var explosion = game.addChild(LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: target.x,
y: target.y
}));
tween(explosion, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
explosion.destroy();
}
});
LK.getSound('explosion').play();
}
LK.getSound('shoot').play();
// Flash blue when shooting
LK.effects.flashObject(self, 0x4444ff, 200);
};
self.down = function (x, y, obj) {
if (placementMode) return; // Don't select turrets in placement mode
selectTurret(self);
}; //{1j_new}
self.update = function () {
self.lastShot += speedMultiplier;
if (self.lastShot >= self.fireRate) {
var target = self.findTarget();
if (target) {
self.shoot(target);
self.lastShot = 0;
}
}
};
return self;
});
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieGraphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
// Remove any YellowEffect or similar effects that might exist
for (var i = self.children.length - 1; i >= 0; i--) {
var child = self.children[i];
if (child.name && (child.name.indexOf('YellowEffect') !== -1 || child.name.indexOf('yellowEffect') !== -1)) {
child.destroy();
self.removeChild(child);
}
}
self.health = 100;
self.maxHealth = 100;
self.speed = 1;
self.reward = 10;
self.pathIndex = 0;
self.targetX = 0;
self.targetY = 0;
self.isDead = false;
// Create health bar
self.healthBar = self.addChild(LK.getAsset('buildSpot', {
anchorX: 0,
anchorY: 0.5,
x: -25,
y: -40,
width: 50,
height: 6,
color: 0x44FF44
}));
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.isDead = true;
// Directly add currency without visual money drop
currency += self.reward;
updateCurrencyDisplay();
LK.getSound('zombieHit').play();
}
};
self.update = function () {
if (self.isDead) return;
// Move towards target continuously
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Always move towards target, no stopping threshold
if (distance > 0.1) {
var moveX = dx / distance * self.speed * speedMultiplier;
var moveY = dy / distance * self.speed * speedMultiplier;
self.x += moveX;
self.y += moveY;
}
// Check if we've reached or passed the current target
if (distance <= self.speed * speedMultiplier + 1) {
// Move to next path point immediately
self.pathIndex++;
if (self.pathIndex >= gamePath.length) {
// Reached end - damage base
lives--;
updateLivesDisplay();
if (lives <= 0) {
LK.showGameOver();
}
self.isDead = true;
} else {
self.targetX = gamePath[self.pathIndex].x;
self.targetY = gamePath[self.pathIndex].y;
}
}
// Handle burning effect
if (self.isBurning) {
self.burnTimer += speedMultiplier;
if (self.burnTimer >= 60) {
// Burn damage every second
self.takeDamage(self.burnDamage);
self.burnTimer = 0;
// Stop burning after duration
if (self.burnTimer > 180) {
// 3 seconds of burning
self.isBurning = false;
tween.stop(self.children[0], {
tint: true
});
self.children[0].tint = 0xFFFFFF;
}
}
}
// Handle freeze effect
if (self.isFrozen) {
self.freezeTimer += speedMultiplier;
if (self.freezeTimer >= 180) {
// 3 seconds of freezing
self.isFrozen = false;
self.speed = self.originalSpeed;
tween.stop(self.children[0], {
tint: true
});
self.children[0].tint = 0xFFFFFF;
}
}
// Update health bar if it exists
if (self.healthBar) {
var healthPercent = self.health / self.maxHealth;
self.healthBar.scaleX = healthPercent;
self.healthBar.tint = healthPercent > 0.5 ? 0x44FF44 : healthPercent > 0.25 ? 0xFFFF44 : 0xFF4444;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
var zombies = [];
var turrets = [];
var bullets = [];
var buildSpots = [];
var fireTraps = [];
var gamePath = [];
var currency = 100;
var lives = 10;
var wave = 1;
var zombiesSpawned = 0;
var zombiesToSpawn = 5;
var spawnTimer = 0;
var spawnRate = 120; // frames between spawns
var baseSpawnRate = 120; // Store base spawn rate
var waveActive = false;
var waveCompleted = false;
var selectedTowerType = 'laser';
var selectedTowerCost = 50;
// Create path points for zombies to follow - Shorter strategic path
gamePath = [{
x: 0,
y: 1366
}, {
x: 400,
y: 1366
}, {
x: 400,
y: 1000
}, {
x: 800,
y: 1000
}, {
x: 800,
y: 1500
}, {
x: 1200,
y: 1500
}, {
x: 1200,
y: 800
}, {
x: 1600,
y: 800
}, {
x: 1600,
y: 400
}, {
x: 1000,
y: 400
}, {
x: 1000,
y: 1800
}, {
x: 1400,
y: 1800
}, {
x: 2048,
y: 1800
}];
// Create visual path
for (var i = 0; i < gamePath.length - 1; i++) {
var start = gamePath[i];
var end = gamePath[i + 1];
var steps = Math.floor(Math.sqrt((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / 120);
for (var j = 0; j <= steps; j++) {
var t = j / steps;
var pathX = start.x + (end.x - start.x) * t;
var pathY = start.y + (end.y - start.y) * t;
var pathTile = game.addChild(LK.getAsset('path', {
anchorX: 0.5,
anchorY: 0.5,
x: pathX,
y: pathY,
alpha: 0.3
}));
}
}
// Build spots are no longer needed - turrets can be placed anywhere
// buildSpots array is kept for compatibility but not used
// UI Elements
var currencyTxt = new Text2('Money: $' + currency, {
size: 72,
fill: 0x00FFFF
});
currencyTxt.anchor.set(0, 0);
currencyTxt.x = 120; // Offset from left edge to avoid platform menu
currencyTxt.y = 100;
LK.gui.topLeft.addChild(currencyTxt);
// Add glowing effect to currency
LK.effects.flashObject(currencyTxt, 0x00FFFF, 2000);
var livesTxt = new Text2('Lives: ' + lives, {
size: 60,
fill: 0xFF4444
});
livesTxt.anchor.set(0, 0);
livesTxt.x = 120; // Offset from left edge to avoid platform menu
livesTxt.y = 20;
LK.gui.topLeft.addChild(livesTxt);
// Tower purchase menu at bottom - vertical layout
var towerMenuBg = game.addChild(LK.getAsset('buildSpot', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2200,
width: 2048,
height: 532,
alpha: 0.9,
tint: 0x1a1a1a
}));
var laserTurretBtn = new Text2('Laser Gun\n$50', {
size: 48,
fill: 0x4444FF
});
laserTurretBtn.anchor.set(0.5, 0.5);
laserTurretBtn.x = 1024;
laserTurretBtn.y = 2280;
game.addChild(laserTurretBtn);
var missileLauncherBtn = new Text2('Missile Tower\n$100', {
size: 48,
fill: 0xFF4444
});
missileLauncherBtn.anchor.set(0.5, 0.5);
missileLauncherBtn.x = 1024;
missileLauncherBtn.y = 2380;
game.addChild(missileLauncherBtn);
var fireDroneBtn = new Text2('Fire Blaster\n$200', {
size: 48,
fill: 0xFF8800
});
fireDroneBtn.anchor.set(0.5, 0.5);
fireDroneBtn.x = 1024;
fireDroneBtn.y = 2480;
game.addChild(fireDroneBtn);
var electricTrapBtn = new Text2('Electric Field\n$300', {
size: 48,
fill: 0xFFFF00
});
electricTrapBtn.anchor.set(0.5, 0.5);
electricTrapBtn.x = 1024;
electricTrapBtn.y = 2580;
game.addChild(electricTrapBtn);
var fireMachineBtn = new Text2('Fire Machine\n$500', {
size: 48,
fill: 0xFF2200
});
fireMachineBtn.anchor.set(0.5, 0.5);
fireMachineBtn.x = 1024;
fireMachineBtn.y = 2680;
game.addChild(fireMachineBtn);
var fireTrapBtn = new Text2('Fire Trap\n$700', {
size: 48,
fill: 0xFF4400
});
fireTrapBtn.anchor.set(0.5, 0.5);
fireTrapBtn.x = 1024;
fireTrapBtn.y = 2780;
game.addChild(fireTrapBtn);
var freezeEnemiesBtn = new Text2('Freeze Enemies\n$1000', {
size: 48,
fill: 0x00FFFF
});
freezeEnemiesBtn.anchor.set(0.5, 0.5);
freezeEnemiesBtn.x = 1024;
freezeEnemiesBtn.y = 2880;
game.addChild(freezeEnemiesBtn);
var waveTxt = new Text2('Level ' + wave, {
size: 80,
fill: 0x44FF44
});
waveTxt.anchor.set(0.5, 0);
waveTxt.y = 20;
LK.gui.top.addChild(waveTxt);
// Bomb system
var bombsLeft = 3;
var bombTxt = new Text2('Bombs: ' + bombsLeft, {
size: 72,
fill: 0xFF0000
});
bombTxt.anchor.set(1, 0);
bombTxt.x = -20;
bombTxt.y = -80;
LK.gui.topRight.addChild(bombTxt);
var bombBtn = new Text2('💣 BOMB', {
size: 80,
fill: 0xFF4444
});
bombBtn.anchor.set(1, 1);
bombBtn.x = -20;
bombBtn.y = -20;
LK.gui.bottomRight.addChild(bombBtn);
var startWaveBtn = new Text2('START WAVE', {
size: 80,
fill: 0xFFFFFF
});
startWaveBtn.anchor.set(0.5, 0.5);
startWaveBtn.x = 500;
startWaveBtn.y = 2500;
game.addChild(startWaveBtn);
var sellBtn = new Text2('SELL\nTURRET\n$0', {
size: 64,
fill: 0xFFAA00
});
sellBtn.anchor.set(0.5, 0.5);
sellBtn.x = 300; // Position to the left
sellBtn.y = 2350; // Move up slightly
sellBtn.alpha = 0.5; // Start dimmed
game.addChild(sellBtn);
var upgradeBtn = new Text2('UPGRADE\nTURRET\n$0', {
size: 64,
fill: 0x00FF00
});
upgradeBtn.anchor.set(0.5, 0.5);
upgradeBtn.x = 700; // Position to the right
upgradeBtn.y = 2350; // Same height as sell button
upgradeBtn.alpha = 0.5; // Start dimmed
game.addChild(upgradeBtn);
// Speed acceleration system
var gameSpeed = 1.0;
var speedMultiplier = 1.0;
// Speed acceleration buttons
var speed1xBtn = new Text2('1x Speed', {
size: 48,
fill: 0x00FF00
});
speed1xBtn.anchor.set(0.5, 0.5);
speed1xBtn.x = 1400;
speed1xBtn.y = 2280;
game.addChild(speed1xBtn);
var speed2xBtn = new Text2('2x Speed', {
size: 48,
fill: 0xFFFF00
});
speed2xBtn.anchor.set(0.5, 0.5);
speed2xBtn.x = 1400;
speed2xBtn.y = 2380;
game.addChild(speed2xBtn);
var speed3xBtn = new Text2('3x Speed', {
size: 48,
fill: 0xFF8800
});
speed3xBtn.anchor.set(0.5, 0.5);
speed3xBtn.x = 1400;
speed3xBtn.y = 2480;
game.addChild(speed3xBtn);
function distanceToLineSegment(px, py, x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
var length = Math.sqrt(dx * dx + dy * dy);
if (length === 0) return Math.sqrt((px - x1) * (px - x1) + (py - y1) * (py - y1));
var t = ((px - x1) * dx + (py - y1) * dy) / (length * length);
t = Math.max(0, Math.min(1, t));
var projX = x1 + t * dx;
var projY = y1 + t * dy;
return Math.sqrt((px - projX) * (px - projX) + (py - projY) * (py - projY));
}
function updateCurrencyDisplay() {
currencyTxt.setText('Money: $' + currency);
// Add glowing effect when currency changes
LK.effects.flashObject(currencyTxt, 0x00FFFF, 500);
}
function updateBombDisplay() {
bombTxt.setText('Bombs: ' + bombsLeft);
}
function useBomb() {
if (bombsLeft <= 0) return;
bombsLeft--;
updateBombDisplay();
// Create massive explosion effect
var bombExplosion = game.addChild(LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 10,
scaleY: 10,
alpha: 0.8
}));
// Damage all zombies significantly
for (var i = 0; i < zombies.length; i++) {
if (!zombies[i].isDead) {
zombies[i].takeDamage(150);
LK.effects.flashObject(zombies[i], 0xFF0000, 500);
}
}
// Animate explosion
tween(bombExplosion, {
alpha: 0,
scaleX: 15,
scaleY: 15
}, {
duration: 1000,
onFinish: function onFinish() {
bombExplosion.destroy();
}
});
LK.getSound('explosion').play();
LK.effects.flashScreen(0xFF4444, 800);
}
function updateLivesDisplay() {
livesTxt.setText('Lives: ' + lives);
}
function updateWaveDisplay() {
waveTxt.setText('Level ' + wave);
}
function startWave() {
if (waveActive) return;
waveActive = true;
waveCompleted = false;
zombiesSpawned = 0;
// Make first level easier with fewer zombies
if (wave === 1) {
zombiesToSpawn = 3; // Only 3 zombies for first wave
} else if (wave >= 9) {
zombiesToSpawn = 10; // Only 10 enemies for levels 9 and 10
} else {
zombiesToSpawn = 5 + (wave - 1) * 2; // Adjusted formula for subsequent waves
}
spawnTimer = 0;
startWaveBtn.alpha = 0.3;
// Increase zombie health each wave, but start lower for first level
if (wave === 1) {
Zombie.prototype.baseHealth = 60; // Weaker zombies for first level
} else if (wave <= 5) {
Zombie.prototype.baseHealth = 100 + (wave - 1) * 35; // Adjusted for waves 2-5
} else {
// After level 5, base health becomes extremely high for boss-level enemies
var levelBonus = wave - 5;
Zombie.prototype.baseHealth = 2000 + levelBonus * 800; // Extremely high base health after level 5 - boss-level
}
}
function spawnZombie() {
if (zombiesSpawned >= zombiesToSpawn) return;
var zombie = new Zombie();
zombie.x = gamePath[0].x;
zombie.y = gamePath[0].y;
zombie.targetX = gamePath[1].x;
zombie.targetY = gamePath[1].y;
// Make first level zombies weaker and slower
if (wave === 1) {
zombie.health = 60; // Much weaker for first level
zombie.speed = 1.2; // Faster for first level
zombie.reward = 15; // Higher reward for first level to help progression
} else if (wave <= 5) {
zombie.health = 100 + (wave - 1) * 35; // Adjusted for waves 2-5
zombie.speed = 1.5 + (wave - 1) * 0.4; // Faster for waves 2-5
zombie.reward = 10 + wave * 5;
} else {
// After level 5, enemies become extremely strong bosses
var levelBonus = wave - 5;
// Levels 9 and 10 have nearly indestructible enemies
if (wave >= 9) {
zombie.health = 15000 + levelBonus * 5000; // Massive health for levels 9-10
} else {
zombie.health = 2000 + levelBonus * 800; // Extremely high health after level 5 - boss-level
}
zombie.speed = 2.5 + levelBonus * 0.3; // Reduced speed after level 5 - not too fast
zombie.reward = 100 + levelBonus * 50; // Much higher rewards for boss-level enemies
// After level 6, some enemies get speed boost
if (wave > 6) {
var shouldGetSpeedBoost = Math.random() < 0.4; // 40% chance for speed boost
if (shouldGetSpeedBoost) {
zombie.speed *= 1.8; // 80% speed increase for boosted enemies
zombie.hasSpeedBoost = true;
// Add visual indicator for speed boosted enemies
zombie.children[0].tint = 0xFF8800; // Orange tint for speed boost
// Add speed boost aura effect
zombie.attachAsset('buildSpot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.4,
tint: 0xFF8800,
scaleX: 1.8,
scaleY: 1.8
});
}
}
}
zombie.maxHealth = zombie.health;
// Add visual effects for higher levels
if (wave >= 5) {
// Add continuous glowing effect for boss-level enemies
LK.effects.flashObject(zombie, 0xFF0000, 2000);
// Make zombies larger and more intimidating - boss size but not huge
zombie.children[0].scaleX = 1.5;
zombie.children[0].scaleY = 1.5;
zombie.children[0].tint = 0xFF0000; // Deep red tint for boss enemies
// Add boss aura effect
zombie.attachAsset('buildSpot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6,
tint: 0xFF0000,
scaleX: 2.5,
scaleY: 2.5
});
// Add second layer boss effect for very high levels
if (wave >= 8) {
// Level 8+ enemies are EXTREMELY strong with maximum boss effects
if (wave >= 9) {
zombie.health *= 3.0; // Triple health for levels 9-10 - nearly indestructible
zombie.reward *= 5; // 5x rewards for these ultimate bosses
} else {
zombie.health *= 1.5; // 50% more health on top of base boss health
zombie.reward *= 2; // Double rewards for these ultra-bosses
}
zombie.maxHealth = zombie.health;
// Maximum boss visual effects
zombie.attachAsset('buildSpot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6,
tint: 0xFFFF00,
scaleX: 4.0,
scaleY: 4.0
});
// Add third layer ultra-boss effect for level 8+
zombie.attachAsset('buildSpot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.4,
tint: 0xFF00FF,
scaleX: 3.5,
scaleY: 3.5
});
// Levels 9-10 get additional intimidating effects
if (wave >= 9) {
// Add fourth layer ultimate boss effect for levels 9-10
zombie.attachAsset('buildSpot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8,
tint: 0x000000,
scaleX: 5.0,
scaleY: 5.0
});
// Add fifth layer ultimate boss effect for levels 9-10
zombie.attachAsset('buildSpot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7,
tint: 0xFFFFFF,
scaleX: 4.5,
scaleY: 4.5
});
// Make them bigger but not absolutely massive - ultimate boss size but smaller
zombie.children[0].scaleX = 1.9;
zombie.children[0].scaleY = 1.9;
zombie.children[0].tint = 0x000000; // Black tint for ultimate bosses
// Multiple continuous pulsing effects for ultimate bosses
LK.effects.flashObject(zombie, 0x000000, 1000);
LK.effects.flashObject(zombie, 0xFFFFFF, 1200);
} else {
// Make them even more intimidating - ultra boss size but smaller
zombie.children[0].scaleX = 1.7;
zombie.children[0].scaleY = 1.7;
zombie.children[0].tint = 0x8B0000; // Dark red tint for ultra bosses
// Continuous pulsing effect for ultra bosses
LK.effects.flashObject(zombie, 0xFF00FF, 1500);
}
}
}
zombies.push(zombie);
game.addChild(zombie);
zombiesSpawned++;
}
function checkWaveComplete() {
if (!waveActive) return;
var aliveZombies = 0;
for (var i = 0; i < zombies.length; i++) {
if (!zombies[i].isDead) {
aliveZombies++;
}
}
if (zombiesSpawned >= zombiesToSpawn && aliveZombies === 0) {
waveActive = false;
waveCompleted = true;
wave++;
updateWaveDisplay();
currency += 50; // Wave completion bonus
updateCurrencyDisplay();
startWaveBtn.alpha = 1;
// Flash screen green for wave completion
LK.effects.flashScreen(0x44ff44, 1000);
// Check win condition
if (wave > 10) {
LK.showYouWin();
}
}
}
// Start wave button interaction
startWaveBtn.down = function (x, y, obj) {
startWave();
};
// Bomb button interaction
bombBtn.down = function (x, y, obj) {
useBomb();
};
// Sell button interaction
sellBtn.down = function (x, y, obj) {
sellTurret();
};
// Upgrade button interaction
upgradeBtn.down = function (x, y, obj) {
upgradeTurret();
};
// Tower selection highlighting
var selectedTowerBtn = laserTurretBtn;
function highlightSelectedTower() {
// Reset all tower buttons
laserTurretBtn.alpha = selectedTowerType === 'laser' ? 1.0 : 0.7;
missileLauncherBtn.alpha = selectedTowerType === 'missile' ? 1.0 : 0.7;
fireDroneBtn.alpha = selectedTowerType === 'fire' ? 1.0 : 0.7;
electricTrapBtn.alpha = selectedTowerType === 'electric' ? 1.0 : 0.7;
fireMachineBtn.alpha = selectedTowerType === 'fireMachine' ? 1.0 : 0.7;
fireTrapBtn.alpha = selectedTowerType === 'fireTrap' ? 1.0 : 0.7;
// Add glow effect to selected tower
if (selectedTowerType === 'laser') {
LK.effects.flashObject(laserTurretBtn, 0x4444FF, 500);
} else if (selectedTowerType === 'missile') {
LK.effects.flashObject(missileLauncherBtn, 0xFF4444, 500);
} else if (selectedTowerType === 'fire') {
LK.effects.flashObject(fireDroneBtn, 0xFF8800, 500);
} else if (selectedTowerType === 'electric') {
LK.effects.flashObject(electricTrapBtn, 0xFFFF00, 500);
} else if (selectedTowerType === 'fireMachine') {
LK.effects.flashObject(fireMachineBtn, 0xFF2200, 500);
} else if (selectedTowerType === 'fireTrap') {
LK.effects.flashObject(fireTrapBtn, 0xFF4400, 500);
}
}
// Initial highlight
highlightSelectedTower();
// Speed button interactions
speed1xBtn.down = function (x, y, obj) {
speedMultiplier = 1.0;
highlightSelectedSpeed();
};
speed2xBtn.down = function (x, y, obj) {
speedMultiplier = 2.0;
highlightSelectedSpeed();
};
speed3xBtn.down = function (x, y, obj) {
speedMultiplier = 3.0;
highlightSelectedSpeed();
};
function highlightSelectedSpeed() {
// Reset all speed buttons
speed1xBtn.alpha = speedMultiplier === 1.0 ? 1.0 : 0.7;
speed2xBtn.alpha = speedMultiplier === 2.0 ? 1.0 : 0.7;
speed3xBtn.alpha = speedMultiplier === 3.0 ? 1.0 : 0.7;
// Add glow effect to selected speed
if (speedMultiplier === 1.0) {
LK.effects.flashObject(speed1xBtn, 0x00FF00, 500);
} else if (speedMultiplier === 2.0) {
LK.effects.flashObject(speed2xBtn, 0xFFFF00, 500);
} else if (speedMultiplier === 3.0) {
LK.effects.flashObject(speed3xBtn, 0xFF8800, 500);
}
}
// Initial speed highlight
highlightSelectedSpeed();
// Tower menu interactions
laserTurretBtn.down = function (x, y, obj) {
if (currency < 50) return; // Not enough money
selectedTowerType = 'laser';
selectedTowerCost = 50;
placementMode = true;
turretToPlace = {
type: 'laser',
cost: 50
};
highlightSelectedTower();
};
missileLauncherBtn.down = function (x, y, obj) {
if (currency < 100) return; // Not enough money
selectedTowerType = 'missile';
selectedTowerCost = 100;
placementMode = true;
turretToPlace = {
type: 'missile',
cost: 100
};
highlightSelectedTower();
};
fireDroneBtn.down = function (x, y, obj) {
if (currency < 200) return; // Not enough money
selectedTowerType = 'fire';
selectedTowerCost = 200;
placementMode = true;
turretToPlace = {
type: 'fire',
cost: 200
};
highlightSelectedTower();
};
electricTrapBtn.down = function (x, y, obj) {
if (currency < 300) return; // Not enough money
selectedTowerType = 'electric';
selectedTowerCost = 300;
placementMode = true;
turretToPlace = {
type: 'electric',
cost: 300
};
highlightSelectedTower();
};
fireMachineBtn.down = function (x, y, obj) {
if (currency < 500) return; // Not enough money
selectedTowerType = 'fireMachine';
selectedTowerCost = 500;
placementMode = true;
turretToPlace = {
type: 'fireMachine',
cost: 500
};
highlightSelectedTower();
};
fireTrapBtn.down = function (x, y, obj) {
if (currency < 700) return; // Not enough money
selectedTowerType = 'fireTrap';
selectedTowerCost = 700;
placementMode = true;
turretToPlace = {
type: 'fireTrap',
cost: 700
};
highlightSelectedTower();
};
freezeEnemiesBtn.down = function (x, y, obj) {
if (currency < 1000) return; // Not enough money
currency -= 1000;
updateCurrencyDisplay();
// Freeze all enemies for 3 seconds
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
if (!zombie.isDead) {
zombie.isFrozen = true;
zombie.freezeTimer = 0;
zombie.originalSpeed = zombie.speed;
zombie.speed = 0;
// Visual freeze effect
tween(zombie.children[0], {
tint: 0x00FFFF
}, {
duration: 300,
onFinish: function onFinish() {
if (zombie.isFrozen && zombie.parent) {
tween(zombie.children[0], {
tint: 0xFFFFFF
}, {
duration: 300,
onFinish: function onFinish() {
if (zombie.isFrozen && zombie.parent) {
tween(zombie.children[0], {
tint: 0x00FFFF
}, {
duration: 300,
onFinish: arguments.callee
});
}
}
});
}
}
});
}
}
LK.effects.flashScreen(0x00FFFF, 1000);
};
var selectedTurret = null;
var placementMode = false;
var turretToPlace = null;
function selectTurret(turret) {
// Deselect previous turret
if (selectedTurret) {
selectedTurret.rangeIndicator.alpha = 0.25;
// Hide cross indicator on previous turret
selectedTurret.crossIndicator.alpha = 0;
}
selectedTurret = turret;
// Highlight selected turret
selectedTurret.rangeIndicator.alpha = 0.5;
// Show cross indicator
selectedTurret.crossIndicator.alpha = 1.0;
sellBtn.alpha = 1.0; // Enable sell button
upgradeBtn.alpha = 1.0; // Enable upgrade button
// Update button texts with prices
sellBtn.setText('SELL\nTURRET\n$' + selectedTurret.sellPrice);
upgradeBtn.setText('UPGRADE\nLv.' + selectedTurret.upgradeLevel + ' → ' + (selectedTurret.upgradeLevel + 1) + '\n$' + selectedTurret.upgradeCost);
LK.effects.flashObject(selectedTurret, 0x00FF00, 300);
}
function deselectTurret() {
if (selectedTurret) {
selectedTurret.rangeIndicator.alpha = 0.25;
// Hide cross indicator
selectedTurret.crossIndicator.alpha = 0;
}
selectedTurret = null;
sellBtn.alpha = 0.5; // Disable sell button
upgradeBtn.alpha = 0.5; // Disable upgrade button
sellBtn.setText('SELL\nTURRET\n$0'); // Reset text
upgradeBtn.setText('UPGRADE\nTURRET\n$0'); // Reset text
}
function sellTurret() {
if (!selectedTurret) return;
// Give money back
currency += selectedTurret.sellPrice;
updateCurrencyDisplay();
// Remove turret from game
for (var i = turrets.length - 1; i >= 0; i--) {
if (turrets[i] === selectedTurret) {
turrets.splice(i, 1);
break;
}
}
selectedTurret.destroy();
// Flash green effect
LK.effects.flashScreen(0x00FF00, 300);
deselectTurret();
}
function upgradeTurret() {
if (!selectedTurret) return;
if (selectedTurret.upgradeLevel >= 5) return; // Max upgrade level
if (currency < selectedTurret.upgradeCost) return; // Not enough money
// Deduct cost
currency -= selectedTurret.upgradeCost;
updateCurrencyDisplay();
// Upgrade turret
selectedTurret.upgradeLevel++;
selectedTurret.updateTowerProperties();
// Update button texts with new prices
sellBtn.setText('SELL\nTURRET\n$' + selectedTurret.sellPrice);
upgradeBtn.setText('UPGRADE\nLv.' + selectedTurret.upgradeLevel + ' → ' + (selectedTurret.upgradeLevel + 1) + '\n$' + selectedTurret.upgradeCost);
// Visual effects
LK.effects.flashObject(selectedTurret, 0x00FFFF, 500);
// Change turret color based on upgrade level
if (selectedTurret.upgradeLevel >= 3) {
selectedTurret.children[0].tint = 0xFFFFFF; // White for high level
} else if (selectedTurret.upgradeLevel >= 2) {
selectedTurret.children[0].tint = 0xFFFF00; // Yellow for mid level
}
}
// Game-wide click handler - enable turret placement when in placement mode
game.down = function (x, y, obj) {
// Check if click is in game area (not on UI elements)
if (y > 2400) return; // Don't place on bottom UI
if (placementMode && turretToPlace) {
// Check if position is too close to path
var tooCloseToPath = false;
for (var i = 0; i < gamePath.length - 1; i++) {
var start = gamePath[i];
var end = gamePath[i + 1];
var distance = distanceToLineSegment(x, y, start.x, start.y, end.x, end.y);
if (distance < 80) {
// Minimum distance from path
tooCloseToPath = true;
break;
}
}
if (tooCloseToPath) {
LK.effects.flashScreen(0xFF0000, 200); // Red flash for invalid placement
return;
}
// Check if position overlaps with existing turrets
var tooCloseToTurret = false;
for (var i = 0; i < turrets.length; i++) {
var turret = turrets[i];
var dx = turret.x - x;
var dy = turret.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 120) {
// Minimum distance between turrets
tooCloseToTurret = true;
break;
}
}
if (tooCloseToTurret) {
LK.effects.flashScreen(0xFF0000, 200); // Red flash for invalid placement
return;
}
if (turretToPlace.type === 'fireTrap') {
// Place fire trap
var fireTrap = new FireTrap();
fireTrap.x = x;
fireTrap.y = y;
currency -= turretToPlace.cost;
updateCurrencyDisplay();
fireTraps.push(fireTrap);
game.addChild(fireTrap);
// Flash orange when built
LK.effects.flashObject(fireTrap, 0xFF4400, 500);
} else {
// Place turret
var turret = new Turret();
turret.x = x;
turret.y = y;
turret.towerType = turretToPlace.type;
turret.cost = turretToPlace.cost;
turret.updateTowerProperties();
currency -= turretToPlace.cost;
updateCurrencyDisplay();
turrets.push(turret);
game.addChild(turret);
// Flash green when built
var flashColor = turretToPlace.type === 'laser' ? 0x4444FF : turretToPlace.type === 'missile' ? 0xFF4444 : turretToPlace.type === 'fire' ? 0xFF8800 : turretToPlace.type === 'fireMachine' ? 0xFF2200 : 0xFFFF00;
LK.effects.flashObject(turret, flashColor, 500);
}
// Exit placement mode
placementMode = false;
turretToPlace = null;
} else {
// Deselect turret when clicking empty area
deselectTurret();
}
};
game.update = function () {
// Spawn zombies
if (waveActive && zombiesSpawned < zombiesToSpawn) {
spawnTimer += speedMultiplier;
// Adjust spawn rate based on wave - slower spawning for first level
var currentSpawnRate = wave === 1 ? baseSpawnRate * 1.5 : baseSpawnRate;
if (spawnTimer >= currentSpawnRate) {
spawnZombie();
spawnTimer = 0;
}
}
// Clean up dead zombies
for (var i = zombies.length - 1; i >= 0; i--) {
if (zombies[i].isDead) {
zombies[i].destroy();
zombies.splice(i, 1);
}
}
checkWaveComplete();
}; ===================================================================
--- original.js
+++ change.js
@@ -380,8 +380,21 @@
self.children[0].tint = 0xFFFFFF;
}
}
}
+ // Handle freeze effect
+ if (self.isFrozen) {
+ self.freezeTimer += speedMultiplier;
+ if (self.freezeTimer >= 180) {
+ // 3 seconds of freezing
+ self.isFrozen = false;
+ self.speed = self.originalSpeed;
+ tween.stop(self.children[0], {
+ tint: true
+ });
+ self.children[0].tint = 0xFFFFFF;
+ }
+ }
// Update health bar if it exists
if (self.healthBar) {
var healthPercent = self.health / self.maxHealth;
self.healthBar.scaleX = healthPercent;
@@ -557,8 +570,16 @@
fireTrapBtn.anchor.set(0.5, 0.5);
fireTrapBtn.x = 1024;
fireTrapBtn.y = 2780;
game.addChild(fireTrapBtn);
+var freezeEnemiesBtn = new Text2('Freeze Enemies\n$1000', {
+ size: 48,
+ fill: 0x00FFFF
+});
+freezeEnemiesBtn.anchor.set(0.5, 0.5);
+freezeEnemiesBtn.x = 1024;
+freezeEnemiesBtn.y = 2880;
+game.addChild(freezeEnemiesBtn);
var waveTxt = new Text2('Level ' + wave, {
size: 80,
fill: 0x44FF44
});
@@ -1020,8 +1041,49 @@
cost: 700
};
highlightSelectedTower();
};
+freezeEnemiesBtn.down = function (x, y, obj) {
+ if (currency < 1000) return; // Not enough money
+ currency -= 1000;
+ updateCurrencyDisplay();
+ // Freeze all enemies for 3 seconds
+ for (var i = 0; i < zombies.length; i++) {
+ var zombie = zombies[i];
+ if (!zombie.isDead) {
+ zombie.isFrozen = true;
+ zombie.freezeTimer = 0;
+ zombie.originalSpeed = zombie.speed;
+ zombie.speed = 0;
+ // Visual freeze effect
+ tween(zombie.children[0], {
+ tint: 0x00FFFF
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ if (zombie.isFrozen && zombie.parent) {
+ tween(zombie.children[0], {
+ tint: 0xFFFFFF
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ if (zombie.isFrozen && zombie.parent) {
+ tween(zombie.children[0], {
+ tint: 0x00FFFF
+ }, {
+ duration: 300,
+ onFinish: arguments.callee
+ });
+ }
+ }
+ });
+ }
+ }
+ });
+ }
+ }
+ LK.effects.flashScreen(0x00FFFF, 1000);
+};
var selectedTurret = null;
var placementMode = false;
var turretToPlace = null;
function selectTurret(turret) {