User prompt
que los objetos jiren y se muevan ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que el fondo del menu tenga obgetos girando por la pantalla ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'ReferenceError: scoreTxt is not defined' in or related to this line: 'scoreTxt.setText('Score: ' + LK.getScore());' Line Number: 1576
User prompt
Please fix the bug: 'Uncaught ReferenceError: waveTxt is not defined' in or related to this line: 'waveTxt.setText('Wave: ' + currentWave);' Line Number: 1360
User prompt
Please fix the bug: 'LK.setSoundVolume is not a function' in or related to this line: 'LK.setSoundVolume(gameOptions.soundVolume / 100);' Line Number: 606
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var savedOptions = storage.get('gameOptions');' Line Number: 583 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
has funsionar las obciones
User prompt
Please fix the bug: 'Uncaught ReferenceError: waveTxt is not defined' in or related to this line: 'waveTxt.setText('Wave: ' + currentWave);' Line Number: 1124
User prompt
crea un menu con las obciones de jugar creditos y obciones
User prompt
que el menu tenga jugar obciones y creditos
User prompt
que haya un menu prinsipal
User prompt
que haya un menu prinsipal con los botones obciones de sonido empesar y creditos.ademas de que el fondo sea de cascos espadas y escudos
User prompt
que cada 5 ordas haya un jefe final que al morir nos de un multiplicador por 5 de daño por 3 rondas ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que la piedra sean ataques infinitos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que la piedra se dirija al enrmigo apenas se presione el boton ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que haya un ataque que sea lejano que lanse una piedra teledirigida ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que cada 100000 de puntage lanse confeti y le triplique el daño a la foca por 10 segundos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
y que ademas de curar a la foca le de un escudo que dure 5 segundos y le de imunidad ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
cada fin de una horda se le dara a la foca un pescado para curarse ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
los ataques tienen que ser instantaneos apenas toque el boton ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que al atacar no se aga daño por 3 segundos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que tengan botones rojos por ataque
User prompt
que cada ataque tenga distintas animaciones ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que cada ataque se actibe con un boton en la pantalla
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of null (reading 'takeDamage')' in or related to this line: 'target.takeDamage(attack.damage);' Line Number: 188
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var HealthBar = Container.expand(function (maxHealth) {
var self = Container.call(this);
self.maxHealth = maxHealth || 100;
self.currentHealth = self.maxHealth;
var bgBar = self.attachAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5
});
var healthBar = self.attachAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
x: -50
});
self.updateHealth = function (health) {
self.currentHealth = Math.max(0, health);
var healthPercent = self.currentHealth / self.maxHealth;
healthBar.width = 100 * healthPercent;
if (healthPercent > 0.6) {
healthBar.tint = 0x00FF00; // Green
} else if (healthPercent > 0.3) {
healthBar.tint = 0xFFFF00; // Yellow
} else {
healthBar.tint = 0xFF0000; // Red
}
};
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Create background decorations
self.createBackground = function () {
// Create scattered helmets, swords and shields
for (var i = 0; i < 30; i++) {
var decoration;
var type = Math.floor(Math.random() * 3);
if (type === 0) {
decoration = self.addChild(LK.getAsset('helmet', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
rotation: Math.random() * Math.PI * 2,
alpha: 0.3
}));
} else if (type === 1) {
decoration = self.addChild(LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
rotation: Math.random() * Math.PI * 2,
alpha: 0.3
}));
} else {
decoration = self.addChild(LK.getAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
rotation: Math.random() * Math.PI * 2,
alpha: 0.3
}));
}
// Animate decorations floating
tween(decoration, {
y: decoration.y + (Math.random() - 0.5) * 100,
rotation: decoration.rotation + Math.PI * 2
}, {
duration: 5000 + Math.random() * 3000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (this.parent) {
tween(this, {
y: this.y - (Math.random() - 0.5) * 100,
rotation: this.rotation + Math.PI * 2
}, {
duration: 5000 + Math.random() * 3000,
easing: tween.easeInOut
});
}
}
});
}
};
// Create title
var titleText = new Text2('ARENA SEALS', {
size: 120,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 500;
self.addChild(titleText);
// Create menu buttons
var buttonData = [{
text: 'EMPEZAR',
y: 900
}, {
text: 'OPCIONES DE SONIDO',
y: 1050
}, {
text: 'CREDITOS',
y: 1200
}];
for (var i = 0; i < buttonData.length; i++) {
var buttonContainer = new Container();
var buttonBg = buttonContainer.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(buttonData[i].text, {
size: 40,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
buttonContainer.addChild(buttonText);
buttonContainer.x = 2048 / 2;
buttonContainer.y = buttonData[i].y;
buttonContainer.buttonType = buttonData[i].text;
buttonContainer.down = function (x, y, obj) {
if (this.buttonType === 'EMPEZAR') {
startGame();
} else if (this.buttonType === 'OPCIONES DE SONIDO') {
showSoundOptions();
} else if (this.buttonType === 'CREDITOS') {
showCredits();
}
};
self.addChild(buttonContainer);
}
self.createBackground();
return self;
});
var Seal = Container.expand(function (isPlayer) {
var self = Container.call(this);
self.isPlayer = isPlayer || false;
self.maxHealth = 100;
self.currentHealth = self.maxHealth;
self.attackDamage = 25;
self.speed = 3;
self.lastAttackTime = 0;
self.attackCooldown = 1000; // 1 second
self.isInvincible = false;
self.invincibilityDuration = 3000; // 3 seconds
var sealBody = self.attachAsset(isPlayer ? 'playerSeal' : 'enemySeal', {
anchorX: 0.5,
anchorY: 0.5
});
self.healthBar = self.addChild(new HealthBar(self.maxHealth));
self.healthBar.y = -80;
self.takeDamage = function (damage) {
// Check if invincible
if (self.isInvincible) {
return; // No damage during invincibility
}
// Check if player has shield active
if (self.isPlayer && shieldActive) {
return; // No damage during shield
}
self.currentHealth -= damage;
self.healthBar.updateHealth(self.currentHealth);
// Flash effect when taking damage
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.currentHealth <= 0) {
self.die();
}
};
self.die = function () {
LK.getSound('defeat').play();
self.isDead = true;
// Death animation
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500,
onFinish: function onFinish() {
if (self.parent) {
self.destroy();
}
}
});
};
// Attack system properties
self.currentAttack = 0; // 0-4 for different attacks
self.isCharging = false;
self.chargeStartTime = 0;
self.chargingIndicator = null;
// Define 5 different attacks with different charge times and effects
self.attackTypes = [{
name: 'Quick Strike',
chargeTime: 200,
// 0.2 seconds
damage: 15,
color: 0xFFFF00,
scale: 1.1
}, {
name: 'Power Slam',
chargeTime: 800,
// 0.8 seconds
damage: 35,
color: 0xFF4500,
scale: 1.3
}, {
name: 'Spinning Attack',
chargeTime: 1200,
// 1.2 seconds
damage: 45,
color: 0x9932CC,
scale: 1.4
}, {
name: 'Devastating Blow',
chargeTime: 2000,
// 2 seconds
damage: 60,
color: 0xFF0000,
scale: 1.6
}, {
name: 'Ultimate Strike',
chargeTime: 3000,
// 3 seconds
damage: 80,
color: 0x00FFFF,
scale: 1.8
}, {
name: 'Stone Throw',
chargeTime: 1000,
// 1 second
damage: 40,
color: 0x8B4513,
scale: 1.2,
ranged: true
}];
self.startCharging = function () {
if (self.isCharging) return;
self.isCharging = true;
self.chargeStartTime = Date.now();
// Create charging indicator
if (!self.chargingIndicator) {
self.chargingIndicator = self.addChild(LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
y: -100,
width: 0,
height: 8
}));
}
var attack = self.attackTypes[self.currentAttack];
self.chargingIndicator.tint = attack.color;
self.chargingIndicator.visible = true;
// Animate charging indicator
tween(self.chargingIndicator, {
width: 120
}, {
duration: attack.chargeTime,
easing: tween.linear
});
// Charging visual effect on seal
tween(self, {
tint: attack.color
}, {
duration: attack.chargeTime / 4,
easing: tween.easeInOut
});
};
self.releaseAttack = function (target) {
if (!self.isCharging) return;
var currentTime = Date.now();
var chargeTime = currentTime - self.chargeStartTime;
var attack = self.attackTypes[self.currentAttack];
// Stop charging
self.isCharging = false;
if (self.chargingIndicator) {
self.chargingIndicator.visible = false;
tween.stop(self.chargingIndicator);
}
// Reset seal color
tween.stop(self);
tween(self, {
tint: 0xFFFFFF
}, {
duration: 200
});
// Check if we have a valid target before attacking
if (!target) return;
// Check if charge time was sufficient
if (chargeTime >= attack.chargeTime) {
// Full power attack
target.takeDamage(attack.damage);
LK.getSound('hit').play();
// Attack animation based on attack type
if (self.currentAttack === 0) {
// Quick Strike - Fast dart forward
var originalX = self.x;
var originalY = self.y;
var angle = Math.atan2(target.y - self.y, target.x - self.x);
tween(self, {
x: self.x + Math.cos(angle) * 30,
y: self.y + Math.sin(angle) * 30,
scaleX: attack.scale,
scaleY: attack.scale
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
x: originalX,
y: originalY,
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeIn
});
}
});
} else if (self.currentAttack === 1) {
// Power Slam - Bounce up and down
tween(self, {
y: self.y - 40,
scaleX: attack.scale,
scaleY: attack.scale * 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: self.y + 40,
scaleX: 1,
scaleY: 0.8
}, {
duration: 150,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(self, {
scaleY: 1
}, {
duration: 100
});
}
});
}
});
} else if (self.currentAttack === 2) {
// Spinning Attack - Full rotation with scale
tween(self, {
rotation: Math.PI * 2,
scaleX: attack.scale,
scaleY: attack.scale
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: 0,
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
} else if (self.currentAttack === 3) {
var _doPulse = function doPulse() {
tween(self, {
scaleX: attack.scale,
scaleY: attack.scale,
tint: 0xFF4444
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.1,
scaleY: 1.1,
tint: 0xFFFFFF
}, {
duration: 80,
easing: tween.easeIn,
onFinish: function onFinish() {
pulseCount++;
if (pulseCount < maxPulses) {
_doPulse();
} else {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
}
});
}
});
};
// Devastating Blow - Multiple quick pulses
var pulseCount = 0;
var maxPulses = 3;
_doPulse();
} else if (self.currentAttack === 4) {
var _doShake = function doShake() {
var shakeAmount = 15;
tween(self, {
x: originalX + (Math.random() - 0.5) * shakeAmount,
y: originalY + (Math.random() - 0.5) * shakeAmount,
scaleX: 1 + shakeCount * 0.1,
scaleY: 1 + shakeCount * 0.1
}, {
duration: 50,
onFinish: function onFinish() {
shakeCount++;
if (shakeCount < maxShakes) {
_doShake();
} else {
// Final explosive strike
tween(self, {
x: originalX,
y: originalY,
scaleX: attack.scale,
scaleY: attack.scale,
tint: 0x00FFFF
}, {
duration: 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1,
tint: 0xFFFFFF
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
}
});
};
// Ultimate Strike - Charge up with shake then explosive strike
var originalX = self.x;
var originalY = self.y;
var shakeCount = 0;
var maxShakes = 8;
_doShake();
}
// Flash effect with attack color
LK.effects.flashObject(target, attack.color, 300);
// Activate invincibility for 3 seconds
self.isInvincible = true;
// Visual feedback for invincibility - make seal semi-transparent and glow
tween(self, {
alpha: 0.6,
tint: 0x00FFFF
}, {
duration: 200,
onFinish: function onFinish() {
// Pulsing effect during invincibility
var _pulseEffect = function pulseEffect() {
if (self.isInvincible) {
tween(self, {
alpha: 0.4
}, {
duration: 300,
onFinish: function onFinish() {
if (self.isInvincible) {
tween(self, {
alpha: 0.6
}, {
duration: 300,
onFinish: _pulseEffect
});
}
}
});
}
};
_pulseEffect();
}
});
// End invincibility after duration
LK.setTimeout(function () {
self.isInvincible = false;
// Restore normal appearance
tween(self, {
alpha: 1,
tint: 0xFFFFFF
}, {
duration: 300
});
}, self.invincibilityDuration);
} else {
// Partial charge - reduced damage
var chargePercent = chargeTime / attack.chargeTime;
var reducedDamage = Math.floor(attack.damage * chargePercent * 0.5);
if (reducedDamage > 0 && target) {
target.takeDamage(reducedDamage);
LK.getSound('hit').play();
}
// Weak attack animation
tween(self, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
}
};
self.cycleAttack = function () {
if (!self.isCharging) {
self.currentAttack = (self.currentAttack + 1) % 6;
}
};
self.attack = function (target) {
var currentTime = Date.now();
if (currentTime - self.lastAttackTime > self.attackCooldown) {
target.takeDamage(self.attackDamage);
LK.getSound('hit').play();
self.lastAttackTime = currentTime;
// Attack animation
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
}
};
return self;
});
var EnemySeal = Seal.expand(function () {
var self = Seal.call(this, false);
self.moveDirection = Math.random() * Math.PI * 2;
self.directionChangeTime = 0;
self.lastPlayerDistance = 1000;
self.update = function () {
if (self.isDead) return;
// Change direction occasionally
if (LK.ticks % 120 === 0) {
self.moveDirection = Math.random() * Math.PI * 2;
}
// Move towards player if close enough
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (distanceToPlayer < 300) {
var angleToPlayer = Math.atan2(player.y - self.y, player.x - self.x);
self.moveDirection = angleToPlayer;
}
// Move
self.x += Math.cos(self.moveDirection) * self.speed;
self.y += Math.sin(self.moveDirection) * self.speed;
// Keep within arena bounds
var centerX = 2048 / 2;
var centerY = 2732 / 2;
var arenaRadius = 700;
var distFromCenter = Math.sqrt(Math.pow(self.x - centerX, 2) + Math.pow(self.y - centerY, 2));
if (distFromCenter > arenaRadius) {
var angleToCenter = Math.atan2(centerY - self.y, centerX - self.x);
self.moveDirection = angleToCenter;
}
// Attack player if touching
if (self.intersects(player) && !player.isDead) {
self.attack(player);
}
};
return self;
});
var Boss = EnemySeal.expand(function () {
var self = EnemySeal.call(this);
// Boss has much higher stats
self.maxHealth = 300;
self.currentHealth = self.maxHealth;
self.attackDamage = 40;
self.speed = 2; // Slower but more dangerous
self.healthBar.updateHealth(self.currentHealth);
// Make boss visually distinct - larger and different color
self.children[0].scaleX = 2.0;
self.children[0].scaleY = 2.0;
self.children[0].tint = 0xFF4500; // Orange color for boss
// Boss death gives damage multiplier
self.die = function () {
LK.getSound('defeat').play();
self.isDead = true;
// Give boss damage multiplier for 3 rounds
bossDamageMultiplier = 5;
bossDamageBoostActive = true;
bossRoundsCompleted = 0;
// Visual feedback for boss damage boost
tween(player, {
tint: 0xFF0000 // Red glow for boss damage boost
}, {
duration: 500,
onFinish: function onFinish() {
// Pulsing effect during boss damage boost
var _pulseBossBoost = function pulseBossBoost() {
if (bossDamageBoostActive) {
tween(player, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 700,
onFinish: function onFinish() {
if (bossDamageBoostActive) {
tween(player, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 700,
onFinish: _pulseBossBoost
});
}
}
});
}
};
_pulseBossBoost();
}
});
// Flash screen to indicate boss defeat
LK.effects.flashScreen(0xFF0000, 1500);
// Death animation
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 1000,
onFinish: function onFinish() {
if (self.parent) {
self.destroy();
}
}
});
};
return self;
});
var Stone = Container.expand(function (target) {
var self = Container.call(this);
var stoneGraphics = self.attachAsset('stone', {
anchorX: 0.5,
anchorY: 0.5
});
self.target = target;
self.speed = 8;
self.damage = 40;
self.lifetime = 0;
self.maxLifetime = 3000; // 3 seconds max
self.update = function () {
if (!self.target || self.target.isDead) {
// Remove stone if target is dead
if (self.parent) {
self.destroy();
}
return;
}
// Calculate direction to target
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize direction and move towards target
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Check collision with target
if (self.intersects(self.target)) {
self.target.takeDamage(self.damage);
LK.getSound('hit').play();
LK.effects.flashObject(self.target, 0x8B4513, 300);
if (self.parent) {
self.destroy();
}
return;
}
// Remove stone after maximum lifetime
self.lifetime += 16; // Approximate frame time at 60fps
if (self.lifetime > self.maxLifetime) {
if (self.parent) {
self.destroy();
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state variables
var gameState = 'menu'; // 'menu', 'playing', 'waveComplete', 'gameOver', 'soundOptions', 'credits'
var mainMenu = null;
var soundVolume = 1.0;
// Game variables
var player;
var enemies = [];
var stones = [];
var currentWave = 1;
var enemiesInWave = 3;
var waveStartTime = 0;
var dragNode = null;
var healingFish = null;
var shieldActive = false;
var shieldDuration = 5000; // 5 seconds
var lastScoreMilestone = 0;
var damageMultiplier = 1;
var damageBoostActive = false;
var damageBoostDuration = 10000; // 10 seconds
var bossRoundsCompleted = 0;
var bossDamageMultiplier = 1;
var bossDamageBoostActive = false;
var bossDamageBoostDuration = 3; // 3 rounds
var currentBoss = null;
// UI Elements (will be created when game starts)
var scoreTxt,
waveTxt,
attackTxt,
attackButtons = [],
instructionTxt;
var arenaOuter, arenaInner;
function showMainMenu() {
// Clear any existing game elements
if (player) player.destroy();
if (arenaOuter) arenaOuter.destroy();
if (arenaInner) arenaInner.destroy();
// Clear arrays
enemies = [];
stones = [];
attackButtons = [];
// Clear GUI elements
if (scoreTxt && scoreTxt.parent) scoreTxt.destroy();
if (waveTxt && waveTxt.parent) waveTxt.destroy();
if (attackTxt && attackTxt.parent) attackTxt.destroy();
if (instructionTxt && instructionTxt.parent) instructionTxt.destroy();
gameState = 'menu';
mainMenu = game.addChild(new MainMenu());
}
function startGame() {
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
gameState = 'playing';
currentWave = 1;
enemiesInWave = 3;
LK.setScore(0);
// Reset game variables
lastScoreMilestone = 0;
damageMultiplier = 1;
damageBoostActive = false;
bossRoundsCompleted = 0;
bossDamageMultiplier = 1;
bossDamageBoostActive = false;
shieldActive = false;
// Create arena
arenaOuter = game.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
}));
arenaInner = game.addChild(LK.getAsset('arenaFloor', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
}));
// Create player
player = game.addChild(new Seal(true));
player.x = 2048 / 2;
player.y = 2732 / 2 + 200;
// Create UI Elements
scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
scoreTxt.x = 120;
scoreTxt.y = 50;
LK.gui.topLeft.addChild(scoreTxt);
waveTxt = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(waveTxt);
// Attack type display
attackTxt = new Text2('Attack: Quick Strike', {
size: 40,
fill: 0xFFFF00
});
attackTxt.anchor.set(0.5, 0);
attackTxt.y = 50;
LK.gui.top.addChild(attackTxt);
// Create attack buttons
attackButtons = [];
for (var i = 0; i < 6; i++) {
var button = new Container();
var buttonBg = button.attachAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
width: 160,
height: 80
});
// Make button background red
buttonBg.tint = 0xFF0000;
var buttonText = new Text2(player.attackTypes[i].name, {
size: 24,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
button.addChild(buttonText);
// Position buttons horizontally across bottom of screen
button.x = (i - 2.5) * 160;
button.y = -120;
// Store button index for reference
button.attackIndex = i;
// Button click handler
button.down = function (x, y, obj) {
if (gameState === 'playing' && !player.isDead) {
player.currentAttack = this.attackIndex;
attackTxt.setText('Attack: ' + player.attackTypes[player.currentAttack].name);
attackTxt.tint = player.attackTypes[player.currentAttack].color;
// Special handling for stone throw attack (infinite usage)
if (player.currentAttack === 5) {
// Find closest enemy for stone targeting
var stoneTarget = null;
var closestStoneDistance = Infinity;
for (var m = 0; m < enemies.length; m++) {
var enemy = enemies[m];
if (enemy && !enemy.isDead) {
var distance = Math.sqrt(Math.pow(player.x - enemy.x, 2) + Math.pow(player.y - enemy.y, 2));
if (distance < closestStoneDistance) {
closestStoneDistance = distance;
stoneTarget = enemy;
}
}
}
if (stoneTarget) {
var stone = new Stone(stoneTarget);
stone.x = player.x;
stone.y = player.y;
stones.push(stone);
game.addChild(stone);
// Throwing animation
var attack = player.attackTypes[player.currentAttack];
tween(player, {
scaleX: attack.scale,
scaleY: attack.scale,
rotation: Math.PI / 4
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(player, {
scaleX: 1,
scaleY: 1,
rotation: 0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
}
// Update button visual states for stone attack
for (var j = 0; j < attackButtons.length; j++) {
if (j === player.currentAttack) {
attackButtons[j].children[0].tint = 0xFFAAAA; // Lighter red for selected
attackButtons[j].children[1].tint = 0x000000;
} else {
attackButtons[j].children[0].tint = 0xFF0000; // Red for unselected
attackButtons[j].children[1].tint = 0xFFFFFF;
}
}
return; // Exit early for stone attacks to avoid melee logic
}
// Find closest enemy and attack instantly for melee attacks
var closestEnemy = null;
var closestDistance = Infinity;
for (var k = 0; k < enemies.length; k++) {
var enemy = enemies[k];
if (enemy && !enemy.isDead) {
var distance = Math.sqrt(Math.pow(player.x - enemy.x, 2) + Math.pow(player.y - enemy.y, 2));
if (distance < closestDistance && distance < 200) {
// Attack range
closestDistance = distance;
closestEnemy = enemy;
}
}
}
// Execute instant attack if enemy in range
if (closestEnemy) {
var attack = player.attackTypes[player.currentAttack];
var finalDamage = attack.damage * damageMultiplier * bossDamageMultiplier;
closestEnemy.takeDamage(finalDamage);
LK.getSound('hit').play();
// Execute attack animation instantly
if (player.currentAttack === 0) {
// Quick Strike - Fast dart forward
var originalX = player.x;
var originalY = player.y;
var angle = Math.atan2(closestEnemy.y - player.y, closestEnemy.x - player.x);
tween(player, {
x: player.x + Math.cos(angle) * 30,
y: player.y + Math.sin(angle) * 30,
scaleX: attack.scale,
scaleY: attack.scale
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(player, {
x: originalX,
y: originalY,
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeIn
});
}
});
} else if (player.currentAttack === 1) {
// Power Slam - Bounce up and down
tween(player, {
y: player.y - 40,
scaleX: attack.scale,
scaleY: attack.scale * 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(player, {
y: player.y + 40,
scaleX: 1,
scaleY: 0.8
}, {
duration: 150,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(player, {
scaleY: 1
}, {
duration: 100
});
}
});
}
});
} else if (player.currentAttack === 2) {
// Spinning Attack - Full rotation with scale
tween(player, {
rotation: Math.PI * 2,
scaleX: attack.scale,
scaleY: attack.scale
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(player, {
rotation: 0,
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
} else if (player.currentAttack === 3) {
// Devastating Blow - Multiple quick pulses
var pulseCount = 0;
var maxPulses = 3;
var _doPulse2 = function doPulse() {
tween(player, {
scaleX: attack.scale,
scaleY: attack.scale,
tint: 0xFF4444
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(player, {
scaleX: 1.1,
scaleY: 1.1,
tint: 0xFFFFFF
}, {
duration: 80,
easing: tween.easeIn,
onFinish: function onFinish() {
pulseCount++;
if (pulseCount < maxPulses) {
_doPulse2();
} else {
tween(player, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
}
});
}
});
};
_doPulse2();
} else if (player.currentAttack === 4) {
// Ultimate Strike - Charge up with shake then explosive strike
var originalX = player.x;
var originalY = player.y;
var shakeCount = 0;
var maxShakes = 8;
var _doShake2 = function doShake() {
var shakeAmount = 15;
tween(player, {
x: originalX + (Math.random() - 0.5) * shakeAmount,
y: originalY + (Math.random() - 0.5) * shakeAmount,
scaleX: 1 + shakeCount * 0.1,
scaleY: 1 + shakeCount * 0.1
}, {
duration: 50,
onFinish: function onFinish() {
shakeCount++;
if (shakeCount < maxShakes) {
_doShake2();
} else {
// Final explosive strike
tween(player, {
x: originalX,
y: originalY,
scaleX: attack.scale,
scaleY: attack.scale,
tint: 0x00FFFF
}, {
duration: 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(player, {
scaleX: 1,
scaleY: 1,
tint: 0xFFFFFF
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
}
});
};
_doShake2();
}
// Flash effect with attack color
if (closestEnemy) {
LK.effects.flashObject(closestEnemy, attack.color, 300);
}
// Activate invincibility for 3 seconds
player.isInvincible = true;
// Visual feedback for invincibility - make seal semi-transparent and glow
tween(player, {
alpha: 0.6,
tint: 0x00FFFF
}, {
duration: 200,
onFinish: function onFinish() {
// Pulsing effect during invincibility
var _pulseEffect2 = function pulseEffect() {
if (player.isInvincible) {
tween(player, {
alpha: 0.4
}, {
duration: 300,
onFinish: function onFinish() {
if (player.isInvincible) {
tween(player, {
alpha: 0.6
}, {
duration: 300,
onFinish: _pulseEffect2
});
}
}
});
}
};
_pulseEffect2();
}
});
// End invincibility after duration
LK.setTimeout(function () {
player.isInvincible = false;
// Restore normal appearance
tween(player, {
alpha: 1,
tint: 0xFFFFFF
}, {
duration: 300
});
}, player.invincibilityDuration);
LK.setScore(LK.getScore() + 100);
scoreTxt.setText('Score: ' + LK.getScore());
checkScoreMilestone();
}
// Update button visual states
for (var j = 0; j < attackButtons.length; j++) {
if (j === player.currentAttack) {
attackButtons[j].children[0].tint = 0xFFAAAA; // Lighter red for selected
attackButtons[j].children[1].tint = 0x000000;
} else {
attackButtons[j].children[0].tint = 0xFF0000; // Red for unselected
attackButtons[j].children[1].tint = 0xFFFFFF;
}
}
}
};
attackButtons.push(button);
LK.gui.bottom.addChild(button);
}
// Set initial button states
attackButtons[0].children[0].tint = 0xFFAAAA; // Lighter red for selected
attackButtons[0].children[1].tint = 0x000000;
for (var i = 1; i < attackButtons.length; i++) {
attackButtons[i].children[0].tint = 0xFF0000; // Red for unselected
attackButtons[i].children[1].tint = 0xFFFFFF;
}
// Instructions
instructionTxt = new Text2('Select attack with buttons | Touch buttons to attack nearby enemies', {
size: 30,
fill: 0xCCCCCC
});
instructionTxt.anchor.set(0.5, 1);
instructionTxt.y = -40;
LK.gui.bottom.addChild(instructionTxt);
// Initialize with main menu
showMainMenu();
// Modify game update to handle different states
var originalUpdate = game.update;
game.update = function () {
if (gameState === 'playing') {
originalUpdate();
}
// Other states don't need update logic
};
// Override input handlers for menu states
var originalDown = game.down;
game.down = function (x, y, obj) {
if (gameState === 'playing') {
originalDown(x, y, obj);
}
};
var originalMove = game.move;
game.move = function (x, y, obj) {
if (gameState === 'playing') {
originalMove(x, y, obj);
}
};
var originalUp = game.up;
game.up = function (x, y, obj) {
if (gameState === 'playing') {
originalUp(x, y, obj);
}
};
}
function showSoundOptions() {
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
gameState = 'soundOptions';
var soundMenu = game.addChild(new Container());
var titleText = new Text2('OPCIONES DE SONIDO', {
size: 80,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 600;
soundMenu.addChild(titleText);
var volumeText = new Text2('Volumen: ' + Math.round(soundVolume * 100) + '%', {
size: 50,
fill: 0xFFFFFF
});
volumeText.anchor.set(0.5, 0.5);
volumeText.x = 2048 / 2;
volumeText.y = 800;
soundMenu.addChild(volumeText);
// Volume up button
var volumeUpBtn = new Container();
var upBg = volumeUpBtn.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 150,
height: 60
});
var upText = new Text2('+', {
size: 40,
fill: 0xFFFFFF
});
upText.anchor.set(0.5, 0.5);
volumeUpBtn.addChild(upText);
volumeUpBtn.x = 2048 / 2 + 100;
volumeUpBtn.y = 900;
volumeUpBtn.down = function () {
soundVolume = Math.min(1.0, soundVolume + 0.1);
volumeText.setText('Volumen: ' + Math.round(soundVolume * 100) + '%');
};
soundMenu.addChild(volumeUpBtn);
// Volume down button
var volumeDownBtn = new Container();
var downBg = volumeDownBtn.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 150,
height: 60
});
var downText = new Text2('-', {
size: 40,
fill: 0xFFFFFF
});
downText.anchor.set(0.5, 0.5);
volumeDownBtn.addChild(downText);
volumeDownBtn.x = 2048 / 2 - 100;
volumeDownBtn.y = 900;
volumeDownBtn.down = function () {
soundVolume = Math.max(0.0, soundVolume - 0.1);
volumeText.setText('Volumen: ' + Math.round(soundVolume * 100) + '%');
};
soundMenu.addChild(volumeDownBtn);
// Back button
var backBtn = new Container();
var backBg = backBtn.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5
});
var backText = new Text2('VOLVER', {
size: 40,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backBtn.addChild(backText);
backBtn.x = 2048 / 2;
backBtn.y = 1100;
backBtn.down = function () {
soundMenu.destroy();
showMainMenu();
};
soundMenu.addChild(backBtn);
}
function showCredits() {
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
gameState = 'credits';
var creditsMenu = game.addChild(new Container());
var titleText = new Text2('CREDITOS', {
size: 80,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 500;
creditsMenu.addChild(titleText);
var gameText = new Text2('ARENA SEALS', {
size: 60,
fill: 0xFFFFFF
});
gameText.anchor.set(0.5, 0.5);
gameText.x = 2048 / 2;
gameText.y = 700;
creditsMenu.addChild(gameText);
var devText = new Text2('Desarrollado por FRVR', {
size: 40,
fill: 0xCCCCCC
});
devText.anchor.set(0.5, 0.5);
devText.x = 2048 / 2;
devText.y = 800;
creditsMenu.addChild(devText);
var engineText = new Text2('Creado con LK Engine', {
size: 40,
fill: 0xCCCCCC
});
engineText.anchor.set(0.5, 0.5);
engineText.x = 2048 / 2;
engineText.y = 850;
creditsMenu.addChild(engineText);
var thanksText = new Text2('¡Gracias por jugar!', {
size: 50,
fill: 0x00FF00
});
thanksText.anchor.set(0.5, 0.5);
thanksText.x = 2048 / 2;
thanksText.y = 950;
creditsMenu.addChild(thanksText);
// Back button
var backBtn = new Container();
var backBg = backBtn.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5
});
var backText = new Text2('VOLVER', {
size: 40,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backBtn.addChild(backText);
backBtn.x = 2048 / 2;
backBtn.y = 1150;
backBtn.down = function () {
creditsMenu.destroy();
showMainMenu();
};
creditsMenu.addChild(backBtn);
}
// Create arena
var arenaOuter = game.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
}));
var arenaInner = game.addChild(LK.getAsset('arenaFloor', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
}));
// Create player
player = game.addChild(new Seal(true));
player.x = 2048 / 2;
player.y = 2732 / 2 + 200;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
scoreTxt.x = 120;
scoreTxt.y = 50;
LK.gui.topLeft.addChild(scoreTxt);
var waveTxt = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(waveTxt);
// Attack type display
var attackTxt = new Text2('Attack: Quick Strike', {
size: 40,
fill: 0xFFFF00
});
attackTxt.anchor.set(0.5, 0);
attackTxt.y = 50;
LK.gui.top.addChild(attackTxt);
// Create attack buttons
var attackButtons = [];
for (var i = 0; i < 6; i++) {
var button = new Container();
var buttonBg = button.attachAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
width: 160,
height: 80
});
// Make button background red
buttonBg.tint = 0xFF0000;
var buttonText = new Text2(player.attackTypes[i].name, {
size: 24,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
button.addChild(buttonText);
// Position buttons horizontally across bottom of screen
button.x = (i - 2.5) * 160;
button.y = -120;
// Store button index for reference
button.attackIndex = i;
// Button click handler
button.down = function (x, y, obj) {
if (gameState === 'playing' && !player.isDead) {
player.currentAttack = this.attackIndex;
attackTxt.setText('Attack: ' + player.attackTypes[player.currentAttack].name);
attackTxt.tint = player.attackTypes[player.currentAttack].color;
// Special handling for stone throw attack (infinite usage)
if (player.currentAttack === 5) {
// Find closest enemy for stone targeting
var stoneTarget = null;
var closestStoneDistance = Infinity;
for (var m = 0; m < enemies.length; m++) {
var enemy = enemies[m];
if (enemy && !enemy.isDead) {
var distance = Math.sqrt(Math.pow(player.x - enemy.x, 2) + Math.pow(player.y - enemy.y, 2));
if (distance < closestStoneDistance) {
closestStoneDistance = distance;
stoneTarget = enemy;
}
}
}
if (stoneTarget) {
var stone = new Stone(stoneTarget);
stone.x = player.x;
stone.y = player.y;
stones.push(stone);
game.addChild(stone);
// Throwing animation
var attack = player.attackTypes[player.currentAttack];
tween(player, {
scaleX: attack.scale,
scaleY: attack.scale,
rotation: Math.PI / 4
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(player, {
scaleX: 1,
scaleY: 1,
rotation: 0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
}
// Update button visual states for stone attack
for (var j = 0; j < attackButtons.length; j++) {
if (j === player.currentAttack) {
attackButtons[j].children[0].tint = 0xFFAAAA; // Lighter red for selected
attackButtons[j].children[1].tint = 0x000000;
} else {
attackButtons[j].children[0].tint = 0xFF0000; // Red for unselected
attackButtons[j].children[1].tint = 0xFFFFFF;
}
}
return; // Exit early for stone attacks to avoid melee logic
}
// Find closest enemy and attack instantly for melee attacks
var closestEnemy = null;
var closestDistance = Infinity;
for (var k = 0; k < enemies.length; k++) {
var enemy = enemies[k];
if (enemy && !enemy.isDead) {
var distance = Math.sqrt(Math.pow(player.x - enemy.x, 2) + Math.pow(player.y - enemy.y, 2));
if (distance < closestDistance && distance < 200) {
// Attack range
closestDistance = distance;
closestEnemy = enemy;
}
}
}
// Execute instant attack if enemy in range
if (closestEnemy) {
var attack = player.attackTypes[player.currentAttack];
var finalDamage = attack.damage * damageMultiplier * bossDamageMultiplier;
closestEnemy.takeDamage(finalDamage);
LK.getSound('hit').play();
// Execute attack animation instantly
if (player.currentAttack === 0) {
// Quick Strike - Fast dart forward
var originalX = player.x;
var originalY = player.y;
var angle = Math.atan2(closestEnemy.y - player.y, closestEnemy.x - player.x);
tween(player, {
x: player.x + Math.cos(angle) * 30,
y: player.y + Math.sin(angle) * 30,
scaleX: attack.scale,
scaleY: attack.scale
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(player, {
x: originalX,
y: originalY,
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeIn
});
}
});
} else if (player.currentAttack === 1) {
// Power Slam - Bounce up and down
tween(player, {
y: player.y - 40,
scaleX: attack.scale,
scaleY: attack.scale * 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(player, {
y: player.y + 40,
scaleX: 1,
scaleY: 0.8
}, {
duration: 150,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(player, {
scaleY: 1
}, {
duration: 100
});
}
});
}
});
} else if (player.currentAttack === 2) {
// Spinning Attack - Full rotation with scale
tween(player, {
rotation: Math.PI * 2,
scaleX: attack.scale,
scaleY: attack.scale
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(player, {
rotation: 0,
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
} else if (player.currentAttack === 3) {
// Devastating Blow - Multiple quick pulses
var pulseCount = 0;
var maxPulses = 3;
var _doPulse2 = function doPulse() {
tween(player, {
scaleX: attack.scale,
scaleY: attack.scale,
tint: 0xFF4444
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(player, {
scaleX: 1.1,
scaleY: 1.1,
tint: 0xFFFFFF
}, {
duration: 80,
easing: tween.easeIn,
onFinish: function onFinish() {
pulseCount++;
if (pulseCount < maxPulses) {
_doPulse2();
} else {
tween(player, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
}
});
}
});
};
_doPulse2();
} else if (player.currentAttack === 4) {
// Ultimate Strike - Charge up with shake then explosive strike
var originalX = player.x;
var originalY = player.y;
var shakeCount = 0;
var maxShakes = 8;
var _doShake2 = function doShake() {
var shakeAmount = 15;
tween(player, {
x: originalX + (Math.random() - 0.5) * shakeAmount,
y: originalY + (Math.random() - 0.5) * shakeAmount,
scaleX: 1 + shakeCount * 0.1,
scaleY: 1 + shakeCount * 0.1
}, {
duration: 50,
onFinish: function onFinish() {
shakeCount++;
if (shakeCount < maxShakes) {
_doShake2();
} else {
// Final explosive strike
tween(player, {
x: originalX,
y: originalY,
scaleX: attack.scale,
scaleY: attack.scale,
tint: 0x00FFFF
}, {
duration: 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(player, {
scaleX: 1,
scaleY: 1,
tint: 0xFFFFFF
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
}
});
};
_doShake2();
}
// Flash effect with attack color
if (closestEnemy) {
LK.effects.flashObject(closestEnemy, attack.color, 300);
}
// Activate invincibility for 3 seconds
player.isInvincible = true;
// Visual feedback for invincibility - make seal semi-transparent and glow
tween(player, {
alpha: 0.6,
tint: 0x00FFFF
}, {
duration: 200,
onFinish: function onFinish() {
// Pulsing effect during invincibility
var _pulseEffect2 = function pulseEffect() {
if (player.isInvincible) {
tween(player, {
alpha: 0.4
}, {
duration: 300,
onFinish: function onFinish() {
if (player.isInvincible) {
tween(player, {
alpha: 0.6
}, {
duration: 300,
onFinish: _pulseEffect2
});
}
}
});
}
};
_pulseEffect2();
}
});
// End invincibility after duration
LK.setTimeout(function () {
player.isInvincible = false;
// Restore normal appearance
tween(player, {
alpha: 1,
tint: 0xFFFFFF
}, {
duration: 300
});
}, player.invincibilityDuration);
LK.setScore(LK.getScore() + 100);
scoreTxt.setText('Score: ' + LK.getScore());
checkScoreMilestone();
}
// Update button visual states
for (var j = 0; j < attackButtons.length; j++) {
if (j === player.currentAttack) {
attackButtons[j].children[0].tint = 0xFFAAAA; // Lighter red for selected
attackButtons[j].children[1].tint = 0x000000;
} else {
attackButtons[j].children[0].tint = 0xFF0000; // Red for unselected
attackButtons[j].children[1].tint = 0xFFFFFF;
}
}
}
};
attackButtons.push(button);
LK.gui.bottom.addChild(button);
}
// Set initial button states
attackButtons[0].children[0].tint = 0xFFAAAA; // Lighter red for selected
attackButtons[0].children[1].tint = 0x000000;
for (var i = 1; i < attackButtons.length; i++) {
attackButtons[i].children[0].tint = 0xFF0000; // Red for unselected
attackButtons[i].children[1].tint = 0xFFFFFF;
}
// Instructions
var instructionTxt = new Text2('Select attack with buttons | Touch buttons to attack nearby enemies', {
size: 30,
fill: 0xCCCCCC
});
instructionTxt.anchor.set(0.5, 1);
instructionTxt.y = -40;
LK.gui.bottom.addChild(instructionTxt);
// Functions
function spawnWave() {
enemies = [];
currentBoss = null;
waveStartTime = Date.now();
// Every 5th wave spawn a boss instead of regular enemies
if (currentWave % 5 === 0) {
// Boss wave
var boss = game.addChild(new Boss());
boss.x = 2048 / 2;
boss.y = 2732 / 2 - 200;
enemies.push(boss);
currentBoss = boss;
} else {
// Regular wave
for (var i = 0; i < enemiesInWave; i++) {
var enemy = game.addChild(new EnemySeal());
// Spawn enemies around the arena edge
var angle = i / enemiesInWave * Math.PI * 2;
var spawnRadius = 500;
enemy.x = 2048 / 2 + Math.cos(angle) * spawnRadius;
enemy.y = 2732 / 2 + Math.sin(angle) * spawnRadius;
enemies.push(enemy);
}
}
waveTxt.setText('Wave: ' + currentWave);
gameState = 'playing';
}
function createConfetti() {
// Create multiple confetti pieces
for (var i = 0; i < 50; i++) {
var confetti = game.addChild(LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
width: 10 + Math.random() * 10,
height: 10 + Math.random() * 10,
x: Math.random() * 2048,
y: -50
}));
// Random colors for confetti
var colors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF];
confetti.tint = colors[Math.floor(Math.random() * colors.length)];
// Animate confetti falling
tween(confetti, {
y: 2732 + 100,
rotation: Math.PI * 4 * (Math.random() - 0.5),
x: confetti.x + (Math.random() - 0.5) * 200
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
if (this.parent) {
this.destroy();
}
}
});
}
}
function checkScoreMilestone() {
var currentScore = LK.getScore();
var currentMilestone = Math.floor(currentScore / 100000);
if (currentMilestone > lastScoreMilestone) {
lastScoreMilestone = currentMilestone;
// Launch confetti
createConfetti();
// Activate triple damage for 10 seconds
damageMultiplier = 3;
damageBoostActive = true;
// Visual feedback for damage boost
tween(player, {
tint: 0xFF4500 // Orange glow for damage boost
}, {
duration: 300,
onFinish: function onFinish() {
// Pulsing effect during damage boost
var _pulseDamageBoost = function pulseDamageBoost() {
if (damageBoostActive) {
tween(player, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 500,
onFinish: function onFinish() {
if (damageBoostActive) {
tween(player, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 500,
onFinish: _pulseDamageBoost
});
}
}
});
}
};
_pulseDamageBoost();
}
});
// End damage boost after duration
LK.setTimeout(function () {
damageMultiplier = 1;
damageBoostActive = false;
// Restore normal appearance
tween(player, {
tint: 0xFFFFFF,
scaleX: 1,
scaleY: 1
}, {
duration: 500
});
}, damageBoostDuration);
// Flash screen to indicate milestone
LK.effects.flashScreen(0xFFD700, 1000);
}
}
function spawnHealingFish() {
if (healingFish) return; // Don't spawn if fish already exists
healingFish = game.addChild(LK.getAsset('fish', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 150
}));
// Animate fish floating and glowing
tween(healingFish, {
y: healingFish.y - 20,
tint: 0x00FFFF
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(healingFish, {
y: healingFish.y + 20,
tint: 0xFFFFFF
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (healingFish && healingFish.parent) {
spawnHealingFish(); // Continue animation loop
}
}
});
}
});
// Make fish clickable for healing
healingFish.down = function (x, y, obj) {
if (player && !player.isDead) {
// Heal player to full health
player.currentHealth = player.maxHealth;
player.healthBar.updateHealth(player.currentHealth);
// Activate shield for 5 seconds
shieldActive = true;
// Visual feedback for shield - golden glow
tween(player, {
alpha: 0.8,
tint: 0xFFD700 // Golden color for shield
}, {
duration: 300,
onFinish: function onFinish() {
// Pulsing shield effect
var _shieldPulse = function shieldPulse() {
if (shieldActive) {
tween(player, {
alpha: 0.6
}, {
duration: 400,
onFinish: function onFinish() {
if (shieldActive) {
tween(player, {
alpha: 0.8
}, {
duration: 400,
onFinish: _shieldPulse
});
}
}
});
}
};
_shieldPulse();
}
});
// End shield after duration
LK.setTimeout(function () {
shieldActive = false;
// Restore normal appearance
tween(player, {
alpha: 1,
tint: 0xFFFFFF
}, {
duration: 500
});
}, shieldDuration);
// Fish consumption animation
tween(healingFish, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0,
tint: 0x00FF00
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
if (healingFish && healingFish.parent) {
healingFish.destroy();
healingFish = null;
}
}
});
// Flash player green to show healing
LK.effects.flashObject(player, 0x00FF00, 500);
}
};
}
function nextWave() {
currentWave++;
enemiesInWave += 2; // Increase difficulty
// Handle boss damage boost round tracking
if (bossDamageBoostActive) {
bossRoundsCompleted++;
if (bossRoundsCompleted >= bossDamageBoostDuration) {
// End boss damage boost after 3 rounds
bossDamageMultiplier = 1;
bossDamageBoostActive = false;
bossRoundsCompleted = 0;
// Restore normal appearance
tween(player, {
tint: 0xFFFFFF,
scaleX: 1,
scaleY: 1
}, {
duration: 500
});
}
}
// Spawn healing fish at the end of each wave
spawnHealingFish();
LK.setTimeout(function () {
spawnWave();
}, 2000);
gameState = 'waveComplete';
}
function checkWaveComplete() {
var aliveEnemies = 0;
for (var i = 0; i < enemies.length; i++) {
if (enemies[i] && !enemies[i].isDead) {
aliveEnemies++;
}
}
if (aliveEnemies === 0 && gameState === 'playing') {
// Wave complete bonus
var timeBonus = Math.max(0, 10000 - (Date.now() - waveStartTime)) / 100;
LK.setScore(LK.getScore() + 500 + Math.floor(timeBonus));
scoreTxt.setText('Score: ' + LK.getScore());
checkScoreMilestone();
if (currentWave >= 5) {
// Victory condition
LK.showYouWin();
} else {
nextWave();
}
}
}
// Input handling
game.down = function (x, y, obj) {
if (gameState === 'playing' && !player.isDead) {
// Start dragging for positioning
dragNode = player;
}
};
game.move = function (x, y, obj) {
if (dragNode && gameState === 'playing' && !player.isDead) {
dragNode.x = x;
dragNode.y = y;
// Keep player within arena bounds
var centerX = 2048 / 2;
var centerY = 2732 / 2;
var arenaRadius = 700;
var distFromCenter = Math.sqrt(Math.pow(dragNode.x - centerX, 2) + Math.pow(dragNode.y - centerY, 2));
if (distFromCenter > arenaRadius) {
var angle = Math.atan2(dragNode.y - centerY, dragNode.x - centerX);
dragNode.x = centerX + Math.cos(angle) * arenaRadius;
dragNode.y = centerY + Math.sin(angle) * arenaRadius;
}
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
if (gameState === 'playing') {
// Update and clean up stone projectiles
for (var i = stones.length - 1; i >= 0; i--) {
var stone = stones[i];
if (stone && stone.parent) {
// Stone is still active, update handled by stone.update()
} else {
// Stone was destroyed, remove from array
stones.splice(i, 1);
}
}
// Remove dead enemies from array and handle enemy updates
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy && enemy.isDead) {
enemies.splice(i, 1);
}
}
// Check if player is dead
if (player.isDead) {
gameState = 'gameOver';
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
// Check wave completion
checkWaveComplete();
}
};
// Start first wave
spawnWave(); ===================================================================
--- original.js
+++ change.js
@@ -32,8 +32,114 @@
}
};
return self;
});
+var MainMenu = Container.expand(function () {
+ var self = Container.call(this);
+ // Create background decorations
+ self.createBackground = function () {
+ // Create scattered helmets, swords and shields
+ for (var i = 0; i < 30; i++) {
+ var decoration;
+ var type = Math.floor(Math.random() * 3);
+ if (type === 0) {
+ decoration = self.addChild(LK.getAsset('helmet', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: Math.random() * 2048,
+ y: Math.random() * 2732,
+ rotation: Math.random() * Math.PI * 2,
+ alpha: 0.3
+ }));
+ } else if (type === 1) {
+ decoration = self.addChild(LK.getAsset('sword', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: Math.random() * 2048,
+ y: Math.random() * 2732,
+ rotation: Math.random() * Math.PI * 2,
+ alpha: 0.3
+ }));
+ } else {
+ decoration = self.addChild(LK.getAsset('shield', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: Math.random() * 2048,
+ y: Math.random() * 2732,
+ rotation: Math.random() * Math.PI * 2,
+ alpha: 0.3
+ }));
+ }
+ // Animate decorations floating
+ tween(decoration, {
+ y: decoration.y + (Math.random() - 0.5) * 100,
+ rotation: decoration.rotation + Math.PI * 2
+ }, {
+ duration: 5000 + Math.random() * 3000,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ if (this.parent) {
+ tween(this, {
+ y: this.y - (Math.random() - 0.5) * 100,
+ rotation: this.rotation + Math.PI * 2
+ }, {
+ duration: 5000 + Math.random() * 3000,
+ easing: tween.easeInOut
+ });
+ }
+ }
+ });
+ }
+ };
+ // Create title
+ var titleText = new Text2('ARENA SEALS', {
+ size: 120,
+ fill: 0xFFD700
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleText.x = 2048 / 2;
+ titleText.y = 500;
+ self.addChild(titleText);
+ // Create menu buttons
+ var buttonData = [{
+ text: 'EMPEZAR',
+ y: 900
+ }, {
+ text: 'OPCIONES DE SONIDO',
+ y: 1050
+ }, {
+ text: 'CREDITOS',
+ y: 1200
+ }];
+ for (var i = 0; i < buttonData.length; i++) {
+ var buttonContainer = new Container();
+ var buttonBg = buttonContainer.attachAsset('menuButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var buttonText = new Text2(buttonData[i].text, {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ buttonText.anchor.set(0.5, 0.5);
+ buttonContainer.addChild(buttonText);
+ buttonContainer.x = 2048 / 2;
+ buttonContainer.y = buttonData[i].y;
+ buttonContainer.buttonType = buttonData[i].text;
+ buttonContainer.down = function (x, y, obj) {
+ if (this.buttonType === 'EMPEZAR') {
+ startGame();
+ } else if (this.buttonType === 'OPCIONES DE SONIDO') {
+ showSoundOptions();
+ } else if (this.buttonType === 'CREDITOS') {
+ showCredits();
+ }
+ };
+ self.addChild(buttonContainer);
+ }
+ self.createBackground();
+ return self;
+});
var Seal = Container.expand(function (isPlayer) {
var self = Container.call(this);
self.isPlayer = isPlayer || false;
self.maxHealth = 100;
@@ -605,23 +711,26 @@
/****
* Initialize Game
****/
var game = new LK.Game({
- backgroundColor: 0x2F4F4F
+ backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
+// Game state variables
+var gameState = 'menu'; // 'menu', 'playing', 'waveComplete', 'gameOver', 'soundOptions', 'credits'
+var mainMenu = null;
+var soundVolume = 1.0;
// Game variables
var player;
var enemies = [];
var stones = [];
var currentWave = 1;
var enemiesInWave = 3;
var waveStartTime = 0;
var dragNode = null;
-var gameState = 'playing'; // 'playing', 'waveComplete', 'gameOver'
var healingFish = null;
var shieldActive = false;
var shieldDuration = 5000; // 5 seconds
var lastScoreMilestone = 0;
@@ -632,8 +741,612 @@
var bossDamageMultiplier = 1;
var bossDamageBoostActive = false;
var bossDamageBoostDuration = 3; // 3 rounds
var currentBoss = null;
+// UI Elements (will be created when game starts)
+var scoreTxt,
+ waveTxt,
+ attackTxt,
+ attackButtons = [],
+ instructionTxt;
+var arenaOuter, arenaInner;
+function showMainMenu() {
+ // Clear any existing game elements
+ if (player) player.destroy();
+ if (arenaOuter) arenaOuter.destroy();
+ if (arenaInner) arenaInner.destroy();
+ // Clear arrays
+ enemies = [];
+ stones = [];
+ attackButtons = [];
+ // Clear GUI elements
+ if (scoreTxt && scoreTxt.parent) scoreTxt.destroy();
+ if (waveTxt && waveTxt.parent) waveTxt.destroy();
+ if (attackTxt && attackTxt.parent) attackTxt.destroy();
+ if (instructionTxt && instructionTxt.parent) instructionTxt.destroy();
+ gameState = 'menu';
+ mainMenu = game.addChild(new MainMenu());
+}
+function startGame() {
+ if (mainMenu) {
+ mainMenu.destroy();
+ mainMenu = null;
+ }
+ gameState = 'playing';
+ currentWave = 1;
+ enemiesInWave = 3;
+ LK.setScore(0);
+ // Reset game variables
+ lastScoreMilestone = 0;
+ damageMultiplier = 1;
+ damageBoostActive = false;
+ bossRoundsCompleted = 0;
+ bossDamageMultiplier = 1;
+ bossDamageBoostActive = false;
+ shieldActive = false;
+ // Create arena
+ arenaOuter = game.addChild(LK.getAsset('arena', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 2048 / 2,
+ y: 2732 / 2
+ }));
+ arenaInner = game.addChild(LK.getAsset('arenaFloor', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 2048 / 2,
+ y: 2732 / 2
+ }));
+ // Create player
+ player = game.addChild(new Seal(true));
+ player.x = 2048 / 2;
+ player.y = 2732 / 2 + 200;
+ // Create UI Elements
+ scoreTxt = new Text2('Score: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ scoreTxt.anchor.set(0, 0);
+ scoreTxt.x = 120;
+ scoreTxt.y = 50;
+ LK.gui.topLeft.addChild(scoreTxt);
+ waveTxt = new Text2('Wave: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ waveTxt.anchor.set(1, 0);
+ LK.gui.topRight.addChild(waveTxt);
+ // Attack type display
+ attackTxt = new Text2('Attack: Quick Strike', {
+ size: 40,
+ fill: 0xFFFF00
+ });
+ attackTxt.anchor.set(0.5, 0);
+ attackTxt.y = 50;
+ LK.gui.top.addChild(attackTxt);
+ // Create attack buttons
+ attackButtons = [];
+ for (var i = 0; i < 6; i++) {
+ var button = new Container();
+ var buttonBg = button.attachAsset('healthBarBg', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 160,
+ height: 80
+ });
+ // Make button background red
+ buttonBg.tint = 0xFF0000;
+ var buttonText = new Text2(player.attackTypes[i].name, {
+ size: 24,
+ fill: 0xFFFFFF
+ });
+ buttonText.anchor.set(0.5, 0.5);
+ button.addChild(buttonText);
+ // Position buttons horizontally across bottom of screen
+ button.x = (i - 2.5) * 160;
+ button.y = -120;
+ // Store button index for reference
+ button.attackIndex = i;
+ // Button click handler
+ button.down = function (x, y, obj) {
+ if (gameState === 'playing' && !player.isDead) {
+ player.currentAttack = this.attackIndex;
+ attackTxt.setText('Attack: ' + player.attackTypes[player.currentAttack].name);
+ attackTxt.tint = player.attackTypes[player.currentAttack].color;
+ // Special handling for stone throw attack (infinite usage)
+ if (player.currentAttack === 5) {
+ // Find closest enemy for stone targeting
+ var stoneTarget = null;
+ var closestStoneDistance = Infinity;
+ for (var m = 0; m < enemies.length; m++) {
+ var enemy = enemies[m];
+ if (enemy && !enemy.isDead) {
+ var distance = Math.sqrt(Math.pow(player.x - enemy.x, 2) + Math.pow(player.y - enemy.y, 2));
+ if (distance < closestStoneDistance) {
+ closestStoneDistance = distance;
+ stoneTarget = enemy;
+ }
+ }
+ }
+ if (stoneTarget) {
+ var stone = new Stone(stoneTarget);
+ stone.x = player.x;
+ stone.y = player.y;
+ stones.push(stone);
+ game.addChild(stone);
+ // Throwing animation
+ var attack = player.attackTypes[player.currentAttack];
+ tween(player, {
+ scaleX: attack.scale,
+ scaleY: attack.scale,
+ rotation: Math.PI / 4
+ }, {
+ duration: 150,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(player, {
+ scaleX: 1,
+ scaleY: 1,
+ rotation: 0
+ }, {
+ duration: 150,
+ easing: tween.easeIn
+ });
+ }
+ });
+ }
+ // Update button visual states for stone attack
+ for (var j = 0; j < attackButtons.length; j++) {
+ if (j === player.currentAttack) {
+ attackButtons[j].children[0].tint = 0xFFAAAA; // Lighter red for selected
+ attackButtons[j].children[1].tint = 0x000000;
+ } else {
+ attackButtons[j].children[0].tint = 0xFF0000; // Red for unselected
+ attackButtons[j].children[1].tint = 0xFFFFFF;
+ }
+ }
+ return; // Exit early for stone attacks to avoid melee logic
+ }
+ // Find closest enemy and attack instantly for melee attacks
+ var closestEnemy = null;
+ var closestDistance = Infinity;
+ for (var k = 0; k < enemies.length; k++) {
+ var enemy = enemies[k];
+ if (enemy && !enemy.isDead) {
+ var distance = Math.sqrt(Math.pow(player.x - enemy.x, 2) + Math.pow(player.y - enemy.y, 2));
+ if (distance < closestDistance && distance < 200) {
+ // Attack range
+ closestDistance = distance;
+ closestEnemy = enemy;
+ }
+ }
+ }
+ // Execute instant attack if enemy in range
+ if (closestEnemy) {
+ var attack = player.attackTypes[player.currentAttack];
+ var finalDamage = attack.damage * damageMultiplier * bossDamageMultiplier;
+ closestEnemy.takeDamage(finalDamage);
+ LK.getSound('hit').play();
+ // Execute attack animation instantly
+ if (player.currentAttack === 0) {
+ // Quick Strike - Fast dart forward
+ var originalX = player.x;
+ var originalY = player.y;
+ var angle = Math.atan2(closestEnemy.y - player.y, closestEnemy.x - player.x);
+ tween(player, {
+ x: player.x + Math.cos(angle) * 30,
+ y: player.y + Math.sin(angle) * 30,
+ scaleX: attack.scale,
+ scaleY: attack.scale
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(player, {
+ x: originalX,
+ y: originalY,
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 100,
+ easing: tween.easeIn
+ });
+ }
+ });
+ } else if (player.currentAttack === 1) {
+ // Power Slam - Bounce up and down
+ tween(player, {
+ y: player.y - 40,
+ scaleX: attack.scale,
+ scaleY: attack.scale * 1.2
+ }, {
+ duration: 200,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(player, {
+ y: player.y + 40,
+ scaleX: 1,
+ scaleY: 0.8
+ }, {
+ duration: 150,
+ easing: tween.bounceOut,
+ onFinish: function onFinish() {
+ tween(player, {
+ scaleY: 1
+ }, {
+ duration: 100
+ });
+ }
+ });
+ }
+ });
+ } else if (player.currentAttack === 2) {
+ // Spinning Attack - Full rotation with scale
+ tween(player, {
+ rotation: Math.PI * 2,
+ scaleX: attack.scale,
+ scaleY: attack.scale
+ }, {
+ duration: 300,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(player, {
+ rotation: 0,
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 200
+ });
+ }
+ });
+ } else if (player.currentAttack === 3) {
+ // Devastating Blow - Multiple quick pulses
+ var pulseCount = 0;
+ var maxPulses = 3;
+ var _doPulse2 = function doPulse() {
+ tween(player, {
+ scaleX: attack.scale,
+ scaleY: attack.scale,
+ tint: 0xFF4444
+ }, {
+ duration: 80,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(player, {
+ scaleX: 1.1,
+ scaleY: 1.1,
+ tint: 0xFFFFFF
+ }, {
+ duration: 80,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ pulseCount++;
+ if (pulseCount < maxPulses) {
+ _doPulse2();
+ } else {
+ tween(player, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 100
+ });
+ }
+ }
+ });
+ }
+ });
+ };
+ _doPulse2();
+ } else if (player.currentAttack === 4) {
+ // Ultimate Strike - Charge up with shake then explosive strike
+ var originalX = player.x;
+ var originalY = player.y;
+ var shakeCount = 0;
+ var maxShakes = 8;
+ var _doShake2 = function doShake() {
+ var shakeAmount = 15;
+ tween(player, {
+ x: originalX + (Math.random() - 0.5) * shakeAmount,
+ y: originalY + (Math.random() - 0.5) * shakeAmount,
+ scaleX: 1 + shakeCount * 0.1,
+ scaleY: 1 + shakeCount * 0.1
+ }, {
+ duration: 50,
+ onFinish: function onFinish() {
+ shakeCount++;
+ if (shakeCount < maxShakes) {
+ _doShake2();
+ } else {
+ // Final explosive strike
+ tween(player, {
+ x: originalX,
+ y: originalY,
+ scaleX: attack.scale,
+ scaleY: attack.scale,
+ tint: 0x00FFFF
+ }, {
+ duration: 200,
+ easing: tween.elasticOut,
+ onFinish: function onFinish() {
+ tween(player, {
+ scaleX: 1,
+ scaleY: 1,
+ tint: 0xFFFFFF
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ }
+ });
+ }
+ }
+ });
+ };
+ _doShake2();
+ }
+ // Flash effect with attack color
+ if (closestEnemy) {
+ LK.effects.flashObject(closestEnemy, attack.color, 300);
+ }
+ // Activate invincibility for 3 seconds
+ player.isInvincible = true;
+ // Visual feedback for invincibility - make seal semi-transparent and glow
+ tween(player, {
+ alpha: 0.6,
+ tint: 0x00FFFF
+ }, {
+ duration: 200,
+ onFinish: function onFinish() {
+ // Pulsing effect during invincibility
+ var _pulseEffect2 = function pulseEffect() {
+ if (player.isInvincible) {
+ tween(player, {
+ alpha: 0.4
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ if (player.isInvincible) {
+ tween(player, {
+ alpha: 0.6
+ }, {
+ duration: 300,
+ onFinish: _pulseEffect2
+ });
+ }
+ }
+ });
+ }
+ };
+ _pulseEffect2();
+ }
+ });
+ // End invincibility after duration
+ LK.setTimeout(function () {
+ player.isInvincible = false;
+ // Restore normal appearance
+ tween(player, {
+ alpha: 1,
+ tint: 0xFFFFFF
+ }, {
+ duration: 300
+ });
+ }, player.invincibilityDuration);
+ LK.setScore(LK.getScore() + 100);
+ scoreTxt.setText('Score: ' + LK.getScore());
+ checkScoreMilestone();
+ }
+ // Update button visual states
+ for (var j = 0; j < attackButtons.length; j++) {
+ if (j === player.currentAttack) {
+ attackButtons[j].children[0].tint = 0xFFAAAA; // Lighter red for selected
+ attackButtons[j].children[1].tint = 0x000000;
+ } else {
+ attackButtons[j].children[0].tint = 0xFF0000; // Red for unselected
+ attackButtons[j].children[1].tint = 0xFFFFFF;
+ }
+ }
+ }
+ };
+ attackButtons.push(button);
+ LK.gui.bottom.addChild(button);
+ }
+ // Set initial button states
+ attackButtons[0].children[0].tint = 0xFFAAAA; // Lighter red for selected
+ attackButtons[0].children[1].tint = 0x000000;
+ for (var i = 1; i < attackButtons.length; i++) {
+ attackButtons[i].children[0].tint = 0xFF0000; // Red for unselected
+ attackButtons[i].children[1].tint = 0xFFFFFF;
+ }
+ // Instructions
+ instructionTxt = new Text2('Select attack with buttons | Touch buttons to attack nearby enemies', {
+ size: 30,
+ fill: 0xCCCCCC
+ });
+ instructionTxt.anchor.set(0.5, 1);
+ instructionTxt.y = -40;
+ LK.gui.bottom.addChild(instructionTxt);
+ // Initialize with main menu
+ showMainMenu();
+ // Modify game update to handle different states
+ var originalUpdate = game.update;
+ game.update = function () {
+ if (gameState === 'playing') {
+ originalUpdate();
+ }
+ // Other states don't need update logic
+ };
+ // Override input handlers for menu states
+ var originalDown = game.down;
+ game.down = function (x, y, obj) {
+ if (gameState === 'playing') {
+ originalDown(x, y, obj);
+ }
+ };
+ var originalMove = game.move;
+ game.move = function (x, y, obj) {
+ if (gameState === 'playing') {
+ originalMove(x, y, obj);
+ }
+ };
+ var originalUp = game.up;
+ game.up = function (x, y, obj) {
+ if (gameState === 'playing') {
+ originalUp(x, y, obj);
+ }
+ };
+}
+function showSoundOptions() {
+ if (mainMenu) {
+ mainMenu.destroy();
+ mainMenu = null;
+ }
+ gameState = 'soundOptions';
+ var soundMenu = game.addChild(new Container());
+ var titleText = new Text2('OPCIONES DE SONIDO', {
+ size: 80,
+ fill: 0xFFD700
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleText.x = 2048 / 2;
+ titleText.y = 600;
+ soundMenu.addChild(titleText);
+ var volumeText = new Text2('Volumen: ' + Math.round(soundVolume * 100) + '%', {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ volumeText.anchor.set(0.5, 0.5);
+ volumeText.x = 2048 / 2;
+ volumeText.y = 800;
+ soundMenu.addChild(volumeText);
+ // Volume up button
+ var volumeUpBtn = new Container();
+ var upBg = volumeUpBtn.attachAsset('menuButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 150,
+ height: 60
+ });
+ var upText = new Text2('+', {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ upText.anchor.set(0.5, 0.5);
+ volumeUpBtn.addChild(upText);
+ volumeUpBtn.x = 2048 / 2 + 100;
+ volumeUpBtn.y = 900;
+ volumeUpBtn.down = function () {
+ soundVolume = Math.min(1.0, soundVolume + 0.1);
+ volumeText.setText('Volumen: ' + Math.round(soundVolume * 100) + '%');
+ };
+ soundMenu.addChild(volumeUpBtn);
+ // Volume down button
+ var volumeDownBtn = new Container();
+ var downBg = volumeDownBtn.attachAsset('menuButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 150,
+ height: 60
+ });
+ var downText = new Text2('-', {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ downText.anchor.set(0.5, 0.5);
+ volumeDownBtn.addChild(downText);
+ volumeDownBtn.x = 2048 / 2 - 100;
+ volumeDownBtn.y = 900;
+ volumeDownBtn.down = function () {
+ soundVolume = Math.max(0.0, soundVolume - 0.1);
+ volumeText.setText('Volumen: ' + Math.round(soundVolume * 100) + '%');
+ };
+ soundMenu.addChild(volumeDownBtn);
+ // Back button
+ var backBtn = new Container();
+ var backBg = backBtn.attachAsset('menuButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var backText = new Text2('VOLVER', {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ backText.anchor.set(0.5, 0.5);
+ backBtn.addChild(backText);
+ backBtn.x = 2048 / 2;
+ backBtn.y = 1100;
+ backBtn.down = function () {
+ soundMenu.destroy();
+ showMainMenu();
+ };
+ soundMenu.addChild(backBtn);
+}
+function showCredits() {
+ if (mainMenu) {
+ mainMenu.destroy();
+ mainMenu = null;
+ }
+ gameState = 'credits';
+ var creditsMenu = game.addChild(new Container());
+ var titleText = new Text2('CREDITOS', {
+ size: 80,
+ fill: 0xFFD700
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleText.x = 2048 / 2;
+ titleText.y = 500;
+ creditsMenu.addChild(titleText);
+ var gameText = new Text2('ARENA SEALS', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ gameText.anchor.set(0.5, 0.5);
+ gameText.x = 2048 / 2;
+ gameText.y = 700;
+ creditsMenu.addChild(gameText);
+ var devText = new Text2('Desarrollado por FRVR', {
+ size: 40,
+ fill: 0xCCCCCC
+ });
+ devText.anchor.set(0.5, 0.5);
+ devText.x = 2048 / 2;
+ devText.y = 800;
+ creditsMenu.addChild(devText);
+ var engineText = new Text2('Creado con LK Engine', {
+ size: 40,
+ fill: 0xCCCCCC
+ });
+ engineText.anchor.set(0.5, 0.5);
+ engineText.x = 2048 / 2;
+ engineText.y = 850;
+ creditsMenu.addChild(engineText);
+ var thanksText = new Text2('¡Gracias por jugar!', {
+ size: 50,
+ fill: 0x00FF00
+ });
+ thanksText.anchor.set(0.5, 0.5);
+ thanksText.x = 2048 / 2;
+ thanksText.y = 950;
+ creditsMenu.addChild(thanksText);
+ // Back button
+ var backBtn = new Container();
+ var backBg = backBtn.attachAsset('menuButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var backText = new Text2('VOLVER', {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ backText.anchor.set(0.5, 0.5);
+ backBtn.addChild(backText);
+ backBtn.x = 2048 / 2;
+ backBtn.y = 1150;
+ backBtn.down = function () {
+ creditsMenu.destroy();
+ showMainMenu();
+ };
+ creditsMenu.addChild(backBtn);
+}
// Create arena
var arenaOuter = game.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
arena de sumo de pixeles. In-Game asset. 2d. High contrast. No shadows
una foca de pixeles con armadura de gladiador. In-Game asset. 2d. High contrast. No shadows
pes de pixeles. In-Game asset. 2d. High contrast. No shadows
piedra de pixeles. In-Game asset. 2d. High contrast. No shadows
casco de gladiador de pixeles. In-Game asset. 2d. High contrast. No shadows
peto de pixeles. In-Game asset. 2d. High contrast. No shadows
espada de pixeles orizontal. In-Game asset. 2d. High contrast. No shadows
boton azul de pixeles. In-Game asset. 2d. High contrast. No shadows