User prompt
que la foca tenga 5 ataques con distinto tiempo de carga ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Gladiator Seals Arena
Initial prompt
crea un juego de focas con trage de gladiador que peleen entre si
/**** * 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 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 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) { 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 }]; 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 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 === 2) { // Spinning Attack tween(self, { rotation: Math.PI * 2, scaleX: attack.scale, scaleY: attack.scale }, { duration: 300, onFinish: function onFinish() { tween(self, { rotation: 0, scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); } else { // Standard scale attack animation tween(self, { scaleX: attack.scale, scaleY: attack.scale }, { duration: 150, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 150 }); } }); } // Flash effect with attack color LK.effects.flashObject(target, attack.color, 300); } else { // Partial charge - reduced damage var chargePercent = chargeTime / attack.chargeTime; var reducedDamage = Math.floor(attack.damage * chargePercent * 0.5); if (reducedDamage > 0) { 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) % 5; } }; 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; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2F4F4F }); /**** * Game Code ****/ // Game variables var player; var enemies = []; var currentWave = 1; var enemiesInWave = 3; var waveStartTime = 0; var dragNode = null; var gameState = 'playing'; // 'playing', 'waveComplete', 'gameOver' // 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); // Instructions var instructionTxt = new Text2('Tap anywhere: Cycle attacks | Hold on enemy: Charge attack', { size: 30, fill: 0xCCCCCC }); instructionTxt.anchor.set(0.5, 1); LK.gui.bottom.addChild(instructionTxt); // Functions function spawnWave() { enemies = []; waveStartTime = Date.now(); 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 nextWave() { currentWave++; enemiesInWave += 2; // Increase difficulty // Heal player slightly between waves player.currentHealth = Math.min(player.maxHealth, player.currentHealth + 25); player.healthBar.updateHealth(player.currentHealth); 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()); if (currentWave >= 5) { // Victory condition LK.showYouWin(); } else { nextWave(); } } } // Input handling game.down = function (x, y, obj) { if (gameState === 'playing' && !player.isDead) { // Check if touching an enemy to start charging attack var touchingEnemy = false; for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (enemy && !enemy.isDead) { var distance = Math.sqrt(Math.pow(x - enemy.x, 2) + Math.pow(y - enemy.y, 2)); if (distance < 100) { // Close enough to enemy touchingEnemy = true; player.startCharging(); break; } } } if (!touchingEnemy) { // Cycle through attack types when not touching enemy player.cycleAttack(); attackTxt.setText('Attack: ' + player.attackTypes[player.currentAttack].name); attackTxt.tint = player.attackTypes[player.currentAttack].color; } else { // Start dragging for positioning while charging 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; if (gameState === 'playing' && !player.isDead && player.isCharging) { // Find enemy to attack for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (enemy && !enemy.isDead && player.intersects(enemy)) { player.releaseAttack(enemy); LK.setScore(LK.getScore() + 100); scoreTxt.setText('Score: ' + LK.getScore()); break; } } // Release attack even if no target (to stop charging) if (player.isCharging) { player.releaseAttack(null); } } }; // Main game loop game.update = function () { if (gameState === 'playing') { // 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
@@ -73,8 +73,173 @@
}
}
});
};
+ // 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
+ }];
+ 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 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 === 2) {
+ // Spinning Attack
+ tween(self, {
+ rotation: Math.PI * 2,
+ scaleX: attack.scale,
+ scaleY: attack.scale
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ tween(self, {
+ rotation: 0,
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 200
+ });
+ }
+ });
+ } else {
+ // Standard scale attack animation
+ tween(self, {
+ scaleX: attack.scale,
+ scaleY: attack.scale
+ }, {
+ duration: 150,
+ onFinish: function onFinish() {
+ tween(self, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 150
+ });
+ }
+ });
+ }
+ // Flash effect with attack color
+ LK.effects.flashObject(target, attack.color, 300);
+ } else {
+ // Partial charge - reduced damage
+ var chargePercent = chargeTime / attack.chargeTime;
+ var reducedDamage = Math.floor(attack.damage * chargePercent * 0.5);
+ if (reducedDamage > 0) {
+ 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) % 5;
+ }
+ };
self.attack = function (target) {
var currentTime = Date.now();
if (currentTime - self.lastAttackTime > self.attackCooldown) {
target.takeDamage(self.attackDamage);
@@ -185,8 +350,23 @@
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);
+// Instructions
+var instructionTxt = new Text2('Tap anywhere: Cycle attacks | Hold on enemy: Charge attack', {
+ size: 30,
+ fill: 0xCCCCCC
+});
+instructionTxt.anchor.set(0.5, 1);
+LK.gui.bottom.addChild(instructionTxt);
// Functions
function spawnWave() {
enemies = [];
waveStartTime = Date.now();
@@ -235,11 +415,31 @@
}
// Input handling
game.down = function (x, y, obj) {
if (gameState === 'playing' && !player.isDead) {
- dragNode = player;
- player.x = x;
- player.y = y;
+ // Check if touching an enemy to start charging attack
+ var touchingEnemy = false;
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ if (enemy && !enemy.isDead) {
+ var distance = Math.sqrt(Math.pow(x - enemy.x, 2) + Math.pow(y - enemy.y, 2));
+ if (distance < 100) {
+ // Close enough to enemy
+ touchingEnemy = true;
+ player.startCharging();
+ break;
+ }
+ }
+ }
+ if (!touchingEnemy) {
+ // Cycle through attack types when not touching enemy
+ player.cycleAttack();
+ attackTxt.setText('Attack: ' + player.attackTypes[player.currentAttack].name);
+ attackTxt.tint = player.attackTypes[player.currentAttack].color;
+ } else {
+ // Start dragging for positioning while charging
+ dragNode = player;
+ }
}
};
game.move = function (x, y, obj) {
if (dragNode && gameState === 'playing' && !player.isDead) {
@@ -258,24 +458,31 @@
}
};
game.up = function (x, y, obj) {
dragNode = null;
+ if (gameState === 'playing' && !player.isDead && player.isCharging) {
+ // Find enemy to attack
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ if (enemy && !enemy.isDead && player.intersects(enemy)) {
+ player.releaseAttack(enemy);
+ LK.setScore(LK.getScore() + 100);
+ scoreTxt.setText('Score: ' + LK.getScore());
+ break;
+ }
+ }
+ // Release attack even if no target (to stop charging)
+ if (player.isCharging) {
+ player.releaseAttack(null);
+ }
+ }
};
// Main game loop
game.update = function () {
if (gameState === 'playing') {
- // Check for player attacks on enemies
+ // 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 && player.intersects(enemy) && !player.isDead) {
- var currentTime = Date.now();
- if (currentTime - player.lastAttackTime > player.attackCooldown) {
- player.attack(enemy);
- LK.setScore(LK.getScore() + 100);
- scoreTxt.setText('Score: ' + LK.getScore());
- }
- }
- // Remove dead enemies from array
if (enemy && enemy.isDead) {
enemies.splice(i, 1);
}
}
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