User prompt
Muestra las barras de vida después de que inicie el combate, no en el menú, en el menú has un fondo en dónde los personajes aparezcan luchando en un vacío y que muestre el puntaje de la anterior partida ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Agrega partículas para cuando estés defendiendo, cuando ataques con el golpe o con patada
User prompt
Que la inteligencia del enemigo sea mayor dependiendo la dificultad pero que aún así pueda moverse y luchar de manera inteligente
User prompt
Que el enemigo se pueda acercar y atacarte, esquivar y defenderse
User prompt
Que puedas elegir entre el tiburón, el lobo y el lagarto y que no solo te ponga al tiburon
User prompt
Arregla que al seleccionar un personaje no te de otro totalmente diferente, que el menú se puedan editar sus assets y que se puedan poner más variedades de enemigos
User prompt
Cada que ganes que aparezca un letrero de k.o de que ganaste y que te dé la opción de seguir luchando con otros enemigos o parar ahí, que haya un total de 20 enemigos y que aparezcan de manera aleatoria pero con sus nombres
User prompt
Que la barra de esta mina disminuya de manera que si atacas mucho te canses y para recuperarla necesites no atacar, que la vida sea mucho mayor para que el combate dure una buena cantidad pero que no sea excesiva
User prompt
Que los botones estén el centro, más grandes y un poco más separados , que el botón de defender reduzca el daño que recibas y que las patadas sean algo lentas pero con un poco más de daño
User prompt
La línea gris que también se vaya con los personajes y que el fondo sea más grande y deja libre la parte de abajo para agregar los botones y que aparezcan en la pantalla
User prompt
Elimina los botones de saltar y morder que sean reemplazados por la cruceta y que tendrán las siguientes funciones, arriba saltar, izquierda ir para la izquierda, derecha para ir a la derecha y abajo para agacharse, necesito que dónde están los personajes se encuentre más centrado de la pantalla para que así puedas poner la cruceta en la parte inferior central izquierda y agregues los botones para golpear, patear y defenderse
Code edit (1 edits merged)
Please save this source code
User prompt
Necesito que implementos las diferentes habilidades y que sean únicas de cada personaje y que no se repitan, también necesito que hagas una cruceta para que te puedas mover de izquierda a derecha y que puedas saltar y agacharte sin necesidad de que la cruceta este hasta la esquina derecha, necesito que esté en el centro izquierdo
User prompt
Necesito que hagas una cruceta , para que puedas moverte de un lado al otro, saltar y agacharse, que el enemigo sea un poco más agresivo y que la cruceta no esté hasta la esquina
Code edit (1 edits merged)
Please save this source code
User prompt
Necesito que los botones de acciones para pelear aparezcan después de iniciar el juego ya que en el menú estorban, también que los botones no estén hasta la esquina derecha, pueden estar en la parte superior central y con separación y algo grandes
User prompt
Necesito que separes un poco los botones del menu y que los botones de movimiento se vean como una cruceta incluyendo un botón para saltar y agacharse y que cada personaje tenga habilidades diferentes por ejemplo el tiburón que lance aguas, que el lagarto se mueva más rápido y que el lobo pueda morder, también necesito que las barras de vida del enemigo sean más altas y que estén del lado del oponente
User prompt
Que los botones de pelear y defenderse aparezcan después del menu, junto a botones en dónde tú personaje se pueda mover y que el botón de atacar no sea el único que también haya botones de patada o agarres que salen al enemigo y que el enemigo también se pueda mover y atacar de manera inteligente dependiendo la dificultad que se podra elegir en el inicio
User prompt
Al momento de iniciar la batalla que inicie un contador y que haya botones en la parte superior para que en móvil se puedan seleccionar al igual Sprites para cada acción que selecciones, también que el oponente tenga una barra de vida y el contador para acabar la pelea se pueda seleccionar sin límite o con un límite de 90 segundos
User prompt
Faltan botones para las acciones y el menú general para iniciar un combate
Code edit (1 edits merged)
Please save this source code
User prompt
Furry Fighter Arena
User prompt
Se me ocurre que los jefes y combatientes tengan pinta de animales furros como tiburones fuertes, lagartos etc,
User prompt
Please continue polishing my design document.
Initial prompt
Se me ocurre un juego de peleas rítmicas en dónde se deban de usar botones al ritmo sonoro con jefes con soundtrack memorables y personajes icónicos
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Button = Container.expand(function (assetName, text) { var self = Container.call(this); var buttonGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2(text, { size: 40, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.down = function (x, y, obj) { tween(buttonGraphics, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, onFinish: function onFinish() { tween(buttonGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); }; return self; }); var CharacterCard = Container.expand(function (characterType, name) { var self = Container.call(this); self.characterType = characterType; self.isSelected = false; var cardBg = self.attachAsset('characterCard', { anchorX: 0.5, anchorY: 0.5 }); var character = self.attachAsset(characterType + 'Fighter', { anchorX: 0.5, anchorY: 0.8, y: -20 }); var nameText = new Text2(name, { size: 30, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.y = 100; self.addChild(nameText); self.setSelected = function (selected) { self.isSelected = selected; if (selected) { cardBg.tint = 0xf39c12; tween(cardBg, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200 }); } else { cardBg.tint = 0xFFFFFF; tween(cardBg, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }; self.down = function (x, y, obj) { if (gameState === 'characterSelect') { selectedCharacter = self.characterType; for (var i = 0; i < characterCards.length; i++) { characterCards[i].setSelected(characterCards[i] === self); } console.log('Selected character:', selectedCharacter); } }; return self; }); var Fighter = Container.expand(function (isPlayer) { var self = Container.call(this); self.isPlayer = isPlayer || false; self.maxHealth = 300; self.health = self.maxHealth; self.maxStamina = 100; self.stamina = self.maxStamina; self.attackPower = 20; self.isBlocking = false; self.isAttacking = false; self.canAttack = true; self.staminaRegenRate = 0.5; self.lastAttackTime = 0; var assetName = 'playerFighter'; if (isPlayer) { // Use the selected character for the player assetName = selectedCharacter + 'Fighter'; console.log('Using player asset:', assetName, 'selectedCharacter:', selectedCharacter); } else { // Randomly select enemy type for variety var enemyTypes = ['enemy', 'lizard', 'shark', 'wolf', 'bear', 'tiger', 'eagle']; var randomType = enemyTypes[Math.floor(Math.random() * enemyTypes.length)]; assetName = randomType + 'Fighter'; console.log('Using enemy asset:', assetName); } var fighterGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 1 }); self.attack = function () { if (!self.canAttack || self.stamina < 25) { return false; } self.isAttacking = true; self.canAttack = false; self.stamina -= 25; self.lastAttackTime = Date.now(); tween(fighterGraphics, { scaleX: 1.2, scaleY: 0.9 }, { duration: 100, onFinish: function onFinish() { tween(fighterGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); LK.getSound('punch').play(); LK.setTimeout(function () { self.isAttacking = false; self.canAttack = true; }, 300); return true; }; self.block = function () { if (self.stamina < 15) { return false; } self.isBlocking = true; self.stamina -= 15; self.lastAttackTime = Date.now(); tween(fighterGraphics, { tint: 0x3498db }, { duration: 200, onFinish: function onFinish() { tween(fighterGraphics, { tint: 0xffffff }, { duration: 200 }); } }); LK.getSound('block').play(); LK.setTimeout(function () { self.isBlocking = false; }, 400); return true; }; self.specialAttack = function () { if (self.stamina < 60) { return false; } self.stamina -= 60; self.lastAttackTime = Date.now(); tween(fighterGraphics, { scaleX: 1.5, scaleY: 1.5, tint: 0xffd700 }, { duration: 300, onFinish: function onFinish() { tween(fighterGraphics, { scaleX: 1, scaleY: 1, tint: 0xffffff }, { duration: 300 }); } }); LK.getSound('special').play(); return true; }; self.takeDamage = function (damage) { if (self.isBlocking) { damage = Math.floor(damage * 0.2); } self.health -= damage; if (self.health < 0) { self.health = 0; } LK.effects.flashObject(self, 0xff0000, 200); tween(fighterGraphics, { x: fighterGraphics.x + (self.isPlayer ? -20 : 20) }, { duration: 100, onFinish: function onFinish() { tween(fighterGraphics, { x: 0 }, { duration: 100 }); } }); }; self.update = function () { var currentTime = Date.now(); // Only regenerate stamina if not attacking recently (1 second cooldown) if (currentTime - self.lastAttackTime > 1000) { if (self.stamina < self.maxStamina) { self.stamina += self.staminaRegenRate; if (self.stamina > self.maxStamina) { self.stamina = self.maxStamina; } } } }; return self; }); var HealthBar = Container.expand(function (maxValue) { var self = Container.call(this); self.maxValue = maxValue; self.currentValue = maxValue; var background = self.attachAsset('healthBarBg', { anchorX: 0, anchorY: 0 }); var bar = self.attachAsset('healthBar', { anchorX: 0, anchorY: 0 }); self.setValue = function (value) { self.currentValue = value; var percentage = value / self.maxValue; bar.scaleX = percentage; if (percentage > 0.6) { bar.tint = 0x2ecc71; } else if (percentage > 0.3) { bar.tint = 0xf39c12; } else { bar.tint = 0xe74c3c; } }; return self; }); var StaminaBar = Container.expand(function (maxValue) { var self = Container.call(this); self.maxValue = maxValue; self.currentValue = maxValue; var background = self.attachAsset('staminaBarBg', { anchorX: 0, anchorY: 0 }); var bar = self.attachAsset('staminaBar', { anchorX: 0, anchorY: 0 }); self.setValue = function (value) { self.currentValue = value; var percentage = value / self.maxValue; bar.scaleX = percentage; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ var gameState = 'menu'; var roundTimer = 60; var roundStartTime = 0; var battleCountdown = 3; var countdownActive = false; var timerMode = 'unlimited'; // 'unlimited' or 'limited' var selectedCharacter = 'shark'; var characterCards = []; var currentEnemyIndex = 0; var totalEnemies = 20; var enemyNames = ['Razor Claw', 'Iron Fang', 'Storm Fury', 'Shadow Beast', 'Thunder Paws', 'Venom Strike', 'Blade Runner', 'Fire Tooth', 'Ice Crusher', 'Wind Slasher', 'Stone Jaw', 'Lightning Bolt', 'Dark Hunter', 'Flame Warrior', 'Frost Bite', 'Night Stalker', 'Blood Fang', 'Steel Claw', 'Wild Storm', 'Bone Breaker', 'Crimson Fang', 'Golden Claw', 'Silver Strike', 'Midnight Howl', 'Dawn Breaker', 'Skull Crusher', 'Void Walker', 'Star Slayer', 'Moon Fang', 'Sun Warrior']; var menuContainer = game.addChild(new Container()); var characterSelectContainer = game.addChild(new Container()); var gameplayContainer = game.addChild(new Container()); var titleText = new Text2('FURRY FIGHTER ARENA', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 600; menuContainer.addChild(titleText); var startButton = new Button('menuButton', 'START COMBAT'); startButton.x = 2048 / 2; startButton.y = 1200; menuContainer.addChild(startButton); startButton.down = function (x, y, obj) { if (gameState === 'menu') { gameState = 'characterSelect'; menuContainer.visible = false; characterSelectContainer.visible = true; } }; var characterSelectTitle = new Text2('SELECT YOUR FIGHTER', { size: 60, fill: 0xFFFFFF }); characterSelectTitle.anchor.set(0.5, 0.5); characterSelectTitle.x = 2048 / 2; characterSelectTitle.y = 400; characterSelectContainer.addChild(characterSelectTitle); var sharkCard = new CharacterCard('shark', 'SHARK'); sharkCard.x = 2048 / 2 - 300; sharkCard.y = 1000; characterSelectContainer.addChild(sharkCard); characterCards.push(sharkCard); var lizardCard = new CharacterCard('lizard', 'LIZARD'); lizardCard.x = 2048 / 2; lizardCard.y = 1000; characterSelectContainer.addChild(lizardCard); characterCards.push(lizardCard); var wolfCard = new CharacterCard('wolf', 'WOLF'); wolfCard.x = 2048 / 2 + 300; wolfCard.y = 1000; characterSelectContainer.addChild(wolfCard); characterCards.push(wolfCard); sharkCard.setSelected(true); selectedCharacter = 'shark'; console.log('Initial selected character:', selectedCharacter); var difficultyText = new Text2('DIFFICULTY: MEDIUM', { size: 50, fill: 0xFFFFFF }); difficultyText.anchor.set(0.5, 0.5); difficultyText.x = 2048 / 2; difficultyText.y = 1300; characterSelectContainer.addChild(difficultyText); var difficultyButton = new Button('menuButton', 'CHANGE DIFFICULTY'); difficultyButton.x = 2048 / 2; difficultyButton.y = 1400; characterSelectContainer.addChild(difficultyButton); var timerModeText = new Text2('TIMER MODE: UNLIMITED', { size: 50, fill: 0xFFFFFF }); timerModeText.anchor.set(0.5, 0.5); timerModeText.x = 2048 / 2; timerModeText.y = 1500; characterSelectContainer.addChild(timerModeText); difficultyButton.down = function (x, y, obj) { if (gameState === 'characterSelect') { if (enemyAI.difficulty === 'easy') { enemyAI.difficulty = 'medium'; difficultyText.setText('DIFFICULTY: MEDIUM'); } else if (enemyAI.difficulty === 'medium') { enemyAI.difficulty = 'hard'; difficultyText.setText('DIFFICULTY: HARD'); } else { enemyAI.difficulty = 'easy'; difficultyText.setText('DIFFICULTY: EASY'); } } }; var timerModeButton = new Button('menuButton', 'TOGGLE TIMER'); timerModeButton.x = 2048 / 2; timerModeButton.y = 1550; characterSelectContainer.addChild(timerModeButton); timerModeButton.down = function (x, y, obj) { if (gameState === 'characterSelect') { if (timerMode === 'unlimited') { timerMode = 'limited'; timerModeText.setText('TIMER MODE: 90 SECONDS'); } else { timerMode = 'unlimited'; timerModeText.setText('TIMER MODE: UNLIMITED'); } } }; var fightButton = new Button('menuButton', 'FIGHT!'); fightButton.x = 2048 / 2; fightButton.y = 1650; characterSelectContainer.addChild(fightButton); fightButton.down = function (x, y, obj) { if (gameState === 'characterSelect') { gameState = 'countdown'; characterSelectContainer.visible = false; gameplayContainer.visible = true; // Recreate player fighter with selected character gameplayContainer.removeChild(playerFighter); playerFighter = gameplayContainer.addChild(new Fighter(true)); playerFighter.x = 2048 / 2 - 300; playerFighter.y = 1600; if (timerMode === 'limited') { roundTimer = 90; } else { roundTimer = -1; // Unlimited time } battleCountdown = 3; countdownActive = true; // Reset enemy progression currentEnemyIndex = 0; // Shuffle enemy names for random encounters for (var i = enemyNames.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = enemyNames[i]; enemyNames[i] = enemyNames[j]; enemyNames[j] = temp; } } }; characterSelectContainer.visible = false; gameplayContainer.visible = false; var arena = gameplayContainer.addChild(LK.getAsset('arena', { anchorX: 0.5, anchorY: 1, x: 2048 / 2, y: 1800 })); var arenaLine = gameplayContainer.addChild(LK.getAsset('arenaLine', { anchorX: 0.5, anchorY: 1, x: 2048 / 2, y: 1600 })); var playerFighter = gameplayContainer.addChild(new Fighter(true)); playerFighter.x = 2048 / 2 - 300; playerFighter.y = 1600; // Aligned with arena line var enemyFighter = gameplayContainer.addChild(new Fighter(false)); enemyFighter.x = 2048 / 2 + 300; enemyFighter.y = 1600; // Aligned with arena line var playerHealthBar = new HealthBar(300); playerHealthBar.x = 100; playerHealthBar.y = 100; LK.gui.topLeft.addChild(playerHealthBar); var enemyHealthBar = new HealthBar(300); enemyHealthBar.x = -500; enemyHealthBar.y = 100; LK.gui.topRight.addChild(enemyHealthBar); var playerStaminaBar = new StaminaBar(100); playerStaminaBar.x = 100; playerStaminaBar.y = 150; LK.gui.topLeft.addChild(playerStaminaBar); var enemyStaminaBar = new StaminaBar(100); enemyStaminaBar.x = -500; enemyStaminaBar.y = 150; LK.gui.topRight.addChild(enemyStaminaBar); var timerText = new Text2('60', { size: 80, fill: 0xFFFFFF }); timerText.anchor.set(0.5, 0); LK.gui.top.addChild(timerText); var countdownText = new Text2('3', { size: 200, fill: 0xf39c12 }); countdownText.anchor.set(0.5, 0.5); countdownText.x = 2048 / 2; countdownText.y = 1366; gameplayContainer.addChild(countdownText); countdownText.visible = false; var scoreText = new Text2('Score: 0', { size: 50, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); scoreText.y = 100; LK.gui.top.addChild(scoreText); var actionSprite = LK.getAsset('actionSprite', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 1000 }); gameplayContainer.addChild(actionSprite); actionSprite.visible = false; // Victory screen elements var victoryContainer = game.addChild(new Container()); victoryContainer.visible = false; var victoryBg = victoryContainer.addChild(LK.getAsset('arena', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 1366, scaleX: 1.2, scaleY: 1.5 })); victoryBg.tint = 0x2c3e50; victoryBg.alpha = 0.9; var koText = new Text2('K.O.!', { size: 150, fill: 0xf39c12 }); koText.anchor.set(0.5, 0.5); koText.x = 2048 / 2; koText.y = 800; victoryContainer.addChild(koText); var victoryText = new Text2('YOU WIN!', { size: 80, fill: 0x2ecc71 }); victoryText.anchor.set(0.5, 0.5); victoryText.x = 2048 / 2; victoryText.y = 950; victoryContainer.addChild(victoryText); var enemyDefeatedText = new Text2('', { size: 60, fill: 0xFFFFFF }); enemyDefeatedText.anchor.set(0.5, 0.5); enemyDefeatedText.x = 2048 / 2; enemyDefeatedText.y = 1100; victoryContainer.addChild(enemyDefeatedText); var progressText = new Text2('', { size: 50, fill: 0xecf0f1 }); progressText.anchor.set(0.5, 0.5); progressText.x = 2048 / 2; progressText.y = 1200; victoryContainer.addChild(progressText); var continueButton = new Button('menuButton', 'CONTINUE FIGHTING'); continueButton.x = 2048 / 2 - 250; continueButton.y = 1400; victoryContainer.addChild(continueButton); var stopButton = new Button('menuButton', 'STOP HERE'); stopButton.x = 2048 / 2 + 250; stopButton.y = 1400; victoryContainer.addChild(stopButton); function showActionSprite(actionType, color) { if (gameState !== 'playing') { return; } actionSprite.visible = true; actionSprite.tint = color; actionSprite.scaleX = 0.5; actionSprite.scaleY = 0.5; tween(actionSprite, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 500, onFinish: function onFinish() { actionSprite.visible = false; actionSprite.alpha = 1; actionSprite.scaleX = 1; actionSprite.scaleY = 1; } }); } // Movement controls in d-pad formation - bottom center-left positioning var moveUpButton = new Button('moveButton', '↑'); moveUpButton.x = -400; moveUpButton.y = -320; moveUpButton.scaleX = 1.5; moveUpButton.scaleY = 1.5; LK.gui.bottom.addChild(moveUpButton); var moveLeftButton = new Button('moveButton', '←'); moveLeftButton.x = -500; moveLeftButton.y = -220; moveLeftButton.scaleX = 1.5; moveLeftButton.scaleY = 1.5; LK.gui.bottom.addChild(moveLeftButton); var moveRightButton = new Button('moveButton', '→'); moveRightButton.x = -300; moveRightButton.y = -220; moveRightButton.scaleX = 1.5; moveRightButton.scaleY = 1.5; LK.gui.bottom.addChild(moveRightButton); var moveDownButton = new Button('moveButton', '↓'); moveDownButton.x = -400; moveDownButton.y = -120; moveDownButton.scaleX = 1.5; moveDownButton.scaleY = 1.5; LK.gui.bottom.addChild(moveDownButton); // Combat controls - bottom center positioning with better spacing var attackButton = new Button('attackButton', 'PUNCH'); attackButton.x = 0; attackButton.y = -320; attackButton.scaleX = 1.5; attackButton.scaleY = 1.5; LK.gui.bottom.addChild(attackButton); var kickButton = new Button('attackButton', 'KICK'); kickButton.x = 300; kickButton.y = -320; kickButton.scaleX = 1.5; kickButton.scaleY = 1.5; LK.gui.bottom.addChild(kickButton); var blockButton = new Button('blockButton', 'BLOCK'); blockButton.x = 150; blockButton.y = -180; blockButton.scaleX = 1.5; blockButton.scaleY = 1.5; LK.gui.bottom.addChild(blockButton); // Hide all action buttons initially moveUpButton.visible = false; moveLeftButton.visible = false; moveRightButton.visible = false; moveDownButton.visible = false; attackButton.visible = false; kickButton.visible = false; blockButton.visible = false; var playerSpeed = selectedCharacter === 'lizard' ? 70 : selectedCharacter === 'wolf' ? 60 : 50; var playerProjectiles = []; moveUpButton.down = function (x, y, obj) { if (gameState !== 'playing') { return; } // Jump functionality tween(playerFighter, { y: playerFighter.y - 100 }, { duration: 300, onFinish: function onFinish() { tween(playerFighter, { y: playerFighter.y + 100 }, { duration: 300 }); } }); }; moveLeftButton.down = function (x, y, obj) { if (gameState !== 'playing') { return; } var currentSpeed = selectedCharacter === 'lizard' ? 70 : selectedCharacter === 'wolf' ? 60 : 50; if (playerFighter.x > 200) { playerFighter.x -= currentSpeed; } }; moveRightButton.down = function (x, y, obj) { if (gameState !== 'playing') { return; } var currentSpeed = selectedCharacter === 'lizard' ? 70 : selectedCharacter === 'wolf' ? 60 : 50; if (playerFighter.x < 1848) { playerFighter.x += currentSpeed; } }; moveDownButton.down = function (x, y, obj) { if (gameState !== 'playing') { return; } // Crouch functionality tween(playerFighter, { scaleY: 0.5 }, { duration: 200, onFinish: function onFinish() { LK.setTimeout(function () { tween(playerFighter, { scaleY: 1 }, { duration: 200 }); }, 500); } }); }; attackButton.down = function (x, y, obj) { if (gameState !== 'playing') { return; } showActionSprite('attack', 0xe74c3c); if (playerFighter.attack()) { var distance = Math.abs(playerFighter.x - enemyFighter.x); if (distance < 350) { var damage = playerFighter.attackPower; enemyFighter.takeDamage(damage); } } }; var kickCooldown = 0; kickButton.down = function (x, y, obj) { if (gameState !== 'playing') { return; } var currentTime = Date.now(); if (currentTime < kickCooldown) { return; // Kick is on cooldown } showActionSprite('kick', 0xff6b35); if (playerFighter.attack()) { var distance = Math.abs(playerFighter.x - enemyFighter.x); if (distance < 400) { var damage = playerFighter.attackPower * 2.0; enemyFighter.takeDamage(damage); } kickCooldown = currentTime + 800; // 800ms cooldown for kicks } }; blockButton.down = function (x, y, obj) { if (gameState !== 'playing') { return; } showActionSprite('block', 0x3498db); playerFighter.block(); }; var enemyAI = { nextActionTime: 0, actionCooldown: 1000, nextMoveTime: 0, moveCooldown: 500, difficulty: 'medium', // easy, medium, hard playerHealthHistory: [], playerMovementHistory: [], consecutiveAttacks: 0, lastPlayerPosition: 0, adaptiveStrategy: 'balanced', // balanced, aggressive, defensive strategyTimer: 0, update: function update() { if (gameState !== 'playing') { return; } var currentTime = Date.now(); var distance = Math.abs(playerFighter.x - enemyFighter.x); // Track player behavior for adaptive AI this.trackPlayerBehavior(currentTime); // Update adaptive strategy based on difficulty this.updateAdaptiveStrategy(currentTime); // Get difficulty-based multipliers var difficultySettings = this.getDifficultySettings(); // Enhanced Movement AI with intelligent positioning if (currentTime >= this.nextMoveTime) { var moveAction = Math.random(); if (moveAction < difficultySettings.moveFrequency) { var optimalDistance = this.getOptimalDistance(); if (distance > optimalDistance + 50) { // Move closer with smart pathfinding var approachSpeed = difficultySettings.moveSpeed * this.getApproachMultiplier(); if (playerFighter.x > enemyFighter.x && enemyFighter.x < 1848) { enemyFighter.x += approachSpeed; } else if (playerFighter.x < enemyFighter.x && enemyFighter.x > 200) { enemyFighter.x -= approachSpeed; } } else if (distance < optimalDistance - 50) { // Maintain optimal distance with tactical retreats var retreatChance = difficultySettings.retreatChance; if (Math.random() < retreatChance) { var retreatSpeed = difficultySettings.moveSpeed * 0.8; if (playerFighter.x > enemyFighter.x && enemyFighter.x > 200) { enemyFighter.x -= retreatSpeed; } else if (playerFighter.x < enemyFighter.x && enemyFighter.x < 1848) { enemyFighter.x += retreatSpeed; } } } else { // Optimal distance - intelligent repositioning based on strategy var repositionChance = difficultySettings.repositionChance; if (Math.random() < repositionChance) { var tacticalMove = this.getTacticalMove(); if (enemyFighter.x + tacticalMove > 200 && enemyFighter.x + tacticalMove < 1848) { enemyFighter.x += tacticalMove; } } } } this.nextMoveTime = currentTime + difficultySettings.moveCooldown + Math.random() * 200; } // Advanced Dodge/Evasion AI with predictive movement if (playerFighter.isAttacking && distance < 400) { var dodgeChance = difficultySettings.dodgeChance; // Increase dodge chance if player is predictable if (this.consecutiveAttacks > 2) { dodgeChance *= 1.5; } if (Math.random() < dodgeChance && currentTime >= this.nextMoveTime) { var dodgeDirection = this.getPredictiveDodge(); if (enemyFighter.x + dodgeDirection > 200 && enemyFighter.x + dodgeDirection < 1848) { enemyFighter.x += dodgeDirection; this.nextMoveTime = currentTime + 150; // Quick cooldown after dodge } } } // Intelligent Combat AI with pattern recognition if (currentTime < this.nextActionTime) { return; } var combatDecision = this.makeCombatDecision(distance, currentTime); if (combatDecision.action === 'attack') { this.executeAttack(combatDecision.attackType, distance); } else if (combatDecision.action === 'block') { enemyFighter.block(); } else if (combatDecision.action === 'special') { if (enemyFighter.specialAttack()) { var specialDamage = enemyFighter.attackPower * (combatDecision.damageMultiplier || 2); playerFighter.takeDamage(specialDamage); } } // Dynamic cooldown based on AI intelligence and player behavior var finalCooldown = this.calculateAdaptiveCooldown(currentTime, difficultySettings); this.nextActionTime = currentTime + finalCooldown; }, getDifficultySettings: function getDifficultySettings() { var settings = { easy: { moveFrequency: 0.3, moveSpeed: 20, retreatChance: 0.2, repositionChance: 0.1, moveCooldown: 800, dodgeChance: 0.15, attackChance: 0.25, blockChance: 0.4, specialChance: 0.05, reactionTime: 1000, patternRecognition: 0.1 }, medium: { moveFrequency: 0.5, moveSpeed: 35, retreatChance: 0.35, repositionChance: 0.25, moveCooldown: 600, dodgeChance: 0.3, attackChance: 0.4, blockChance: 0.55, specialChance: 0.15, reactionTime: 700, patternRecognition: 0.3 }, hard: { moveFrequency: 0.7, moveSpeed: 50, retreatChance: 0.5, repositionChance: 0.4, moveCooldown: 400, dodgeChance: 0.45, attackChance: 0.55, blockChance: 0.7, specialChance: 0.25, reactionTime: 400, patternRecognition: 0.6 } }; return settings[this.difficulty]; }, trackPlayerBehavior: function trackPlayerBehavior(currentTime) { // Track player health changes this.playerHealthHistory.push({ time: currentTime, health: playerFighter.health, stamina: playerFighter.stamina }); if (this.playerHealthHistory.length > 10) { this.playerHealthHistory.shift(); } // Track player movement patterns if (this.lastPlayerPosition !== playerFighter.x) { this.playerMovementHistory.push({ time: currentTime, position: playerFighter.x, direction: playerFighter.x > this.lastPlayerPosition ? 'right' : 'left' }); this.lastPlayerPosition = playerFighter.x; } if (this.playerMovementHistory.length > 8) { this.playerMovementHistory.shift(); } // Track consecutive attacks if (playerFighter.isAttacking) { this.consecutiveAttacks++; } else if (currentTime - (playerFighter.lastAttackTime || 0) > 1000) { this.consecutiveAttacks = 0; } }, updateAdaptiveStrategy: function updateAdaptiveStrategy(currentTime) { if (currentTime < this.strategyTimer) return; var difficultySettings = this.getDifficultySettings(); var healthPercentage = enemyFighter.health / enemyFighter.maxHealth; var staminaPercentage = enemyFighter.stamina / enemyFighter.maxStamina; // Switch strategies based on situation and difficulty intelligence if (difficultySettings.patternRecognition > Math.random()) { if (healthPercentage < 0.3) { this.adaptiveStrategy = 'defensive'; } else if (playerFighter.health < enemyFighter.health && staminaPercentage > 0.6) { this.adaptiveStrategy = 'aggressive'; } else { this.adaptiveStrategy = 'balanced'; } } this.strategyTimer = currentTime + 3000; // Re-evaluate every 3 seconds }, getOptimalDistance: function getOptimalDistance() { var baseDistance = 250; switch (this.adaptiveStrategy) { case 'aggressive': return baseDistance - 50; case 'defensive': return baseDistance + 100; default: return baseDistance; } }, getApproachMultiplier: function getApproachMultiplier() { var playerHealthPercentage = playerFighter.health / playerFighter.maxHealth; var multiplier = 1.0; // More aggressive approach when player is weak if (playerHealthPercentage < 0.3) { multiplier = 1.5; } else if (playerHealthPercentage < 0.6) { multiplier = 1.2; } return multiplier; }, getTacticalMove: function getTacticalMove() { var baseMove = Math.random() < 0.5 ? -30 : 30; // Add tactical positioning based on player movement patterns if (this.playerMovementHistory.length >= 3) { var recentMoves = this.playerMovementHistory.slice(-3); var rightMovements = recentMoves.filter(function (move) { return move.direction === 'right'; }).length; if (rightMovements >= 2) { // Player moving right, position for intercept baseMove = 40; } else if (rightMovements === 0) { // Player moving left, position for intercept baseMove = -40; } } return baseMove; }, getPredictiveDodge: function getPredictiveDodge() { var baseDodge = Math.random() < 0.5 ? -60 : 60; // Predict player attack direction based on position if (playerFighter.x > enemyFighter.x) { // Player attacking from right, dodge left baseDodge = -Math.abs(baseDodge); } else { // Player attacking from left, dodge right baseDodge = Math.abs(baseDodge); } return baseDodge; }, makeCombatDecision: function makeCombatDecision(distance, currentTime) { var difficultySettings = this.getDifficultySettings(); var decision = { action: 'wait' }; // Enhanced decision making based on multiple factors var playerAttackingRecently = currentTime - (playerFighter.lastAttackTime || 0) < 800; var shouldBlock = playerAttackingRecently && Math.random() < difficultySettings.blockChance * 1.5; var staminaPercentage = enemyFighter.stamina / enemyFighter.maxStamina; var action = Math.random(); if (distance < 350) { if (shouldBlock && !enemyFighter.isBlocking) { decision.action = 'block'; } else if (action < difficultySettings.attackChance && enemyFighter.canAttack && enemyFighter.stamina >= 25) { decision.action = 'attack'; decision.attackType = this.chooseAttackType(distance, staminaPercentage); } else if (action < difficultySettings.blockChance && !playerAttackingRecently) { decision.action = 'block'; } } else if (distance < 500 && enemyFighter.stamina >= 60 && Math.random() < difficultySettings.specialChance) { decision.action = 'special'; decision.damageMultiplier = 1.5; } return decision; }, chooseAttackType: function chooseAttackType(distance, staminaPercentage) { var attackType = Math.random(); if (distance < 200 && attackType < 0.4) { return 'punch'; } else if (distance < 300 && attackType < 0.7) { return 'kick'; } else if (distance < 180 && attackType < 0.9) { return 'grab'; } else if (staminaPercentage > 0.6 && Math.random() < 0.3) { return 'special'; } return 'punch'; }, executeAttack: function executeAttack(attackType, distance) { switch (attackType) { case 'punch': if (enemyFighter.attack()) { playerFighter.takeDamage(enemyFighter.attackPower); } break; case 'kick': if (enemyFighter.attack()) { LK.setTimeout(function () { // Kick delay effect }, 400); playerFighter.takeDamage(enemyFighter.attackPower * 2.0); } break; case 'grab': if (enemyFighter.attack()) { playerFighter.takeDamage(enemyFighter.attackPower * 1.2); // Intelligent grab positioning var pullDistance = this.difficulty === 'hard' ? 40 : 30; if (playerFighter.x > enemyFighter.x) { playerFighter.x -= pullDistance; } else { playerFighter.x += pullDistance; } } break; case 'special': if (enemyFighter.specialAttack()) { playerFighter.takeDamage(enemyFighter.attackPower * 2); } break; } }, calculateAdaptiveCooldown: function calculateAdaptiveCooldown(currentTime, difficultySettings) { var baseCooldown = difficultySettings.reactionTime; var cooldownVariation = baseCooldown * 0.3; // Reduce cooldown based on player aggression var playerAttackingRecently = currentTime - (playerFighter.lastAttackTime || 0) < 800; var playerAggressiveBonus = playerAttackingRecently ? 0.7 : 1.0; // Increase cooldown if enemy is low on stamina var staminaPenalty = enemyFighter.stamina < 30 ? 1.5 : 1.0; // Strategy-based cooldown modification var strategyMultiplier = 1.0; switch (this.adaptiveStrategy) { case 'aggressive': strategyMultiplier = 0.8; break; case 'defensive': strategyMultiplier = 1.2; break; } var finalCooldown = baseCooldown * playerAggressiveBonus * staminaPenalty * strategyMultiplier + Math.random() * cooldownVariation; return Math.max(finalCooldown, 100); // Minimum 100ms cooldown } }; function checkGameEnd() { if (playerFighter.health <= 0) { gameState = 'gameOver'; LK.showGameOver(); return true; } if (enemyFighter.health <= 0) { gameState = 'victory'; LK.setScore(LK.getScore() + 100); // Show victory screen gameplayContainer.visible = false; victoryContainer.visible = true; enemyDefeatedText.setText(enemyNames[currentEnemyIndex] + ' DEFEATED!'); progressText.setText('Enemies Defeated: ' + (currentEnemyIndex + 1) + '/' + totalEnemies); // Hide action buttons moveUpButton.visible = false; moveLeftButton.visible = false; moveRightButton.visible = false; moveDownButton.visible = false; attackButton.visible = false; kickButton.visible = false; blockButton.visible = false; return true; } if (timerMode === 'limited' && roundTimer <= 0) { gameState = 'timeUp'; if (playerFighter.health > enemyFighter.health) { LK.setScore(LK.getScore() + 50); LK.showYouWin(); } else { LK.showGameOver(); } return true; } return false; } continueButton.down = function (x, y, obj) { if (gameState === 'victory') { currentEnemyIndex++; if (currentEnemyIndex >= totalEnemies) { // All enemies defeated var finalText = new Text2('CHAMPION!', { size: 100, fill: 0xf39c12 }); finalText.anchor.set(0.5, 0.5); finalText.x = 2048 / 2; finalText.y = 1366; game.addChild(finalText); LK.setScore(LK.getScore() + 500); LK.showYouWin(); return; } // Start next fight victoryContainer.visible = false; gameplayContainer.visible = true; gameState = 'countdown'; battleCountdown = 3; countdownActive = true; // Reset and recreate both fighters to ensure proper character selection gameplayContainer.removeChild(playerFighter); gameplayContainer.removeChild(enemyFighter); playerFighter = gameplayContainer.addChild(new Fighter(true)); playerFighter.x = 2048 / 2 - 300; playerFighter.y = 1600; enemyFighter = gameplayContainer.addChild(new Fighter(false)); enemyFighter.x = 2048 / 2 + 300; enemyFighter.y = 1600; if (timerMode === 'limited') { roundTimer = 90; } else { roundTimer = -1; } } }; stopButton.down = function (x, y, obj) { if (gameState === 'victory') { LK.setScore(LK.getScore() + 50); LK.showYouWin(); } }; LK.playMusic('battleMusic'); game.update = function () { if (gameState === 'countdown') { if (countdownActive) { countdownText.visible = true; countdownText.setText(battleCountdown.toString()); if (LK.ticks % 60 === 0) { battleCountdown--; if (battleCountdown <= 0) { countdownActive = false; countdownText.visible = false; gameState = 'playing'; } } } } if (gameState === 'playing') { // Show action buttons when game starts moveUpButton.visible = true; moveLeftButton.visible = true; moveRightButton.visible = true; moveDownButton.visible = true; attackButton.visible = true; kickButton.visible = true; blockButton.visible = true; if (timerMode === 'limited') { if (LK.ticks % 60 === 0) { roundTimer--; timerText.setText(roundTimer.toString()); if (roundTimer <= 10) { timerText.tint = 0xe74c3c; } } } else { timerText.setText('∞'); } playerHealthBar.setValue(playerFighter.health); enemyHealthBar.setValue(enemyFighter.health); playerStaminaBar.setValue(playerFighter.stamina); enemyStaminaBar.setValue(enemyFighter.stamina); scoreText.setText('Score: ' + LK.getScore()); enemyAI.update(); // Update projectiles for (var i = playerProjectiles.length - 1; i >= 0; i--) { var projectile = playerProjectiles[i]; var deltaX = projectile.targetX - projectile.x; var deltaY = (projectile.targetY || enemyFighter.y - 50) - projectile.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance < 50) { // Hit enemy var damage = selectedCharacter === 'shark' ? playerFighter.attackPower * 1.8 : playerFighter.attackPower * 2; enemyFighter.takeDamage(damage); projectile.destroy(); playerProjectiles.splice(i, 1); } else if (distance > 800) { // Out of range projectile.destroy(); playerProjectiles.splice(i, 1); } else { // Move projectile projectile.x += deltaX / distance * projectile.speed; projectile.y += deltaY / distance * projectile.speed; } } checkGameEnd(); } };
===================================================================
--- original.js
+++ change.js
@@ -723,128 +723,332 @@
nextMoveTime: 0,
moveCooldown: 500,
difficulty: 'medium',
// easy, medium, hard
+ playerHealthHistory: [],
+ playerMovementHistory: [],
+ consecutiveAttacks: 0,
+ lastPlayerPosition: 0,
+ adaptiveStrategy: 'balanced',
+ // balanced, aggressive, defensive
+ strategyTimer: 0,
update: function update() {
if (gameState !== 'playing') {
return;
}
var currentTime = Date.now();
var distance = Math.abs(playerFighter.x - enemyFighter.x);
- // Enhanced Movement AI with better positioning
+ // Track player behavior for adaptive AI
+ this.trackPlayerBehavior(currentTime);
+ // Update adaptive strategy based on difficulty
+ this.updateAdaptiveStrategy(currentTime);
+ // Get difficulty-based multipliers
+ var difficultySettings = this.getDifficultySettings();
+ // Enhanced Movement AI with intelligent positioning
if (currentTime >= this.nextMoveTime) {
var moveAction = Math.random();
- var difficultyMultiplier = this.difficulty === 'easy' ? 0.4 : this.difficulty === 'medium' ? 0.6 : 0.8;
- var moveSpeed = this.difficulty === 'easy' ? 25 : this.difficulty === 'medium' ? 35 : 50;
- if (moveAction < difficultyMultiplier) {
- if (distance > 350) {
- // Move closer to player more aggressively
+ if (moveAction < difficultySettings.moveFrequency) {
+ var optimalDistance = this.getOptimalDistance();
+ if (distance > optimalDistance + 50) {
+ // Move closer with smart pathfinding
+ var approachSpeed = difficultySettings.moveSpeed * this.getApproachMultiplier();
if (playerFighter.x > enemyFighter.x && enemyFighter.x < 1848) {
- enemyFighter.x += moveSpeed;
+ enemyFighter.x += approachSpeed;
} else if (playerFighter.x < enemyFighter.x && enemyFighter.x > 200) {
- enemyFighter.x -= moveSpeed;
+ enemyFighter.x -= approachSpeed;
}
- } else if (distance < 150) {
- // Move away if too close (but less frequently)
- if (Math.random() < 0.3) {
+ } else if (distance < optimalDistance - 50) {
+ // Maintain optimal distance with tactical retreats
+ var retreatChance = difficultySettings.retreatChance;
+ if (Math.random() < retreatChance) {
+ var retreatSpeed = difficultySettings.moveSpeed * 0.8;
if (playerFighter.x > enemyFighter.x && enemyFighter.x > 200) {
- enemyFighter.x -= moveSpeed * 0.7;
+ enemyFighter.x -= retreatSpeed;
} else if (playerFighter.x < enemyFighter.x && enemyFighter.x < 1848) {
- enemyFighter.x += moveSpeed * 0.7;
+ enemyFighter.x += retreatSpeed;
}
}
} else {
- // Optimal distance - slight repositioning for better attack angles
- if (Math.random() < 0.2) {
- var sideStep = Math.random() < 0.5 ? -20 : 20;
- if (enemyFighter.x + sideStep > 200 && enemyFighter.x + sideStep < 1848) {
- enemyFighter.x += sideStep;
+ // Optimal distance - intelligent repositioning based on strategy
+ var repositionChance = difficultySettings.repositionChance;
+ if (Math.random() < repositionChance) {
+ var tacticalMove = this.getTacticalMove();
+ if (enemyFighter.x + tacticalMove > 200 && enemyFighter.x + tacticalMove < 1848) {
+ enemyFighter.x += tacticalMove;
}
}
}
}
- this.nextMoveTime = currentTime + this.moveCooldown + Math.random() * 300;
+ this.nextMoveTime = currentTime + difficultySettings.moveCooldown + Math.random() * 200;
}
- // Dodge/Evasion AI - react to player attacks
- if (playerFighter.isAttacking && distance < 300) {
- var dodgeChance = this.difficulty === 'easy' ? 0.2 : this.difficulty === 'medium' ? 0.35 : 0.5;
+ // Advanced Dodge/Evasion AI with predictive movement
+ if (playerFighter.isAttacking && distance < 400) {
+ var dodgeChance = difficultySettings.dodgeChance;
+ // Increase dodge chance if player is predictable
+ if (this.consecutiveAttacks > 2) {
+ dodgeChance *= 1.5;
+ }
if (Math.random() < dodgeChance && currentTime >= this.nextMoveTime) {
- // Quick dodge movement
- var dodgeDirection = Math.random() < 0.5 ? -60 : 60;
+ var dodgeDirection = this.getPredictiveDodge();
if (enemyFighter.x + dodgeDirection > 200 && enemyFighter.x + dodgeDirection < 1848) {
enemyFighter.x += dodgeDirection;
- this.nextMoveTime = currentTime + 200; // Short cooldown after dodge
+ this.nextMoveTime = currentTime + 150; // Quick cooldown after dodge
}
}
}
- // Combat AI
+ // Intelligent Combat AI with pattern recognition
if (currentTime < this.nextActionTime) {
return;
}
- var action = Math.random();
- var attackChance = this.difficulty === 'easy' ? 0.3 : this.difficulty === 'medium' ? 0.4 : 0.5;
- var blockChance = this.difficulty === 'easy' ? 0.5 : this.difficulty === 'medium' ? 0.6 : 0.7;
- var specialChance = this.difficulty === 'easy' ? 0.7 : this.difficulty === 'medium' ? 0.8 : 0.9;
- // Enhanced combat decision making
+ var combatDecision = this.makeCombatDecision(distance, currentTime);
+ if (combatDecision.action === 'attack') {
+ this.executeAttack(combatDecision.attackType, distance);
+ } else if (combatDecision.action === 'block') {
+ enemyFighter.block();
+ } else if (combatDecision.action === 'special') {
+ if (enemyFighter.specialAttack()) {
+ var specialDamage = enemyFighter.attackPower * (combatDecision.damageMultiplier || 2);
+ playerFighter.takeDamage(specialDamage);
+ }
+ }
+ // Dynamic cooldown based on AI intelligence and player behavior
+ var finalCooldown = this.calculateAdaptiveCooldown(currentTime, difficultySettings);
+ this.nextActionTime = currentTime + finalCooldown;
+ },
+ getDifficultySettings: function getDifficultySettings() {
+ var settings = {
+ easy: {
+ moveFrequency: 0.3,
+ moveSpeed: 20,
+ retreatChance: 0.2,
+ repositionChance: 0.1,
+ moveCooldown: 800,
+ dodgeChance: 0.15,
+ attackChance: 0.25,
+ blockChance: 0.4,
+ specialChance: 0.05,
+ reactionTime: 1000,
+ patternRecognition: 0.1
+ },
+ medium: {
+ moveFrequency: 0.5,
+ moveSpeed: 35,
+ retreatChance: 0.35,
+ repositionChance: 0.25,
+ moveCooldown: 600,
+ dodgeChance: 0.3,
+ attackChance: 0.4,
+ blockChance: 0.55,
+ specialChance: 0.15,
+ reactionTime: 700,
+ patternRecognition: 0.3
+ },
+ hard: {
+ moveFrequency: 0.7,
+ moveSpeed: 50,
+ retreatChance: 0.5,
+ repositionChance: 0.4,
+ moveCooldown: 400,
+ dodgeChance: 0.45,
+ attackChance: 0.55,
+ blockChance: 0.7,
+ specialChance: 0.25,
+ reactionTime: 400,
+ patternRecognition: 0.6
+ }
+ };
+ return settings[this.difficulty];
+ },
+ trackPlayerBehavior: function trackPlayerBehavior(currentTime) {
+ // Track player health changes
+ this.playerHealthHistory.push({
+ time: currentTime,
+ health: playerFighter.health,
+ stamina: playerFighter.stamina
+ });
+ if (this.playerHealthHistory.length > 10) {
+ this.playerHealthHistory.shift();
+ }
+ // Track player movement patterns
+ if (this.lastPlayerPosition !== playerFighter.x) {
+ this.playerMovementHistory.push({
+ time: currentTime,
+ position: playerFighter.x,
+ direction: playerFighter.x > this.lastPlayerPosition ? 'right' : 'left'
+ });
+ this.lastPlayerPosition = playerFighter.x;
+ }
+ if (this.playerMovementHistory.length > 8) {
+ this.playerMovementHistory.shift();
+ }
+ // Track consecutive attacks
+ if (playerFighter.isAttacking) {
+ this.consecutiveAttacks++;
+ } else if (currentTime - (playerFighter.lastAttackTime || 0) > 1000) {
+ this.consecutiveAttacks = 0;
+ }
+ },
+ updateAdaptiveStrategy: function updateAdaptiveStrategy(currentTime) {
+ if (currentTime < this.strategyTimer) return;
+ var difficultySettings = this.getDifficultySettings();
+ var healthPercentage = enemyFighter.health / enemyFighter.maxHealth;
+ var staminaPercentage = enemyFighter.stamina / enemyFighter.maxStamina;
+ // Switch strategies based on situation and difficulty intelligence
+ if (difficultySettings.patternRecognition > Math.random()) {
+ if (healthPercentage < 0.3) {
+ this.adaptiveStrategy = 'defensive';
+ } else if (playerFighter.health < enemyFighter.health && staminaPercentage > 0.6) {
+ this.adaptiveStrategy = 'aggressive';
+ } else {
+ this.adaptiveStrategy = 'balanced';
+ }
+ }
+ this.strategyTimer = currentTime + 3000; // Re-evaluate every 3 seconds
+ },
+ getOptimalDistance: function getOptimalDistance() {
+ var baseDistance = 250;
+ switch (this.adaptiveStrategy) {
+ case 'aggressive':
+ return baseDistance - 50;
+ case 'defensive':
+ return baseDistance + 100;
+ default:
+ return baseDistance;
+ }
+ },
+ getApproachMultiplier: function getApproachMultiplier() {
+ var playerHealthPercentage = playerFighter.health / playerFighter.maxHealth;
+ var multiplier = 1.0;
+ // More aggressive approach when player is weak
+ if (playerHealthPercentage < 0.3) {
+ multiplier = 1.5;
+ } else if (playerHealthPercentage < 0.6) {
+ multiplier = 1.2;
+ }
+ return multiplier;
+ },
+ getTacticalMove: function getTacticalMove() {
+ var baseMove = Math.random() < 0.5 ? -30 : 30;
+ // Add tactical positioning based on player movement patterns
+ if (this.playerMovementHistory.length >= 3) {
+ var recentMoves = this.playerMovementHistory.slice(-3);
+ var rightMovements = recentMoves.filter(function (move) {
+ return move.direction === 'right';
+ }).length;
+ if (rightMovements >= 2) {
+ // Player moving right, position for intercept
+ baseMove = 40;
+ } else if (rightMovements === 0) {
+ // Player moving left, position for intercept
+ baseMove = -40;
+ }
+ }
+ return baseMove;
+ },
+ getPredictiveDodge: function getPredictiveDodge() {
+ var baseDodge = Math.random() < 0.5 ? -60 : 60;
+ // Predict player attack direction based on position
+ if (playerFighter.x > enemyFighter.x) {
+ // Player attacking from right, dodge left
+ baseDodge = -Math.abs(baseDodge);
+ } else {
+ // Player attacking from left, dodge right
+ baseDodge = Math.abs(baseDodge);
+ }
+ return baseDodge;
+ },
+ makeCombatDecision: function makeCombatDecision(distance, currentTime) {
+ var difficultySettings = this.getDifficultySettings();
+ var decision = {
+ action: 'wait'
+ };
+ // Enhanced decision making based on multiple factors
var playerAttackingRecently = currentTime - (playerFighter.lastAttackTime || 0) < 800;
- var shouldBlock = playerAttackingRecently && Math.random() < blockChance * 1.5;
+ var shouldBlock = playerAttackingRecently && Math.random() < difficultySettings.blockChance * 1.5;
+ var staminaPercentage = enemyFighter.stamina / enemyFighter.maxStamina;
+ var action = Math.random();
if (distance < 350) {
if (shouldBlock && !enemyFighter.isBlocking) {
- // Priority blocking when player is attacking
- enemyFighter.block();
- } else if (action < attackChance && enemyFighter.canAttack && enemyFighter.stamina >= 25) {
- // Choose attack type based on distance and stamina
- var attackType = Math.random();
- if (distance < 200 && attackType < 0.3) {
- // Close range - quick punch
- if (enemyFighter.attack()) {
- playerFighter.takeDamage(enemyFighter.attackPower);
+ decision.action = 'block';
+ } else if (action < difficultySettings.attackChance && enemyFighter.canAttack && enemyFighter.stamina >= 25) {
+ decision.action = 'attack';
+ decision.attackType = this.chooseAttackType(distance, staminaPercentage);
+ } else if (action < difficultySettings.blockChance && !playerAttackingRecently) {
+ decision.action = 'block';
+ }
+ } else if (distance < 500 && enemyFighter.stamina >= 60 && Math.random() < difficultySettings.specialChance) {
+ decision.action = 'special';
+ decision.damageMultiplier = 1.5;
+ }
+ return decision;
+ },
+ chooseAttackType: function chooseAttackType(distance, staminaPercentage) {
+ var attackType = Math.random();
+ if (distance < 200 && attackType < 0.4) {
+ return 'punch';
+ } else if (distance < 300 && attackType < 0.7) {
+ return 'kick';
+ } else if (distance < 180 && attackType < 0.9) {
+ return 'grab';
+ } else if (staminaPercentage > 0.6 && Math.random() < 0.3) {
+ return 'special';
+ }
+ return 'punch';
+ },
+ executeAttack: function executeAttack(attackType, distance) {
+ switch (attackType) {
+ case 'punch':
+ if (enemyFighter.attack()) {
+ playerFighter.takeDamage(enemyFighter.attackPower);
+ }
+ break;
+ case 'kick':
+ if (enemyFighter.attack()) {
+ LK.setTimeout(function () {
+ // Kick delay effect
+ }, 400);
+ playerFighter.takeDamage(enemyFighter.attackPower * 2.0);
+ }
+ break;
+ case 'grab':
+ if (enemyFighter.attack()) {
+ playerFighter.takeDamage(enemyFighter.attackPower * 1.2);
+ // Intelligent grab positioning
+ var pullDistance = this.difficulty === 'hard' ? 40 : 30;
+ if (playerFighter.x > enemyFighter.x) {
+ playerFighter.x -= pullDistance;
+ } else {
+ playerFighter.x += pullDistance;
}
- } else if (distance < 300 && attackType < 0.6) {
- // Medium range - kick (slower but more damage)
- if (enemyFighter.attack()) {
- // Simulate kick cooldown
- LK.setTimeout(function () {
- // Kick delay effect
- }, 400);
- playerFighter.takeDamage(enemyFighter.attackPower * 2.0);
- }
- } else if (distance < 180 && attackType < 0.8) {
- // Very close - grab attack
- if (enemyFighter.attack()) {
- playerFighter.takeDamage(enemyFighter.attackPower * 1.2);
- // Pull player closer
- if (playerFighter.x > enemyFighter.x) {
- playerFighter.x -= 30;
- } else {
- playerFighter.x += 30;
- }
- }
- } else if (enemyFighter.stamina >= 60 && Math.random() < 0.2) {
- // Special attack when high stamina
- if (enemyFighter.specialAttack()) {
- playerFighter.takeDamage(enemyFighter.attackPower * 2);
- }
}
- } else if (action < blockChance && !playerAttackingRecently) {
- // Block when not reacting to immediate threat
- enemyFighter.block();
- }
- } else if (distance < 500 && enemyFighter.stamina >= 60 && Math.random() < 0.15) {
- // Long range special attack
- if (enemyFighter.specialAttack()) {
- playerFighter.takeDamage(enemyFighter.attackPower * 1.5);
- }
+ break;
+ case 'special':
+ if (enemyFighter.specialAttack()) {
+ playerFighter.takeDamage(enemyFighter.attackPower * 2);
+ }
+ break;
}
- // Adaptive cooldown based on player activity and difficulty
- var baseCooldown = this.difficulty === 'easy' ? 1200 : this.difficulty === 'medium' ? 800 : 400;
- var cooldownVariation = this.difficulty === 'easy' ? 800 : this.difficulty === 'medium' ? 600 : 400;
- // Reduce cooldown if player is aggressive (attacking frequently)
+ },
+ calculateAdaptiveCooldown: function calculateAdaptiveCooldown(currentTime, difficultySettings) {
+ var baseCooldown = difficultySettings.reactionTime;
+ var cooldownVariation = baseCooldown * 0.3;
+ // Reduce cooldown based on player aggression
+ var playerAttackingRecently = currentTime - (playerFighter.lastAttackTime || 0) < 800;
var playerAggressiveBonus = playerAttackingRecently ? 0.7 : 1.0;
// Increase cooldown if enemy is low on stamina
var staminaPenalty = enemyFighter.stamina < 30 ? 1.5 : 1.0;
- var finalCooldown = baseCooldown * playerAggressiveBonus * staminaPenalty + Math.random() * cooldownVariation;
- this.nextActionTime = currentTime + finalCooldown;
+ // Strategy-based cooldown modification
+ var strategyMultiplier = 1.0;
+ switch (this.adaptiveStrategy) {
+ case 'aggressive':
+ strategyMultiplier = 0.8;
+ break;
+ case 'defensive':
+ strategyMultiplier = 1.2;
+ break;
+ }
+ var finalCooldown = baseCooldown * playerAggressiveBonus * staminaPenalty * strategyMultiplier + Math.random() * cooldownVariation;
+ return Math.max(finalCooldown, 100); // Minimum 100ms cooldown
}
};
function checkGameEnd() {
if (playerFighter.health <= 0) {
Una arena al aire libre rodeada por muros altos con patrones geométricos azul oscuro. El suelo está cubierto de hierba púrpura que brilla tenuemente y tiene zonas con charcos de líquido azul resplandeciente que pueden reflejar efectos de ataques o provocar pequeñas explosiones visuales al contacto. Los árboles están dispuestos al fondo y tienen copas rojas con formas pixeladas, no interactúan con los personajes pero aportan un fondo vibrante. La iluminación es baja, con tonos neón que cambian ligeramente de intensidad durante el combate. El área de batalla es plana, con textura suave pero con efectos de distorsión en los bordes, como si el entorno estuviera parcialmente corrompido.. In-Game asset. 2d. High contrast. No shadows
Botón de golpe sin necesidad de que diga para que es, que sea un símbolo de un puño ardiente. In-Game asset. 2d. High contrast. No shadows
Símbolo de escudo pixelado con pixeles amarillos. In-Game asset. 2d. High contrast. No shadows
Toro furry fuerte sin camisa pixelado. In-Game asset. 2d. High contrast. No shadows
Lagarto furry fuerte sin camisa y con taparrabos, que en la cara lleve un cráneo de otro lagarto, que lleve colgantes y que sea pixeleado. In-Game asset. 2d. High contrast. No shadows
Tiburón furry fuerte sin camisa y con shorts, que en la cara lleve unas gafas de sol, que lleve colgantes y que sea pixeleado que se vea todo su cuerpo In-Game asset. 2d. High contrast. No shadows
Lobo blanco fuerte revelando sus pectorales pero usando una capa y un taparrabos, que se vea todo su cuerpo y pixelado. In-Game asset. 2d. High contrast. No shadows
Tigre furry fuerte con una marca de x en su pectoral y pixeleado y que se vea todo su cuerpo, con un taparrabos y una piernera con una daga In-Game asset. 2d. High contrast. No shadows
Barra de vida llamativa In-Game asset. 2d. High contrast. No shadows
Barra de energía llamativa. In-Game asset. 2d. High contrast. No shadows
Mordida, dientes de lobo cerrados. In-Game asset. 2d. High contrast. No shadows
Botón de líneas curvas en total 3 pixeleado. In-Game asset. 2d. High contrast. No shadows
Oso polar furry fuerte con bufanda y pantalones largos y sin camisa, pixeleado. In-Game asset. 2d. High contrast. No shadows
Aguila real furry fuerte cruzando los brazos sin camisa y gran pectoral con un taparrabos de hojas pixeleado todo el cuerpo. In-Game asset. 2d. High contrast. No shadows
Partículas al golpear pixeleado In-Game asset. 2d. High contrast. No shadows
Particula de escudo siendo golpeado pixeleado In-Game asset. 2d. High contrast. No shadows
Barra de vida vacia con un corazón roto In-Game asset. 2d. High contrast. No shadows
Barra de energia vacia In-Game asset. 2d. High contrast. No shadows
Una particular de rayo pixeleada. In-Game asset. 2d. High contrast. No shadows