User prompt
Alt kısımdaki yeşil arka planı tamamen kaldır, sadece yazılar kalsın.
User prompt
Alt kısımdaki yeşil arka planı tamamen kaldır, sadece yazılar kalsın.
User prompt
Let the flying zombies go wherever they want without getting stuck anywhere, and these zombies should appear after the ninth level. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'call')' in or related to this line: 'originalUpdate.call(self);' Line Number: 280
User prompt
There will be a flying zombie in the game for some of the enemies, it will not be in that place, it will look like it is flying ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Reduce the size of all zombies just like the first levels
User prompt
Levels 11 and 15: Freeze 2 machines for 2 seconds so that when the machines use that zombie effect, all machines will not hit. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let there be 15 levels
User prompt
Slightly reduce the range of the fire trap.
User prompt
Make all the machines vertical and orderly, not scattered, not left or right, but only in the middle.
User prompt
Delete the freeze enimies
User prompt
The fire trap should be powerful enough to burn enemies when they come within range of the machine and also allow the machine to hit them. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The fire trap will hit all enemies and the fire trap will have a firing range ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
We can place the fire trap wherever we want, even where the enemies pass
User prompt
Only the fire trap can be placed where the enemy passes and when the enemy touches the fire, it will burn for 5 seconds. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Fire trap range size like others
User prompt
Make the fire trap size square
User prompt
Increase the range of the fire trap to more than five hundred
User prompt
Now let them all be at the level of the machine, let all the machines be the same, let no text shift to the right or left.
User prompt
Delete the gun text, I wanted the machine to be at his level directly
User prompt
Make all the machines vertical to it like a laser gun and make them all the same length
User prompt
Ok do it
User prompt
All the things I write will be vertical and none of them will stick together and there will be spaces between them.
User prompt
Arrange the text items 'SELL TURRET $0', 'UPGRADE TURRET $0', 'START WAVE', 'Laser Gun $10', 'Middle Tower $20', 'Fire Blaster $30', 'Electric Field $40', 'Ice Machine $50', 'Fire Trap $60', 'Freeze Enemies $70' in a neat, vertical list in the highlighted area of the game screen in the image
User prompt
Drag the text up a little then to the left
/****
* 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: 2100,
width: 2048,
height: 532,
alpha: 0.9,
tint: 0x1a1a1a
}));
var laserTurretBtn = new Text2('Laser Turret Gun\n$50', {
size: 48,
fill: 0x4444FF
});
laserTurretBtn.anchor.set(0.5, 0.5);
laserTurretBtn.x = 1024;
laserTurretBtn.y = 2160;
game.addChild(laserTurretBtn);
var missileLauncherBtn = new Text2('Missile Tower Gun\n$100', {
size: 48,
fill: 0xFF4444
});
missileLauncherBtn.anchor.set(0.5, 0.5);
missileLauncherBtn.x = 1024;
missileLauncherBtn.y = 2260;
game.addChild(missileLauncherBtn);
var fireDroneBtn = new Text2('Fire Blaster Gun\n$200', {
size: 48,
fill: 0xFF8800
});
fireDroneBtn.anchor.set(0.5, 0.5);
fireDroneBtn.x = 1024;
fireDroneBtn.y = 2360;
game.addChild(fireDroneBtn);
var electricTrapBtn = new Text2('Electric Field Gun\n$300', {
size: 48,
fill: 0xFFFF00
});
electricTrapBtn.anchor.set(0.5, 0.5);
electricTrapBtn.x = 1024;
electricTrapBtn.y = 2460;
game.addChild(electricTrapBtn);
var fireMachineBtn = new Text2('Fire Machine Gun\n$500', {
size: 48,
fill: 0xFF2200
});
fireMachineBtn.anchor.set(0.5, 0.5);
fireMachineBtn.x = 1024;
fireMachineBtn.y = 2560;
game.addChild(fireMachineBtn);
var fireTrapBtn = new Text2('Fire Trap Gun\n$700', {
size: 48,
fill: 0xFF4400
});
fireTrapBtn.anchor.set(0.5, 0.5);
fireTrapBtn.x = 1024;
fireTrapBtn.y = 2660;
game.addChild(fireTrapBtn);
var freezeEnemiesBtn = new Text2('Freeze Enemies Gun\n$1000', {
size: 48,
fill: 0x00FFFF
});
freezeEnemiesBtn.anchor.set(0.5, 0.5);
freezeEnemiesBtn.x = 1024;
freezeEnemiesBtn.y = 2760;
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 = 2400;
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 = 2250; // 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 = 2250; // 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 = 2180;
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 = 2280;
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 = 2380;
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;
if (!zombie.originalSpeed) zombie.originalSpeed = zombie.speed;
zombie.speed = 0;
// Visual freeze effect with continuous blue tint
tween(zombie.children[0], {
tint: 0x00FFFF
}, {
duration: 200
});
}
}
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 > 2300) 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
@@ -522,57 +522,57 @@
height: 532,
alpha: 0.9,
tint: 0x1a1a1a
}));
-var laserTurretBtn = new Text2('Laser Gun\n$50', {
+var laserTurretBtn = new Text2('Laser Turret Gun\n$50', {
size: 48,
fill: 0x4444FF
});
laserTurretBtn.anchor.set(0.5, 0.5);
laserTurretBtn.x = 1024;
laserTurretBtn.y = 2160;
game.addChild(laserTurretBtn);
-var missileLauncherBtn = new Text2('Missile Tower\n$100', {
+var missileLauncherBtn = new Text2('Missile Tower Gun\n$100', {
size: 48,
fill: 0xFF4444
});
missileLauncherBtn.anchor.set(0.5, 0.5);
missileLauncherBtn.x = 1024;
missileLauncherBtn.y = 2260;
game.addChild(missileLauncherBtn);
-var fireDroneBtn = new Text2('Fire Blaster\n$200', {
+var fireDroneBtn = new Text2('Fire Blaster Gun\n$200', {
size: 48,
fill: 0xFF8800
});
fireDroneBtn.anchor.set(0.5, 0.5);
fireDroneBtn.x = 1024;
fireDroneBtn.y = 2360;
game.addChild(fireDroneBtn);
-var electricTrapBtn = new Text2('Electric Field\n$300', {
+var electricTrapBtn = new Text2('Electric Field Gun\n$300', {
size: 48,
fill: 0xFFFF00
});
electricTrapBtn.anchor.set(0.5, 0.5);
electricTrapBtn.x = 1024;
electricTrapBtn.y = 2460;
game.addChild(electricTrapBtn);
-var fireMachineBtn = new Text2('Fire Machine\n$500', {
+var fireMachineBtn = new Text2('Fire Machine Gun\n$500', {
size: 48,
fill: 0xFF2200
});
fireMachineBtn.anchor.set(0.5, 0.5);
fireMachineBtn.x = 1024;
fireMachineBtn.y = 2560;
game.addChild(fireMachineBtn);
-var fireTrapBtn = new Text2('Fire Trap\n$700', {
+var fireTrapBtn = new Text2('Fire Trap Gun\n$700', {
size: 48,
fill: 0xFF4400
});
fireTrapBtn.anchor.set(0.5, 0.5);
fireTrapBtn.x = 1024;
fireTrapBtn.y = 2660;
game.addChild(fireTrapBtn);
-var freezeEnemiesBtn = new Text2('Freeze Enemies\n$1000', {
+var freezeEnemiesBtn = new Text2('Freeze Enemies Gun\n$1000', {
size: 48,
fill: 0x00FFFF
});
freezeEnemiesBtn.anchor.set(0.5, 0.5);