User prompt
cada vez que se toca un enemigo el mago tira un proyectil ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
el proyectil sale en direccion al enemigo a eliminar ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
cada vez que el mago ataca sale un hechizo que golpea al enemigo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ahora el jugador es un brujo y ataca con un hechizo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ahora que los caminos del nivel 1 sean de piedras
User prompt
todo el fondo celste
User prompt
ahora hazlo celeste
User prompt
no se cambio el fondo
User prompt
ahora el menu es celste
User prompt
que no se vea el juego desde el menu
User prompt
has que el fondo del menu sea celste
User prompt
cambia el color negro del menu por celeste
User prompt
ahora cambia el fondo del menu por un color celeste
User prompt
ahora el fondo del menu va a ser de color azul
User prompt
que no se vea el juego desde el menu
User prompt
Please fix the bug: 'Uncaught ReferenceError: levelText is not defined' in or related to this line: 'levelText.setText('Level: ' + self.level);' Line Number: 296
User prompt
Please fix the bug: 'Uncaught ReferenceError: scoreText is not defined' in or related to this line: 'scoreText.setText('Score: ' + LK.getScore());' Line Number: 156
User prompt
crea un menu para el juego
User prompt
quita la s y l que salen arriba a la derecha en la pantalla
User prompt
los siguientes 20 alternan entre el medio y las diagonales
User prompt
ahora los primeros 10 enemigos salen del medio
User prompt
cada vez que se mata un enemigo las monedas se mueven hacia coins ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
cambia el nombre de enemies a puntuacion
User prompt
crea un indicador de la puntuacion que sube 1 con cada enemigo]
User prompt
cada vez que matas un enemigo se suma monedas a monedas
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.bobOffset = Math.random() * Math.PI * 2;
self.initialY = 0;
self.update = function () {
if (self.initialY === 0) {
self.initialY = self.y;
}
// Only do bobbing animation and collection if not animating to coin counter
if (!self.isAnimating) {
// Bobbing animation
self.y = self.initialY + Math.sin(LK.ticks * 0.1 + self.bobOffset) * 10;
// Check collection by knight
if (knight && self.intersects(knight)) {
self.collect();
}
}
};
self.collect = function () {
LK.getSound('coinCollect').play();
LK.setScore(LK.getScore() + 5);
coinCounter++;
coinText.setText('Coins: ' + coinCounter);
// Remove from coins array
for (var i = coins.length - 1; i >= 0; i--) {
if (coins[i] === self) {
coins.splice(i, 1);
break;
}
}
self.destroy();
};
return self;
});
// Game arrays to track objects
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 1.0
});
self.health = 100;
self.maxHealth = 100;
self.speed = 3;
self.lastX = 0;
self.update = function () {
// Move along the assigned path toward the wizard
if (wizard && self.pathAngle !== undefined) {
// Move along the path direction toward the wizard
var moveX = -Math.cos(self.pathAngle) * self.speed;
var moveY = -Math.sin(self.pathAngle) * self.speed;
self.x += moveX;
self.y += moveY;
} else if (wizard) {
// Fallback: move directly toward the wizard if no path assigned
var dx = wizard.x - self.x;
var dy = wizard.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
// Normalize direction and apply speed
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
} else {
// Fallback: move down if knight doesn't exist
self.y += self.speed;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
// Flash red when hit
LK.effects.flashObject(self, 0xFF0000, 200);
if (self.health <= 0) {
self.die();
}
};
self.down = function (x, y, obj) {
// Create projectile targeting this enemy when tapped
var projectile = game.addChild(new Projectile());
projectile.x = wizard.x;
projectile.y = wizard.y;
projectile.targetEnemy = self;
projectiles.push(projectile);
// Play spell cast sound
LK.getSound('spellCast').play();
// Visual effect on wizard
LK.effects.flashObject(wizard, 0x00ffff, 200);
};
self.die = function () {
// Drop coin
var coin = game.addChild(new Coin());
coin.x = self.x;
coin.y = self.y - 50;
coin.isAnimating = true;
coins.push(coin);
// Animate coin moving toward coin counter
var coinTargetX = 120 + coinText.width / 2;
var coinTargetY = 90 + coinText.height / 2;
tween(coin, {
x: coinTargetX,
y: coinTargetY,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Increment coin counter after animation
coinCounter++;
coinText.setText('Coins: ' + coinCounter);
// Remove coin from array and destroy
for (var i = coins.length - 1; i >= 0; i--) {
if (coins[i] === coin) {
coins.splice(i, 1);
break;
}
}
coin.destroy();
}
});
// Increment enemy kill counter
enemyKillCounter++;
killCountText.setText('Puntuacion: ' + enemyKillCounter);
// Add experience to wizard
wizard.gainExperience(25);
// Remove from enemies array
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
self.destroy();
LK.setScore(LK.getScore() + 10);
};
return self;
});
var GameMenu = Container.expand(function () {
var self = Container.call(this);
// Semi-transparent background overlay
var menuBg = self.attachAsset('pathSelector', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 35,
scaleY: 45
});
menuBg.alpha = 0.9;
menuBg.tint = 0x87CEEB; // Celeste (sky blue) color
// Title text
var titleText = new Text2('WIZARD DEFENDER', {
size: 150,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 800;
self.addChild(titleText);
// Instructions text
var instructionsText = new Text2('TAP PATHS TO CAST SPELLS\nDEFEND YOUR CASTLE!', {
size: 80,
fill: 0xFFFFFF
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = 2048 / 2;
instructionsText.y = 1200;
self.addChild(instructionsText);
// Start button
var startButton = self.attachAsset('wizard', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1600,
scaleX: 2,
scaleY: 2
});
var startButtonText = new Text2('START GAME', {
size: 100,
fill: 0x000000
});
startButtonText.anchor.set(0.5, 0.5);
startButtonText.x = 2048 / 2;
startButtonText.y = 1700;
self.addChild(startButtonText);
// Button interaction
self.down = function (x, y, obj) {
// Start the game by hiding menu
self.startGame();
};
self.startGame = function () {
// Hide menu and start game
self.visible = false;
gameStarted = true;
// Show all game elements
castle.visible = true;
wizard.visible = true;
for (var i = 0; i < paths.length; i++) {
paths[i].visible = true;
}
coinText.visible = true;
killCountText.visible = true;
tapText.visible = true;
healthBarBg.visible = true;
healthBar.visible = true;
healthText.visible = true;
// Start medieval music
LK.playMusic('medievalTheme');
};
return self;
});
var Projectile = Container.expand(function () {
var self = Container.call(this);
var projectileGraphics = self.attachAsset('projectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.targetEnemy = null;
self.damage = 50;
self.update = function () {
if (self.targetEnemy && self.targetEnemy.parent) {
// Move toward target enemy
var dx = self.targetEnemy.x - self.x;
var dy = self.targetEnemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 20) {
// Hit the enemy
self.targetEnemy.takeDamage(self.damage);
self.destroy();
// Remove from projectiles array
for (var i = projectiles.length - 1; i >= 0; i--) {
if (projectiles[i] === self) {
projectiles.splice(i, 1);
break;
}
}
} else if (distance > 0) {
// Move toward enemy
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
} else {
// Target enemy destroyed, remove projectile
self.destroy();
for (var i = projectiles.length - 1; i >= 0; i--) {
if (projectiles[i] === self) {
projectiles.splice(i, 1);
break;
}
}
}
// Remove if off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.destroy();
for (var i = projectiles.length - 1; i >= 0; i--) {
if (projectiles[i] === self) {
projectiles.splice(i, 1);
break;
}
}
}
};
return self;
});
var Wizard = Container.expand(function () {
var self = Container.call(this);
var wizardGraphics = self.attachAsset('wizard', {
anchorX: 0.5,
anchorY: 1.0
});
self.attackCooldown = 0;
self.level = 1;
self.experience = 0;
self.health = 100;
self.maxHealth = 100;
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
};
self.attack = function (direction) {
if (self.attackCooldown <= 0) {
// Default direction if none specified
if (direction === undefined) {
direction = 0; // Default to center path
}
// Get attack angle based on path direction
var attackAngle = pathAngles[direction];
var attackDistance = 100;
// Calculate spell position based on attack direction
var spellX = self.x + Math.cos(attackAngle) * attackDistance;
var spellY = self.y + Math.sin(attackAngle) * attackDistance;
// Create spell effect
var spell = game.addChild(LK.getAsset('spell', {
anchorX: 0.5,
anchorY: 0.5,
x: spellX,
y: spellY,
scaleX: 0.5,
scaleY: 0.5
}));
// Animate spell with magical effects
tween(spell, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
spell.destroy();
}
});
// Add rotation animation to spell
tween(spell, {
rotation: Math.PI * 2
}, {
duration: 500,
easing: tween.linear
});
self.attackCooldown = 30; // 0.5 seconds at 60fps
LK.getSound('spellCast').play();
// Attack enemies in the specified direction/path
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.pathIndex === direction) {
// Check if enemy is within attack range along this path
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 150) {
// Attack range
enemy.takeDamage(50);
}
}
}
return true;
}
return false;
};
self.gainExperience = function (amount) {
self.experience += amount;
var expNeeded = self.level * 100;
if (self.experience >= expNeeded) {
self.levelUp();
}
};
self.levelUp = function () {
self.level++;
self.experience = 0;
// Visual level up effect
LK.effects.flashObject(self, 0xFFD700, 500);
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
// Game over when health reaches 0
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
}
// Update health bar
updateHealthBar();
// Flash red when hit
LK.effects.flashObject(self, 0xFF0000, 200);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Celeste (sky blue) background
});
/****
* Game Code
****/
// Game state variables
var gameStarted = false;
var gameMenu;
// Game arrays to track objects
var enemies = [];
var coins = [];
var projectiles = [];
// Create and show game menu
gameMenu = game.addChild(new GameMenu());
// Create castle background
var castle = game.addChild(LK.getAsset('castle', {
anchorX: 0.5,
anchorY: 1.0,
x: 2048 / 2,
y: 2732 - 200
}));
castle.visible = false;
// Create 5 dirt paths leading toward the knight position
var paths = [];
var knightX = 2048 / 2;
var knightY = 2732 - 250;
// Create paths: center, two diagonal, and two side paths
var pathAngles = [-Math.PI / 2,
// Center (straight down)
-Math.PI / 4,
// Diagonal right
-3 * Math.PI / 4,
// Diagonal left
0,
// Right side (horizontal)
Math.PI // Left side (horizontal)
]; // 5 paths: center, two diagonal, two sides
for (var p = 0; p < 5; p++) {
var angle = pathAngles[p];
// Calculate path length - make center path longer
var pathLength = p === 0 ? 3000 : 1800; // Center path is longer
// Calculate path center position to extend from screen edge to knight
var centerX = knightX + Math.cos(angle) * (pathLength / 2);
var centerY = knightY + Math.sin(angle) * (pathLength / 2);
// Create stone path with extended length
var path = game.addChild(LK.getAsset('stonePath', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX,
y: centerY,
scaleY: pathLength / 800,
// Scale to desired length
rotation: angle + Math.PI / 2 // Rotate path to point toward knight
}));
// Make paths slightly transparent so they don't overwhelm the game
path.alpha = 0.7;
path.visible = false;
// Store path index for identification
path.pathIndex = p;
// Add touch handler for directional attacks (enemy elimination is now handled by attacks)
path.down = function (x, y, obj) {
// Attack in this path's direction
wizard.attack(obj.pathIndex);
// Visual feedback - flash the path briefly
LK.effects.flashObject(obj, 0xFFFFFF, 300);
};
paths.push(path);
}
// Create wizard
var wizard = game.addChild(new Wizard());
wizard.x = knightX;
wizard.y = knightY;
wizard.visible = false;
// UI Elements
// Removed scoreText and levelText to eliminate stray characters in top right
var coinCounter = 0;
var enemyKillCounter = 0;
var coinText = new Text2('Coins: 0', {
size: 60,
fill: 0xFFD700
});
coinText.anchor.set(0, 0);
LK.gui.topLeft.addChild(coinText);
coinText.x = 120;
coinText.y = 90;
coinText.visible = false;
var killCountText = new Text2('Puntuacion: 0', {
size: 60,
fill: 0xFF6B6B
});
killCountText.anchor.set(0, 0);
LK.gui.topLeft.addChild(killCountText);
killCountText.x = 120;
killCountText.y = 150;
killCountText.visible = false;
var tapText = new Text2('TAP TO CAST SPELLS!', {
size: 100,
fill: 0xFF6B6B
});
tapText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(tapText);
tapText.y = -200;
tapText.visible = false;
// Health bar UI
var healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0,
anchorY: 0
});
LK.gui.topLeft.addChild(healthBarBg);
healthBarBg.x = 120;
healthBarBg.y = 20;
healthBarBg.visible = false;
var healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0
});
LK.gui.topLeft.addChild(healthBar);
healthBar.x = 120;
healthBar.y = 20;
healthBar.visible = false;
var healthText = new Text2('Health: 100/100', {
size: 50,
fill: 0xFFFFFF
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120;
healthText.y = 50;
healthText.visible = false;
function updateHealthBar() {
var healthPercent = wizard.health / wizard.maxHealth;
healthBar.scaleX = healthPercent;
healthText.setText('Health: ' + wizard.health + '/' + wizard.maxHealth);
// Change color based on health
if (healthPercent > 0.6) {
healthBar.tint = 0x00ff00; // Green
} else if (healthPercent > 0.3) {
healthBar.tint = 0xffff00; // Yellow
} else {
healthBar.tint = 0xff0000; // Red
}
}
// Enemy spawning variables
var enemySpawnTimer = 0;
var enemySpawnRate = 60; // 1 second at 60fps
// Game input handling
game.down = function (x, y, obj) {
// Check if a path was tapped for directional attack
var pathTapped = false;
for (var p = 0; p < paths.length; p++) {
var path = paths[p];
// Convert tap position to path's local coordinates
var localPos = path.toLocal({
x: x,
y: y
});
// Check if tap is within path bounds
if (Math.abs(localPos.x) < path.width / 2 && Math.abs(localPos.y) < path.height / 2) {
// Attack in this path's direction
wizard.attack(path.pathIndex);
pathTapped = true;
break;
}
}
// No default attack - player must tap a path to attack
};
// Main game update loop
game.update = function () {
// Only update game logic if game has started
if (!gameStarted) {
return;
}
// Spawn enemies
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnRate) {
enemySpawnTimer = 0;
var enemy = game.addChild(new Enemy());
// Spawn enemy at a random path entrance
var randomPathIndex;
if (enemyKillCounter < 10) {
// First 10 enemies spawn from center path only
randomPathIndex = 0; // Center path
} else if (enemyKillCounter < 30) {
// Next 20 enemies (11-30) alternate between center and diagonal paths
var alternatingPaths = [0, 1, 2]; // Center, diagonal right, diagonal left
randomPathIndex = alternatingPaths[enemyKillCounter % 3];
} else {
// After 30 enemies, spawn from any path
randomPathIndex = Math.floor(Math.random() * 5);
}
var pathAngle = pathAngles[randomPathIndex];
// Store the path information on the enemy
enemy.pathIndex = randomPathIndex;
enemy.pathAngle = pathAngle;
// Calculate spawn position at the far end of the path (screen edge)
var pathLength = randomPathIndex === 0 ? 3000 : 1800; // Match path lengths
var spawnDistance = pathLength * 0.8; // Spawn farther away - 80% of path length
enemy.x = knightX + Math.cos(pathAngle) * spawnDistance;
enemy.y = knightY + Math.sin(pathAngle) * spawnDistance;
// Make sure enemies spawn within screen bounds
enemy.x = Math.max(50, Math.min(1998, enemy.x));
enemy.y = Math.max(-200, Math.min(2732 + 100, enemy.y));
enemy.lastX = enemy.x;
enemies.push(enemy);
// Increase difficulty over time
if (enemySpawnRate > 30) {
enemySpawnRate -= 2;
}
}
// Check enemy-knight collisions and cleanup off-screen enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Remove enemies that went off-screen at bottom
if (enemy.y > 2732 + 100) {
enemies.splice(i, 1);
enemy.destroy();
continue;
}
// Initialize lastIntersecting if not set
if (enemy.lastIntersecting === undefined) {
enemy.lastIntersecting = false;
}
// Check for collision transition
var currentIntersecting = enemy.intersects(wizard);
if (!enemy.lastIntersecting && currentIntersecting) {
// Damage wizard when enemy touches for the first time
wizard.takeDamage(20);
// Remove enemy after dealing damage
enemies.splice(i, 1);
enemy.destroy();
continue;
}
// Update last intersecting state
enemy.lastIntersecting = currentIntersecting;
}
// Make tap text pulse
var pulse = 1 + Math.sin(LK.ticks * 0.1) * 0.2;
tapText.scale.set(pulse, pulse);
};
// Remove tap text after 5 seconds
tween({}, {}, {
duration: 5000,
onFinish: function onFinish() {
if (tapText && tapText.parent) {
tapText.destroy();
}
}
}); ===================================================================
--- original.js
+++ change.js
@@ -86,10 +86,18 @@
self.die();
}
};
self.down = function (x, y, obj) {
- // Enemy dies when tapped
- self.die();
+ // Create projectile targeting this enemy when tapped
+ var projectile = game.addChild(new Projectile());
+ projectile.x = wizard.x;
+ projectile.y = wizard.y;
+ projectile.targetEnemy = self;
+ projectiles.push(projectile);
+ // Play spell cast sound
+ LK.getSound('spellCast').play();
+ // Visual effect on wizard
+ LK.effects.flashObject(wizard, 0x00ffff, 200);
};
self.die = function () {
// Drop coin
var coin = game.addChild(new Coin());
@@ -212,8 +220,62 @@
LK.playMusic('medievalTheme');
};
return self;
});
+var Projectile = Container.expand(function () {
+ var self = Container.call(this);
+ var projectileGraphics = self.attachAsset('projectile', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 8;
+ self.targetEnemy = null;
+ self.damage = 50;
+ self.update = function () {
+ if (self.targetEnemy && self.targetEnemy.parent) {
+ // Move toward target enemy
+ var dx = self.targetEnemy.x - self.x;
+ var dy = self.targetEnemy.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < 20) {
+ // Hit the enemy
+ self.targetEnemy.takeDamage(self.damage);
+ self.destroy();
+ // Remove from projectiles array
+ for (var i = projectiles.length - 1; i >= 0; i--) {
+ if (projectiles[i] === self) {
+ projectiles.splice(i, 1);
+ break;
+ }
+ }
+ } else if (distance > 0) {
+ // Move toward enemy
+ self.x += dx / distance * self.speed;
+ self.y += dy / distance * self.speed;
+ }
+ } else {
+ // Target enemy destroyed, remove projectile
+ self.destroy();
+ for (var i = projectiles.length - 1; i >= 0; i--) {
+ if (projectiles[i] === self) {
+ projectiles.splice(i, 1);
+ break;
+ }
+ }
+ }
+ // Remove if off screen
+ if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
+ self.destroy();
+ for (var i = projectiles.length - 1; i >= 0; i--) {
+ if (projectiles[i] === self) {
+ projectiles.splice(i, 1);
+ break;
+ }
+ }
+ }
+ };
+ return self;
+});
var Wizard = Container.expand(function () {
var self = Container.call(this);
var wizardGraphics = self.attachAsset('wizard', {
anchorX: 0.5,
@@ -234,75 +296,58 @@
// Default direction if none specified
if (direction === undefined) {
direction = 0; // Default to center path
}
- // Find the closest enemy in the specified path direction
- var targetEnemy = null;
- var closestDistance = Infinity;
- for (var i = 0; i < enemies.length; i++) {
+ // Get attack angle based on path direction
+ var attackAngle = pathAngles[direction];
+ var attackDistance = 100;
+ // Calculate spell position based on attack direction
+ var spellX = self.x + Math.cos(attackAngle) * attackDistance;
+ var spellY = self.y + Math.sin(attackAngle) * attackDistance;
+ // Create spell effect
+ var spell = game.addChild(LK.getAsset('spell', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: spellX,
+ y: spellY,
+ scaleX: 0.5,
+ scaleY: 0.5
+ }));
+ // Animate spell with magical effects
+ tween(spell, {
+ scaleX: 2,
+ scaleY: 2,
+ alpha: 0
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ spell.destroy();
+ }
+ });
+ // Add rotation animation to spell
+ tween(spell, {
+ rotation: Math.PI * 2
+ }, {
+ duration: 500,
+ easing: tween.linear
+ });
+ self.attackCooldown = 30; // 0.5 seconds at 60fps
+ LK.getSound('spellCast').play();
+ // Attack enemies in the specified direction/path
+ for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.pathIndex === direction) {
+ // Check if enemy is within attack range along this path
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
- if (distance < closestDistance) {
- closestDistance = distance;
- targetEnemy = enemy;
+ if (distance < 150) {
+ // Attack range
+ enemy.takeDamage(50);
}
}
}
- // Only cast spell if there's a target enemy
- if (targetEnemy) {
- // Create spell projectile at wizard position
- var spell = game.addChild(LK.getAsset('spell', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: self.x,
- y: self.y,
- scaleX: 0.8,
- scaleY: 0.8
- }));
- // Store target enemy reference on spell
- spell.targetEnemy = targetEnemy;
- spell.damage = 50;
- // Add spell to spells array for tracking
- spells.push(spell);
- // Add rotation animation to spell
- tween(spell, {
- rotation: Math.PI * 4
- }, {
- duration: 1000,
- easing: tween.linear
- });
- // Calculate direction towards target enemy
- var dx = targetEnemy.x - spell.x;
- var dy = targetEnemy.y - spell.y;
- var distance = Math.sqrt(dx * dx + dy * dy);
- // Animate spell traveling to target enemy
- tween(spell, {
- x: targetEnemy.x,
- y: targetEnemy.y
- }, {
- duration: 300,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- // Check if target enemy still exists and spell hits it
- if (spell.targetEnemy && spell.targetEnemy.parent) {
- spell.targetEnemy.takeDamage(spell.damage);
- }
- // Remove spell from spells array
- for (var j = spells.length - 1; j >= 0; j--) {
- if (spells[j] === spell) {
- spells.splice(j, 1);
- break;
- }
- }
- spell.destroy();
- }
- });
- }
- self.attackCooldown = 30; // 0.5 seconds at 60fps
- LK.getSound('spellCast').play();
return true;
}
return false;
};
@@ -350,9 +395,9 @@
var gameMenu;
// Game arrays to track objects
var enemies = [];
var coins = [];
-var spells = [];
+var projectiles = [];
// Create and show game menu
gameMenu = game.addChild(new GameMenu());
// Create castle background
var castle = game.addChild(LK.getAsset('castle', {
@@ -574,23 +619,8 @@
}
// Update last intersecting state
enemy.lastIntersecting = currentIntersecting;
}
- // Clean up spells that are off-screen or have invalid targets
- for (var s = spells.length - 1; s >= 0; s--) {
- var spell = spells[s];
- // Remove spell if target enemy no longer exists
- if (!spell.targetEnemy || !spell.targetEnemy.parent) {
- spells.splice(s, 1);
- spell.destroy();
- continue;
- }
- // Remove spell if it goes off-screen
- if (spell.x < -100 || spell.x > 2148 || spell.y < -100 || spell.y > 2832) {
- spells.splice(s, 1);
- spell.destroy();
- }
- }
// Make tap text pulse
var pulse = 1 + Math.sin(LK.ticks * 0.1) * 0.2;
tapText.scale.set(pulse, pulse);
};