User prompt
Quiero que agreges un mecánica de toca los cuadros para evitar los ataques agrega 4 ataques que aparezcan en el mapa para evitar la bomba atómica en la torre ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Crea una mecánica nueva y ingnobadora y arregla errores y reworkea animaciones ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Arregla errores y agregá mejoras
User prompt
Corrige errores
User prompt
No se agregó la lluvia de misiles
User prompt
Quiero que aleatoria mente allá una lluvia de misiles que dure 20segundos y que quite 5 de daño cada misil pero que muestre aviso
User prompt
Pero quita el viejo botón de curación y que el nuevo aparezca también solo cuando se active el secret Boos
User prompt
Please fix the bug: 'TypeError: healButton.setText is not a function' in or related to this line: 'healButton.setText('CURAR');' Line Number: 1941
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'setText')' in or related to this line: 'healButton.healText.setText('CURAR');' Line Number: 1941
User prompt
Quiero que el botón este alado del botón de escudo y tenga el mismo diseño y mecanica
User prompt
Agrega un botón de curación que aparece solo cuando se activa el secreto boos que cura 11 puntos de vida y que tenga enfriamiento de 6 segundos
User prompt
Directamente que no se acerque que ataque a la distancia
User prompt
Quiero que el jefe secreto quede en partes del mapa pero no se acerque de todo a la fortaleza
User prompt
Quiero que busque y arregles errores que tenga y mejor algunos aspectos para mejor jugabilidad
User prompt
Saca la cinemática al colisiónar en la torre
User prompt
Agrega la clase "sonido de diálogo" que suene cada que los personajes hablen en las cinemáticas
User prompt
Quiero que antes de la colisión aparezca una cinemática como la del inico pero con un enemigo que diga:nai Nai nai Nair ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agregar una explosión al colisiónar el avión con las torres ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Cambia la limpieza al colisionar a limpieza al cambiar de escenario
User prompt
Quiero que cambies lo de limpieza al colisionar para limpieza al cambiar de escenario
User prompt
Y quiero que también se limpie los soldados puestos por el jugador para dejar el escenario limpió
User prompt
Ok pero quiero que el avión impacte con Latorre directamente y que se detenga instaneamente la generación y visibilidad de los enemigos del escenario no alternativo y que solo sea visible el avion y quiero que el botón para cambiar de escenario aparezca 1 cada 20 segundos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: self.target.takeDamage is not a function' in or related to this line: 'self.target.takeDamage(self.damage);' Line Number: 1007
User prompt
La fortaleza tiene que cambiar a "fortaleza2" y el entorno sea gris y quiero que solo se genere "avión" y ningún otro enemigo
User prompt
Quiero que sea solo 1 avión y que al Estrellar con la fortaleza sea el fin del juego
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Avion = Container.expand(function () {
var self = Container.call(this);
var avionGraphics = self.attachAsset('avion', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
// Flight properties
self.speed = 3;
self.altitude = Math.random() * 200 + 100; // Random altitude
self.direction = Math.random() < 0.5 ? 1 : -1; // Random direction
self.bobAmount = 0;
self.bobSpeed = 0.05;
// Set initial position based on direction
if (self.direction > 0) {
self.x = -250; // Start from left
} else {
self.x = 2298; // Start from right
}
self.y = Math.random() * 800 + 200;
// Flip airplane if moving right to left
if (self.direction < 0) {
avionGraphics.scaleX = -1.5;
}
self.update = function () {
// Move directly toward fortress instead of horizontally
if (fortress) {
var dx = fortress.x - self.x;
var dy = fortress.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 250) {
// Move toward fortress
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
// Add bobbing motion for realistic flight
self.bobAmount += self.bobSpeed;
self.y += Math.sin(self.bobAmount) * 2;
// Slight rotation for banking effect
avionGraphics.rotation = Math.sin(self.bobAmount) * 0.1;
// Check collision with fortress
if (fortress) {
var fortressDist = Math.sqrt(Math.pow(fortress.x - self.x, 2) + Math.pow(fortress.y - self.y, 2));
if (fortressDist < 350 && !self.cinematicStarted) {
// Start pre-collision cinematic
self.cinematicStarted = true;
self.speed = 0; // Stop airplane movement
gameState = 'cinematic'; // Pause game
// Create enemy character for dialogue
var enemyCharacter = LK.getAsset('enemy', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 3.0,
scaleY: 3.0
});
enemyCharacter.x = 1024;
enemyCharacter.y = 1800;
game.addChild(enemyCharacter);
// Create dialogue box background
var dialogueBox = LK.getAsset('HealthBarBg', {
width: 1600,
height: 250,
anchorX: 0.5,
anchorY: 0.5
});
dialogueBox.x = 1024;
dialogueBox.y = 2200;
dialogueBox.tint = 0x222222;
game.addChild(dialogueBox);
// Create dialogue text
var dialogueText = new Text2('', {
size: 70,
fill: 0xFFFFFF
});
dialogueText.anchor.set(0.5, 0.5);
dialogueText.x = 1024;
dialogueText.y = 2200;
game.addChild(dialogueText);
// Animate enemy entering from bottom
tween(enemyCharacter, {
y: 1600
}, {
duration: 1000,
easing: tween.easeOut
});
// Start dialogue sequence after character is in position
LK.setTimeout(function () {
// Enemy speaks the dialogue
dialogueText.setText('Enemigo: "nai Nai nai Nair"');
tween(enemyCharacter, {
scaleX: 3.3,
scaleY: 3.3
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(enemyCharacter, {
scaleX: 3.0,
scaleY: 3.0
}, {
duration: 300,
easing: tween.easeIn
});
}
});
// After 2 seconds, fade out and continue collision
LK.setTimeout(function () {
// Fade out all cinematic elements
tween(enemyCharacter, {
alpha: 0
}, {
duration: 800,
easing: tween.easeOut
});
tween(dialogueBox, {
alpha: 0
}, {
duration: 800,
easing: tween.easeOut
});
tween(dialogueText, {
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Clean up cinematic elements
enemyCharacter.destroy();
dialogueBox.destroy();
dialogueText.destroy();
// Resume game state
gameState = 'playing';
// Continue with collision
var explosion = new Explosion(self.x, self.y);
game.addChild(explosion);
// Play explosion sound
LK.getSound('explosion').play();
// Airplane crashed into fortress - hide all non-alternate enemies
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
// Hide enemies that are not airplanes
if (!enemy.direction && !enemy.speed === undefined) {
enemy.visible = false;
}
}
// Stop enemy spawning by setting current scenario permanently
currentScenario = 'alternate';
// Airplane crashed into fortress - game over
LK.effects.flashObject(fortress, 0xFF0000, 1000);
LK.effects.flashScreen(0xFF0000, 1000);
gameOver = true;
self.markForDestroy = true;
}
});
}, 2000);
}, 1200);
return;
}
}
// Remove when off screen
if (self.x < -300 || self.x > 2348) {
self.markForDestroy = true;
}
};
return self;
});
var BigPoderProjectile = Container.expand(function (startX, startY, target, damage) {
var self = Container.call(this);
var projectileGraphics = self.attachAsset('BigPoder', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = startX;
self.y = startY;
self.target = target;
self.damage = damage;
self.speed = 6; // Slower than regular Poder
// Calculate direction to target
var dx = target.x - startX;
var dy = target.y - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.dirX = dx / distance;
self.dirY = dy / distance;
// Set rotation to face target
projectileGraphics.rotation = Math.atan2(dy, dx);
// Start with growing animation
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.easeOut
});
// Add pulsing effect
var spinSpeed = 0.08;
self.pulseDirection = 1;
self.update = function () {
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
// Spin and pulse the projectile
projectileGraphics.rotation += spinSpeed;
// Pulsing scale effect
if (self.scaleX >= 1.8) {
self.pulseDirection = -1;
} else if (self.scaleX <= 1.2) {
self.pulseDirection = 1;
}
self.scaleX += self.pulseDirection * 0.02;
self.scaleY += self.pulseDirection * 0.02;
// Check if hit fortress (secret boss attacks fortress directly)
if (fortress && fortress.takeDamage) {
var fortressDist = Math.sqrt(Math.pow(fortress.x - self.x, 2) + Math.pow(fortress.y - self.y, 2));
if (fortressDist < 250) {
// Ensure damage is exactly 2 points for reduced boss attack power
fortress.takeDamage(2);
// Big explosion effect
LK.effects.flashObject(fortress, 0x00FFFF, 800);
// Shrinking effect on hit
tween(self, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
self.markForDestroy = true;
}
});
return;
}
}
// Remove if off screen
if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.markForDestroy = true;
}
};
return self;
});
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('Bossogro', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 2.0,
// Make boss twice as big
scaleY: 2.0
});
// Add boss details
var eyesAsset = self.attachAsset('spear', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
eyesAsset.x = 0;
eyesAsset.y = -240; // Adjusted for larger size
eyesAsset.tint = 0xFF0000; // Red eyes for boss
// Add crown/spikes
var crownAsset = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.6,
scaleY: 1.2
});
crownAsset.x = 0;
crownAsset.y = -320; // Adjusted for larger size
crownAsset.tint = 0xFFD700; // Gold crown
self.health = 500; // Same health as secret boss
self.maxHealth = 500;
self.speed = 0.5; // Slower than regular enemies
self.damage = 30; // More damage than regular enemies
self.coinValue = 50; // Lots of coins when defeated
self.enemyType = 'boss';
self.isBoss = true;
self.lastSpecialAttack = 0;
self.specialAttackCooldown = 300; // 5 seconds at 60fps
self.update = function () {
// Enemy special power - speed boost when in range of units
if (LK.ticks - self.lastSpecialPower >= self.specialPowerCooldown && self.canUseSpecialPower) {
for (var i = 0; i < defensiveUnits.length; i++) {
var unit = defensiveUnits[i];
var unitDistance = Math.sqrt(Math.pow(unit.x - self.x, 2) + Math.pow(unit.y - self.y, 2));
if (unitDistance <= 300) {
// Within range of a unit
self.lastSpecialPower = LK.ticks;
// Temporary speed boost and visual effect
var originalSpeed = self.speed;
self.speed *= 2.5; // 2.5x speed boost
LK.effects.flashObject(self, 0xFF8800, 300); // Orange flash
// Special attack when in range but not at fortress yet
// Speed boost animation
tween(self, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
easing: tween.easeOut
});
// Return to normal after 1 second
LK.setTimeout(function () {
self.speed = originalSpeed;
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeIn
});
}, 1000);
break; // Only use power once per cooldown
}
}
}
// Move toward fortress
var dx = fortress.x - self.x;
var dy = fortress.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= 400 && distance > 215 && LK.ticks - self.lastSpecialAttack >= self.specialAttackCooldown) {
self.lastSpecialAttack = LK.ticks;
// Boss special power - weakens fortress
LK.effects.flashObject(self, 0xFF00FF, 500);
fortress.takeDamage(15); // Special attack damage
tween(self, {
scaleX: 2.5,
scaleY: 2.5
}, {
duration: 300,
easing: tween.easeOut
});
tween(self, {
scaleX: 2.0,
scaleY: 2.0
}, {
duration: 300,
easing: tween.easeIn
});
}
if (distance > 300) {
// Not at fortress yet - move closer
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
// Boss doesn't reach fortress - just damages it from distance and disappears
fortress.takeDamage(5);
enemiesEntered++; // Count boss entry
self.markForDestroy = true;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
coins += self.coinValue;
enemiesKilled++;
// Reset trollface flag when boss dies to allow repeat triggers
trollfaceShown = false;
gameWon = true; // Win when boss is defeated!
self.markForDestroy = true;
}
};
return self;
});
var DefensiveUnit = Container.expand(function (unitType) {
var self = Container.call(this);
var unitGraphics = self.attachAsset(unitType, {
anchorX: 0.5,
anchorY: 1.0
});
// Add character details for Mario-style appearance
var hatAsset, weaponAsset;
if (unitType === 'archer') {
// Add archer hat
hatAsset = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.8,
scaleY: 0.6
});
hatAsset.x = 0;
hatAsset.y = -140;
hatAsset.tint = 0x228B22;
} else if (unitType === 'spearman') {
// Add spearman helmet
hatAsset = self.attachAsset('spear', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.9,
scaleY: 0.7
});
hatAsset.x = 0;
hatAsset.y = -140;
hatAsset.tint = 0x4169E1;
} else if (unitType === 'cavalry') {
// Add cavalry plume
hatAsset = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.2,
scaleY: 0.8
});
hatAsset.x = 0;
hatAsset.y = -140;
hatAsset.tint = 0x9932CC;
}
if (unitType === 'archer') {
self.damage = 15;
self.range = 350;
self.attackSpeed = 45; // frames between attacks
self.cost = 10;
} else if (unitType === 'spearman') {
self.damage = 25;
self.range = 225;
self.attackSpeed = 30;
self.cost = 15;
} else if (unitType === 'cavalry') {
self.damage = 35;
self.range = 250;
self.attackSpeed = 20;
self.cost = 25;
}
self.unitType = unitType;
self.attackTimer = 0;
self.target = null;
self.battlesCount = 0; // Track number of battles
self.maxDamage = self.damage; // Store original damage for weakening calculation
self.fatigueLevel = 0; // Unit fatigue from battles
self.update = function () {
self.attackTimer--;
if (self.attackTimer <= 0) {
self.findTarget();
if (self.target && self.isInRange(self.target)) {
self.attack();
self.attackTimer = self.attackSpeed;
}
}
};
self.findTarget = function () {
var closestDistance = self.range;
self.target = null;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2));
if (distance < closestDistance) {
closestDistance = distance;
self.target = enemy;
}
}
};
self.isInRange = function (target) {
var distance = Math.sqrt(Math.pow(target.x - self.x, 2) + Math.pow(target.y - self.y, 2));
return distance <= self.range;
};
self.attack = function () {
if (self.target) {
// Apply battle fatigue - units get weaker with each battle
self.battlesCount++;
self.fatigueLevel = Math.min(self.battlesCount * 0.05, 0.4); // Max 40% damage reduction
var currentDamage = Math.floor(self.maxDamage * (1 - self.fatigueLevel));
var projectile = new Projectile(self.unitType, self.x, self.y, self.target, currentDamage);
// Mark projectile with unit type for tracking
projectile.sourceUnitType = self.unitType;
projectiles.push(projectile);
game.addChild(projectile);
// Play general attack sound for all units
LK.getSound('Ataque').play();
if (self.unitType === 'cavalry') {
LK.getSound('Espada').play();
} else if (self.unitType === 'archer') {
LK.getSound('Arco').play();
}
// Visual feedback for tired units
if (self.fatigueLevel > 0.2) {
tween(self, {
alpha: 0.7
}, {
duration: 200,
easing: tween.easeOut
});
tween(self, {
alpha: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
}
};
self.takeDamage = function (damage) {
// Units can be damaged by enemy Poder attacks
self.fatigueLevel += 0.1; // Extra fatigue from being attacked
self.fatigueLevel = Math.min(self.fatigueLevel, 0.6); // Max 60% damage reduction
// Visual feedback for being hit
LK.effects.flashObject(self, 0xFF0000, 300);
};
return self;
});
var Enemy = Container.expand(function (enemyType) {
var self = Container.call(this);
var enemyGraphics = self.attachAsset(enemyType, {
anchorX: 0.5,
anchorY: 1.0
});
// Add enemy details for Mario-style appearance
var eyesAsset = self.attachAsset('spear', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
eyesAsset.x = 0;
eyesAsset.y = -120;
eyesAsset.tint = 0xFFFFFF;
if (enemyType === 'strongEnemy') {
// Add spikes for strong enemy
var spikesAsset = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.8,
scaleY: 0.6
});
spikesAsset.x = 0;
spikesAsset.y = -160;
spikesAsset.tint = 0x000000;
}
if (enemyType === 'enemy') {
self.health = 30;
self.maxHealth = 30;
self.speed = 1;
self.damage = 10;
self.coinValue = 2;
} else if (enemyType === 'strongEnemy') {
self.health = 60;
self.maxHealth = 60;
self.speed = 0.8;
self.damage = 20;
self.coinValue = 5;
}
self.enemyType = enemyType;
self.lastSpecialPower = 0;
self.specialPowerCooldown = 120; // 2 seconds at 60fps (shorter than other units)
self.canUseSpecialPower = true;
self.update = function () {
// Enemy special power - launch Poder attack when in range of units
if (LK.ticks - self.lastSpecialPower >= self.specialPowerCooldown && self.canUseSpecialPower) {
for (var i = 0; i < defensiveUnits.length; i++) {
var unit = defensiveUnits[i];
var unitDistance = Math.sqrt(Math.pow(unit.x - self.x, 2) + Math.pow(unit.y - self.y, 2));
if (unitDistance <= 300) {
// Within range of a unit - launch Poder attack
self.lastSpecialPower = LK.ticks;
var poderProjectile = new PoderProjectile(self.x, self.y, unit, self.damage * 0.5);
projectiles.push(poderProjectile);
game.addChild(poderProjectile);
// Play power sound effect
LK.getSound('Poder').play();
// Visual effect for enemy using power
LK.effects.flashObject(self, 0x00FFFF, 300);
break; // Only use power once per cooldown
}
}
}
// Move toward fortress
var dx = fortress.x - self.x;
var dy = fortress.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 215) {
// Not at fortress yet
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
// Attack fortress
fortress.takeDamage(self.damage);
enemiesEntered++; // Count enemy entry
self.markForDestroy = true;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
coins += self.coinValue;
enemiesKilled++;
// Reset trollface flag when enemy dies to allow repeat triggers
trollfaceShown = false;
self.markForDestroy = true;
}
};
return self;
});
var Explosion = Container.expand(function (x, y) {
var self = Container.call(this);
// Create multiple explosion particles
var particles = [];
for (var i = 0; i < 8; i++) {
var particle = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3 + Math.random() * 0.4,
scaleY: 0.3 + Math.random() * 0.4
});
// Random position offset
particle.x = (Math.random() - 0.5) * 100;
particle.y = (Math.random() - 0.5) * 100;
// Random color tint for variety
var colors = [0xFF4500, 0xFF6600, 0xFF8800, 0xFFAA00, 0xFFCC00];
particle.tint = colors[Math.floor(Math.random() * colors.length)];
particles.push(particle);
}
self.x = x;
self.y = y;
// Animate explosion particles
for (var j = 0; j < particles.length; j++) {
var particle = particles[j];
var finalX = particle.x + (Math.random() - 0.5) * 200;
var finalY = particle.y + (Math.random() - 0.5) * 200;
// Expanding animation
tween(particle, {
x: finalX,
y: finalY,
scaleX: particle.scaleX * 2,
scaleY: particle.scaleY * 2,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut
});
}
// Auto-destroy after animation
LK.setTimeout(function () {
self.markForDestroy = true;
}, 900);
return self;
});
var Fortress = Container.expand(function () {
var self = Container.call(this);
var fortressGraphics = self.attachAsset('fortress', {
anchorX: 0.5,
anchorY: 1.0
});
// Add castle tower details
var leftTower = self.attachAsset('spearman', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.6,
scaleY: 0.8
});
leftTower.x = -125;
leftTower.y = -75;
leftTower.tint = 0x696969;
var rightTower = self.attachAsset('spearman', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.6,
scaleY: 0.8
});
rightTower.x = 125;
rightTower.y = -75;
rightTower.tint = 0x696969;
// Add flag
var flag = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.8,
scaleY: 0.5
});
flag.x = 0;
flag.y = -350;
flag.tint = 0xFF4500;
// Add shield visual effect
var shieldGraphics = self.attachAsset('fortress', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.2,
scaleY: 1.2
});
shieldGraphics.alpha = 0;
shieldGraphics.tint = 0x00FFFF;
self.health = fortressMaxHealth;
self.maxHealth = fortressMaxHealth;
self.activateShield = function () {
if (shieldCooldown <= 0) {
shieldActive = true;
shieldCooldown = shieldMaxCooldown;
shieldGraphics.alpha = 0.5;
tween(shieldGraphics, {
alpha: 0.8
}, {
duration: 500,
easing: tween.easeInOut
});
LK.setTimeout(function () {
shieldActive = false;
tween(shieldGraphics, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut
});
}, 3000); // Shield lasts 3 seconds
}
};
self.takeDamage = function (damage) {
if (!shieldActive) {
fortressCurrentHealth -= damage;
self.health = fortressCurrentHealth;
LK.effects.flashObject(self, 0xFF0000, 300);
if (fortressCurrentHealth <= 0) {
gameOver = true;
}
} else {
// Shield blocks damage
LK.effects.flashObject(shieldGraphics, 0xFFFFFF, 200);
}
};
return self;
});
var Fortress2 = Container.expand(function () {
var self = Container.call(this);
var fortressGraphics = self.attachAsset('fortress2', {
anchorX: 0.5,
anchorY: 1.0
});
// Add castle tower details
var leftTower = self.attachAsset('spearman', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.6,
scaleY: 0.8
});
leftTower.x = -125;
leftTower.y = -75;
leftTower.tint = 0x696969;
var rightTower = self.attachAsset('spearman', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.6,
scaleY: 0.8
});
rightTower.x = 125;
rightTower.y = -75;
rightTower.tint = 0x696969;
// Add flag
var flag = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.8,
scaleY: 0.5
});
flag.x = 0;
flag.y = -350;
flag.tint = 0xFF4500;
// Add shield visual effect
var shieldGraphics = self.attachAsset('fortress2', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.2,
scaleY: 1.2
});
shieldGraphics.alpha = 0;
shieldGraphics.tint = 0x00FFFF;
self.health = fortressMaxHealth;
self.maxHealth = fortressMaxHealth;
self.activateShield = function () {
if (shieldCooldown <= 0) {
shieldActive = true;
shieldCooldown = shieldMaxCooldown;
shieldGraphics.alpha = 0.5;
tween(shieldGraphics, {
alpha: 0.8
}, {
duration: 500,
easing: tween.easeInOut
});
LK.setTimeout(function () {
shieldActive = false;
tween(shieldGraphics, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut
});
}, 3000); // Shield lasts 3 seconds
}
};
self.takeDamage = function (damage) {
if (!shieldActive) {
fortressCurrentHealth -= damage;
self.health = fortressCurrentHealth;
LK.effects.flashObject(self, 0xFF0000, 300);
if (fortressCurrentHealth <= 0) {
gameOver = true;
}
} else {
// Shield blocks damage
LK.effects.flashObject(shieldGraphics, 0xFFFFFF, 200);
}
};
return self;
});
var MiniBoss = Container.expand(function () {
var self = Container.call(this);
var miniBossGraphics = self.attachAsset('miniboos1', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
// Smaller than regular boss but bigger than normal enemy
scaleY: 1.5
});
// Add mini boss details
var eyesAsset = self.attachAsset('spear', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
eyesAsset.x = 0;
eyesAsset.y = -180; // Adjusted for smaller size
eyesAsset.tint = 0xFFFF00; // Yellow eyes for mini boss
// Add small crown/spikes
var crownAsset = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.2,
scaleY: 1.0
});
crownAsset.x = 0;
crownAsset.y = -240; // Adjusted for smaller size
crownAsset.tint = 0xC0C0C0; // Silver crown
self.health = 150; // More health than enemies but less than boss
self.maxHealth = 150;
self.speed = 0.8; // Faster than regular boss but slower than normal enemies
self.damage = 20; // Less damage than regular boss
self.coinValue = 25; // Medium reward
self.enemyType = 'miniboss';
self.isMiniBoss = true;
self.lastSpecialAttack = 0;
self.specialAttackCooldown = 240; // 4 seconds at 60fps
self.lastSpecialPower = 0;
self.specialPowerCooldown = 120; // 2 seconds at 60fps
self.canUseSpecialPower = true;
self.update = function () {
// Mini boss special power - similar to regular boss but weaker
if (LK.ticks - self.lastSpecialPower >= self.specialPowerCooldown && self.canUseSpecialPower) {
for (var i = 0; i < defensiveUnits.length; i++) {
var unit = defensiveUnits[i];
var unitDistance = Math.sqrt(Math.pow(unit.x - self.x, 2) + Math.pow(unit.y - self.y, 2));
if (unitDistance <= 250) {
// Shorter range than regular boss
// Within range of a unit
self.lastSpecialPower = LK.ticks;
// Temporary speed boost and visual effect
var originalSpeed = self.speed;
self.speed *= 2.0; // 2x speed boost (less than regular boss)
LK.effects.flashObject(self, 0xFFFF00, 300); // Yellow flash
// Speed boost animation
tween(self, {
scaleX: 1.7,
scaleY: 1.7
}, {
duration: 300,
easing: tween.easeOut
});
// Return to normal after 1 second
LK.setTimeout(function () {
self.speed = originalSpeed;
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
easing: tween.easeIn
});
}, 1000);
break; // Only use power once per cooldown
}
}
}
// Move toward fortress
var dx = fortress.x - self.x;
var dy = fortress.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= 350 && distance > 215 && LK.ticks - self.lastSpecialAttack >= self.specialAttackCooldown) {
self.lastSpecialAttack = LK.ticks;
// Mini boss special power - weakens fortress but less than regular boss
LK.effects.flashObject(self, 0xFFFF00, 400);
fortress.takeDamage(10); // Less special attack damage than regular boss
tween(self, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 200,
easing: tween.easeOut
});
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeIn
});
}
if (distance > 300) {
// Not at fortress yet - move closer
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
// Mini boss doesn't reach fortress - just damages it from distance and disappears
fortress.takeDamage(5);
enemiesEntered++; // Count mini boss entry
self.markForDestroy = true;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
coins += self.coinValue;
enemiesKilled++;
// Reset trollface flag when mini boss dies to allow repeat triggers
trollfaceShown = false;
self.markForDestroy = true;
}
};
return self;
});
var MiniBoss2 = Container.expand(function () {
var self = Container.call(this);
var miniBossGraphics = self.attachAsset('Miniboos2', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
// Smaller than regular boss but bigger than normal enemy
scaleY: 1.5
});
// Add mini boss details
var eyesAsset = self.attachAsset('spear', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
eyesAsset.x = 0;
eyesAsset.y = -180; // Adjusted for smaller size
eyesAsset.tint = 0xFFFF00; // Yellow eyes for mini boss
// Add small crown/spikes
var crownAsset = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.2,
scaleY: 1.0
});
crownAsset.x = 0;
crownAsset.y = -240; // Adjusted for smaller size
crownAsset.tint = 0xC0C0C0; // Silver crown
self.health = 150; // More health than enemies but less than boss
self.maxHealth = 150;
self.speed = 0.8; // Faster than regular boss but slower than normal enemies
self.damage = 20; // Less damage than regular boss
self.coinValue = 25; // Medium reward
self.enemyType = 'miniboss';
self.isMiniBoss = true;
self.lastSpecialAttack = 0;
self.specialAttackCooldown = 240; // 4 seconds at 60fps
self.lastSpecialPower = 0;
self.specialPowerCooldown = 120; // 2 seconds at 60fps
self.canUseSpecialPower = true;
self.update = function () {
// Mini boss special power - similar to regular boss but weaker
if (LK.ticks - self.lastSpecialPower >= self.specialPowerCooldown && self.canUseSpecialPower) {
for (var i = 0; i < defensiveUnits.length; i++) {
var unit = defensiveUnits[i];
var unitDistance = Math.sqrt(Math.pow(unit.x - self.x, 2) + Math.pow(unit.y - self.y, 2));
if (unitDistance <= 250) {
// Shorter range than regular boss
// Within range of a unit
self.lastSpecialPower = LK.ticks;
// Temporary speed boost and visual effect
var originalSpeed = self.speed;
self.speed *= 2.0; // 2x speed boost (less than regular boss)
LK.effects.flashObject(self, 0xFFFF00, 300); // Yellow flash
// Speed boost animation
tween(self, {
scaleX: 1.7,
scaleY: 1.7
}, {
duration: 300,
easing: tween.easeOut
});
// Return to normal after 1 second
LK.setTimeout(function () {
self.speed = originalSpeed;
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
easing: tween.easeIn
});
}, 1000);
break; // Only use power once per cooldown
}
}
}
// Move toward fortress
var dx = fortress.x - self.x;
var dy = fortress.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= 350 && distance > 215 && LK.ticks - self.lastSpecialAttack >= self.specialAttackCooldown) {
self.lastSpecialAttack = LK.ticks;
// Mini boss special power - weakens fortress but less than regular boss
LK.effects.flashObject(self, 0xFFFF00, 400);
fortress.takeDamage(10); // Less special attack damage than regular boss
tween(self, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 200,
easing: tween.easeOut
});
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeIn
});
}
if (distance > 300) {
// Not at fortress yet - move closer
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
// Mini boss doesn't reach fortress - just damages it from distance and disappears
fortress.takeDamage(5);
enemiesEntered++; // Count mini boss entry
self.markForDestroy = true;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
coins += self.coinValue;
enemiesKilled++;
// Reset trollface flag when mini boss dies to allow repeat triggers
trollfaceShown = false;
self.markForDestroy = true;
}
};
return self;
});
var PoderProjectile = Container.expand(function (startX, startY, target, damage) {
var self = Container.call(this);
var projectileGraphics = self.attachAsset('Poder', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = startX;
self.y = startY;
self.target = target;
self.damage = damage;
self.speed = 8; // Slower than regular projectiles
// Calculate direction to target
var dx = target.x - startX;
var dy = target.y - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.dirX = dx / distance;
self.dirY = dy / distance;
// Set rotation to face target
projectileGraphics.rotation = Math.atan2(dy, dx);
// Add spinning effect
var spinSpeed = 0.1;
self.update = function () {
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
// Spin the projectile
projectileGraphics.rotation += spinSpeed;
// Check if hit target
if (self.target && self.target.takeDamage && Math.sqrt(Math.pow(self.target.x - self.x, 2) + Math.pow(self.target.y - self.y, 2)) < 80) {
self.target.takeDamage(self.damage);
// Add special effect when hitting
LK.effects.flashObject(self.target, 0x00FFFF, 500);
self.markForDestroy = true;
}
// Remove if off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.markForDestroy = true;
}
};
return self;
});
var Projectile = Container.expand(function (unitType, startX, startY, target, damage) {
var self = Container.call(this);
var assetType = unitType === 'archer' ? 'arrow' : 'spear';
var projectileGraphics = self.attachAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = startX;
self.y = startY;
self.target = target;
self.damage = damage;
self.speed = 12;
// Calculate direction to target
var dx = target.x - startX;
var dy = target.y - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.dirX = dx / distance;
self.dirY = dy / distance;
// Set rotation to face target
projectileGraphics.rotation = Math.atan2(dy, dx);
self.update = function () {
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
// Check if hit target
if (self.target && self.target.takeDamage && Math.sqrt(Math.pow(self.target.x - self.x, 2) + Math.pow(self.target.y - self.y, 2)) < 80) {
// Track health before damage for kill detection
var targetHealthBefore = self.target.health;
self.target.takeDamage(self.damage);
// Check if this projectile killed the target and we're tracking
if (trackingActive && targetHealthBefore > 0 && self.target.health <= 0) {
// Only count kills from archer or spearman projectiles
if (self.sourceUnitType === 'archer' || self.sourceUnitType === 'spearman') {
enemiesKilledByTrackedUnits++;
// Check if we've killed 5 enemies with only our tracked units
if (enemiesKilledByTrackedUnits >= 5 && !secretBossSpawned) {
secretBossConditionMet = true;
}
}
}
self.markForDestroy = true;
}
// Remove if off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.markForDestroy = true;
}
};
return self;
});
var ScenarioCube = Container.expand(function () {
var self = Container.call(this);
var cubeGraphics = self.attachAsset('ScenarioCube', {
anchorX: 0.5,
anchorY: 0.5
});
// Add pulsing animation
self.pulseDirection = 1;
self.spawnTime = LK.ticks;
self.update = function () {
// Pulsing effect
if (cubeGraphics.scaleX >= 1.3) {
self.pulseDirection = -1;
} else if (cubeGraphics.scaleX <= 0.8) {
self.pulseDirection = 1;
}
cubeGraphics.scaleX += self.pulseDirection * 0.02;
cubeGraphics.scaleY += self.pulseDirection * 0.02;
// Rotation effect
cubeGraphics.rotation += 0.1;
// Auto-disappear after 10 seconds
if (LK.ticks - self.spawnTime > 600) {
self.markForDestroy = true;
}
};
self.down = function (x, y, obj) {
// Trigger scenario change
changeScenario();
self.markForDestroy = true;
};
return self;
});
var SecretBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('Jefesecreto', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 3.0,
scaleY: 3.0
});
// Add mystical aura
var auraAsset = self.attachAsset('Poder', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
auraAsset.x = 0;
auraAsset.y = -200;
auraAsset.alpha = 0.3;
auraAsset.tint = 0xFF00FF;
// Add health bar background
var healthBarBg = self.attachAsset('HealthBarBg', {
anchorX: 0.5,
anchorY: 0.5
});
healthBarBg.x = 0;
healthBarBg.y = -350;
// Add health bar fill
var healthBarFill = self.attachAsset('HealthBarFill', {
anchorX: 0,
anchorY: 0.5
});
healthBarFill.x = -200;
healthBarFill.y = -350;
self.health = 500; // Even more health than regular boss
self.maxHealth = 500;
self.speed = 0.3; // Very slow but powerful
self.damage = 50; // Massive damage
self.coinValue = 100; // Huge reward
self.enemyType = 'secretboss';
self.isSecretBoss = true;
self.lastSpecialAttack = 0;
self.specialAttackCooldown = 180; // 3 seconds
self.update = function () {
// Update health bar
var healthPercent = self.health / self.maxHealth;
healthBarFill.width = 400 * healthPercent;
if (healthPercent > 0.6) {
healthBarFill.tint = 0x00FF00;
} else if (healthPercent > 0.3) {
healthBarFill.tint = 0xFFFF00;
} else {
healthBarFill.tint = 0xFF0000;
}
// Mystical aura spinning effect
auraAsset.rotation += 0.05;
// Check distance to fortress for BigPoder attack
var dx = fortress.x - self.x;
var dy = fortress.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// BigPoder attack when in range but not too close
if (LK.ticks - self.lastSpecialAttack >= self.specialAttackCooldown && distance <= 600 && distance > 300) {
self.lastSpecialAttack = LK.ticks;
// Launch BigPoder projectile at fortress with reduced damage
var bigPoderProjectile = new BigPoderProjectile(self.x, self.y, fortress, 2);
projectiles.push(bigPoderProjectile);
game.addChild(bigPoderProjectile);
// Play power sound effect louder
LK.getSound('Poder').play();
// Visual effect with growing animation
LK.effects.flashObject(self, 0xFF00FF, 500);
tween(self, {
scaleX: 3.5,
scaleY: 3.5
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 3.0,
scaleY: 3.0
}, {
duration: 400,
easing: tween.easeIn
});
}
});
} else if (distance > 300) {
// Move toward fortress when far away
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else if (distance <= 300 && distance > 215) {
// Stay in attack range, don't get too close
// Do nothing, just stay and attack
} else if (distance <= 215) {
// Only attack fortress directly if very close
fortress.takeDamage(self.damage);
enemiesEntered++;
self.markForDestroy = true;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
coins += self.coinValue;
enemiesKilled++;
LK.getSound('jefesecreto').play();
// Switch back to normal background music when secret boss is defeated
LK.playMusic('background');
gameWon = true; // Win when secret boss is defeated!
self.markForDestroy = true;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xFFCC00 // Bright 8-bit yellow desert background
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu' or 'playing'
var menuElements = [];
// Scenario change variables
var scenarioCubes = [];
var lastCubeSpawn = 0;
var cubeSpawnInterval = 1200; // 20 seconds at 60fps
var currentScenario = 'desert'; // 'desert' or 'alternate'
var scenarioChangeActive = false;
// Game variables
var fortress;
var defensiveUnits = [];
var enemies = [];
var projectiles = [];
var coins = 50;
var currentWave = 1;
var enemiesInWave = 5;
var enemiesSpawned = 0;
var waveDelay = 180; // 3 seconds at 60fps
var spawnDelay = 60; // 1 second between enemy spawns
var gameOver = false;
var enemiesKilled = 0;
var selectedUnitType = 'archer';
var enemiesEntered = 0; // Track enemies that entered fortress
var maxEnemiesAllowed = 10; // Game ends when 10 enemies enter
var bossSpawned = false;
var bossWave = 10; // Boss appears on wave 10
var gameWon = false;
var fortressMaxHealth = 200;
var fortressCurrentHealth = 200;
var shieldActive = false;
var shieldCooldown = 0;
var shieldMaxCooldown = 600; // 10 seconds at 60fps
var lastShieldTime = 0;
var trollfaceOverlay = null;
var trollfaceShown = false;
var lastAlarmTime = 0;
var alarmCooldown = 300; // 5 seconds at 60fps
// Secret boss tracking variables
var secretBossConditionMet = false;
var secretBossSpawned = false;
var archerCount = 0;
var spearmanCount = 0;
var cavalryCount = 0;
var enemiesKilledByTrackedUnits = 0;
var trackingActive = false;
// Boss spawn tracking variables
var lastBossSpawnKillCount = 0;
var totalMiniBossesSpawned = 0;
var maxMiniBossesToSpawn = 20;
// Menu initialization function
function initMainMenu() {
gameState = 'menu';
// Clear any existing menu elements
for (var i = 0; i < menuElements.length; i++) {
menuElements[i].destroy();
}
menuElements = [];
// Set blue background for menu
game.setBackgroundColor(0x0000FF);
// Play menu music
LK.playMusic('Pantalladeinicio');
// Game title
var titleText = new Text2('DEFENSA DE FORTALEZA', {
size: 120,
fill: 0xFFFF00
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 600;
game.addChild(titleText);
menuElements.push(titleText);
// Subtitle
var subtitleText = new Text2('Torre de Defensa Islámica', {
size: 80,
fill: 0xFFFF00
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 700;
game.addChild(subtitleText);
menuElements.push(subtitleText);
// Start button
var startButton = new Text2('TOCAR PARA EMPEZAR', {
size: 90,
fill: 0xFFFF00
});
startButton.anchor.set(0.5, 0.5);
startButton.x = 1024;
startButton.y = 1400;
game.addChild(startButton);
menuElements.push(startButton);
// Instructions
var instructionsText = new Text2('¡Defiende tu fortaleza!\nColoca unidades para detener enemigos\n¡No dejes que entren 10 enemigos!', {
size: 90,
fill: 0xFFFF00
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = 1024;
instructionsText.y = 1000;
game.addChild(instructionsText);
menuElements.push(instructionsText);
// Animate start button with continuous twinkling effect
function startTwinkle() {
if (gameState === 'menu') {
tween(startButton, {
alpha: 0.3,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (gameState === 'menu') {
tween(startButton, {
alpha: 1.0,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Restart the twinkling cycle continuously
startTwinkle();
}
});
}
}
});
}
}
startTwinkle();
}
// Cinematic initialization function
function initCinematic() {
gameState = 'cinematic';
// Clear menu elements
for (var i = 0; i < menuElements.length; i++) {
menuElements[i].destroy();
}
menuElements = [];
// Set dark background for cinematic
game.setBackgroundColor(0x000020);
// Play cinematic music
LK.playMusic('cinematica');
// Create knight character on left
var knight = LK.getAsset('cavalry', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 2.0,
scaleY: 2.0
});
knight.x = 400;
knight.y = 1800;
game.addChild(knight);
// Create spearman character on right
var spearman = LK.getAsset('spearman', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 2.0,
scaleY: 2.0
});
spearman.x = 1648;
spearman.y = 1800;
game.addChild(spearman);
// Create dialogue box background
var dialogueBox = LK.getAsset('HealthBarBg', {
width: 1800,
height: 300,
anchorX: 0.5,
anchorY: 0.5
});
dialogueBox.x = 1024;
dialogueBox.y = 2200;
dialogueBox.tint = 0x222222;
game.addChild(dialogueBox);
// Create dialogue text
var dialogueText = new Text2('', {
size: 60,
fill: 0xFFFFFF
});
dialogueText.anchor.set(0.5, 0.5);
dialogueText.x = 1024;
dialogueText.y = 2200;
game.addChild(dialogueText);
// Animate characters entering from sides
tween(knight, {
x: 600
}, {
duration: 1000,
easing: tween.easeOut
});
tween(spearman, {
x: 1448
}, {
duration: 1000,
easing: tween.easeOut
});
// Start dialogue sequence after characters are in position
LK.setTimeout(function () {
// Knight speaks first
dialogueText.setText('Caballero: "Está a punto de empezar el conflicto"');
tween(knight, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(knight, {
scaleX: 2.0,
scaleY: 2.0
}, {
duration: 300,
easing: tween.easeIn
});
}
});
// After 3 seconds, spearman responds
LK.setTimeout(function () {
dialogueText.setText('Lancero: "Sí, en guardia"');
tween(spearman, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(spearman, {
scaleX: 2.0,
scaleY: 2.0
}, {
duration: 300,
easing: tween.easeIn
});
}
});
// After another 2 seconds, fade out and start game
LK.setTimeout(function () {
// Fade out all cinematic elements
tween(knight, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut
});
tween(spearman, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut
});
tween(dialogueBox, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut
});
tween(dialogueText, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Clean up cinematic elements
knight.destroy();
spearman.destroy();
dialogueBox.destroy();
dialogueText.destroy();
// Start the actual game
initGame();
}
});
}, 2000);
}, 3000);
}, 1500);
}
// Game initialization function
function initGame() {
gameState = 'playing';
// Reset background to game color
game.setBackgroundColor(0xFFCC00);
// Clear menu elements (already cleared in cinematic)
for (var i = 0; i < menuElements.length; i++) {
menuElements[i].destroy();
}
menuElements = [];
// Reset game variables
coins = 50;
currentWave = 1;
enemiesInWave = 5;
enemiesSpawned = 0;
waveDelay = 180;
spawnDelay = 60;
gameOver = false;
enemiesKilled = 0;
selectedUnitType = 'archer';
enemiesEntered = 0;
bossSpawned = false;
gameWon = false;
fortressCurrentHealth = 200;
shieldActive = false;
shieldCooldown = 0;
trollfaceShown = false;
if (trollfaceOverlay) {
trollfaceOverlay.destroy();
trollfaceOverlay = null;
}
// Reset secret boss tracking
secretBossConditionMet = false;
secretBossSpawned = false;
archerCount = 0;
spearmanCount = 0;
cavalryCount = 0;
enemiesKilledByTrackedUnits = 0;
trackingActive = false;
// Reset boss spawn tracking
lastBossSpawnKillCount = 0;
totalMiniBossesSpawned = 0;
// Reset alarm cooldown
lastAlarmTime = 0;
// Clear arrays
defensiveUnits = [];
enemies = [];
projectiles = [];
scenarioCubes = [];
// Reset scenario variables
currentScenario = 'desert';
scenarioChangeActive = false;
lastCubeSpawn = 0;
cubeSpawnInterval = 1200;
// Initialize fortress at center
fortress = new Fortress();
fortress.x = 1024;
fortress.y = 1366;
game.addChild(fortress);
// Start background music for gameplay
LK.playMusic('background');
}
// Scenario change function
function changeScenario() {
if (scenarioChangeActive) return;
scenarioChangeActive = true;
// Clear all existing enemies except the fortress
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
enemies.splice(i, 1);
}
// Clear all projectiles
for (var j = projectiles.length - 1; j >= 0; j--) {
projectiles[j].destroy();
projectiles.splice(j, 1);
}
// Clear all defensive units placed by player to leave clean scenario
for (var k = defensiveUnits.length - 1; k >= 0; k--) {
var unit = defensiveUnits[k];
unit.destroy();
defensiveUnits.splice(k, 1);
}
// Change scenario
if (currentScenario === 'desert') {
currentScenario = 'alternate';
game.setBackgroundColor(0x808080); // Gray environment
// Change fortress to fortress2
fortress.destroy();
fortress = new Fortress2();
fortress.x = 1024;
fortress.y = 1366;
game.addChild(fortress);
} else {
currentScenario = 'desert';
game.setBackgroundColor(0xFFCC00); // Desert yellow
// Reset fortress to normal
fortress.destroy();
fortress = new Fortress();
fortress.x = 1024;
fortress.y = 1366;
game.addChild(fortress);
}
// Spawn only airplane in alternate scenario, strongEnemy in desert
if (currentScenario === 'alternate') {
var airplane = new Avion();
enemies.push(airplane);
game.addChild(airplane);
} else {
var singleEnemy = new Enemy('strongEnemy');
singleEnemy.x = Math.random() * 1500 + 274; // Random position not too close to edges
singleEnemy.y = Math.random() * 1000 + 200;
enemies.push(singleEnemy);
game.addChild(singleEnemy);
}
// Visual effect for scenario change
LK.effects.flashScreen(0xFFFFFF, 1000);
// Reset scenario change flag after a delay
LK.setTimeout(function () {
scenarioChangeActive = false;
}, 2000);
}
// Start with main menu
initMainMenu();
// UI Elements
var coinsText = new Text2('Monedas: ' + coins, {
size: 32,
fill: 0xFFFF00
});
coinsText.anchor.set(0, 0);
coinsText.x = 120;
coinsText.y = 50;
LK.gui.topLeft.addChild(coinsText);
var waveText = new Text2('Oleada: ' + currentWave, {
size: 32,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
waveText.x = 0;
waveText.y = 50;
LK.gui.top.addChild(waveText);
var healthText = new Text2('Fortaleza: ' + fortressCurrentHealth + '/' + fortressMaxHealth, {
size: 32,
fill: 0xFF0000
});
healthText.anchor.set(1, 0);
healthText.x = -20;
healthText.y = 50;
LK.gui.topRight.addChild(healthText);
// Add health bar
var healthBarBg = LK.getAsset('fortress', {
width: 200,
height: 20,
anchorX: 0.5,
anchorY: 0
});
healthBarBg.tint = 0x666666;
healthBarBg.x = 0;
healthBarBg.y = 90;
LK.gui.top.addChild(healthBarBg);
var healthBarFill = LK.getAsset('fortress', {
width: 200,
height: 20,
anchorX: 0,
anchorY: 0
});
healthBarFill.tint = 0x00FF00;
healthBarFill.x = -100;
healthBarFill.y = 90;
LK.gui.top.addChild(healthBarFill);
// Add shield button
var shieldButton = new Text2('Escudo (Listo)', {
size: 24,
fill: 0x00FFFF
});
shieldButton.anchor.set(0.5, 1);
shieldButton.x = 0;
shieldButton.y = -100;
LK.gui.bottom.addChild(shieldButton);
shieldButton.down = function () {
fortress.activateShield();
};
var enemiesEnteredText = new Text2('Enemigos Entraron: ' + enemiesEntered + '/' + maxEnemiesAllowed, {
size: 28,
fill: 0xFFFFFF
});
enemiesEnteredText.anchor.set(0.5, 0);
enemiesEnteredText.x = 0;
enemiesEnteredText.y = 100;
LK.gui.top.addChild(enemiesEnteredText);
// Unit selection buttons
var archerButton = new Text2('Arquero (10)', {
size: 28,
fill: 0x00FF00
});
archerButton.anchor.set(0.5, 1);
archerButton.x = -200;
archerButton.y = -50;
LK.gui.bottom.addChild(archerButton);
var spearmanButton = new Text2('Lancero (15)', {
size: 28,
fill: 0x0080FF
});
spearmanButton.anchor.set(0.5, 1);
spearmanButton.x = 0;
spearmanButton.y = -50;
LK.gui.bottom.addChild(spearmanButton);
var cavalryButton = new Text2('Caballería (25)', {
size: 28,
fill: 0xFF00FF
});
cavalryButton.anchor.set(0.5, 1);
cavalryButton.x = 200;
cavalryButton.y = -50;
LK.gui.bottom.addChild(cavalryButton);
// Button press handlers
archerButton.down = function () {
selectedUnitType = 'archer';
updateButtonColors();
};
spearmanButton.down = function () {
selectedUnitType = 'spearman';
updateButtonColors();
};
cavalryButton.down = function () {
selectedUnitType = 'cavalry';
updateButtonColors();
};
function updateButtonColors() {
archerButton.fill = selectedUnitType === 'archer' ? 0xFFFFFF : 0x00FF00;
spearmanButton.fill = selectedUnitType === 'spearman' ? 0xFFFFFF : 0x0080FF;
cavalryButton.fill = selectedUnitType === 'cavalry' ? 0xFFFFFF : 0xFF00FF;
}
updateButtonColors();
// Game input
game.down = function (x, y, obj) {
if (gameState === 'menu') {
// Start the cinematic when tapping on menu
initCinematic();
return;
}
if (gameState === 'cinematic') {
// Skip cinematic if tapped during dialogue
return;
}
if (gameOver) return;
var unitCost = selectedUnitType === 'archer' ? 10 : selectedUnitType === 'spearman' ? 15 : 25;
if (coins >= unitCost) {
var newUnit = new DefensiveUnit(selectedUnitType);
newUnit.x = x;
newUnit.y = y;
defensiveUnits.push(newUnit);
game.addChild(newUnit);
coins -= unitCost;
LK.getSound('deploy').play();
// Track unit counts for secret boss condition
if (selectedUnitType === 'archer') {
archerCount++;
} else if (selectedUnitType === 'spearman') {
spearmanCount++;
} else if (selectedUnitType === 'cavalry') {
cavalryCount++;
}
// Check if we have exactly 3 archers and 1 spearman with no cavalry
if (archerCount === 3 && spearmanCount === 1 && cavalryCount === 0 && !trackingActive) {
trackingActive = true;
enemiesKilledByTrackedUnits = 0;
}
// If we deploy any other units or wrong counts, disable tracking
if (trackingActive && (archerCount !== 3 || spearmanCount !== 1 || cavalryCount > 0)) {
trackingActive = false;
}
}
};
// Spawn enemies
function spawnEnemy() {
var enemy;
// Spawn boss on wave 10
if (currentWave >= bossWave && !bossSpawned) {
enemy = new Boss();
bossSpawned = true;
} else {
var enemyType = currentWave > 3 && Math.random() < 0.3 ? 'strongEnemy' : 'enemy';
enemy = new Enemy(enemyType);
}
// Spawn from random edge
var side = Math.floor(Math.random() * 4);
if (side === 0) {
// Top
enemy.x = Math.random() * 2048;
enemy.y = -50;
} else if (side === 1) {
// Right
enemy.x = 2098;
enemy.y = Math.random() * 2732;
} else if (side === 2) {
// Bottom
enemy.x = Math.random() * 2048;
enemy.y = 2782;
} else {
// Left
enemy.x = -50;
enemy.y = Math.random() * 2732;
}
enemies.push(enemy);
game.addChild(enemy);
}
game.update = function () {
// Don't run game logic when in menu or cinematic
if (gameState === 'menu' || gameState === 'cinematic') {
return;
}
// Check win condition - boss defeated
if (gameWon) {
LK.showYouWin();
return;
}
// Check lose conditions
if (gameOver || enemiesEntered >= maxEnemiesAllowed) {
LK.showGameOver();
return;
}
// Update shield cooldown
if (shieldCooldown > 0) {
shieldCooldown--;
}
// Update UI
coinsText.setText('Monedas: ' + coins);
waveText.setText('Oleada: ' + currentWave);
healthText.setText('Fortaleza: ' + fortressCurrentHealth + '/' + fortressMaxHealth);
enemiesEnteredText.setText('Enemigos Entraron: ' + enemiesEntered + '/' + maxEnemiesAllowed);
LK.setScore(enemiesKilled);
// Update health bar
var healthPercent = fortressCurrentHealth / fortressMaxHealth;
healthBarFill.width = 200 * healthPercent;
if (healthPercent > 0.6) {
healthBarFill.tint = 0x00FF00;
} else if (healthPercent > 0.3) {
healthBarFill.tint = 0xFFFF00;
} else {
healthBarFill.tint = 0xFF0000;
}
// Update shield button
if (shieldCooldown > 0) {
var secondsLeft = Math.ceil(shieldCooldown / 60);
shieldButton.setText('Escudo (' + secondsLeft + 's)');
shieldButton.fill = 0x666666;
} else {
shieldButton.setText('Escudo (Listo)');
shieldButton.fill = 0x00FFFF;
}
// Spawn enemies for current wave - only if in desert scenario
if (currentScenario === 'desert' && enemiesSpawned < enemiesInWave && LK.ticks % spawnDelay === 0) {
spawnEnemy();
enemiesSpawned++;
}
// Check if wave is complete
if (enemiesSpawned >= enemiesInWave && enemies.length === 0) {
if (waveDelay > 0) {
waveDelay--;
} else {
// Start next wave
currentWave++;
enemiesInWave = Math.min(5 + currentWave * 2, 20);
enemiesSpawned = 0;
waveDelay = 180;
spawnDelay = Math.max(30, 60 - currentWave * 2);
}
}
// Update defensive units
for (var i = 0; i < defensiveUnits.length; i++) {
defensiveUnits[i].update();
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.update();
// Auto-disappear enemies after they've been alive for too long (except bosses)
if (!enemy.isBoss && !enemy.isMiniBoss && !enemy.isSecretBoss) {
// Initialize spawn time if not set
if (enemy.spawnTime === undefined) {
enemy.spawnTime = LK.ticks;
}
// Auto-disappear after 30 seconds (1800 ticks at 60fps)
if (LK.ticks - enemy.spawnTime > 1800) {
enemy.markForDestroy = true;
}
}
if (enemy.markForDestroy) {
enemy.destroy();
enemies.splice(i, 1);
}
}
// Check if we're in boss mode (any boss or mini boss exists)
var inBossMode = false;
for (var j = 0; j < enemies.length; j++) {
if (enemies[j].isBoss || enemies[j].isMiniBoss || enemies[j].isSecretBoss) {
inBossMode = true;
break;
}
}
// Check for alerta warning when 5 enemies enter fortress (only if not in boss mode)
if (enemiesEntered === 5 && LK.ticks - lastAlarmTime >= alarmCooldown && !inBossMode) {
lastAlarmTime = LK.ticks;
// Play danger sound effect
LK.getSound('alerta').play();
// Create alerta overlay that appears quickly and fades out - same size as trollface
var alertaOverlay = LK.getAsset('Alerta', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 15
});
alertaOverlay.x = 1024;
alertaOverlay.y = 1366;
game.addChild(alertaOverlay);
// Quick flash effect - instantly visible then fade out
alertaOverlay.alpha = 1.0;
tween(alertaOverlay, {
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
alertaOverlay.destroy();
}
});
}
// Check for trollface trigger every 10 enemies killed (10, 20, 30, etc.) (only if not in boss mode)
if (enemiesKilled > 0 && enemiesKilled % 10 === 0 && !trollfaceShown && !inBossMode) {
trollfaceShown = true;
// Create trollface overlay that starts small and expands
trollfaceOverlay = LK.getAsset('Trollface', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0,
scaleY: 0
});
trollfaceOverlay.x = 1024;
trollfaceOverlay.y = 1366;
game.addChild(trollfaceOverlay);
// Play trollface sound effect when appearing
LK.getSound('trollface').play();
// Tornado expanding effect when appearing
tween(trollfaceOverlay, {
scaleX: 20,
scaleY: 15,
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeOut
});
// Show trollface for 1 second to match shorter sound, then animate it away
LK.setTimeout(function () {
if (trollfaceOverlay) {
// Play trollface sound effect when disappearing
LK.getSound('trollface').play();
// Swirling and shrinking animation - shorter to match sound
tween(trollfaceOverlay, {
rotation: Math.PI * 4,
// 2 full rotations for faster animation
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (trollfaceOverlay) {
trollfaceOverlay.destroy();
trollfaceOverlay = null;
}
}
});
}
}, 1000);
}
// Check for boss spawn every 10 enemies killed
if (enemiesKilled >= lastBossSpawnKillCount + 10) {
lastBossSpawnKillCount = enemiesKilled;
// Spawn main boss only once (first time reaching 10 kills)
if (enemiesKilled === 10) {
var mainBoss = new Boss();
mainBoss.x = 1024; // Center top
mainBoss.y = -100;
enemies.push(mainBoss);
game.addChild(mainBoss);
// Play boss music when main boss spawns
LK.playMusic('Bossogro');
}
// Only spawn mini bosses if we haven't reached the limit of 20
if (totalMiniBossesSpawned < maxMiniBossesToSpawn) {
// Spawn horde of mini bosses (4 mini bosses each time)
// Spawn mini boss from top left
var miniBoss1 = new MiniBoss();
miniBoss1.x = 200;
miniBoss1.y = -50;
enemies.push(miniBoss1);
game.addChild(miniBoss1);
totalMiniBossesSpawned++;
// Spawn mini boss from top right
var miniBoss2 = new MiniBoss2();
miniBoss2.x = 1800;
miniBoss2.y = -50;
enemies.push(miniBoss2);
game.addChild(miniBoss2);
totalMiniBossesSpawned++;
// Spawn mini boss from left side
var miniBoss3 = new MiniBoss();
miniBoss3.x = -50;
miniBoss3.y = Math.random() * 1000 + 500;
enemies.push(miniBoss3);
game.addChild(miniBoss3);
totalMiniBossesSpawned++;
// Spawn mini boss from right side
var miniBoss4 = new MiniBoss2();
miniBoss4.x = 2098;
miniBoss4.y = Math.random() * 1000 + 500;
enemies.push(miniBoss4);
game.addChild(miniBoss4);
totalMiniBossesSpawned++;
// Play special sound effect
LK.getSound('jefesecreto').play();
// Visual effect for boss appearance
LK.effects.flashScreen(0xFF8800, 800);
}
}
// Check for secret boss spawn condition
if (secretBossConditionMet && !secretBossSpawned) {
secretBossSpawned = true;
trackingActive = false; // Stop tracking once boss spawns
// Clear all existing enemies when secret boss appears
for (var j = enemies.length - 1; j >= 0; j--) {
var existingEnemy = enemies[j];
existingEnemy.destroy();
enemies.splice(j, 1);
}
// Spawn secret boss
var secretBoss = new SecretBoss();
// Spawn from a dramatic location (top center)
secretBoss.x = 1024;
secretBoss.y = -100;
enemies.push(secretBoss);
game.addChild(secretBoss);
// Play special sound effect
LK.getSound('jefesecreto').play();
// Start secret boss music
LK.playMusic('Secretboos');
// Visual effect for secret boss appearance
LK.effects.flashScreen(0xFF00FF, 1000);
}
// Spawn scenario cube every 20 seconds
if (LK.ticks - lastCubeSpawn >= cubeSpawnInterval && !scenarioChangeActive) {
lastCubeSpawn = LK.ticks;
cubeSpawnInterval = 1200; // 20 seconds at 60fps
var cube = new ScenarioCube();
// Spawn in safe area away from fortress
var spawnX, spawnY;
do {
spawnX = Math.random() * 1500 + 274;
spawnY = Math.random() * 1500 + 300;
} while (Math.sqrt(Math.pow(spawnX - fortress.x, 2) + Math.pow(spawnY - fortress.y, 2)) < 300);
cube.x = spawnX;
cube.y = spawnY;
scenarioCubes.push(cube);
game.addChild(cube);
}
// Update scenario cubes
for (var i = scenarioCubes.length - 1; i >= 0; i--) {
var cube = scenarioCubes[i];
cube.update();
if (cube.markForDestroy) {
cube.destroy();
scenarioCubes.splice(i, 1);
}
}
// Spawn airplane occasionally in alternate scenario only - only if no airplane exists
if (currentScenario === 'alternate') {
var airplaneExists = false;
for (var k = 0; k < enemies.length; k++) {
if (enemies[k].speed !== undefined && enemies[k].direction !== undefined) {
airplaneExists = true;
break;
}
}
if (!airplaneExists && LK.ticks % (Math.floor(Math.random() * 300) + 300) === 0) {
var airplane = new Avion();
game.addChild(airplane);
// Store airplanes in enemies array for easy cleanup
enemies.push(airplane);
}
}
// Update projectiles
for (var i = projectiles.length - 1; i >= 0; i--) {
var projectile = projectiles[i];
projectile.update();
if (projectile.markForDestroy) {
projectile.destroy();
projectiles.splice(i, 1);
}
}
// Update explosions - find and update all explosion objects
var allChildren = game.children.slice();
for (var i = allChildren.length - 1; i >= 0; i--) {
var child = allChildren[i];
if (child.markForDestroy) {
child.destroy();
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -51,29 +51,121 @@
avionGraphics.rotation = Math.sin(self.bobAmount) * 0.1;
// Check collision with fortress
if (fortress) {
var fortressDist = Math.sqrt(Math.pow(fortress.x - self.x, 2) + Math.pow(fortress.y - self.y, 2));
- if (fortressDist < 250) {
- // Create explosion at collision point
- var explosion = new Explosion(self.x, self.y);
- game.addChild(explosion);
- // Play explosion sound
- LK.getSound('explosion').play();
- // Airplane crashed into fortress - hide all non-alternate enemies
- for (var i = 0; i < enemies.length; i++) {
- var enemy = enemies[i];
- // Hide enemies that are not airplanes
- if (!enemy.direction && !enemy.speed === undefined) {
- enemy.visible = false;
- }
- }
- // Stop enemy spawning by setting current scenario permanently
- currentScenario = 'alternate';
- // Airplane crashed into fortress - game over
- LK.effects.flashObject(fortress, 0xFF0000, 1000);
- LK.effects.flashScreen(0xFF0000, 1000);
- gameOver = true;
- self.markForDestroy = true;
+ if (fortressDist < 350 && !self.cinematicStarted) {
+ // Start pre-collision cinematic
+ self.cinematicStarted = true;
+ self.speed = 0; // Stop airplane movement
+ gameState = 'cinematic'; // Pause game
+ // Create enemy character for dialogue
+ var enemyCharacter = LK.getAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 1.0,
+ scaleX: 3.0,
+ scaleY: 3.0
+ });
+ enemyCharacter.x = 1024;
+ enemyCharacter.y = 1800;
+ game.addChild(enemyCharacter);
+ // Create dialogue box background
+ var dialogueBox = LK.getAsset('HealthBarBg', {
+ width: 1600,
+ height: 250,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ dialogueBox.x = 1024;
+ dialogueBox.y = 2200;
+ dialogueBox.tint = 0x222222;
+ game.addChild(dialogueBox);
+ // Create dialogue text
+ var dialogueText = new Text2('', {
+ size: 70,
+ fill: 0xFFFFFF
+ });
+ dialogueText.anchor.set(0.5, 0.5);
+ dialogueText.x = 1024;
+ dialogueText.y = 2200;
+ game.addChild(dialogueText);
+ // Animate enemy entering from bottom
+ tween(enemyCharacter, {
+ y: 1600
+ }, {
+ duration: 1000,
+ easing: tween.easeOut
+ });
+ // Start dialogue sequence after character is in position
+ LK.setTimeout(function () {
+ // Enemy speaks the dialogue
+ dialogueText.setText('Enemigo: "nai Nai nai Nair"');
+ tween(enemyCharacter, {
+ scaleX: 3.3,
+ scaleY: 3.3
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(enemyCharacter, {
+ scaleX: 3.0,
+ scaleY: 3.0
+ }, {
+ duration: 300,
+ easing: tween.easeIn
+ });
+ }
+ });
+ // After 2 seconds, fade out and continue collision
+ LK.setTimeout(function () {
+ // Fade out all cinematic elements
+ tween(enemyCharacter, {
+ alpha: 0
+ }, {
+ duration: 800,
+ easing: tween.easeOut
+ });
+ tween(dialogueBox, {
+ alpha: 0
+ }, {
+ duration: 800,
+ easing: tween.easeOut
+ });
+ tween(dialogueText, {
+ alpha: 0
+ }, {
+ duration: 800,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ // Clean up cinematic elements
+ enemyCharacter.destroy();
+ dialogueBox.destroy();
+ dialogueText.destroy();
+ // Resume game state
+ gameState = 'playing';
+ // Continue with collision
+ var explosion = new Explosion(self.x, self.y);
+ game.addChild(explosion);
+ // Play explosion sound
+ LK.getSound('explosion').play();
+ // Airplane crashed into fortress - hide all non-alternate enemies
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ // Hide enemies that are not airplanes
+ if (!enemy.direction && !enemy.speed === undefined) {
+ enemy.visible = false;
+ }
+ }
+ // Stop enemy spawning by setting current scenario permanently
+ currentScenario = 'alternate';
+ // Airplane crashed into fortress - game over
+ LK.effects.flashObject(fortress, 0xFF0000, 1000);
+ LK.effects.flashScreen(0xFF0000, 1000);
+ gameOver = true;
+ self.markForDestroy = true;
+ }
+ });
+ }, 2000);
+ }, 1200);
return;
}
}
// Remove when off screen
Una lanza para el guerrero. In-Game asset. 2d. High contrast. No shadows
Flecha. In-Game asset. 2d. High contrast. No shadows
Trollface. In-Game asset. 2d. High contrast. No shadows
Personaje aterrador. In-Game asset. 2d. High contrast. No shadows
Ogro. In-Game asset. 2d. High contrast. No shadows
Ogro músculoso y gigante. In-Game asset. 2d. High contrast. No shadows
Lucky block. In-Game asset. 2d. High contrast. No shadows
Torres gemelas. In-Game asset. 2d. High contrast. No shadows
Avión de color gris sin ruedas 8 bit. In-Game asset. 2d. High contrast. No shadows
Explosión efecto. In-Game asset. 2d. High contrast. No shadows
Cuadrado con signo de !. In-Game asset. 2d. High contrast. No shadows
Imagien bde un jefe terrorífico humanoide de color negro. In-Game asset. 2d. High contrast. No shadows