User prompt
Haz que la explosión sea un poco más grande
User prompt
Haz que cuando un slime sea destruido, explote (Con el sprite: Explosion) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Haz que cuando el tajo toque a un slime azul, este slime es destruido
User prompt
Cambia el tiempo de recarga del ataque a 2 segundos
User prompt
Elimina el botón de atacar y haz que el ataque sea automático cada 3 segundos
User prompt
Reduce el tiempo de aparición del slime azul a 8 segundos y haz que avancen un poco más rápido
User prompt
Crea un enemigo que se mueva lentamente hacia el jugador, este enemigo aparece en un borde aleatoriamente, aparecen cada dos segundos (Su sprite es: [slime_blue]) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Haz que el tajo se mueva el doble de rápido
User prompt
Haz al tajo más grande y que se mueva el doble de rápido
User prompt
Crea una función que cuando el jugador ataque, lance un tajo de su espada (Con el sprite: tajo) que se mueva rapidamente en la última dirección que se haya movido el guerrero (Cuando el tajo llega al borde desaparece) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Haz al jugador el doble de grande
User prompt
Haz el botón de ataque el triple de grande
User prompt
Haz el botón de ataque un poco más grande
User prompt
Haz el botón de atacar más grande
User prompt
Aumenta la velocidad de movimiento del jugador ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Crea un botón en la esquina inferior derecha, pero que no moleste al jugador, con el sprite: (boton_ataque)
User prompt
Cambia la animación, quiero que sea una animación de caminar continua ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Crea una animación para el personaje cuando se mueva ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Haz desaparecer el sprite: jostick cuando el jugador haya llegado a su objetivo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Y como se hace para eliminar el sprite (Guerrero) que no se mueve?ç
User prompt
Reemplaza el movimiento actual del jugador y añade una función para que el personaje guerrero se mueva automáticamente, para indicar a donde tiene que ir el personaje crea una función para que: al hacer click en un lugar de la pantalla aparezca el sprite: (joystick) para indicar el sitio donde quiere que ir caminando el personaje automáticamente (Si después de hacer click en un lugar el jugador vuelve a hacer click en otro lugar, el sprite: (joystick) desaparecera y será remplazado a ese lugar nuevo, y el personaje, independientemente de que aún no haya llegado al lugar, cambiará su rumbo automaticamente y avanzará automaticamente hacia el nuevo punto) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Crea al jugador que es un guerrero
User prompt
Añade el fondo que es el asset: Suelo
User prompt
Guerrero Pixel - Aventura de Espada
Initial prompt
Me gustaría que crearas un juego pixelart en español en el que el jugador controlase un humano que se pudiese mover por toda la pantalla, ya que todo el fondo es suelo. El humano puede atacar con una espada dandole a la tecla space y puede moverse con las teclas: flecha arriba, flecha abajo, flecha izquierda y flecha derecha.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Explosion = Container.expand(function () { var self = Container.call(this); // Attach the explosion sprite var explosionSprite = self.attachAsset('Explosion', { anchorX: 0.5, anchorY: 0.5 }); // Animation properties self.animationTimer = 500; // Animation duration in ms self.initialScale = 0.1; self.finalScale = 3.0; // Set initial scale explosionSprite.scaleX = self.initialScale; explosionSprite.scaleY = self.initialScale; // Start explosion animation tween(explosionSprite, { scaleX: self.finalScale, scaleY: self.finalScale, alpha: 0 }, { duration: self.animationTimer, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); return self; }); var Guerrero = Container.expand(function () { var self = Container.call(this); // Attach the warrior sprite var guerreroSprite = self.attachAsset('Guerrero', { anchorX: 0.5, anchorY: 0.5 }); // Movement properties self.speed = 600; // Speed for tween animation self.isAttacking = false; self.attackDuration = 300; // Attack animation duration in ms self.attackTimer = 0; // Target position for automatic movement self.targetX = null; self.targetY = null; self.isMoving = false; // Track last movement direction for slash attacks self.lastDirection = { x: 1, y: 0 }; // Default direction (right) // Update method called every frame self.update = function () { // Handle attack animation if (self.isAttacking) { self.attackTimer -= 16; // Approximate 60fps if (self.attackTimer <= 0) { self.isAttacking = false; guerreroSprite.rotation = 0; guerreroSprite.scaleX = 1; } else { // Simple attack animation - rotate and scale var progress = 1 - self.attackTimer / self.attackDuration; guerreroSprite.rotation = Math.sin(progress * Math.PI) * 0.5; guerreroSprite.scaleX = 1 + Math.sin(progress * Math.PI) * 0.3; } } }; // Move to target position using tween self.moveToTarget = function (targetX, targetY) { // Stop any current movement tween.stop(self, { x: true, y: true }); // Set new target self.targetX = targetX; self.targetY = targetY; self.isMoving = true; // Calculate distance for duration var distance = Math.sqrt(Math.pow(targetX - self.x, 2) + Math.pow(targetY - self.y, 2)); var duration = distance / self.speed * 1000; // Convert to milliseconds // Update last movement direction if (distance > 0) { self.lastDirection.x = (targetX - self.x) / distance; self.lastDirection.y = (targetY - self.y) / distance; } // Start continuous walking animation self.startWalkingAnimation(); // Start tween to target position tween(self, { x: targetX, y: targetY }, { duration: duration, easing: tween.linear, onFinish: function onFinish() { self.isMoving = false; self.targetX = null; self.targetY = null; // Stop walking animation and reset sprite to normal state tween.stop(guerreroSprite, { scaleX: true, scaleY: true }); guerreroSprite.scaleX = 1; guerreroSprite.scaleY = 1; // Hide joystick when target is reached if (joystickSprite) { joystickSprite.destroy(); joystickSprite = null; } } }); }; // Attack method self.attack = function () { if (!self.isAttacking) { self.isAttacking = true; self.attackTimer = self.attackDuration; // Create and launch slash in last movement direction self.createSlash(); } }; // Create slash method self.createSlash = function () { var slash = new Slash(); slash.x = self.x; slash.y = self.y; // Find the nearest enemy var nearestEnemy = null; var nearestDistance = Infinity; for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = enemy.x - self.x; var dy = enemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestEnemy = enemy; } } // Set direction towards nearest enemy, or use last direction if no enemies exist if (nearestEnemy) { var dx = nearestEnemy.x - self.x; var dy = nearestEnemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { slash.setDirection(dx / distance, dy / distance); } else { slash.setDirection(self.lastDirection.x, self.lastDirection.y); } } else { slash.setDirection(self.lastDirection.x, self.lastDirection.y); } game.addChild(slash); }; // Start continuous walking animation self.startWalkingAnimation = function () { self.walkCycle(); }; // Continuous walking cycle animation self.walkCycle = function () { if (!self.isMoving) return; // Stop animation if not moving tween(guerreroSprite, { scaleX: 1.1, scaleY: 0.9 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { if (!self.isMoving) return; // Check again before next cycle tween(guerreroSprite, { scaleX: 0.9, scaleY: 1.1 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { if (self.isMoving) { self.walkCycle(); // Continue the loop } } }); } }); }; return self; }); var RedSlimeEnemy = Container.expand(function () { var self = Container.call(this); // Attach the red slime sprite var slimeSprite = self.attachAsset('Slime_Red', { anchorX: 0.5, anchorY: 0.5 }); // Health property - takes 1 hit to destroy self.health = 1; // Collision cooldown property - prevents taking damage for 1 second after hit self.canTakeDamage = true; // Movement properties self.speed = 320; // Four times the speed of blue slimes (80 * 4) // Update method called every frame self.update = function () { // Calculate direction towards player var dx = guerrero.x - self.x; var dy = guerrero.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // Move towards player if distance > 0 if (distance > 0) { var normalizedX = dx / distance; var normalizedY = dy / distance; self.x += normalizedX * self.speed * (16 / 1000); // 16ms per frame at 60fps self.y += normalizedY * self.speed * (16 / 1000); } }; return self; }); var Slash = Container.expand(function () { var self = Container.call(this); // Attach the slash sprite var slashSprite = self.attachAsset('tajo', { anchorX: 0.5, anchorY: 0.5 }); // Movement properties self.speed = 3200; // Quadruple fast movement speed self.directionX = 1; // Movement direction X self.directionY = 0; // Movement direction Y // Update method called every frame self.update = function () { // Move in the specified direction self.x += self.directionX * self.speed * (16 / 1000); // 16ms per frame at 60fps self.y += self.directionY * self.speed * (16 / 1000); // Check if slash is off screen and destroy it if (self.x < -50 || self.x > 2048 + 50 || self.y < -50 || self.y > 2732 + 50) { self.destroy(); } }; // Set direction method self.setDirection = function (dirX, dirY) { self.directionX = dirX; self.directionY = dirY; // Rotate sprite to match direction slashSprite.rotation = Math.atan2(dirY, dirX); }; return self; }); var SlimeEnemy = Container.expand(function () { var self = Container.call(this); // Attach the slime sprite var slimeSprite = self.attachAsset('slime_blue', { anchorX: 0.5, anchorY: 0.5 }); // Movement properties self.speed = 80; // Slightly faster movement speed // Update method called every frame self.update = function () { // Calculate direction towards player var dx = guerrero.x - self.x; var dy = guerrero.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // Move towards player if distance > 0 if (distance > 0) { var normalizedX = dx / distance; var normalizedY = dy / distance; self.x += normalizedX * self.speed * (16 / 1000); // 16ms per frame at 60fps self.y += normalizedY * self.speed * (16 / 1000); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Calculate how many tiles we need to cover the full screen (2048x2732) // Create ground background covering the entire screen var tileWidth = 100; var tileHeight = 100; var tilesX = Math.ceil(2048 / tileWidth); var tilesY = Math.ceil(2732 / tileHeight); // Create a container for all ground tiles var groundContainer = new Container(); game.addChild(groundContainer); // Fill the entire screen with ground tiles for (var x = 0; x < tilesX; x++) { for (var y = 0; y < tilesY; y++) { var groundTile = LK.getAsset('Suelo', { x: x * tileWidth, y: y * tileHeight }); groundContainer.addChild(groundTile); } ; // Game update loop game.update = function () { // Update enemy spawn timer enemySpawnTimer += 16; // 16ms per frame at 60fps // Spawn enemy every 8 seconds (only if game is not over) if (!gameOver && enemySpawnTimer >= enemySpawnInterval) { spawnEnemy(); enemySpawnTimer = 0; } // Update red slime spawn timer redSlimeSpawnTimer += 16; // 16ms per frame at 60fps // Spawn red slime every 7 seconds (only if game is not over) if (!gameOver && redSlimeSpawnTimer >= redSlimeSpawnInterval) { spawnRedSlime(); redSlimeSpawnTimer = 0; } // Update auto attack timer autoAttackTimer += 16; // 16ms per frame at 60fps // Auto attack every 4 seconds if (autoAttackTimer >= autoAttackInterval) { guerrero.attack(); autoAttackTimer = 0; } // Check for score milestones and reduce spawn intervals var currentScore = LK.getScore(); var currentCheckpoint = Math.floor(currentScore / 10) * 10; if (currentCheckpoint > lastScoreCheckpoint && currentCheckpoint > 0) { // Calculate how many 10-point milestones we've reached var reductionSteps = currentCheckpoint / 10; // Reduce intervals by 15% for each 10-point milestone var reductionFactor = Math.pow(0.85, reductionSteps); // Apply reduction to both spawn intervals enemySpawnInterval = Math.max(1000, initialBlueSlimeInterval * reductionFactor); // Minimum 1 second redSlimeSpawnInterval = Math.max(1000, initialRedSlimeInterval * reductionFactor); // Minimum 1 second // Update last checkpoint lastScoreCheckpoint = currentCheckpoint; } // Check slash-enemy collisions var slashes = []; for (var i = 0; i < game.children.length; i++) { if (game.children[i] instanceof Slash) { slashes.push(game.children[i]); } } for (var s = 0; s < slashes.length; s++) { var slash = slashes[s]; for (var e = enemies.length - 1; e >= 0; e--) { var enemy = enemies[e]; if (slash.intersects(enemy)) { // Check if enemy is a red slime with health system if (enemy instanceof RedSlimeEnemy && enemy.canTakeDamage) { enemy.health -= 1; // Start cooldown period - red slime cannot take damage for 1 second enemy.canTakeDamage = false; // Use closure to capture the current enemy instance (function (currentEnemy) { tween(currentEnemy, {}, { duration: 1000, onFinish: function onFinish() { currentEnemy.canTakeDamage = true; } }); })(enemy); // Add visual feedback during invulnerability (function (currentEnemy) { tween(currentEnemy, { alpha: 0.5 }, { duration: 100, onFinish: function onFinish() { tween(currentEnemy, { alpha: 1 }, { duration: 100 }); } }); })(enemy); if (enemy.health <= 0) { // Create explosion effect at enemy position var explosion = new Explosion(); explosion.x = enemy.x; explosion.y = enemy.y; game.addChild(explosion); // Award 2 points for red slime destruction LK.setScore(LK.getScore() + 2); scoreText.setText('Puntos: ' + LK.getScore()); // Destroy the red slime after 2 hits enemy.destroy(); enemies.splice(e, 1); } // Red slime takes damage but might survive, don't destroy slash } else { // Regular blue slime - destroy immediately var explosion = new Explosion(); explosion.x = enemy.x; explosion.y = enemy.y; game.addChild(explosion); // Award 1 point for blue slime destruction LK.setScore(LK.getScore() + 1); scoreText.setText('Puntos: ' + LK.getScore()); // Destroy only the enemy, keep the slash enemy.destroy(); enemies.splice(e, 1); } // Don't break here so slash can hit multiple enemies } } } // Check player-enemy collisions for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (guerrero.intersects(enemy)) { // Player loses 1 health point playerHealth -= 1; healthText.setText('Vida: ' + playerHealth.toString()); // Play damage sound LK.getSound('Damage').play(); // Create explosion effect at enemy position var explosion = new Explosion(); explosion.x = enemy.x; explosion.y = enemy.y; game.addChild(explosion); // Destroy the enemy enemy.destroy(); enemies.splice(i, 1); // Check for game over if (playerHealth <= 0) { // Set game over flag to prevent enemy spawning gameOver = true; // Destroy all sprites except health text // Destroy all game children (including player, enemies, ground, etc.) for (var i = game.children.length - 1; i >= 0; i--) { game.children[i].destroy(); } // Clear enemies array enemies = []; // Add Game_Over sprite var gameOverSprite = LK.getAsset('Game_Over', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(gameOverSprite); // Play Pierdes music LK.playMusic('Pierdes'); return; // Exit game update loop } } } // Clean up enemies that are too far off screen for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (enemy.x < -200 || enemy.x > 2248 || enemy.y < -200 || enemy.y > 2932) { enemy.destroy(); enemies.splice(i, 1); } } }; } // Start cavern background music LK.playMusic('cavern'); // Create the warrior player var guerrero = new Guerrero(); guerrero.x = 2048 / 2; // Center horizontally guerrero.y = 2732 / 2; // Center vertically game.addChild(guerrero); // Player health system var playerHealth = 5; // Score display in bottom right corner var scoreText = new Text2('Puntos: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(1, 1); // Bottom right anchor LK.gui.bottomRight.addChild(scoreText); // Health display in top right corner var healthText = new Text2('Vida: ' + playerHealth.toString(), { size: 60, fill: 0xFFFFFF }); healthText.anchor.set(1, 0); // Top right anchor LK.gui.topRight.addChild(healthText); // Joystick sprite for target indication var joystickSprite = null; // Auto attack timer (every 4 seconds = 4000ms) var autoAttackTimer = 0; var autoAttackInterval = 4000; // Enemy tracking array var enemies = []; // Enemy spawn timer (every 8 seconds = 8000ms) var enemySpawnTimer = 0; var enemySpawnInterval = 8000; // Red slime spawn timer (every 7 seconds = 7000ms) var redSlimeSpawnTimer = 0; var redSlimeSpawnInterval = 7000; // Score tracking for spawn interval reduction var lastScoreCheckpoint = 0; // Track last 10-point milestone var initialBlueSlimeInterval = 8000; // Store original blue slime interval var initialRedSlimeInterval = 7000; // Store original red slime interval // Game over flag to prevent enemy spawning var gameOver = false; // Function to spawn enemy at random edge function spawnEnemy() { var enemy = new SlimeEnemy(); // Choose random edge (0=top, 1=right, 2=bottom, 3=left) var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: // Top edge enemy.x = Math.random() * 2048; enemy.y = -50; break; case 1: // Right edge enemy.x = 2048 + 50; enemy.y = Math.random() * 2732; break; case 2: // Bottom edge enemy.x = Math.random() * 2048; enemy.y = 2732 + 50; break; case 3: // Left edge enemy.x = -50; enemy.y = Math.random() * 2732; break; } enemies.push(enemy); game.addChild(enemy); } // Function to spawn red slime at random edge function spawnRedSlime() { var redSlime = new RedSlimeEnemy(); // Choose random edge (0=top, 1=right, 2=bottom, 3=left) var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: // Top edge redSlime.x = Math.random() * 2048; redSlime.y = -50; break; case 1: // Right edge redSlime.x = 2048 + 50; redSlime.y = Math.random() * 2732; break; case 2: // Bottom edge redSlime.x = Math.random() * 2048; redSlime.y = 2732 + 50; break; case 3: // Left edge redSlime.x = -50; redSlime.y = Math.random() * 2732; break; } enemies.push(redSlime); game.addChild(redSlime); } // Handle touch/mouse down for movement only game.down = function (x, y, obj) { // Check if game is over and restart if clicked if (gameOver) { // Reset game state variables gameOver = false; playerHealth = 5; LK.setScore(0); enemies = []; enemySpawnTimer = 0; redSlimeSpawnTimer = 0; autoAttackTimer = 0; lastScoreCheckpoint = 0; enemySpawnInterval = 8000; redSlimeSpawnInterval = 7000; // Clear all game objects for (var i = game.children.length - 1; i >= 0; i--) { game.children[i].destroy(); } // Recreate ground tiles var groundContainer = new Container(); game.addChild(groundContainer); for (var x = 0; x < tilesX; x++) { for (var y = 0; y < tilesY; y++) { var groundTile = LK.getAsset('Suelo', { x: x * tileWidth, y: y * tileHeight }); groundContainer.addChild(groundTile); } } // Recreate player guerrero = new Guerrero(); guerrero.x = 2048 / 2; guerrero.y = 2732 / 2; game.addChild(guerrero); // Update UI texts scoreText.setText('Puntos: 0'); healthText.setText('Vida: ' + playerHealth.toString()); // Restart background music LK.playMusic('cavern'); return; } // Remove existing joystick if it exists if (joystickSprite) { joystickSprite.destroy(); joystickSprite = null; } // Create new joystick at clicked position joystickSprite = LK.getAsset('joystick', { anchorX: 0.5, anchorY: 0.5, x: x, y: y }); game.addChild(joystickSprite); // Make warrior move to clicked position guerrero.moveToTarget(x, y); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Explosion = Container.expand(function () {
var self = Container.call(this);
// Attach the explosion sprite
var explosionSprite = self.attachAsset('Explosion', {
anchorX: 0.5,
anchorY: 0.5
});
// Animation properties
self.animationTimer = 500; // Animation duration in ms
self.initialScale = 0.1;
self.finalScale = 3.0;
// Set initial scale
explosionSprite.scaleX = self.initialScale;
explosionSprite.scaleY = self.initialScale;
// Start explosion animation
tween(explosionSprite, {
scaleX: self.finalScale,
scaleY: self.finalScale,
alpha: 0
}, {
duration: self.animationTimer,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
return self;
});
var Guerrero = Container.expand(function () {
var self = Container.call(this);
// Attach the warrior sprite
var guerreroSprite = self.attachAsset('Guerrero', {
anchorX: 0.5,
anchorY: 0.5
});
// Movement properties
self.speed = 600; // Speed for tween animation
self.isAttacking = false;
self.attackDuration = 300; // Attack animation duration in ms
self.attackTimer = 0;
// Target position for automatic movement
self.targetX = null;
self.targetY = null;
self.isMoving = false;
// Track last movement direction for slash attacks
self.lastDirection = {
x: 1,
y: 0
}; // Default direction (right)
// Update method called every frame
self.update = function () {
// Handle attack animation
if (self.isAttacking) {
self.attackTimer -= 16; // Approximate 60fps
if (self.attackTimer <= 0) {
self.isAttacking = false;
guerreroSprite.rotation = 0;
guerreroSprite.scaleX = 1;
} else {
// Simple attack animation - rotate and scale
var progress = 1 - self.attackTimer / self.attackDuration;
guerreroSprite.rotation = Math.sin(progress * Math.PI) * 0.5;
guerreroSprite.scaleX = 1 + Math.sin(progress * Math.PI) * 0.3;
}
}
};
// Move to target position using tween
self.moveToTarget = function (targetX, targetY) {
// Stop any current movement
tween.stop(self, {
x: true,
y: true
});
// Set new target
self.targetX = targetX;
self.targetY = targetY;
self.isMoving = true;
// Calculate distance for duration
var distance = Math.sqrt(Math.pow(targetX - self.x, 2) + Math.pow(targetY - self.y, 2));
var duration = distance / self.speed * 1000; // Convert to milliseconds
// Update last movement direction
if (distance > 0) {
self.lastDirection.x = (targetX - self.x) / distance;
self.lastDirection.y = (targetY - self.y) / distance;
}
// Start continuous walking animation
self.startWalkingAnimation();
// Start tween to target position
tween(self, {
x: targetX,
y: targetY
}, {
duration: duration,
easing: tween.linear,
onFinish: function onFinish() {
self.isMoving = false;
self.targetX = null;
self.targetY = null;
// Stop walking animation and reset sprite to normal state
tween.stop(guerreroSprite, {
scaleX: true,
scaleY: true
});
guerreroSprite.scaleX = 1;
guerreroSprite.scaleY = 1;
// Hide joystick when target is reached
if (joystickSprite) {
joystickSprite.destroy();
joystickSprite = null;
}
}
});
};
// Attack method
self.attack = function () {
if (!self.isAttacking) {
self.isAttacking = true;
self.attackTimer = self.attackDuration;
// Create and launch slash in last movement direction
self.createSlash();
}
};
// Create slash method
self.createSlash = function () {
var slash = new Slash();
slash.x = self.x;
slash.y = self.y;
// Find the nearest enemy
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemy;
}
}
// Set direction towards nearest enemy, or use last direction if no enemies exist
if (nearestEnemy) {
var dx = nearestEnemy.x - self.x;
var dy = nearestEnemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
slash.setDirection(dx / distance, dy / distance);
} else {
slash.setDirection(self.lastDirection.x, self.lastDirection.y);
}
} else {
slash.setDirection(self.lastDirection.x, self.lastDirection.y);
}
game.addChild(slash);
};
// Start continuous walking animation
self.startWalkingAnimation = function () {
self.walkCycle();
};
// Continuous walking cycle animation
self.walkCycle = function () {
if (!self.isMoving) return; // Stop animation if not moving
tween(guerreroSprite, {
scaleX: 1.1,
scaleY: 0.9
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!self.isMoving) return; // Check again before next cycle
tween(guerreroSprite, {
scaleX: 0.9,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.isMoving) {
self.walkCycle(); // Continue the loop
}
}
});
}
});
};
return self;
});
var RedSlimeEnemy = Container.expand(function () {
var self = Container.call(this);
// Attach the red slime sprite
var slimeSprite = self.attachAsset('Slime_Red', {
anchorX: 0.5,
anchorY: 0.5
});
// Health property - takes 1 hit to destroy
self.health = 1;
// Collision cooldown property - prevents taking damage for 1 second after hit
self.canTakeDamage = true;
// Movement properties
self.speed = 320; // Four times the speed of blue slimes (80 * 4)
// Update method called every frame
self.update = function () {
// Calculate direction towards player
var dx = guerrero.x - self.x;
var dy = guerrero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Move towards player if distance > 0
if (distance > 0) {
var normalizedX = dx / distance;
var normalizedY = dy / distance;
self.x += normalizedX * self.speed * (16 / 1000); // 16ms per frame at 60fps
self.y += normalizedY * self.speed * (16 / 1000);
}
};
return self;
});
var Slash = Container.expand(function () {
var self = Container.call(this);
// Attach the slash sprite
var slashSprite = self.attachAsset('tajo', {
anchorX: 0.5,
anchorY: 0.5
});
// Movement properties
self.speed = 3200; // Quadruple fast movement speed
self.directionX = 1; // Movement direction X
self.directionY = 0; // Movement direction Y
// Update method called every frame
self.update = function () {
// Move in the specified direction
self.x += self.directionX * self.speed * (16 / 1000); // 16ms per frame at 60fps
self.y += self.directionY * self.speed * (16 / 1000);
// Check if slash is off screen and destroy it
if (self.x < -50 || self.x > 2048 + 50 || self.y < -50 || self.y > 2732 + 50) {
self.destroy();
}
};
// Set direction method
self.setDirection = function (dirX, dirY) {
self.directionX = dirX;
self.directionY = dirY;
// Rotate sprite to match direction
slashSprite.rotation = Math.atan2(dirY, dirX);
};
return self;
});
var SlimeEnemy = Container.expand(function () {
var self = Container.call(this);
// Attach the slime sprite
var slimeSprite = self.attachAsset('slime_blue', {
anchorX: 0.5,
anchorY: 0.5
});
// Movement properties
self.speed = 80; // Slightly faster movement speed
// Update method called every frame
self.update = function () {
// Calculate direction towards player
var dx = guerrero.x - self.x;
var dy = guerrero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Move towards player if distance > 0
if (distance > 0) {
var normalizedX = dx / distance;
var normalizedY = dy / distance;
self.x += normalizedX * self.speed * (16 / 1000); // 16ms per frame at 60fps
self.y += normalizedY * self.speed * (16 / 1000);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Calculate how many tiles we need to cover the full screen (2048x2732)
// Create ground background covering the entire screen
var tileWidth = 100;
var tileHeight = 100;
var tilesX = Math.ceil(2048 / tileWidth);
var tilesY = Math.ceil(2732 / tileHeight);
// Create a container for all ground tiles
var groundContainer = new Container();
game.addChild(groundContainer);
// Fill the entire screen with ground tiles
for (var x = 0; x < tilesX; x++) {
for (var y = 0; y < tilesY; y++) {
var groundTile = LK.getAsset('Suelo', {
x: x * tileWidth,
y: y * tileHeight
});
groundContainer.addChild(groundTile);
}
;
// Game update loop
game.update = function () {
// Update enemy spawn timer
enemySpawnTimer += 16; // 16ms per frame at 60fps
// Spawn enemy every 8 seconds (only if game is not over)
if (!gameOver && enemySpawnTimer >= enemySpawnInterval) {
spawnEnemy();
enemySpawnTimer = 0;
}
// Update red slime spawn timer
redSlimeSpawnTimer += 16; // 16ms per frame at 60fps
// Spawn red slime every 7 seconds (only if game is not over)
if (!gameOver && redSlimeSpawnTimer >= redSlimeSpawnInterval) {
spawnRedSlime();
redSlimeSpawnTimer = 0;
}
// Update auto attack timer
autoAttackTimer += 16; // 16ms per frame at 60fps
// Auto attack every 4 seconds
if (autoAttackTimer >= autoAttackInterval) {
guerrero.attack();
autoAttackTimer = 0;
}
// Check for score milestones and reduce spawn intervals
var currentScore = LK.getScore();
var currentCheckpoint = Math.floor(currentScore / 10) * 10;
if (currentCheckpoint > lastScoreCheckpoint && currentCheckpoint > 0) {
// Calculate how many 10-point milestones we've reached
var reductionSteps = currentCheckpoint / 10;
// Reduce intervals by 15% for each 10-point milestone
var reductionFactor = Math.pow(0.85, reductionSteps);
// Apply reduction to both spawn intervals
enemySpawnInterval = Math.max(1000, initialBlueSlimeInterval * reductionFactor); // Minimum 1 second
redSlimeSpawnInterval = Math.max(1000, initialRedSlimeInterval * reductionFactor); // Minimum 1 second
// Update last checkpoint
lastScoreCheckpoint = currentCheckpoint;
}
// Check slash-enemy collisions
var slashes = [];
for (var i = 0; i < game.children.length; i++) {
if (game.children[i] instanceof Slash) {
slashes.push(game.children[i]);
}
}
for (var s = 0; s < slashes.length; s++) {
var slash = slashes[s];
for (var e = enemies.length - 1; e >= 0; e--) {
var enemy = enemies[e];
if (slash.intersects(enemy)) {
// Check if enemy is a red slime with health system
if (enemy instanceof RedSlimeEnemy && enemy.canTakeDamage) {
enemy.health -= 1;
// Start cooldown period - red slime cannot take damage for 1 second
enemy.canTakeDamage = false;
// Use closure to capture the current enemy instance
(function (currentEnemy) {
tween(currentEnemy, {}, {
duration: 1000,
onFinish: function onFinish() {
currentEnemy.canTakeDamage = true;
}
});
})(enemy);
// Add visual feedback during invulnerability
(function (currentEnemy) {
tween(currentEnemy, {
alpha: 0.5
}, {
duration: 100,
onFinish: function onFinish() {
tween(currentEnemy, {
alpha: 1
}, {
duration: 100
});
}
});
})(enemy);
if (enemy.health <= 0) {
// Create explosion effect at enemy position
var explosion = new Explosion();
explosion.x = enemy.x;
explosion.y = enemy.y;
game.addChild(explosion);
// Award 2 points for red slime destruction
LK.setScore(LK.getScore() + 2);
scoreText.setText('Puntos: ' + LK.getScore());
// Destroy the red slime after 2 hits
enemy.destroy();
enemies.splice(e, 1);
}
// Red slime takes damage but might survive, don't destroy slash
} else {
// Regular blue slime - destroy immediately
var explosion = new Explosion();
explosion.x = enemy.x;
explosion.y = enemy.y;
game.addChild(explosion);
// Award 1 point for blue slime destruction
LK.setScore(LK.getScore() + 1);
scoreText.setText('Puntos: ' + LK.getScore());
// Destroy only the enemy, keep the slash
enemy.destroy();
enemies.splice(e, 1);
}
// Don't break here so slash can hit multiple enemies
}
}
}
// Check player-enemy collisions
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (guerrero.intersects(enemy)) {
// Player loses 1 health point
playerHealth -= 1;
healthText.setText('Vida: ' + playerHealth.toString());
// Play damage sound
LK.getSound('Damage').play();
// Create explosion effect at enemy position
var explosion = new Explosion();
explosion.x = enemy.x;
explosion.y = enemy.y;
game.addChild(explosion);
// Destroy the enemy
enemy.destroy();
enemies.splice(i, 1);
// Check for game over
if (playerHealth <= 0) {
// Set game over flag to prevent enemy spawning
gameOver = true;
// Destroy all sprites except health text
// Destroy all game children (including player, enemies, ground, etc.)
for (var i = game.children.length - 1; i >= 0; i--) {
game.children[i].destroy();
}
// Clear enemies array
enemies = [];
// Add Game_Over sprite
var gameOverSprite = LK.getAsset('Game_Over', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(gameOverSprite);
// Play Pierdes music
LK.playMusic('Pierdes');
return; // Exit game update loop
}
}
}
// Clean up enemies that are too far off screen
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.x < -200 || enemy.x > 2248 || enemy.y < -200 || enemy.y > 2932) {
enemy.destroy();
enemies.splice(i, 1);
}
}
};
}
// Start cavern background music
LK.playMusic('cavern');
// Create the warrior player
var guerrero = new Guerrero();
guerrero.x = 2048 / 2; // Center horizontally
guerrero.y = 2732 / 2; // Center vertically
game.addChild(guerrero);
// Player health system
var playerHealth = 5;
// Score display in bottom right corner
var scoreText = new Text2('Puntos: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 1); // Bottom right anchor
LK.gui.bottomRight.addChild(scoreText);
// Health display in top right corner
var healthText = new Text2('Vida: ' + playerHealth.toString(), {
size: 60,
fill: 0xFFFFFF
});
healthText.anchor.set(1, 0); // Top right anchor
LK.gui.topRight.addChild(healthText);
// Joystick sprite for target indication
var joystickSprite = null;
// Auto attack timer (every 4 seconds = 4000ms)
var autoAttackTimer = 0;
var autoAttackInterval = 4000;
// Enemy tracking array
var enemies = [];
// Enemy spawn timer (every 8 seconds = 8000ms)
var enemySpawnTimer = 0;
var enemySpawnInterval = 8000;
// Red slime spawn timer (every 7 seconds = 7000ms)
var redSlimeSpawnTimer = 0;
var redSlimeSpawnInterval = 7000;
// Score tracking for spawn interval reduction
var lastScoreCheckpoint = 0; // Track last 10-point milestone
var initialBlueSlimeInterval = 8000; // Store original blue slime interval
var initialRedSlimeInterval = 7000; // Store original red slime interval
// Game over flag to prevent enemy spawning
var gameOver = false;
// Function to spawn enemy at random edge
function spawnEnemy() {
var enemy = new SlimeEnemy();
// Choose random edge (0=top, 1=right, 2=bottom, 3=left)
var edge = Math.floor(Math.random() * 4);
switch (edge) {
case 0:
// Top edge
enemy.x = Math.random() * 2048;
enemy.y = -50;
break;
case 1:
// Right edge
enemy.x = 2048 + 50;
enemy.y = Math.random() * 2732;
break;
case 2:
// Bottom edge
enemy.x = Math.random() * 2048;
enemy.y = 2732 + 50;
break;
case 3:
// Left edge
enemy.x = -50;
enemy.y = Math.random() * 2732;
break;
}
enemies.push(enemy);
game.addChild(enemy);
}
// Function to spawn red slime at random edge
function spawnRedSlime() {
var redSlime = new RedSlimeEnemy();
// Choose random edge (0=top, 1=right, 2=bottom, 3=left)
var edge = Math.floor(Math.random() * 4);
switch (edge) {
case 0:
// Top edge
redSlime.x = Math.random() * 2048;
redSlime.y = -50;
break;
case 1:
// Right edge
redSlime.x = 2048 + 50;
redSlime.y = Math.random() * 2732;
break;
case 2:
// Bottom edge
redSlime.x = Math.random() * 2048;
redSlime.y = 2732 + 50;
break;
case 3:
// Left edge
redSlime.x = -50;
redSlime.y = Math.random() * 2732;
break;
}
enemies.push(redSlime);
game.addChild(redSlime);
}
// Handle touch/mouse down for movement only
game.down = function (x, y, obj) {
// Check if game is over and restart if clicked
if (gameOver) {
// Reset game state variables
gameOver = false;
playerHealth = 5;
LK.setScore(0);
enemies = [];
enemySpawnTimer = 0;
redSlimeSpawnTimer = 0;
autoAttackTimer = 0;
lastScoreCheckpoint = 0;
enemySpawnInterval = 8000;
redSlimeSpawnInterval = 7000;
// Clear all game objects
for (var i = game.children.length - 1; i >= 0; i--) {
game.children[i].destroy();
}
// Recreate ground tiles
var groundContainer = new Container();
game.addChild(groundContainer);
for (var x = 0; x < tilesX; x++) {
for (var y = 0; y < tilesY; y++) {
var groundTile = LK.getAsset('Suelo', {
x: x * tileWidth,
y: y * tileHeight
});
groundContainer.addChild(groundTile);
}
}
// Recreate player
guerrero = new Guerrero();
guerrero.x = 2048 / 2;
guerrero.y = 2732 / 2;
game.addChild(guerrero);
// Update UI texts
scoreText.setText('Puntos: 0');
healthText.setText('Vida: ' + playerHealth.toString());
// Restart background music
LK.playMusic('cavern');
return;
}
// Remove existing joystick if it exists
if (joystickSprite) {
joystickSprite.destroy();
joystickSprite = null;
}
// Create new joystick at clicked position
joystickSprite = LK.getAsset('joystick', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y
});
game.addChild(joystickSprite);
// Make warrior move to clicked position
guerrero.moveToTarget(x, y);
};
Un suelo de una cueva pixelart visto desde arriba, por lo que cubre toda la pantalla. In-Game asset. High contrast. No shadows
Círculo grande con transparencia, dentro un círculo pequeño gris. In-Game asset. 2d. High contrast. No shadows
Retro pixel style
Un slime azul con ojos grandes brillantes. Cute. Pixelart. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Una explosión normal pixelart. In-Game asset. 2d. High contrast. No shadows
Cambia el color a rojo.
Un corazón rojo pixelart. Pixelart. No background. Transparent background. Blank background. 2d. In-Game asset. flat
Fondo negro con un texto rojo pixelart bonito que ponga "GAME OVER". In-Game asset. 2d. High contrast. cute