User prompt
aumenta el rango de la torre rapida y crea una torre que tarde un poco entre los disparos pero al disparar deja quieto al enemigo por 10 segudos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
crea una torre que dispare dos a la vez,haga mucho daño y dispare a distancia llamado doblecañon, vale 500, haz tambien una torre llamada supercañon que haga daño en area grade,que dispare a distacia y vale 500 y haz una torre que dispare a gran velocidad pero tenga poco alcanze,vale 100
User prompt
crea un enemigo que no reciba daño hasta el 50% del camino,cuando no reciba daño usa el assest topo y cuado ya puede recibir daño usa el assets topo2
User prompt
usa el assets "super" para el supertankboss2
User prompt
crea un menu de star con el play y otra opcion que sea eleguir de que ronda empezar
User prompt
crea a un super taknboss2 que tenga 2000 de vida y tenga pocas probabilidades de aparecer pero despues de la oleada 11 empieza a aumentar la probabilidad
User prompt
hay un problema,cuando clickeo los botones se ponen torres
User prompt
crea que si se preciona sobre una torre ya puesta se quite y te devuelva el dinero
User prompt
que el juego no termine que continue las oleadas y que despues de la oleada 11 cada vez los enemigos raros tengan mas posibilidades de aparecer
User prompt
que el mago se teletranporte mas adelante en el camino apenas aparezca ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
haz que el mago se traporte ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
separa mas la torres de la shop
User prompt
separa los torres de la shop que sean 3 por fila
User prompt
crea una torre que cueste 110 y dispare a distacia,llegado a toda la patalla y crea una torre que dispare y despues tarde e volver a disparar pero haga un gran daño y crea una torre que dispare 1 vez por wave pero haga un daño extremadamente alto ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
subele la vida al taknboss a 1000, al cerdo a 100 y al taknenemy a 40
User prompt
crea un enemigo que sea un mago y teletransporte mas adelante e el camino solo una vez y uno que se llame taknboss y tenga una resistencia extremadamente alta y salga de desencuado ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
crea un enemigo que es un mago y se trasporta mas adelante e el camino solo una vez y crea un enemigo llamado tankboss que tenga una resistecia extremadamente alta y salga de desencuado ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
crea otro enemigo que es mas rapido y uno que reciste mucho mas que se llame cerdo
User prompt
crea un nuevo tipo de enemigo que se llame esqueleto y vengan todos juntos
User prompt
crea otro tipo de enemigo llamado esqueletos que vienen todos juntos, tambien unos que sean mas rapidos y unos que sean mas lentos pero resistan mucho mas
User prompt
haz mas grade el camino de los enemigos y que no se pueda poner torres en el camino del enemigo
User prompt
crea a un enemigo un poco mas resistente y otro que solo aparesca de desencuando que resista mucho
User prompt
hay un pequeño problema,el menu de shop se muestra al principio aunque no le precione
User prompt
Please fix the bug: 'Timeout.tick error: Cannot read properties of undefined (reading 'destroy')' in or related to this line: 'self.children[0].destroy();' Line Number: 220
/****
* 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 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 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 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 - 4) {
return;
}
// Calculate teleport distance (30-50% of remaining path)
var remainingPath = enemyPath.length - self.pathIndex;
var teleportDistance = Math.floor(remainingPath * (0.3 + Math.random() * 0.2));
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: 200,
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: 200
});
}
});
self.hasTeleported = true;
};
// Override update to include teleport logic
var originalUpdate = self.update;
self.update = function () {
// Teleport when about 25% through the path
if (!self.hasTeleported && self.pathIndex >= Math.floor(enemyPath.length * 0.25)) {
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 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 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 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;
// 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);
// Close shop button
var closeShopBtn = game.addChild(LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5,
x: shopPanel.x,
y: shopPanel.y + 250,
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;
longRangeTowerBtn.visible = shopOpen;
longRangeTowerText.visible = shopOpen;
heavyTowerBtn.visible = shopOpen;
heavyTowerText.visible = shopOpen;
superTowerBtn.visible = shopOpen;
superTowerText.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 >= 10 && enemyType < 0.01) {
// 1% chance for tank boss enemy from wave 10+ (extremely rare)
enemy = new TankBossEnemy();
} else if (currentWave >= 7 && enemyType < 0.06) {
// 5% chance for boss enemy from wave 7+
enemy = new BossEnemy();
} else if (currentWave >= 6 && enemyType < 0.16) {
// 10% chance for pig enemy from wave 6+
enemy = new PigEnemy();
} else if (currentWave >= 3 && enemyType < 0.28) {
// 12% chance for mage enemy from wave 3+
enemy = new MageEnemy();
} else if (currentWave >= 4 && enemyType < 0.43) {
// 15% chance for armored enemy from wave 4+
enemy = new ArmoredEnemy();
} else if (currentWave >= 2 && enemyType < 0.53) {
// 10% chance for skeleton group from wave 2+
// Spawn 3-5 skeletons together
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 (currentWave >= 2 && enemyType < 0.68) {
// 15% chance for fast enemy from wave 2+
enemy = new FastEnemy();
} else if (currentWave >= 5 && enemyType < 0.85) {
// 17% chance for tank enemy from wave 5+
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;
}
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 {
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';
}
};
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
@@ -69,9 +69,11 @@
}
}
};
self.shoot = function (target) {
- if (!self.canShoot()) return;
+ if (!self.canShoot()) {
+ return;
+ }
self.explode(target.x, target.y);
self.lastShot = LK.ticks;
LK.getSound('shoot').play();
};
@@ -171,9 +173,11 @@
}
self.lastPoisonTick = LK.ticks;
}
}
- if (self.pathIndex >= enemyPath.length) return;
+ 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);
@@ -288,9 +292,11 @@
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 - 4) return;
+ if (self.hasTeleported || self.pathIndex >= enemyPath.length - 4) {
+ return;
+ }
// Calculate teleport distance (30-50% of remaining path)
var remainingPath = enemyPath.length - self.pathIndex;
var teleportDistance = Math.floor(remainingPath * (0.3 + Math.random() * 0.2));
var newPathIndex = Math.min(self.pathIndex + teleportDistance, enemyPath.length - 1);
@@ -409,9 +415,11 @@
}
return closestEnemy;
};
self.shoot = function (target) {
- if (!self.canShoot()) return;
+ if (!self.canShoot()) {
+ return;
+ }
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.target = target;
@@ -458,9 +466,11 @@
}
return closestEnemy;
};
self.shoot = function (target) {
- if (!self.canShoot()) return;
+ if (!self.canShoot()) {
+ return;
+ }
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.target = target;
@@ -506,9 +516,11 @@
}
return targetsInRange;
};
self.applyPoison = function () {
- if (!self.canShoot()) return;
+ if (!self.canShoot()) {
+ return;
+ }
var targets = self.findTargetsInRange();
for (var i = 0; i < targets.length; i++) {
var enemy = targets[i];
if (!enemy.isPoisoned) {
@@ -560,9 +572,11 @@
}
return targetsInRange;
};
self.applySlowEffect = function () {
- if (!self.canShoot()) return;
+ if (!self.canShoot()) {
+ return;
+ }
var targets = self.findTargetsInRange();
for (var i = 0; i < targets.length; i++) {
var enemy = targets[i];
if (!enemy.isSlowed) {
@@ -620,9 +634,11 @@
}
return strongestEnemy;
};
self.shoot = function (target) {
- if (!self.canShoot()) return;
+ if (!self.canShoot()) {
+ return;
+ }
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.target = target;
@@ -686,9 +702,11 @@
}
return closestEnemy;
};
self.shoot = function (target) {
- if (!self.canShoot()) return;
+ if (!self.canShoot()) {
+ return;
+ }
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.target = target;
@@ -834,9 +852,9 @@
livesText.anchor.set(0, 0);
livesText.x = 120;
livesText.y = 130;
LK.gui.topLeft.addChild(livesText);
-var waveText = new Text2('Wave: ' + currentWave, {
+var waveText = new Text2('OLEADA: ' + currentWave, {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(1, 0);
@@ -1050,9 +1068,11 @@
closeShopBtn.visible = shopOpen;
closeShopText.visible = shopOpen;
}
function startWave() {
- if (waveInProgress) return;
+ if (waveInProgress) {
+ return;
+ }
waveInProgress = true;
var enemiesToSpawn = 3 + currentWave;
var spawnDelay = 0;
for (var i = 0; i < enemiesToSpawn; i++) {
@@ -1117,10 +1137,24 @@
}
}
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;
- if (!placingTower || playerMoney < towerCost) return false;
+ 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;
+ }
+ 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;
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