User prompt
hay un problema,cuando inicias el juego se ven las palabras de las torres aunque no haya abierto la tienda
User prompt
aumenta mucho mas los botones de los enemigos y los nombres, y separalos
User prompt
agranda mucho mas los botones de la tienda de enemigos y separalos mas y añadele relieve a las letras
User prompt
hay un problema,cuando toco los botones de la tienda se ponen bombas
User prompt
agranda mucho mas los botenes de la tienda los nombres y dale relieve a las letras y separalos mas
User prompt
agregale a las torres nuevas que cuando se cliquean a una que ya este colocada se quite y te devuelva el dinero
User prompt
para bomb usa el assest bomba y hay un problema que cuando toco los botones de la tienda se colocan torres
User prompt
pero el assest bomba es para la bomba normal, para la bomba nuclear usa el asset nuclear,para la super bomba usa el assest superbomba para la super omega tower usa el assest triple
User prompt
para el doble cañon usa el assets "doble", para el super cañon usa el assest canon, para el torre rapida usa el assest rapida,para la torre que deja quietos usa el assets stop,para la bomba el assest bomba,para la omega tower el asset omegatower
User prompt
crea un nuevo enemigo que no pueda recibir daño hasta el 50% del camino,mietras avanza cada 5 segundos pone un enemigo en su posicion,y cuado muere,espawea 3 de los que pone usa el asset cabeza y el enemigo que pone es rapido,usa el assets famtasma para los que pone ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
haz que la torre que deja quieto,que solo pueda un enemigo a la vez y que tenga un tiempo de 30 segundos entre disparos y que las torres no ataque al topo hasta que pueda recibir daño
User prompt
aumenta el rango de daño de la bomba nuclear a toda la pantalla y que se active apenas la pongas y explote ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
agrega los nuevos enemigos a la tienda de enemigos, tambie crea una nueva de una bomba nuclear que al ponerla crece y explota a rango de toda la pantalla y quita 5000 de vida y cuesta 10000 y una nueva torre que lanza proyectiles a todos los enemigos al mismo tiempo y quita 300 de vida ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
crea a un super omega tankboss que tenga 30000 de vida y tiene posibilidades de aparecer en la oleada 43 y aumenta cada oleada,para este usa el assets omega, tambie crea otro que tenga 50000 de vida y tenga posibilidades de aparecer en la oleada 45 y aumenta cada oleada,usa el assest omegaarmor
User prompt
aumeta el area de activacion de las bombas y que el omega super tower tenga rango de toda la pantalla
User prompt
crea un mega super tower que dispare cada 30 segundos y quite 500 de vida ,vale 2000 y crea una bonba que cuado se le acerca un enemigo explote y desaparesca en gran area y quite 200 de vida,vale 150 y una super bomba que quite 1000 de vida cuado un enemigo se acerque en una area masiva y cueste 2000 money
User prompt
hay un problema, no sale los botones de los enemigos e la tienda y la super tower no dispara ,y el super cañon debe atacar a distacia de toda la pantalla y aumenta su area de ataque
User prompt
hay un problema,cuando apreto en los botones de la tienda se ponen torres,tambien agranda mucho mas los botones de las tiendas y separalos mas y que la tiwnda se vea por encima del juego por que sino los enemigos y torres quedan encima y no puedo ver
User prompt
pon que se vea la barra de vida de cada enemigo
User prompt
crea a un super tankboss obcidiana armor, este tiene 10000 de vida,a partir de la oleada 30 tiene probabilidad de aparecer y va aumetado cada ronda usa el asset obcidiaaarmor,tambie crea un super tankboss dorado,este tiene 15000 de vida y a partir de la oleada 40 tiene probabilidad de aparecer y va aumentando cada oleada,usa el assets gold
User prompt
añade a los demas enemigos al modo sandbox
User prompt
crea otro modo en el menu,que sea "sadbox" donde tengas dinero infiito y otra tienda que hace aparecer al enemigo que quieras
User prompt
crea a un super tankboss armor, este tiene 4000 de vida,a partir de la oleada 15 tiene probabilidad de aparecer y va aumetado cada ronda usa el asset armor,tambie crea un super tankboss de obsidiana,este tiene 6000 de vida y a partir de la oleada 25 tiene probabilidad de aparecer y va aumentando cada oleada,usa el assets obcidiaa
User prompt
haz que la torre que deja quieto tenga de rango toda la patalla
/****
* 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 DoubleCannon = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('tower', {
anchorX: 0.5,
anchorY: 0.5
});
towerGraphics.tint = 0x795548; // Brown color for double cannon
self.range = 300; // Long range
self.damage = 8; // High damage per bullet
self.fireRate = 90; // Moderate fire rate
self.lastShot = 0;
self.cost = 500;
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;
}
// Fire two bullets simultaneously
for (var i = 0; i < 2; i++) {
var bullet = new Bullet();
bullet.x = self.x + (i === 0 ? -10 : 10); // Offset bullets slightly
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;
});
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 freeze effect should end
if (self.isFrozen && LK.ticks >= self.freezeEndTick) {
self.speed = self.originalSpeed;
self.isFrozen = false;
// Remove freeze tint
tween(self.children[0], {
tint: 0xFFFFFF
}, {
duration: 200
});
}
// 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 TankEnemy = Enemy.expand(function () {
var self = Enemy.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 = 40;
self.maxHealth = 40;
self.speed = 1; // Slower than normal enemy
self.reward = 25; // Higher reward
return self;
});
var TankBossEnemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Override graphics with tank boss appearance
self.children[0].destroy();
var enemyGraphics = self.attachAsset('tankboss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
enemyGraphics.tint = 0x263238; // Very dark grey for extreme tank boss
self.health = 1000; // Extremely high health
self.maxHealth = 1000;
self.speed = 0.4; // Very slow due to extreme armor
self.reward = 100; // Very high reward for extreme difficulty
self.armor = 0.5; // Takes 50% less damage from all sources
// Override takeDamage to apply armor reduction
self.takeDamage = function (damage) {
var reducedDamage = Math.max(1, Math.floor(damage * (1 - self.armor)));
self.health -= reducedDamage;
// Flash red when hit with special armor effect
tween(self.children[0], {
tint: 0x795548
}, {
duration: 150,
onFinish: function onFinish() {
tween(self.children[0], {
tint: 0x263238
}, {
duration: 150
});
}
});
LK.getSound('enemyHit').play();
return self.health <= 0;
};
return self;
});
var SuperTankBossObsidianEnemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Override graphics with obsidian tank boss appearance
self.children[0].destroy();
var enemyGraphics = self.attachAsset('obcidiaa', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.0,
scaleY: 3.0
});
enemyGraphics.tint = 0x1a1a1a; // Very dark color for obsidian tank boss
self.health = 6000; // Extremely high health
self.maxHealth = 6000;
self.speed = 0.2; // Extremely slow due to obsidian armor
self.reward = 500; // Highest reward for ultimate difficulty
self.armor = 0.9; // Takes 90% less damage from all sources
// Override takeDamage to apply armor reduction
self.takeDamage = function (damage) {
var reducedDamage = Math.max(1, Math.floor(damage * (1 - self.armor)));
self.health -= reducedDamage;
// Flash purple when hit with special obsidian effect
tween(self.children[0], {
tint: 0x9C27B0
}, {
duration: 250,
onFinish: function onFinish() {
tween(self.children[0], {
tint: 0x1a1a1a
}, {
duration: 250
});
}
});
LK.getSound('enemyHit').play();
return self.health <= 0;
};
return self;
});
var SuperTankBossArmorEnemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Override graphics with armor tank boss appearance
self.children[0].destroy();
var enemyGraphics = self.attachAsset('armor', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.5
});
enemyGraphics.tint = 0x424242; // Dark grey color for armor tank boss
self.health = 4000; // Very high health
self.maxHealth = 4000;
self.speed = 0.25; // Very slow due to heavy armor
self.reward = 300; // Very high reward for extreme difficulty
self.armor = 0.8; // Takes 80% less damage from all sources
// Override takeDamage to apply armor reduction
self.takeDamage = function (damage) {
var reducedDamage = Math.max(1, Math.floor(damage * (1 - self.armor)));
self.health -= reducedDamage;
// Flash red when hit with special armor effect
tween(self.children[0], {
tint: 0xFF0000
}, {
duration: 200,
onFinish: function onFinish() {
tween(self.children[0], {
tint: 0x424242
}, {
duration: 200
});
}
});
LK.getSound('enemyHit').play();
return self.health <= 0;
};
return self;
});
var SuperTankBoss2Enemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Override graphics with super tank boss appearance
self.children[0].destroy();
var enemyGraphics = self.attachAsset('super', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.5
});
enemyGraphics.tint = 0x8B0000; // Dark red color for super tank boss
self.health = 2000; // Extremely high health
self.maxHealth = 2000;
self.speed = 0.3; // Very slow due to massive armor
self.reward = 200; // Very high reward for extreme difficulty
self.armor = 0.7; // Takes 70% less damage from all sources
// Override takeDamage to apply armor reduction
self.takeDamage = function (damage) {
var reducedDamage = Math.max(1, Math.floor(damage * (1 - self.armor)));
self.health -= reducedDamage;
// Flash red when hit with special armor effect
tween(self.children[0], {
tint: 0xFF0000
}, {
duration: 200,
onFinish: function onFinish() {
tween(self.children[0], {
tint: 0x8B0000
}, {
duration: 200
});
}
});
LK.getSound('enemyHit').play();
return self.health <= 0;
};
return self;
});
var SkeletonEnemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Override graphics with skeleton appearance
self.children[0].destroy();
var enemyGraphics = self.attachAsset('skeleton', {
anchorX: 0.5,
anchorY: 0.5
});
enemyGraphics.tint = 0xf5f5f5; // Light grey/white color for skeleton
self.health = 1;
self.maxHealth = 1;
self.speed = 2.5; // Slightly faster than normal enemy
self.reward = 8; // Lower reward since they come in groups
return self;
});
var PigEnemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Override graphics with pig enemy asset
self.children[0].destroy();
var enemyGraphics = self.attachAsset('pigEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.speed = 1.2; // Slightly slower than normal enemy
self.reward = 30; // High reward for very tough enemy
return self;
});
var MoleEnemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Override graphics with mole appearance
self.children[0].destroy();
var enemyGraphics = self.attachAsset('topo', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 5;
self.maxHealth = 5;
self.speed = 1.5;
self.reward = 25;
self.isInvulnerable = true; // Start invulnerable
self.pathProgress = 0; // Track progress along path (0 to 1)
self.vulnerabilityThreshold = 0.5; // Becomes vulnerable at 50% of path
// Override takeDamage to handle invulnerability
self.takeDamage = function (damage) {
if (self.isInvulnerable) {
return false; // No damage taken while invulnerable
}
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;
};
// Override update to handle vulnerability transition
var originalUpdate = self.update;
self.update = function () {
// Calculate progress along path
if (enemyPath.length > 1) {
self.pathProgress = self.pathIndex / (enemyPath.length - 1);
}
// Check if should become vulnerable
if (self.isInvulnerable && self.pathProgress >= self.vulnerabilityThreshold) {
self.isInvulnerable = false;
// Change graphics to vulnerable state
enemyGraphics.destroy();
enemyGraphics = self.attachAsset('topo2', {
anchorX: 0.5,
anchorY: 0.5
});
// Flash to indicate vulnerability change
tween(enemyGraphics, {
tint: 0x00FF00
}, {
duration: 300,
onFinish: function onFinish() {
tween(enemyGraphics, {
tint: 0xFFFFFF
}, {
duration: 300
});
}
});
}
// Call original update
originalUpdate.call(self);
};
return self;
});
var MageEnemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Override graphics with mage appearance
self.children[0].destroy();
var enemyGraphics = self.attachAsset('mage', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 4;
self.maxHealth = 4;
self.speed = 1.8;
self.reward = 20;
self.hasTeleported = false; // Track if mage has teleported
self.teleport = function () {
if (self.hasTeleported || self.pathIndex >= enemyPath.length - 2) {
return;
}
// Calculate teleport distance (jump forward 3-6 path points)
var teleportDistance = 3 + Math.floor(Math.random() * 4);
var newPathIndex = Math.min(self.pathIndex + teleportDistance, enemyPath.length - 1);
// Visual teleport effect - flash purple and disappear
tween(self.children[0], {
tint: 0x9c27b0,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.2
}, {
duration: 300,
onFinish: function onFinish() {
// Move to new position instantly
self.x = enemyPath[newPathIndex].x;
self.y = enemyPath[newPathIndex].y;
self.pathIndex = newPathIndex;
// Reappear with effect
tween(self.children[0], {
tint: 0xFFFFFF,
scaleX: 1.0,
scaleY: 1.0,
alpha: 1.0
}, {
duration: 300
});
}
});
self.hasTeleported = true;
};
// Override update to include teleport logic
var originalUpdate = self.update;
self.update = function () {
// Teleport immediately when the mage appears (after first update tick)
if (!self.hasTeleported && LK.ticks > 0) {
self.teleport();
}
originalUpdate.call(self);
};
return self;
});
var FastEnemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Override graphics with dedicated fast enemy asset
self.children[0].destroy();
var enemyGraphics = self.attachAsset('fastEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 2;
self.maxHealth = 2;
self.speed = 5; // Much faster than normal enemy
self.reward = 15; // Higher reward
return self;
});
var BossEnemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Override graphics with different color and much larger size
self.children[0].destroy();
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.5
});
enemyGraphics.tint = 0x000000; // Black color for boss
self.health = 15;
self.maxHealth = 15;
self.speed = 0.8; // Very slow but very tough
self.reward = 50; // High reward for boss
return self;
});
var ArmoredEnemy = Enemy.expand(function () {
var self = Enemy.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.2,
scaleY: 1.2
});
enemyGraphics.tint = 0x607d8b; // Blue-grey color for armor
self.health = 5;
self.maxHealth = 5;
self.speed = 1.5; // Slightly slower than normal enemy
self.reward = 20; // Higher reward for tougher enemy
return self;
});
var FreezeTower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('tower', {
anchorX: 0.5,
anchorY: 0.5
});
towerGraphics.tint = 0x00BCD4; // Cyan color for freeze tower
self.range = 2048; // Full screen range
self.freezeDuration = 600; // 10 seconds (10 * 60 ticks)
self.fireRate = 180; // Slower fire rate (3 seconds between shots)
self.lastShot = 0;
self.cost = 150;
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 && !enemy.isFrozen) {
closestDistance = distance;
closestEnemy = enemy;
}
}
return closestEnemy;
};
self.freezeEnemy = function (target) {
if (!self.canShoot()) {
return;
}
// Apply freeze effect
target.isFrozen = true;
target.originalSpeed = target.speed;
target.speed = 0; // Stop the enemy
target.freezeEndTick = LK.ticks + self.freezeDuration;
// Visual effect - tint enemy light blue
tween(target.children[0], {
tint: 0x87CEEB
}, {
duration: 300
});
self.lastShot = LK.ticks;
LK.getSound('shoot').play();
};
self.update = function () {
var target = self.findTarget();
if (target) {
self.freezeEnemy(target);
}
};
return self;
});
var HeavyTower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('heavyTower', {
anchorX: 0.5,
anchorY: 0.5
});
towerGraphics.tint = 0x795548; // Brown color for heavy tower
self.range = 180;
self.damage = 15; // High damage
self.fireRate = 300; // Very slow fire rate (5 seconds)
self.lastShot = 0;
self.cost = 150;
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;
});
var LongRangeTower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('longRangeTower', {
anchorX: 0.5,
anchorY: 0.5
});
self.range = 2732; // Full screen range (height of screen)
self.damage = 2;
self.fireRate = 90; // Moderate fire rate
self.lastShot = 0;
self.cost = 110;
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;
});
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 RapidTower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('tower', {
anchorX: 0.5,
anchorY: 0.5
});
towerGraphics.tint = 0x2196F3; // Blue color for rapid tower
self.range = 200; // Increased range
self.damage = 1; // Low damage but very fast
self.fireRate = 15; // Very fast fire rate
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.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;
});
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 SuperCannon = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('tower', {
anchorX: 0.5,
anchorY: 0.5
});
towerGraphics.tint = 0xFF5722; // Red/orange color for super cannon
self.range = 280; // Long range
self.damage = 3; // Lower damage per target but area effect
self.areaDamage = 120; // Large area damage radius
self.fireRate = 120; // Slower fire rate due to area effect
self.lastShot = 0;
self.cost = 500;
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.5,
scaleY: 2.5,
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Damage all enemies in large 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 SuperTower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('superTower', {
anchorX: 0.5,
anchorY: 0.5
});
towerGraphics.tint = 0x9c27b0; // Purple color for super tower
self.range = 250;
self.damage = 200; // Extreme damage
self.hasFiredThisWave = false;
self.lastWave = 0;
self.cost = 300;
self.canShoot = function () {
// Check if it's a new wave
if (currentWave > self.lastWave) {
self.hasFiredThisWave = false;
self.lastWave = currentWave;
}
return !self.hasFiredThisWave && waveInProgress;
};
self.findTarget = function () {
var strongestEnemy = null;
var highestHealth = 0;
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 && enemy.health > highestHealth) {
highestHealth = enemy.health;
strongestEnemy = enemy;
}
}
return strongestEnemy;
};
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.hasFiredThisWave = true;
// Special visual effect for super shot
tween(towerGraphics, {
scaleX: 1.5,
scaleY: 1.5,
tint: 0xFFFFFF
}, {
duration: 200,
onFinish: function onFinish() {
tween(towerGraphics, {
scaleX: 1.0,
scaleY: 1.0,
tint: 0x9c27b0
}, {
duration: 200
});
}
});
LK.getSound('shoot').play();
};
self.update = function () {
var target = self.findTarget();
if (target) {
self.shoot(target);
}
};
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;
var gameStarted = false;
var showingWaveSelect = false;
var selectedStartWave = 1;
var sandboxMode = false;
var showingEnemyShop = false;
// Game arrays
var towers = [];
var enemies = [];
var bullets = [];
var pathSegments = [];
// 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)) / 80);
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;
pathSegments.push(pathSegment);
}
}
// 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('OLEADA: ' + 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);
// Tower shop layout - 3 towers per row with increased spacing
// Row 1: Basic, Slow, Area
var basicTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x - 200,
y: shopPanel.y - 350
}));
basicTowerBtn.visible = false;
var basicTowerText = new Text2('Basic Tower\n$50', {
size: 25,
fill: 0xFFFFFF
});
basicTowerText.anchor.set(0.5, 0.5);
basicTowerText.x = basicTowerBtn.x;
basicTowerText.y = basicTowerBtn.y;
game.addChild(basicTowerText);
var slowTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x,
y: shopPanel.y - 350,
color: 0x2196f3
}));
slowTowerBtn.visible = false;
var slowTowerText = new Text2('Slow Tower\n$75', {
size: 25,
fill: 0xFFFFFF
});
slowTowerText.anchor.set(0.5, 0.5);
slowTowerText.x = slowTowerBtn.x;
slowTowerText.y = slowTowerBtn.y;
game.addChild(slowTowerText);
var areaTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x + 200,
y: shopPanel.y - 350,
color: 0xff9800
}));
areaTowerBtn.visible = false;
var areaTowerText = new Text2('Area Tower\n$100', {
size: 25,
fill: 0xFFFFFF
});
areaTowerText.anchor.set(0.5, 0.5);
areaTowerText.x = areaTowerBtn.x;
areaTowerText.y = areaTowerBtn.y;
game.addChild(areaTowerText);
// Row 2: Poison, Long Range, Heavy
var poisonTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x - 200,
y: shopPanel.y - 150,
color: 0x4caf50
}));
poisonTowerBtn.visible = false;
var poisonTowerText = new Text2('Poison Tower\n$80', {
size: 25,
fill: 0xFFFFFF
});
poisonTowerText.anchor.set(0.5, 0.5);
poisonTowerText.x = poisonTowerBtn.x;
poisonTowerText.y = poisonTowerBtn.y;
game.addChild(poisonTowerText);
var longRangeTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x,
y: shopPanel.y - 150,
color: 0x607d8b
}));
longRangeTowerBtn.visible = false;
var longRangeTowerText = new Text2('Long Range\n$110', {
size: 25,
fill: 0xFFFFFF
});
longRangeTowerText.anchor.set(0.5, 0.5);
longRangeTowerText.x = longRangeTowerBtn.x;
longRangeTowerText.y = longRangeTowerBtn.y;
game.addChild(longRangeTowerText);
var heavyTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x + 200,
y: shopPanel.y - 150,
color: 0x795548
}));
heavyTowerBtn.visible = false;
var heavyTowerText = new Text2('Heavy Tower\n$150', {
size: 25,
fill: 0xFFFFFF
});
heavyTowerText.anchor.set(0.5, 0.5);
heavyTowerText.x = heavyTowerBtn.x;
heavyTowerText.y = heavyTowerBtn.y;
game.addChild(heavyTowerText);
// Row 3: Super Tower (centered)
var superTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x,
y: shopPanel.y + 50,
color: 0x9c27b0
}));
superTowerBtn.visible = false;
var superTowerText = new Text2('Super Tower\n$300', {
size: 25,
fill: 0xFFFFFF
});
superTowerText.anchor.set(0.5, 0.5);
superTowerText.x = superTowerBtn.x;
superTowerText.y = superTowerBtn.y;
game.addChild(superTowerText);
// Row 4: New towers
var doubleCannonBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x - 200,
y: shopPanel.y + 200,
color: 0x795548
}));
doubleCannonBtn.visible = false;
var doubleCannonText = new Text2('Doble Cañón\n$500', {
size: 25,
fill: 0xFFFFFF
});
doubleCannonText.anchor.set(0.5, 0.5);
doubleCannonText.x = doubleCannonBtn.x;
doubleCannonText.y = doubleCannonBtn.y;
game.addChild(doubleCannonText);
var superCannonBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x,
y: shopPanel.y + 200,
color: 0xFF5722
}));
superCannonBtn.visible = false;
var superCannonText = new Text2('Super Cañón\n$500', {
size: 25,
fill: 0xFFFFFF
});
superCannonText.anchor.set(0.5, 0.5);
superCannonText.x = superCannonBtn.x;
superCannonText.y = superCannonBtn.y;
game.addChild(superCannonText);
var rapidTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x + 200,
y: shopPanel.y + 200,
color: 0x2196F3
}));
rapidTowerBtn.visible = false;
var rapidTowerText = new Text2('Torre Rápida\n$100', {
size: 25,
fill: 0xFFFFFF
});
rapidTowerText.anchor.set(0.5, 0.5);
rapidTowerText.x = rapidTowerBtn.x;
rapidTowerText.y = rapidTowerBtn.y;
game.addChild(rapidTowerText);
// Row 5: Freeze Tower
var freezeTowerBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x - 100,
y: shopPanel.y + 350,
color: 0x00BCD4
}));
freezeTowerBtn.visible = false;
var freezeTowerText = new Text2('Torre Hielo\n$150', {
size: 25,
fill: 0xFFFFFF
});
freezeTowerText.anchor.set(0.5, 0.5);
freezeTowerText.x = freezeTowerBtn.x;
freezeTowerText.y = freezeTowerBtn.y;
game.addChild(freezeTowerText);
// Close shop button
var closeShopBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x + 100,
y: shopPanel.y + 350,
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);
// Start Menu Elements
var startMenuTitle = new Text2('TOWER DEFENSE', {
size: 80,
fill: 0xFFFFFF
});
startMenuTitle.anchor.set(0.5, 0.5);
startMenuTitle.x = 1024;
startMenuTitle.y = 800;
game.addChild(startMenuTitle);
var playBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200,
color: 0x4CAF50,
scaleX: 1.5,
scaleY: 1.5
}));
var playBtnText = new Text2('JUGAR', {
size: 40,
fill: 0xFFFFFF
});
playBtnText.anchor.set(0.5, 0.5);
playBtnText.x = playBtn.x;
playBtnText.y = playBtn.y;
game.addChild(playBtnText);
var waveSelectBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1450,
color: 0x2196F3,
scaleX: 1.5,
scaleY: 1.5
}));
var waveSelectBtnText = new Text2('ELEGIR OLEADA', {
size: 35,
fill: 0xFFFFFF
});
waveSelectBtnText.anchor.set(0.5, 0.5);
waveSelectBtnText.x = waveSelectBtn.x;
waveSelectBtnText.y = waveSelectBtn.y;
game.addChild(waveSelectBtnText);
// Wave Selection Menu Elements
var waveSelectTitle = new Text2('ELEGIR OLEADA INICIAL', {
size: 60,
fill: 0xFFFFFF
});
waveSelectTitle.anchor.set(0.5, 0.5);
waveSelectTitle.x = 1024;
waveSelectTitle.y = 600;
waveSelectTitle.visible = false;
game.addChild(waveSelectTitle);
var waveMinusBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 700,
y: 1200,
color: 0xFF5722,
width: 100,
height: 100
}));
waveMinusBtn.visible = false;
var waveMinusText = new Text2('-', {
size: 60,
fill: 0xFFFFFF
});
waveMinusText.anchor.set(0.5, 0.5);
waveMinusText.x = waveMinusBtn.x;
waveMinusText.y = waveMinusBtn.y;
waveMinusText.visible = false;
game.addChild(waveMinusText);
var waveDisplayText = new Text2('Oleada: ' + selectedStartWave, {
size: 50,
fill: 0xFFFFFF
});
waveDisplayText.anchor.set(0.5, 0.5);
waveDisplayText.x = 1024;
waveDisplayText.y = 1200;
waveDisplayText.visible = false;
game.addChild(waveDisplayText);
var wavePlusBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1348,
y: 1200,
color: 0x4CAF50,
width: 100,
height: 100
}));
wavePlusBtn.visible = false;
var wavePlusText = new Text2('+', {
size: 60,
fill: 0xFFFFFF
});
wavePlusText.anchor.set(0.5, 0.5);
wavePlusText.x = wavePlusBtn.x;
wavePlusText.y = wavePlusBtn.y;
wavePlusText.visible = false;
game.addChild(wavePlusText);
var startGameBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1500,
color: 0x4CAF50,
scaleX: 1.5,
scaleY: 1.5
}));
startGameBtn.visible = false;
var startGameBtnText = new Text2('COMENZAR', {
size: 40,
fill: 0xFFFFFF
});
startGameBtnText.anchor.set(0.5, 0.5);
startGameBtnText.x = startGameBtn.x;
startGameBtnText.y = startGameBtn.y;
startGameBtnText.visible = false;
game.addChild(startGameBtnText);
var sandboxBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1700,
color: 0xFFC107,
scaleX: 1.5,
scaleY: 1.5
}));
var sandboxBtnText = new Text2('SANDBOX', {
size: 40,
fill: 0xFFFFFF
});
sandboxBtnText.anchor.set(0.5, 0.5);
sandboxBtnText.x = sandboxBtn.x;
sandboxBtnText.y = sandboxBtn.y;
game.addChild(sandboxBtnText);
var backBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1800,
color: 0x795548
}));
backBtn.visible = false;
var backBtnText = new Text2('VOLVER', {
size: 30,
fill: 0xFFFFFF
});
backBtnText.anchor.set(0.5, 0.5);
backBtnText.x = backBtn.x;
backBtnText.y = backBtn.y;
backBtnText.visible = false;
game.addChild(backBtnText);
// Enemy Shop Panel for Sandbox Mode
var enemyShopPanel = game.addChild(LK.getAsset('shopPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
enemyShopPanel.visible = false;
var enemyShopTitle = new Text2('ENEMY SHOP', {
size: 50,
fill: 0xFFFFFF
});
enemyShopTitle.anchor.set(0.5, 0);
enemyShopTitle.x = enemyShopPanel.x;
enemyShopTitle.y = enemyShopPanel.y - 450;
enemyShopTitle.visible = false;
game.addChild(enemyShopTitle);
// Enemy buttons - Row 1
var spawnEnemyBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x - 200,
y: enemyShopPanel.y - 350,
color: 0x4CAF50
}));
spawnEnemyBtn.visible = false;
var spawnEnemyText = new Text2('Basic Enemy', {
size: 25,
fill: 0xFFFFFF
});
spawnEnemyText.anchor.set(0.5, 0.5);
spawnEnemyText.x = spawnEnemyBtn.x;
spawnEnemyText.y = spawnEnemyBtn.y;
spawnEnemyText.visible = false;
game.addChild(spawnEnemyText);
var spawnFastBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x,
y: enemyShopPanel.y - 350,
color: 0x2196F3
}));
spawnFastBtn.visible = false;
var spawnFastText = new Text2('Fast Enemy', {
size: 25,
fill: 0xFFFFFF
});
spawnFastText.anchor.set(0.5, 0.5);
spawnFastText.x = spawnFastBtn.x;
spawnFastText.y = spawnFastBtn.y;
spawnFastText.visible = false;
game.addChild(spawnFastText);
var spawnTankBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x + 200,
y: enemyShopPanel.y - 350,
color: 0x9C27B0
}));
spawnTankBtn.visible = false;
var spawnTankText = new Text2('Tank Enemy', {
size: 25,
fill: 0xFFFFFF
});
spawnTankText.anchor.set(0.5, 0.5);
spawnTankText.x = spawnTankBtn.x;
spawnTankText.y = spawnTankBtn.y;
spawnTankText.visible = false;
game.addChild(spawnTankText);
// Enemy buttons - Row 2
var spawnBossBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x - 200,
y: enemyShopPanel.y - 150,
color: 0x000000
}));
spawnBossBtn.visible = false;
var spawnBossText = new Text2('Boss Enemy', {
size: 25,
fill: 0xFFFFFF
});
spawnBossText.anchor.set(0.5, 0.5);
spawnBossText.x = spawnBossBtn.x;
spawnBossText.y = spawnBossBtn.y;
spawnBossText.visible = false;
game.addChild(spawnBossText);
var spawnMageBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x,
y: enemyShopPanel.y - 150,
color: 0x795548
}));
spawnMageBtn.visible = false;
var spawnMageText = new Text2('Mage Enemy', {
size: 25,
fill: 0xFFFFFF
});
spawnMageText.anchor.set(0.5, 0.5);
spawnMageText.x = spawnMageBtn.x;
spawnMageText.y = spawnMageBtn.y;
spawnMageText.visible = false;
game.addChild(spawnMageText);
var spawnTankBossBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x + 200,
y: enemyShopPanel.y - 150,
color: 0x263238
}));
spawnTankBossBtn.visible = false;
var spawnTankBossText = new Text2('Tank Boss', {
size: 25,
fill: 0xFFFFFF
});
spawnTankBossText.anchor.set(0.5, 0.5);
spawnTankBossText.x = spawnTankBossBtn.x;
spawnTankBossText.y = spawnTankBossBtn.y;
spawnTankBossText.visible = false;
game.addChild(spawnTankBossText);
// Enemy buttons - Row 3
var spawnArmoredBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x - 200,
y: enemyShopPanel.y + 50,
color: 0x607d8b
}));
spawnArmoredBtn.visible = false;
var spawnArmoredText = new Text2('Armored', {
size: 25,
fill: 0xFFFFFF
});
spawnArmoredText.anchor.set(0.5, 0.5);
spawnArmoredText.x = spawnArmoredBtn.x;
spawnArmoredText.y = spawnArmoredBtn.y;
spawnArmoredText.visible = false;
game.addChild(spawnArmoredText);
var spawnPigBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x,
y: enemyShopPanel.y + 50,
color: 0xE91E63
}));
spawnPigBtn.visible = false;
var spawnPigText = new Text2('Pig Enemy', {
size: 25,
fill: 0xFFFFFF
});
spawnPigText.anchor.set(0.5, 0.5);
spawnPigText.x = spawnPigBtn.x;
spawnPigText.y = spawnPigBtn.y;
spawnPigText.visible = false;
game.addChild(spawnPigText);
var spawnMoleBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x + 200,
y: enemyShopPanel.y + 50,
color: 0x8D6E63
}));
spawnMoleBtn.visible = false;
var spawnMoleText = new Text2('Mole Enemy', {
size: 25,
fill: 0xFFFFFF
});
spawnMoleText.anchor.set(0.5, 0.5);
spawnMoleText.x = spawnMoleBtn.x;
spawnMoleText.y = spawnMoleBtn.y;
spawnMoleText.visible = false;
game.addChild(spawnMoleText);
// Enemy buttons - Row 4
var spawnSkeletonBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x - 200,
y: enemyShopPanel.y + 200,
color: 0xF5F5F5
}));
spawnSkeletonBtn.visible = false;
var spawnSkeletonText = new Text2('Skeleton', {
size: 25,
fill: 0x000000
});
spawnSkeletonText.anchor.set(0.5, 0.5);
spawnSkeletonText.x = spawnSkeletonBtn.x;
spawnSkeletonText.y = spawnSkeletonBtn.y;
spawnSkeletonText.visible = false;
game.addChild(spawnSkeletonText);
var spawnSuperTank2Btn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x,
y: enemyShopPanel.y + 200,
color: 0x8B0000
}));
spawnSuperTank2Btn.visible = false;
var spawnSuperTank2Text = new Text2('Super Tank2', {
size: 22,
fill: 0xFFFFFF
});
spawnSuperTank2Text.anchor.set(0.5, 0.5);
spawnSuperTank2Text.x = spawnSuperTank2Btn.x;
spawnSuperTank2Text.y = spawnSuperTank2Btn.y;
spawnSuperTank2Text.visible = false;
game.addChild(spawnSuperTank2Text);
var spawnArmorBossBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x + 200,
y: enemyShopPanel.y + 200,
color: 0x424242
}));
spawnArmorBossBtn.visible = false;
var spawnArmorBossText = new Text2('Armor Boss', {
size: 22,
fill: 0xFFFFFF
});
spawnArmorBossText.anchor.set(0.5, 0.5);
spawnArmorBossText.x = spawnArmorBossBtn.x;
spawnArmorBossText.y = spawnArmorBossBtn.y;
spawnArmorBossText.visible = false;
game.addChild(spawnArmorBossText);
// Enemy buttons - Row 5
var spawnObsidianBossBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x - 100,
y: enemyShopPanel.y + 350,
color: 0x1a1a1a
}));
spawnObsidianBossBtn.visible = false;
var spawnObsidianBossText = new Text2('Obsidian Boss', {
size: 20,
fill: 0xFFFFFF
});
spawnObsidianBossText.anchor.set(0.5, 0.5);
spawnObsidianBossText.x = spawnObsidianBossBtn.x;
spawnObsidianBossText.y = spawnObsidianBossBtn.y;
spawnObsidianBossText.visible = false;
game.addChild(spawnObsidianBossText);
// Enemy Shop close button
var closeEnemyShopBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: enemyShopPanel.x + 100,
y: enemyShopPanel.y + 350,
color: 0xFF5722
}));
closeEnemyShopBtn.visible = false;
var closeEnemyShopText = new Text2('CLOSE', {
size: 30,
fill: 0xFFFFFF
});
closeEnemyShopText.anchor.set(0.5, 0.5);
closeEnemyShopText.x = closeEnemyShopBtn.x;
closeEnemyShopText.y = closeEnemyShopBtn.y;
closeEnemyShopText.visible = false;
game.addChild(closeEnemyShopText);
// Sandbox UI elements
var enemyShopBtn = game.addChild(LK.getAsset('shopButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 800,
y: 2500,
color: 0xFFC107
}));
enemyShopBtn.visible = false;
var enemyShopBtnText = new Text2('ENEMIES', {
size: 40,
fill: 0xFFFFFF
});
enemyShopBtnText.anchor.set(0.5, 0.5);
enemyShopBtnText.x = enemyShopBtn.x;
enemyShopBtnText.y = enemyShopBtn.y;
enemyShopBtnText.visible = false;
game.addChild(enemyShopBtnText);
// Functions
function hideStartMenu() {
startMenuTitle.visible = false;
playBtn.visible = false;
playBtnText.visible = false;
waveSelectBtn.visible = false;
waveSelectBtnText.visible = false;
sandboxBtn.visible = false;
sandboxBtnText.visible = false;
}
function showStartMenu() {
startMenuTitle.visible = true;
playBtn.visible = true;
playBtnText.visible = true;
waveSelectBtn.visible = true;
waveSelectBtnText.visible = true;
sandboxBtn.visible = true;
sandboxBtnText.visible = true;
}
function hideWaveSelect() {
waveSelectTitle.visible = false;
waveMinusBtn.visible = false;
waveMinusText.visible = false;
waveDisplayText.visible = false;
wavePlusBtn.visible = false;
wavePlusText.visible = false;
startGameBtn.visible = false;
startGameBtnText.visible = false;
backBtn.visible = false;
backBtnText.visible = false;
}
function showWaveSelect() {
waveSelectTitle.visible = true;
waveMinusBtn.visible = true;
waveMinusText.visible = true;
waveDisplayText.visible = true;
wavePlusBtn.visible = true;
wavePlusText.visible = true;
startGameBtn.visible = true;
startGameBtnText.visible = true;
backBtn.visible = true;
backBtnText.visible = true;
}
function updateWaveDisplay() {
waveDisplayText.setText('Oleada: ' + selectedStartWave);
}
function toggleEnemyShop() {
showingEnemyShop = !showingEnemyShop;
enemyShopPanel.visible = showingEnemyShop;
enemyShopTitle.visible = showingEnemyShop;
spawnEnemyBtn.visible = showingEnemyShop;
spawnEnemyText.visible = showingEnemyShop;
spawnFastBtn.visible = showingEnemyShop;
spawnFastText.visible = showingEnemyShop;
spawnTankBtn.visible = showingEnemyShop;
spawnTankText.visible = showingEnemyShop;
spawnBossBtn.visible = showingEnemyShop;
spawnBossText.visible = showingEnemyShop;
spawnMageBtn.visible = showingEnemyShop;
spawnMageText.visible = showingEnemyShop;
spawnTankBossBtn.visible = showingEnemyShop;
spawnTankBossText.visible = showingEnemyShop;
spawnArmoredBtn.visible = showingEnemyShop;
spawnArmoredText.visible = showingEnemyShop;
spawnPigBtn.visible = showingEnemyShop;
spawnPigText.visible = showingEnemyShop;
spawnMoleBtn.visible = showingEnemyShop;
spawnMoleText.visible = showingEnemyShop;
spawnSkeletonBtn.visible = showingEnemyShop;
spawnSkeletonText.visible = showingEnemyShop;
spawnSuperTank2Btn.visible = showingEnemyShop;
spawnSuperTank2Text.visible = showingEnemyShop;
spawnArmorBossBtn.visible = showingEnemyShop;
spawnArmorBossText.visible = showingEnemyShop;
spawnObsidianBossBtn.visible = showingEnemyShop;
spawnObsidianBossText.visible = showingEnemyShop;
closeEnemyShopBtn.visible = showingEnemyShop;
closeEnemyShopText.visible = showingEnemyShop;
}
function startSandboxMode() {
gameStarted = true;
sandboxMode = true;
playerMoney = 999999; // Infinite money
hideStartMenu();
hideWaveSelect();
showingWaveSelect = false;
updateWaveDisplay();
updateMoneyDisplay();
}
function spawnEnemy(enemyType) {
var enemy;
switch (enemyType) {
case 'basic':
enemy = new Enemy();
break;
case 'fast':
enemy = new FastEnemy();
break;
case 'tank':
enemy = new TankEnemy();
break;
case 'boss':
enemy = new BossEnemy();
break;
case 'mage':
enemy = new MageEnemy();
break;
case 'tankboss':
enemy = new TankBossEnemy();
break;
case 'armored':
enemy = new ArmoredEnemy();
break;
case 'pig':
enemy = new PigEnemy();
break;
case 'mole':
enemy = new MoleEnemy();
break;
case 'skeleton':
enemy = new SkeletonEnemy();
break;
case 'supertank2':
enemy = new SuperTankBoss2Enemy();
break;
case 'armorboss':
enemy = new SuperTankBossArmorEnemy();
break;
case 'obsidianboss':
enemy = new SuperTankBossObsidianEnemy();
break;
default:
enemy = new Enemy();
}
enemy.x = enemyPath[0].x;
enemy.y = enemyPath[0].y;
enemies.push(enemy);
game.addChild(enemy);
}
function startGame() {
gameStarted = true;
currentWave = selectedStartWave;
hideStartMenu();
hideWaveSelect();
showingWaveSelect = false;
updateWaveDisplay();
}
function updateMoneyDisplay() {
moneyText.setText('Money: $' + playerMoney);
}
function updateLivesDisplay() {
livesText.setText('Lives: ' + playerLives);
}
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;
longRangeTowerBtn.visible = shopOpen;
longRangeTowerText.visible = shopOpen;
heavyTowerBtn.visible = shopOpen;
heavyTowerText.visible = shopOpen;
superTowerBtn.visible = shopOpen;
superTowerText.visible = shopOpen;
doubleCannonBtn.visible = shopOpen;
doubleCannonText.visible = shopOpen;
superCannonBtn.visible = shopOpen;
superCannonText.visible = shopOpen;
rapidTowerBtn.visible = shopOpen;
rapidTowerText.visible = shopOpen;
freezeTowerBtn.visible = shopOpen;
freezeTowerText.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();
// Calculate increased spawn rates for rare enemies after wave 11
var waveMultiplier = currentWave > 11 ? Math.min(2.0, 1 + (currentWave - 11) * 0.1) : 1;
var superTankBossObsidianChance = currentWave >= 25 ? 0.003 * Math.max(1, (currentWave - 25) * 0.05) : 0; // Very low chance starting at wave 25, increases each wave
var superTankBossArmorChance = currentWave >= 15 ? 0.005 * Math.max(1, (currentWave - 15) * 0.05) : 0; // Low chance starting at wave 15, increases each wave
var superTankBoss2Chance = currentWave >= 8 ? 0.005 * waveMultiplier : 0; // Very low chance, increases after wave 11
var tankBossChance = currentWave >= 10 ? 0.01 * waveMultiplier : 0;
var bossChance = currentWave >= 7 ? 0.05 * waveMultiplier : 0;
var pigChance = currentWave >= 6 ? 0.10 * waveMultiplier : 0;
var mageChance = currentWave >= 3 ? 0.12 * waveMultiplier : 0;
var armoredChance = currentWave >= 4 ? 0.15 * waveMultiplier : 0;
var moleChance = currentWave >= 3 ? 0.08 * waveMultiplier : 0;
var skeletonChance = currentWave >= 2 ? 0.10 * waveMultiplier : 0;
var fastChance = currentWave >= 2 ? 0.15 * waveMultiplier : 0;
var tankChance = currentWave >= 5 ? 0.17 * waveMultiplier : 0;
if (enemyType < superTankBossObsidianChance) {
// Super Tank Boss Obsidian enemy with very low chance starting at wave 25
enemy = new SuperTankBossObsidianEnemy();
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance) {
// Super Tank Boss Armor enemy with low chance starting at wave 15
enemy = new SuperTankBossArmorEnemy();
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance + superTankBoss2Chance) {
// Super Tank Boss 2 enemy with very low chance, increases after wave 11
enemy = new SuperTankBoss2Enemy();
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance + superTankBoss2Chance + tankBossChance) {
// Tank boss enemy with increased chance after wave 11
enemy = new TankBossEnemy();
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance + superTankBoss2Chance + tankBossChance + bossChance) {
// Boss enemy with increased chance after wave 11
enemy = new BossEnemy();
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance + superTankBoss2Chance + tankBossChance + bossChance + pigChance) {
// Pig enemy with increased chance after wave 11
enemy = new PigEnemy();
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance + superTankBoss2Chance + tankBossChance + bossChance + pigChance + mageChance) {
// Mage enemy with increased chance after wave 11
enemy = new MageEnemy();
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance + superTankBoss2Chance + tankBossChance + bossChance + pigChance + mageChance + armoredChance) {
// Armored enemy with increased chance after wave 11
enemy = new ArmoredEnemy();
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance + superTankBoss2Chance + tankBossChance + bossChance + pigChance + mageChance + armoredChance + moleChance) {
// Mole enemy with invulnerability until 50% of path
enemy = new MoleEnemy();
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance + superTankBoss2Chance + tankBossChance + bossChance + pigChance + mageChance + armoredChance + moleChance + skeletonChance) {
// Skeleton group with increased chance after wave 11
var skeletonCount = 3 + Math.floor(Math.random() * 3);
for (var j = 0; j < skeletonCount; j++) {
var skeleton = new SkeletonEnemy();
skeleton.x = enemyPath[0].x + (Math.random() - 0.5) * 40; // Slight random positioning
skeleton.y = enemyPath[0].y + (Math.random() - 0.5) * 40;
skeleton.health += Math.floor(currentWave / 4); // Slower health increase for skeletons
skeleton.maxHealth = skeleton.health;
enemies.push(skeleton);
game.addChild(skeleton);
}
return; // Skip the normal enemy spawn below
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance + superTankBoss2Chance + tankBossChance + bossChance + pigChance + mageChance + armoredChance + skeletonChance + fastChance) {
// Fast enemy with increased chance after wave 11
enemy = new FastEnemy();
} else if (enemyType < superTankBossObsidianChance + superTankBossArmorChance + superTankBoss2Chance + tankBossChance + bossChance + pigChance + mageChance + armoredChance + skeletonChance + fastChance + tankChance) {
// Tank enemy with increased chance after wave 11
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;
} else if (selectedTowerType === 'longrange') {
towerCost = 110;
} else if (selectedTowerType === 'heavy') {
towerCost = 150;
} else if (selectedTowerType === 'super') {
towerCost = 300;
} else if (selectedTowerType === 'doublecannon') {
towerCost = 500;
} else if (selectedTowerType === 'supercannon') {
towerCost = 500;
} else if (selectedTowerType === 'rapid') {
towerCost = 100;
} else if (selectedTowerType === 'freeze') {
towerCost = 150;
}
if (!placingTower || playerMoney < towerCost) {
return false;
}
// Check if position is valid (not on path)
for (var i = 0; i < pathSegments.length; i++) {
var pathSegment = pathSegments[i];
var dx = pathSegment.x - x;
var dy = pathSegment.y - y;
if (Math.sqrt(dx * dx + dy * dy) < 80) {
return false; // Too close to path
}
}
// Check if position is valid (not too close to 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 if (selectedTowerType === 'longrange') {
tower = new LongRangeTower();
} else if (selectedTowerType === 'heavy') {
tower = new HeavyTower();
} else if (selectedTowerType === 'super') {
tower = new SuperTower();
} else if (selectedTowerType === 'doublecannon') {
tower = new DoubleCannon();
} else if (selectedTowerType === 'supercannon') {
tower = new SuperCannon();
} else if (selectedTowerType === 'rapid') {
tower = new RapidTower();
} else if (selectedTowerType === 'freeze') {
tower = new FreezeTower();
} 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';
}
};
slowTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 75) {
placingTower = true;
selectedTowerType = 'slow';
}
};
areaTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 100) {
placingTower = true;
selectedTowerType = 'area';
}
};
poisonTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 80) {
placingTower = true;
selectedTowerType = 'poison';
}
};
longRangeTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 110) {
placingTower = true;
selectedTowerType = 'longrange';
}
};
heavyTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 150) {
placingTower = true;
selectedTowerType = 'heavy';
}
};
superTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 300) {
placingTower = true;
selectedTowerType = 'super';
}
};
doubleCannonBtn.down = function (x, y, obj) {
if (playerMoney >= 500) {
placingTower = true;
selectedTowerType = 'doublecannon';
}
};
superCannonBtn.down = function (x, y, obj) {
if (playerMoney >= 500) {
placingTower = true;
selectedTowerType = 'supercannon';
}
};
rapidTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 100) {
placingTower = true;
selectedTowerType = 'rapid';
}
};
freezeTowerBtn.down = function (x, y, obj) {
if (playerMoney >= 150) {
placingTower = true;
selectedTowerType = 'freeze';
}
};
closeShopBtn.down = function (x, y, obj) {
toggleShop();
};
// Start Menu Event Handlers
playBtn.down = function (x, y, obj) {
if (!gameStarted) {
startGame();
}
};
waveSelectBtn.down = function (x, y, obj) {
if (!gameStarted) {
hideStartMenu();
showWaveSelect();
showingWaveSelect = true;
}
};
waveMinusBtn.down = function (x, y, obj) {
if (showingWaveSelect && selectedStartWave > 1) {
selectedStartWave--;
updateWaveDisplay();
}
};
wavePlusBtn.down = function (x, y, obj) {
if (showingWaveSelect && selectedStartWave < 50) {
selectedStartWave++;
updateWaveDisplay();
}
};
startGameBtn.down = function (x, y, obj) {
if (showingWaveSelect) {
startGame();
}
};
backBtn.down = function (x, y, obj) {
if (showingWaveSelect) {
hideWaveSelect();
showStartMenu();
showingWaveSelect = false;
}
};
// Sandbox mode event handlers
sandboxBtn.down = function (x, y, obj) {
if (!gameStarted) {
startSandboxMode();
}
};
enemyShopBtn.down = function (x, y, obj) {
if (sandboxMode) {
toggleEnemyShop();
}
};
spawnEnemyBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('basic');
}
};
spawnFastBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('fast');
}
};
spawnTankBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('tank');
}
};
spawnBossBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('boss');
}
};
spawnMageBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('mage');
}
};
spawnTankBossBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('tankboss');
}
};
spawnArmoredBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('armored');
}
};
spawnPigBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('pig');
}
};
spawnMoleBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('mole');
}
};
spawnSkeletonBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('skeleton');
}
};
spawnSuperTank2Btn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('supertank2');
}
};
spawnArmorBossBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('armorboss');
}
};
spawnObsidianBossBtn.down = function (x, y, obj) {
if (sandboxMode) {
spawnEnemy('obsidianboss');
}
};
closeEnemyShopBtn.down = function (x, y, obj) {
if (sandboxMode) {
toggleEnemyShop();
}
};
// Initially hide game UI elements
moneyText.visible = false;
livesText.visible = false;
waveText.visible = false;
shopBtn.visible = false;
shopBtnText.visible = false;
readyBtn.visible = false;
readyBtnText.visible = false;
game.down = function (x, y, obj) {
// Don't handle game clicks if not started or in menu
if (!gameStarted || showingWaveSelect) {
return;
}
// Don't place towers if clicking on UI elements (shop area or buttons)
if (y > 2400) {
return; // Clicking in UI area at bottom
}
// Don't place towers if shop is open and clicking in shop area
if (shopOpen && x > 724 && x < 1324 && y > 866 && y < 1866) {
return; // Clicking inside shop panel
}
if (placingTower) {
placeTower(x, y);
} else {
// Check if clicking on an existing tower to remove it
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
var dx = tower.x - x;
var dy = tower.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If clicking within tower bounds (75px radius)
if (distance <= 75) {
// Refund the tower cost
playerMoney += tower.cost;
updateMoneyDisplay();
// Remove tower from game and array
tower.destroy();
towers.splice(i, 1);
return; // Exit after removing first tower found
}
}
}
};
game.up = function (x, y, obj) {
// Don't handle game clicks if not started or in menu
if (!gameStarted || showingWaveSelect) {
return;
}
// Double tap to cancel tower placement
if (placingTower && obj.doubleTap) {
placingTower = false;
selectedTowerType = null;
}
};
// Main game loop
game.update = function () {
// Don't update game logic if not started
if (!gameStarted) {
return;
}
// Show game UI when game starts
if (gameStarted && !moneyText.visible) {
moneyText.visible = true;
livesText.visible = !sandboxMode; // Hide lives in sandbox mode
waveText.visible = !sandboxMode; // Hide wave text in sandbox mode
shopBtn.visible = true;
shopBtnText.visible = true;
readyBtn.visible = !sandboxMode; // Hide ready button in sandbox mode
readyBtnText.visible = !sandboxMode;
enemyShopBtn.visible = sandboxMode; // Show enemy shop in sandbox mode
enemyShopBtnText.visible = sandboxMode;
updateWaveDisplay();
}
// 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 (only in normal mode)
if (!sandboxMode && playerLives <= 0) {
LK.showGameOver();
}
// Keep money infinite in sandbox mode
if (sandboxMode && playerMoney < 999999) {
playerMoney = 999999;
updateMoneyDisplay();
}
// Update lives display if changed
updateLivesDisplay();
// Check if wave is complete
checkWaveComplete();
// Game continues indefinitely - no win condition
}; ===================================================================
--- original.js
+++ change.js
@@ -1820,13 +1820,135 @@
spawnTankBossText.x = spawnTankBossBtn.x;
spawnTankBossText.y = spawnTankBossBtn.y;
spawnTankBossText.visible = false;
game.addChild(spawnTankBossText);
+// Enemy buttons - Row 3
+var spawnArmoredBtn = game.addChild(LK.getAsset('towerButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: enemyShopPanel.x - 200,
+ y: enemyShopPanel.y + 50,
+ color: 0x607d8b
+}));
+spawnArmoredBtn.visible = false;
+var spawnArmoredText = new Text2('Armored', {
+ size: 25,
+ fill: 0xFFFFFF
+});
+spawnArmoredText.anchor.set(0.5, 0.5);
+spawnArmoredText.x = spawnArmoredBtn.x;
+spawnArmoredText.y = spawnArmoredBtn.y;
+spawnArmoredText.visible = false;
+game.addChild(spawnArmoredText);
+var spawnPigBtn = game.addChild(LK.getAsset('towerButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: enemyShopPanel.x,
+ y: enemyShopPanel.y + 50,
+ color: 0xE91E63
+}));
+spawnPigBtn.visible = false;
+var spawnPigText = new Text2('Pig Enemy', {
+ size: 25,
+ fill: 0xFFFFFF
+});
+spawnPigText.anchor.set(0.5, 0.5);
+spawnPigText.x = spawnPigBtn.x;
+spawnPigText.y = spawnPigBtn.y;
+spawnPigText.visible = false;
+game.addChild(spawnPigText);
+var spawnMoleBtn = game.addChild(LK.getAsset('towerButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: enemyShopPanel.x + 200,
+ y: enemyShopPanel.y + 50,
+ color: 0x8D6E63
+}));
+spawnMoleBtn.visible = false;
+var spawnMoleText = new Text2('Mole Enemy', {
+ size: 25,
+ fill: 0xFFFFFF
+});
+spawnMoleText.anchor.set(0.5, 0.5);
+spawnMoleText.x = spawnMoleBtn.x;
+spawnMoleText.y = spawnMoleBtn.y;
+spawnMoleText.visible = false;
+game.addChild(spawnMoleText);
+// Enemy buttons - Row 4
+var spawnSkeletonBtn = game.addChild(LK.getAsset('towerButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: enemyShopPanel.x - 200,
+ y: enemyShopPanel.y + 200,
+ color: 0xF5F5F5
+}));
+spawnSkeletonBtn.visible = false;
+var spawnSkeletonText = new Text2('Skeleton', {
+ size: 25,
+ fill: 0x000000
+});
+spawnSkeletonText.anchor.set(0.5, 0.5);
+spawnSkeletonText.x = spawnSkeletonBtn.x;
+spawnSkeletonText.y = spawnSkeletonBtn.y;
+spawnSkeletonText.visible = false;
+game.addChild(spawnSkeletonText);
+var spawnSuperTank2Btn = game.addChild(LK.getAsset('towerButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: enemyShopPanel.x,
+ y: enemyShopPanel.y + 200,
+ color: 0x8B0000
+}));
+spawnSuperTank2Btn.visible = false;
+var spawnSuperTank2Text = new Text2('Super Tank2', {
+ size: 22,
+ fill: 0xFFFFFF
+});
+spawnSuperTank2Text.anchor.set(0.5, 0.5);
+spawnSuperTank2Text.x = spawnSuperTank2Btn.x;
+spawnSuperTank2Text.y = spawnSuperTank2Btn.y;
+spawnSuperTank2Text.visible = false;
+game.addChild(spawnSuperTank2Text);
+var spawnArmorBossBtn = game.addChild(LK.getAsset('towerButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: enemyShopPanel.x + 200,
+ y: enemyShopPanel.y + 200,
+ color: 0x424242
+}));
+spawnArmorBossBtn.visible = false;
+var spawnArmorBossText = new Text2('Armor Boss', {
+ size: 22,
+ fill: 0xFFFFFF
+});
+spawnArmorBossText.anchor.set(0.5, 0.5);
+spawnArmorBossText.x = spawnArmorBossBtn.x;
+spawnArmorBossText.y = spawnArmorBossBtn.y;
+spawnArmorBossText.visible = false;
+game.addChild(spawnArmorBossText);
+// Enemy buttons - Row 5
+var spawnObsidianBossBtn = game.addChild(LK.getAsset('towerButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: enemyShopPanel.x - 100,
+ y: enemyShopPanel.y + 350,
+ color: 0x1a1a1a
+}));
+spawnObsidianBossBtn.visible = false;
+var spawnObsidianBossText = new Text2('Obsidian Boss', {
+ size: 20,
+ fill: 0xFFFFFF
+});
+spawnObsidianBossText.anchor.set(0.5, 0.5);
+spawnObsidianBossText.x = spawnObsidianBossBtn.x;
+spawnObsidianBossText.y = spawnObsidianBossBtn.y;
+spawnObsidianBossText.visible = false;
+game.addChild(spawnObsidianBossText);
// Enemy Shop close button
var closeEnemyShopBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
- x: enemyShopPanel.x,
+ x: enemyShopPanel.x + 100,
y: enemyShopPanel.y + 350,
color: 0xFF5722
}));
closeEnemyShopBtn.visible = false;
@@ -1918,8 +2040,22 @@
spawnMageBtn.visible = showingEnemyShop;
spawnMageText.visible = showingEnemyShop;
spawnTankBossBtn.visible = showingEnemyShop;
spawnTankBossText.visible = showingEnemyShop;
+ spawnArmoredBtn.visible = showingEnemyShop;
+ spawnArmoredText.visible = showingEnemyShop;
+ spawnPigBtn.visible = showingEnemyShop;
+ spawnPigText.visible = showingEnemyShop;
+ spawnMoleBtn.visible = showingEnemyShop;
+ spawnMoleText.visible = showingEnemyShop;
+ spawnSkeletonBtn.visible = showingEnemyShop;
+ spawnSkeletonText.visible = showingEnemyShop;
+ spawnSuperTank2Btn.visible = showingEnemyShop;
+ spawnSuperTank2Text.visible = showingEnemyShop;
+ spawnArmorBossBtn.visible = showingEnemyShop;
+ spawnArmorBossText.visible = showingEnemyShop;
+ spawnObsidianBossBtn.visible = showingEnemyShop;
+ spawnObsidianBossText.visible = showingEnemyShop;
closeEnemyShopBtn.visible = showingEnemyShop;
closeEnemyShopText.visible = showingEnemyShop;
}
function startSandboxMode() {
@@ -1952,8 +2088,29 @@
break;
case 'tankboss':
enemy = new TankBossEnemy();
break;
+ case 'armored':
+ enemy = new ArmoredEnemy();
+ break;
+ case 'pig':
+ enemy = new PigEnemy();
+ break;
+ case 'mole':
+ enemy = new MoleEnemy();
+ break;
+ case 'skeleton':
+ enemy = new SkeletonEnemy();
+ break;
+ case 'supertank2':
+ enemy = new SuperTankBoss2Enemy();
+ break;
+ case 'armorboss':
+ enemy = new SuperTankBossArmorEnemy();
+ break;
+ case 'obsidianboss':
+ enemy = new SuperTankBossObsidianEnemy();
+ break;
default:
enemy = new Enemy();
}
enemy.x = enemyPath[0].x;
@@ -2332,8 +2489,43 @@
if (sandboxMode) {
spawnEnemy('tankboss');
}
};
+spawnArmoredBtn.down = function (x, y, obj) {
+ if (sandboxMode) {
+ spawnEnemy('armored');
+ }
+};
+spawnPigBtn.down = function (x, y, obj) {
+ if (sandboxMode) {
+ spawnEnemy('pig');
+ }
+};
+spawnMoleBtn.down = function (x, y, obj) {
+ if (sandboxMode) {
+ spawnEnemy('mole');
+ }
+};
+spawnSkeletonBtn.down = function (x, y, obj) {
+ if (sandboxMode) {
+ spawnEnemy('skeleton');
+ }
+};
+spawnSuperTank2Btn.down = function (x, y, obj) {
+ if (sandboxMode) {
+ spawnEnemy('supertank2');
+ }
+};
+spawnArmorBossBtn.down = function (x, y, obj) {
+ if (sandboxMode) {
+ spawnEnemy('armorboss');
+ }
+};
+spawnObsidianBossBtn.down = function (x, y, obj) {
+ if (sandboxMode) {
+ spawnEnemy('obsidianboss');
+ }
+};
closeEnemyShopBtn.down = function (x, y, obj) {
if (sandboxMode) {
toggleEnemyShop();
}
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