User prompt
crea otra torre que haga daño en area y uno que ponga veneno y crea otros enemigos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
pon que al seleccionar uno pueda seguir poniendolo mientras tenga para comprarlo
User prompt
crea otra torre para comprar que haga que los enemigos vallan mas lento ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que el recorrido de los enemigos sea marro y pase por toda la pantalla
Code edit (1 edits merged)
Please save this source code
User prompt
Tower Defense: Strategic Wave Control
Initial prompt
hola,me gustaria un juego tower defence, con un boton para la tienda y que los enemigos no vengan hasta precionar el boto de listo
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AreaTower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('areaTower', {
anchorX: 0.5,
anchorY: 0.5
});
self.range = 160;
self.damage = 2;
self.areaDamage = 100; // Area damage radius
self.fireRate = 90; // Slower fire rate due to area effect
self.lastShot = 0;
self.cost = 100;
self.canShoot = function () {
return LK.ticks - self.lastShot >= self.fireRate;
};
self.findTarget = function () {
var closestEnemy = null;
var closestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range && distance < closestDistance) {
closestDistance = distance;
closestEnemy = enemy;
}
}
return closestEnemy;
};
self.explode = function (targetX, targetY) {
// Create explosion visual effect
var explosion = game.addChild(LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: targetX,
y: targetY
}));
// Animate explosion
tween(explosion, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Damage all enemies in area
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - targetX;
var dy = enemy.y - targetY;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.areaDamage) {
if (enemy.takeDamage(self.damage)) {
playerMoney += enemy.reward;
updateMoneyDisplay();
}
}
}
};
self.shoot = function (target) {
if (!self.canShoot()) return;
self.explode(target.x, target.y);
self.lastShot = LK.ticks;
LK.getSound('shoot').play();
};
self.update = function () {
var target = self.findTarget();
if (target) {
self.shoot(target);
}
};
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.target = null;
self.damage = 1;
self.update = function () {
if (!self.target || self.target.health <= 0) {
return;
}
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 20) {
// Hit target
if (self.target.takeDamage(self.damage)) {
// Enemy died, give reward
playerMoney += self.target.reward;
updateMoneyDisplay();
}
return true; // Mark for removal
}
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.maxHealth = 3;
self.speed = 2;
self.pathIndex = 0;
self.reward = 10;
self.takeDamage = function (damage) {
self.health -= damage;
// Flash red when hit
tween(enemyGraphics, {
tint: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(enemyGraphics, {
tint: 0xFFFFFF
}, {
duration: 100
});
}
});
LK.getSound('enemyHit').play();
return self.health <= 0;
};
self.update = function () {
// Check if slow effect should end
if (self.isSlowed && LK.ticks >= self.slowEndTick) {
self.speed = self.originalSpeed;
self.isSlowed = false;
// Remove blue tint
tween(self.children[0], {
tint: 0xFFFFFF
}, {
duration: 200
});
}
// Handle poison effect
if (self.isPoisoned) {
if (LK.ticks >= self.poisonEndTick) {
self.isPoisoned = false;
// Remove green tint
tween(self.children[0], {
tint: 0xFFFFFF
}, {
duration: 200
});
} else if (LK.ticks >= self.lastPoisonTick + self.poisonTickInterval) {
if (self.takeDamage(self.poisonDamage)) {
playerMoney += self.reward;
updateMoneyDisplay();
}
self.lastPoisonTick = LK.ticks;
}
}
if (self.pathIndex >= enemyPath.length) return;
var targetPoint = enemyPath[self.pathIndex];
var dx = targetPoint.x - self.x;
var dy = targetPoint.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 10) {
self.pathIndex++;
if (self.pathIndex >= enemyPath.length) {
// Enemy reached base
playerLives--;
return;
}
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
return self;
});
var FastEnemy = Container.expand(function () {
var self = Container.call(this);
// Override graphics with different color
self.children[0].destroy();
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
enemyGraphics.tint = 0xff9800; // Orange color
self.health = 2;
self.maxHealth = 2;
self.speed = 4; // Faster than normal enemy
self.reward = 15; // Higher reward
return self;
});
var PoisonTower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('poisonTower', {
anchorX: 0.5,
anchorY: 0.5
});
self.range = 150;
self.poisonDamage = 1;
self.poisonDuration = 180; // 3 seconds of poison
self.fireRate = 120; // Slower fire rate
self.lastShot = 0;
self.cost = 80;
self.canShoot = function () {
return LK.ticks - self.lastShot >= self.fireRate;
};
self.findTargetsInRange = function () {
var targetsInRange = [];
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range) {
targetsInRange.push(enemy);
}
}
return targetsInRange;
};
self.applyPoison = function () {
if (!self.canShoot()) return;
var targets = self.findTargetsInRange();
for (var i = 0; i < targets.length; i++) {
var enemy = targets[i];
if (!enemy.isPoisoned) {
enemy.isPoisoned = true;
enemy.poisonDamage = self.poisonDamage;
enemy.poisonEndTick = LK.ticks + self.poisonDuration;
enemy.poisonTickInterval = 30; // Damage every 0.5 seconds
enemy.lastPoisonTick = LK.ticks;
// Visual effect - tint enemy green
tween(enemy.children[0], {
tint: 0x4caf50
}, {
duration: 200
});
}
}
self.lastShot = LK.ticks;
};
self.update = function () {
self.applyPoison();
};
return self;
});
var SlowTower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('slowTower', {
anchorX: 0.5,
anchorY: 0.5
});
self.range = 180;
self.slowEffect = 0.5; // Reduces enemy speed by 50%
self.effectDuration = 120; // Effect lasts 2 seconds (120 ticks)
self.fireRate = 90; // Slower than basic tower
self.lastShot = 0;
self.cost = 75;
self.canShoot = function () {
return LK.ticks - self.lastShot >= self.fireRate;
};
self.findTargetsInRange = function () {
var targetsInRange = [];
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range) {
targetsInRange.push(enemy);
}
}
return targetsInRange;
};
self.applySlowEffect = function () {
if (!self.canShoot()) return;
var targets = self.findTargetsInRange();
for (var i = 0; i < targets.length; i++) {
var enemy = targets[i];
if (!enemy.isSlowed) {
enemy.isSlowed = true;
enemy.originalSpeed = enemy.speed;
enemy.speed = enemy.originalSpeed * self.slowEffect;
enemy.slowEndTick = LK.ticks + self.effectDuration;
// Visual effect - tint enemy blue
tween(enemy.children[0], {
tint: 0x2196f3
}, {
duration: 200
});
}
}
self.lastShot = LK.ticks;
};
self.update = function () {
self.applySlowEffect();
};
return self;
});
var TankEnemy = Container.expand(function () {
var self = Container.call(this);
// Override graphics with different color and size
self.children[0].destroy();
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
enemyGraphics.tint = 0x9c27b0; // Purple color
self.health = 8;
self.maxHealth = 8;
self.speed = 1; // Slower than normal enemy
self.reward = 25; // Higher reward
return self;
});
var Tower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('tower', {
anchorX: 0.5,
anchorY: 0.5
});
self.range = 200;
self.damage = 1;
self.fireRate = 60; // ticks between shots
self.lastShot = 0;
self.cost = 50;
self.canShoot = function () {
return LK.ticks - self.lastShot >= self.fireRate;
};
self.findTarget = function () {
var closestEnemy = null;
var closestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range && distance < closestDistance) {
closestDistance = distance;
closestEnemy = enemy;
}
}
return closestEnemy;
};
self.shoot = function (target) {
if (!self.canShoot()) return;
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.target = target;
bullet.damage = self.damage;
bullets.push(bullet);
game.addChild(bullet);
self.lastShot = LK.ticks;
LK.getSound('shoot').play();
};
self.update = function () {
var target = self.findTarget();
if (target) {
self.shoot(target);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2E7D32
});
/****
* Game Code
****/
// Game variables
var playerMoney = 200;
var playerLives = 10;
var currentWave = 1;
var waveInProgress = false;
var shopOpen = false;
var placingTower = false;
var selectedTowerType = null;
// Game arrays
var towers = [];
var enemies = [];
var bullets = [];
// Enemy path (comprehensive brown winding path covering the entire screen)
var enemyPath = [{
x: 0,
y: 300
}, {
x: 400,
y: 300
}, {
x: 400,
y: 600
}, {
x: 800,
y: 600
}, {
x: 800,
y: 200
}, {
x: 1200,
y: 200
}, {
x: 1200,
y: 900
}, {
x: 1600,
y: 900
}, {
x: 1600,
y: 500
}, {
x: 2000,
y: 500
}, {
x: 2000,
y: 1100
}, {
x: 1400,
y: 1100
}, {
x: 1400,
y: 1400
}, {
x: 600,
y: 1400
}, {
x: 600,
y: 1800
}, {
x: 1000,
y: 1800
}, {
x: 1000,
y: 2200
}, {
x: 1800,
y: 2200
}, {
x: 1800,
y: 1600
}, {
x: 2048,
y: 1600
}];
// Create visual path segments
for (var i = 0; i < enemyPath.length - 1; i++) {
var startPoint = enemyPath[i];
var endPoint = enemyPath[i + 1];
var segments = Math.ceil(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2)) / 50);
for (var j = 0; j <= segments; j++) {
var t = j / segments;
var pathX = startPoint.x + (endPoint.x - startPoint.x) * t;
var pathY = startPoint.y + (endPoint.y - startPoint.y) * t;
var pathSegment = game.addChild(LK.getAsset('pathSegment', {
anchorX: 0.5,
anchorY: 0.5,
x: pathX,
y: pathY
}));
pathSegment.alpha = 0.7;
}
}
// Create base at end of path
var base = game.addChild(LK.getAsset('base', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyPath[enemyPath.length - 1].x,
y: enemyPath[enemyPath.length - 1].y
}));
// UI Elements
var moneyText = new Text2('Money: $' + playerMoney, {
size: 60,
fill: 0xFFFFFF
});
moneyText.anchor.set(0, 0);
moneyText.x = 120;
moneyText.y = 50;
LK.gui.topLeft.addChild(moneyText);
var livesText = new Text2('Lives: ' + playerLives, {
size: 60,
fill: 0xFFFFFF
});
livesText.anchor.set(0, 0);
livesText.x = 120;
livesText.y = 130;
LK.gui.topLeft.addChild(livesText);
var waveText = new Text2('Wave: ' + currentWave, {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(1, 0);
LK.gui.topRight.addChild(waveText);
// Shop button
var shopBtn = game.addChild(LK.getAsset('shopButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: 2500
}));
var shopBtnText = new Text2('SHOP', {
size: 40,
fill: 0xFFFFFF
});
shopBtnText.anchor.set(0.5, 0.5);
shopBtnText.x = shopBtn.x;
shopBtnText.y = shopBtn.y;
game.addChild(shopBtnText);
// Ready button
var readyBtn = game.addChild(LK.getAsset('readyButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 500,
y: 2500
}));
var readyBtnText = new Text2('READY', {
size: 40,
fill: 0xFFFFFF
});
readyBtnText.anchor.set(0.5, 0.5);
readyBtnText.x = readyBtn.x;
readyBtnText.y = readyBtn.y;
game.addChild(readyBtnText);
// Shop panel (initially hidden)
var shopPanel = game.addChild(LK.getAsset('shopPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
shopPanel.visible = false;
var shopTitle = new Text2('TOWER SHOP', {
size: 50,
fill: 0xFFFFFF
});
shopTitle.anchor.set(0.5, 0);
shopTitle.x = shopPanel.x;
shopTitle.y = shopPanel.y - 450;
game.addChild(shopTitle);
// Basic tower button in shop
var basicTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x,
y: shopPanel.y - 350
}));
basicTowerBtn.visible = false;
var basicTowerText = new Text2('Basic Tower\n$50', {
size: 30,
fill: 0xFFFFFF
});
basicTowerText.anchor.set(0.5, 0.5);
basicTowerText.x = basicTowerBtn.x;
basicTowerText.y = basicTowerBtn.y;
game.addChild(basicTowerText);
// Slow tower button in shop
var slowTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x,
y: shopPanel.y - 200,
color: 0x2196f3
}));
slowTowerBtn.visible = false;
var slowTowerText = new Text2('Slow Tower\n$75', {
size: 30,
fill: 0xFFFFFF
});
slowTowerText.anchor.set(0.5, 0.5);
slowTowerText.x = slowTowerBtn.x;
slowTowerText.y = slowTowerBtn.y;
game.addChild(slowTowerText);
// Area tower button in shop
var areaTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x,
y: shopPanel.y - 50,
color: 0xff9800
}));
areaTowerBtn.visible = false;
var areaTowerText = new Text2('Area Tower\n$100', {
size: 30,
fill: 0xFFFFFF
});
areaTowerText.anchor.set(0.5, 0.5);
areaTowerText.x = areaTowerBtn.x;
areaTowerText.y = areaTowerBtn.y;
game.addChild(areaTowerText);
// Poison tower button in shop
var poisonTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x,
y: shopPanel.y + 100,
color: 0x4caf50
}));
poisonTowerBtn.visible = false;
var poisonTowerText = new Text2('Poison Tower\n$80', {
size: 30,
fill: 0xFFFFFF
});
poisonTowerText.anchor.set(0.5, 0.5);
poisonTowerText.x = poisonTowerBtn.x;
poisonTowerText.y = poisonTowerBtn.y;
game.addChild(poisonTowerText);
// Close shop button
var closeShopBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x,
y: shopPanel.y + 400,
color: 0xFF5722
}));
closeShopBtn.visible = false;
var closeShopText = new Text2('CLOSE', {
size: 30,
fill: 0xFFFFFF
});
closeShopText.anchor.set(0.5, 0.5);
closeShopText.x = closeShopBtn.x;
closeShopText.y = closeShopBtn.y;
game.addChild(closeShopText);
// Functions
function updateMoneyDisplay() {
moneyText.setText('Money: $' + playerMoney);
}
function updateLivesDisplay() {
livesText.setText('Lives: ' + playerLives);
}
function updateWaveDisplay() {
waveText.setText('Wave: ' + currentWave);
}
function toggleShop() {
shopOpen = !shopOpen;
shopPanel.visible = shopOpen;
shopTitle.visible = shopOpen;
basicTowerBtn.visible = shopOpen;
basicTowerText.visible = shopOpen;
slowTowerBtn.visible = shopOpen;
slowTowerText.visible = shopOpen;
areaTowerBtn.visible = shopOpen;
areaTowerText.visible = shopOpen;
poisonTowerBtn.visible = shopOpen;
poisonTowerText.visible = shopOpen;
closeShopBtn.visible = shopOpen;
closeShopText.visible = shopOpen;
}
function startWave() {
if (waveInProgress) return;
waveInProgress = true;
var enemiesToSpawn = 3 + currentWave;
var spawnDelay = 0;
for (var i = 0; i < enemiesToSpawn; i++) {
LK.setTimeout(function () {
var enemy;
var enemyType = Math.random();
if (currentWave >= 3 && enemyType < 0.3) {
enemy = new FastEnemy();
} else if (currentWave >= 5 && enemyType < 0.6) {
enemy = new TankEnemy();
} else {
enemy = new Enemy();
}
enemy.x = enemyPath[0].x;
enemy.y = enemyPath[0].y;
enemy.health += Math.floor(currentWave / 3); // Increase health every 3 waves
enemy.maxHealth = enemy.health;
enemies.push(enemy);
game.addChild(enemy);
}, spawnDelay);
spawnDelay += 1000; // 1 second between spawns
}
}
function checkWaveComplete() {
if (waveInProgress && enemies.length === 0) {
waveInProgress = false;
currentWave++;
updateWaveDisplay();
playerMoney += 50; // Wave completion bonus
updateMoneyDisplay();
}
}
function placeTower(x, y) {
var towerCost = 50;
if (selectedTowerType === 'slow') towerCost = 75;else if (selectedTowerType === 'area') towerCost = 100;else if (selectedTowerType === 'poison') towerCost = 80;
if (!placingTower || playerMoney < towerCost) return false;
// Check if position is valid (not too close to path or other towers)
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
var dx = tower.x - x;
var dy = tower.y - y;
if (Math.sqrt(dx * dx + dy * dy) < 100) {
return false; // Too close to another tower
}
}
var tower;
if (selectedTowerType === 'slow') {
tower = new SlowTower();
} else if (selectedTowerType === 'area') {
tower = new AreaTower();
} else if (selectedTowerType === 'poison') {
tower = new PoisonTower();
} else {
tower = new Tower();
}
tower.x = x;
tower.y = y;
towers.push(tower);
game.addChild(tower);
playerMoney -= tower.cost;
updateMoneyDisplay();
// Only stop placing if player doesn't have enough money for another tower
if (playerMoney < towerCost) {
placingTower = false;
}
return true;
}
// Event handlers
shopBtn.down = function (x, y, obj) {
toggleShop();
};
readyBtn.down = function (x, y, obj) {
if (!waveInProgress) {
startWave();
}
};
basicTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 50) {
placingTower = true;
selectedTowerType = 'basic';
toggleShop();
}
};
slowTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 75) {
placingTower = true;
selectedTowerType = 'slow';
toggleShop();
}
};
areaTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 100) {
placingTower = true;
selectedTowerType = 'area';
toggleShop();
}
};
poisonTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 80) {
placingTower = true;
selectedTowerType = 'poison';
toggleShop();
}
};
closeShopBtn.down = function (x, y, obj) {
toggleShop();
};
game.down = function (x, y, obj) {
if (placingTower) {
placeTower(x, y);
}
};
game.up = function (x, y, obj) {
// Double tap to cancel tower placement
if (placingTower && obj.doubleTap) {
placingTower = false;
selectedTowerType = null;
}
};
// Main game loop
game.update = function () {
// Update towers
for (var i = 0; i < towers.length; i++) {
towers[i].update();
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.update();
// Remove dead enemies
if (enemy.health <= 0) {
enemy.destroy();
enemies.splice(i, 1);
}
// Remove enemies that reached the end
else if (enemy.pathIndex >= enemyPath.length) {
enemy.destroy();
enemies.splice(i, 1);
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
var shouldRemove = bullet.update();
if (shouldRemove || !bullet.target || bullet.target.health <= 0) {
bullet.destroy();
bullets.splice(i, 1);
}
}
// Check for game over
if (playerLives <= 0) {
LK.showGameOver();
}
// Update lives display if changed
updateLivesDisplay();
// Check if wave is complete
checkWaveComplete();
// Win condition - survive 10 waves
if (currentWave > 10 && !waveInProgress && enemies.length === 0) {
LK.showYouWin();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -5,8 +5,85 @@
/****
* Classes
****/
+var AreaTower = Container.expand(function () {
+ var self = Container.call(this);
+ var towerGraphics = self.attachAsset('areaTower', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.range = 160;
+ self.damage = 2;
+ self.areaDamage = 100; // Area damage radius
+ self.fireRate = 90; // Slower fire rate due to area effect
+ self.lastShot = 0;
+ self.cost = 100;
+ self.canShoot = function () {
+ return LK.ticks - self.lastShot >= self.fireRate;
+ };
+ self.findTarget = function () {
+ var closestEnemy = null;
+ var closestDistance = Infinity;
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ var dx = enemy.x - self.x;
+ var dy = enemy.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance <= self.range && distance < closestDistance) {
+ closestDistance = distance;
+ closestEnemy = enemy;
+ }
+ }
+ return closestEnemy;
+ };
+ self.explode = function (targetX, targetY) {
+ // Create explosion visual effect
+ var explosion = game.addChild(LK.getAsset('explosion', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: targetX,
+ y: targetY
+ }));
+ // Animate explosion
+ tween(explosion, {
+ scaleX: 2,
+ scaleY: 2,
+ alpha: 0
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ explosion.destroy();
+ }
+ });
+ // Damage all enemies in area
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ var dx = enemy.x - targetX;
+ var dy = enemy.y - targetY;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance <= self.areaDamage) {
+ if (enemy.takeDamage(self.damage)) {
+ playerMoney += enemy.reward;
+ updateMoneyDisplay();
+ }
+ }
+ }
+ };
+ self.shoot = function (target) {
+ if (!self.canShoot()) return;
+ self.explode(target.x, target.y);
+ self.lastShot = LK.ticks;
+ LK.getSound('shoot').play();
+ };
+ self.update = function () {
+ var target = self.findTarget();
+ if (target) {
+ self.shoot(target);
+ }
+ };
+ return self;
+});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
@@ -76,8 +153,26 @@
}, {
duration: 200
});
}
+ // Handle poison effect
+ if (self.isPoisoned) {
+ if (LK.ticks >= self.poisonEndTick) {
+ self.isPoisoned = false;
+ // Remove green tint
+ tween(self.children[0], {
+ tint: 0xFFFFFF
+ }, {
+ duration: 200
+ });
+ } else if (LK.ticks >= self.lastPoisonTick + self.poisonTickInterval) {
+ if (self.takeDamage(self.poisonDamage)) {
+ playerMoney += self.reward;
+ updateMoneyDisplay();
+ }
+ self.lastPoisonTick = LK.ticks;
+ }
+ }
if (self.pathIndex >= enemyPath.length) return;
var targetPoint = enemyPath[self.pathIndex];
var dx = targetPoint.x - self.x;
var dy = targetPoint.y - self.y;
@@ -95,8 +190,77 @@
}
};
return self;
});
+var FastEnemy = Container.expand(function () {
+ var self = Container.call(this);
+ // Override graphics with different color
+ self.children[0].destroy();
+ var enemyGraphics = self.attachAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ enemyGraphics.tint = 0xff9800; // Orange color
+ self.health = 2;
+ self.maxHealth = 2;
+ self.speed = 4; // Faster than normal enemy
+ self.reward = 15; // Higher reward
+ return self;
+});
+var PoisonTower = Container.expand(function () {
+ var self = Container.call(this);
+ var towerGraphics = self.attachAsset('poisonTower', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.range = 150;
+ self.poisonDamage = 1;
+ self.poisonDuration = 180; // 3 seconds of poison
+ self.fireRate = 120; // Slower fire rate
+ self.lastShot = 0;
+ self.cost = 80;
+ self.canShoot = function () {
+ return LK.ticks - self.lastShot >= self.fireRate;
+ };
+ self.findTargetsInRange = function () {
+ var targetsInRange = [];
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ var dx = enemy.x - self.x;
+ var dy = enemy.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance <= self.range) {
+ targetsInRange.push(enemy);
+ }
+ }
+ return targetsInRange;
+ };
+ self.applyPoison = function () {
+ if (!self.canShoot()) return;
+ var targets = self.findTargetsInRange();
+ for (var i = 0; i < targets.length; i++) {
+ var enemy = targets[i];
+ if (!enemy.isPoisoned) {
+ enemy.isPoisoned = true;
+ enemy.poisonDamage = self.poisonDamage;
+ enemy.poisonEndTick = LK.ticks + self.poisonDuration;
+ enemy.poisonTickInterval = 30; // Damage every 0.5 seconds
+ enemy.lastPoisonTick = LK.ticks;
+ // Visual effect - tint enemy green
+ tween(enemy.children[0], {
+ tint: 0x4caf50
+ }, {
+ duration: 200
+ });
+ }
+ }
+ self.lastShot = LK.ticks;
+ };
+ self.update = function () {
+ self.applyPoison();
+ };
+ return self;
+});
var SlowTower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('slowTower', {
anchorX: 0.5,
@@ -148,8 +312,25 @@
self.applySlowEffect();
};
return self;
});
+var TankEnemy = Container.expand(function () {
+ var self = Container.call(this);
+ // Override graphics with different color and size
+ self.children[0].destroy();
+ var enemyGraphics = self.attachAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1.5,
+ scaleY: 1.5
+ });
+ enemyGraphics.tint = 0x9c27b0; // Purple color
+ self.health = 8;
+ self.maxHealth = 8;
+ self.speed = 1; // Slower than normal enemy
+ self.reward = 25; // Higher reward
+ return self;
+});
var Tower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('tower', {
anchorX: 0.5,
@@ -409,8 +590,42 @@
slowTowerText.anchor.set(0.5, 0.5);
slowTowerText.x = slowTowerBtn.x;
slowTowerText.y = slowTowerBtn.y;
game.addChild(slowTowerText);
+// Area tower button in shop
+var areaTowerBtn = game.addChild(LK.getAsset('towerButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: shopPanel.x,
+ y: shopPanel.y - 50,
+ color: 0xff9800
+}));
+areaTowerBtn.visible = false;
+var areaTowerText = new Text2('Area Tower\n$100', {
+ size: 30,
+ fill: 0xFFFFFF
+});
+areaTowerText.anchor.set(0.5, 0.5);
+areaTowerText.x = areaTowerBtn.x;
+areaTowerText.y = areaTowerBtn.y;
+game.addChild(areaTowerText);
+// Poison tower button in shop
+var poisonTowerBtn = game.addChild(LK.getAsset('towerButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: shopPanel.x,
+ y: shopPanel.y + 100,
+ color: 0x4caf50
+}));
+poisonTowerBtn.visible = false;
+var poisonTowerText = new Text2('Poison Tower\n$80', {
+ size: 30,
+ fill: 0xFFFFFF
+});
+poisonTowerText.anchor.set(0.5, 0.5);
+poisonTowerText.x = poisonTowerBtn.x;
+poisonTowerText.y = poisonTowerBtn.y;
+game.addChild(poisonTowerText);
// Close shop button
var closeShopBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
@@ -444,8 +659,12 @@
basicTowerBtn.visible = shopOpen;
basicTowerText.visible = shopOpen;
slowTowerBtn.visible = shopOpen;
slowTowerText.visible = shopOpen;
+ areaTowerBtn.visible = shopOpen;
+ areaTowerText.visible = shopOpen;
+ poisonTowerBtn.visible = shopOpen;
+ poisonTowerText.visible = shopOpen;
closeShopBtn.visible = shopOpen;
closeShopText.visible = shopOpen;
}
function startWave() {
@@ -454,9 +673,17 @@
var enemiesToSpawn = 3 + currentWave;
var spawnDelay = 0;
for (var i = 0; i < enemiesToSpawn; i++) {
LK.setTimeout(function () {
- var enemy = new Enemy();
+ var enemy;
+ var enemyType = Math.random();
+ if (currentWave >= 3 && enemyType < 0.3) {
+ enemy = new FastEnemy();
+ } else if (currentWave >= 5 && enemyType < 0.6) {
+ enemy = new TankEnemy();
+ } else {
+ enemy = new Enemy();
+ }
enemy.x = enemyPath[0].x;
enemy.y = enemyPath[0].y;
enemy.health += Math.floor(currentWave / 3); // Increase health every 3 waves
enemy.maxHealth = enemy.health;
@@ -475,9 +702,10 @@
updateMoneyDisplay();
}
}
function placeTower(x, y) {
- var towerCost = selectedTowerType === 'slow' ? 75 : 50;
+ var towerCost = 50;
+ if (selectedTowerType === 'slow') towerCost = 75;else if (selectedTowerType === 'area') towerCost = 100;else if (selectedTowerType === 'poison') towerCost = 80;
if (!placingTower || playerMoney < towerCost) return false;
// Check if position is valid (not too close to path or other towers)
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
@@ -486,9 +714,18 @@
if (Math.sqrt(dx * dx + dy * dy) < 100) {
return false; // Too close to another tower
}
}
- var tower = selectedTowerType === 'slow' ? new SlowTower() : new Tower();
+ var tower;
+ if (selectedTowerType === 'slow') {
+ tower = new SlowTower();
+ } else if (selectedTowerType === 'area') {
+ tower = new AreaTower();
+ } else if (selectedTowerType === 'poison') {
+ tower = new PoisonTower();
+ } else {
+ tower = new Tower();
+ }
tower.x = x;
tower.y = y;
towers.push(tower);
game.addChild(tower);
@@ -522,8 +759,22 @@
selectedTowerType = 'slow';
toggleShop();
}
};
+areaTowerBtn.down = function (x, y, obj) {
+ if (playerMoney >= 100) {
+ placingTower = true;
+ selectedTowerType = 'area';
+ toggleShop();
+ }
+};
+poisonTowerBtn.down = function (x, y, obj) {
+ if (playerMoney >= 80) {
+ placingTower = true;
+ selectedTowerType = 'poison';
+ toggleShop();
+ }
+};
closeShopBtn.down = function (x, y, obj) {
toggleShop();
};
game.down = function (x, y, obj) {
castillo desde arriba. In-Game asset. 2d. High contrast. No shadows
torrre de fuego desde arriba. In-Game asset. 2d. High contrast. No shadows
torre de hielo desde arriba. In-Game asset. 2d. High contrast. No shadows
cañon desde arriba. In-Game asset. 2d. High contrast. No shadows
torrre con serpientes desde arriba. In-Game asset. 2d. High contrast. No shadows
torre con cristal encima desde arriba. In-Game asset. 2d. High contrast. No shadows
torre con cañones desde arriba. In-Game asset. 2d. High contrast. No shadows
torre con un cañon gigante desde arriba. In-Game asset. 2d. High contrast. No shadows
montruo volado. In-Game asset. 2d. High contrast. No shadows
mostruo con visor sobre moto. In-Game asset. 2d. High contrast. No shadows
auto con 3 esqueletos. In-Game asset. 2d. High contrast. No shadows
mago. In-Game asset. 2d. High contrast. No shadows
cerdo en 2 patas musculoso con armadura. In-Game asset. 2d. High contrast. No shadows
mostruo musculoso zombie. In-Game asset. 2d. High contrast. No shadows
blast. In-Game asset. 2d. High contrast. No shadows
piso marron. In-Game asset. 2d. High contrast. No shadows
con la piel toda roja y con los ojos rojos
tierrra,le salen unos ojos con un casco. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
de cuerpo completo
con piel de obsidiana
con una armadura negra y casco
con una armadura
con una armadura dorada y casco
montruo blanco de ojos negros con dos cabezas con flora en el cuerpo. In-Game asset. 2d. High contrast. No shadows
montruo blanco de ojos negros de dos cabezas musculoso esqueletico. In-Game asset. 2d. High contrast. No shadows
con 4 cabezas y armadura
explosion nuclear. In-Game asset. 2d. High contrast. No shadows
cabeza de esqueleto con montruos blancos en la boca. In-Game asset. 2d. High contrast. No shadows
doble cañon. In-Game asset. 2d. High contrast. No shadows
cañon gigante desde frete. In-Game asset. 2d. High contrast. No shadows
torre con 1 cañon con las balas de minigun desde arriba. In-Game asset. 2d. High contrast. No shadows
bomba. In-Game asset. 2d. High contrast. No shadows
torre con hielo y nieve desde arriba. In-Game asset. 2d. High contrast. No shadows
torre con 10 cañones desde arriba. In-Game asset. 2d. High contrast. No shadows
bomba nuclear. In-Game asset. 2d. High contrast. No shadows
torre con captus desde arriba. In-Game asset. 2d. High contrast. No shadows
globo con cara enojada. In-Game asset. 2d. High contrast. No shadows
con el traje de color rojo