Spaces:
Running
Running
import gradio as gr | |
import os | |
import subprocess | |
import time | |
from collections import deque | |
# Criar pasta para armazenar as classes Java | |
os.makedirs("combat_classes", exist_ok=True) | |
# Templates de código para as aeronaves com altura dinâmica e novos atributos | |
TEAM1_TEMPLATE = '''import java.util.ArrayList; | |
import java.util.Random; | |
/** | |
* Time 1 - Configure sua aeronave! | |
* | |
* SISTEMA DE PONTOS: | |
* - Você tem 100 pontos para distribuir entre os atributos | |
* - Escolha com sabedoria para criar uma aeronave competitiva | |
* | |
* ATRIBUTOS: | |
* - speed: Velocidade da aeronave (1-10) - Afeta quão rápido sua aeronave pode se mover | |
* - fireRate: Taxa de disparo (1-10) - Controla com que frequência sua aeronave pode atirar | |
* - maneuverability: Manobrabilidade (1-10) - Facilita mudanças de altitude e esquivas | |
* - shotPower: Poder do tiro normal (5-20) - Dano causado por tiros normais | |
* - supersonicPower: Poder do tiro supersônico (10-30) - Dano causado por tiros supersônicos | |
* - missilePower: Poder do míssil (15-40) - Dano causado pelo míssil especial | |
* - defense: Defesa (5-25) - Reduz o dano recebido | |
* - stealthChance: Chance de furtividade (0-20) - Probabilidade de evitar ataques | |
* - radar: Radar (0-10) - Capacidade de detectar projéteis inimigos | |
* - doubleShot: Tiro duplo (0-10) - Permite disparar em duas altitudes diferentes | |
* - nuclearPower: Poder nuclear (0-10) - Poder do míssil nuclear (dano massivo) | |
*/ | |
public class Team1Aircraft extends Aircraft { | |
private Random random = new Random(); | |
private int maxAltitude; // Armazena a altura máxima do campo | |
public Team1Aircraft() { | |
super( | |
// DISTRIBUA 100 PONTOS ENTRE ESSES ATRIBUTOS | |
5, // Velocidade (1-10) | |
5, // Taxa de fogo (1-10) | |
5, // Manobrabilidade (1-10) | |
15, // Dano do tiro normal (5-20) | |
20, // Dano do tiro supersônico (10-30) | |
25, // Dano do míssil (15-40) | |
15, // Defesa (5-25) | |
5, // Chance de furtividade (0-20) | |
2, // Radar (0-10) | |
2, // Tiro duplo (0-10) | |
1, // Poder nuclear (0-10) | |
"▶" // Símbolo da aeronave (não altere) | |
); | |
// IMPORTANTE: A soma de todos os atributos deve ser <= 100 | |
// Exemplo: 5+5+5+15+20+25+15+5+2+2+1 = 100 | |
// Verifica dinamicamente a altura do campo (será definida pelo BattleMain) | |
try { | |
String heightEnv = System.getProperty("battlefield.height", "3"); | |
maxAltitude = Integer.parseInt(heightEnv) - 1; | |
} catch (Exception e) { | |
maxAltitude = 2; // Valor padrão se não conseguir ler | |
} | |
} | |
/** | |
* Controla o movimento da aeronave. | |
* Valor padrão: Movimento aleatório baseado na velocidade | |
* Dica: Você pode personalizar para criar padrões de movimento mais inteligentes | |
*/ | |
@Override | |
public int move() { | |
// Retorna um número entre -speed/2 e +speed | |
return random.nextInt(speed + 1) - speed / 2; | |
} | |
/** | |
* Controla a mudança de altitude da aeronave. | |
* Valor padrão: Mudança aleatória entre subir, descer ou manter altitude | |
* Dica: Uma boa estratégia pode aumentar suas chances de esquiva | |
*/ | |
@Override | |
public int changeAltitude() { | |
int direction = random.nextInt(3) - 1; // -1 (descer), 0 (manter), 1 (subir) | |
this.posY = Math.max(0, Math.min(maxAltitude, posY + direction)); | |
return direction; | |
} | |
/** | |
* Tiro normal - mais frequente, menos dano | |
*/ | |
@Override | |
public Projectile shoot(int posX, int direction) { | |
return new Projectile(posX, this.posY, direction, 1, "->"); | |
} | |
/** | |
* Tiro supersônico - mais rápido, mais dano | |
*/ | |
@Override | |
public Projectile shootSupersonic(int posX, int direction) { | |
return new Projectile(posX, this.posY, direction, 2, ">>"); | |
} | |
/** | |
* Míssil especial - muito dano, com cooldown | |
*/ | |
@Override | |
public Projectile specialMissile(int posX, int direction) { | |
if (missileCooldown == 0) { | |
missileCooldown = 3; // Espera 3 turnos para usar novamente | |
return new Projectile(posX, this.posY, direction, 1, "=>"); | |
} | |
missileCooldown--; | |
return null; | |
} | |
/** | |
* Tiro duplo - ataca em duas altitudes diferentes | |
*/ | |
@Override | |
public Projectile doubleShot(int posX, int direction) { | |
// Define a segunda altitude para o tiro (diferente da atual) | |
int currentAlt = this.posY; | |
int secondAlt = (currentAlt + 1) % (maxAltitude + 1); | |
// Guarda essa altitude para ser usada pelo BattleMain | |
this.secondShotAltitude = secondAlt; | |
// Retorna o projétil principal | |
return new Projectile(posX, this.posY, direction, 1, "⇉"); | |
} | |
/** | |
* Míssil nuclear - dano massivo | |
*/ | |
@Override | |
public Projectile nuclearMissile(int posX, int direction) { | |
if (missileCooldown == 0) { | |
missileCooldown = 5; // Longo cooldown para o poder nuclear | |
return new Projectile(posX, this.posY, direction, 1, "-]=>"); | |
} | |
return null; | |
} | |
/** | |
* Radar - detecta projéteis inimigos | |
*/ | |
@Override | |
public void radarScan(ArrayList<Projectile> projectiles, int enemyPosX, int enemyPosY) { | |
// Implementação básica: apenas detecta projéteis próximos | |
// Em uma implementação mais avançada, você poderia usar essas informações | |
// para ajustar seu movimento e evitar projéteis | |
} | |
}''' | |
TEAM2_TEMPLATE = '''import java.util.ArrayList; | |
import java.util.Random; | |
/** | |
* Time 2 - Configure sua aeronave! | |
* | |
* SISTEMA DE PONTOS: | |
* - Você tem 100 pontos para distribuir entre os atributos | |
* - Escolha com sabedoria para criar uma aeronave competitiva | |
* | |
* ATRIBUTOS: | |
* - speed: Velocidade da aeronave (1-10) - Afeta quão rápido sua aeronave pode se mover | |
* - fireRate: Taxa de disparo (1-10) - Controla com que frequência sua aeronave pode atirar | |
* - maneuverability: Manobrabilidade (1-10) - Facilita mudanças de altitude e esquivas | |
* - shotPower: Poder do tiro normal (5-20) - Dano causado por tiros normais | |
* - supersonicPower: Poder do tiro supersônico (10-30) - Dano causado por tiros supersônicos | |
* - missilePower: Poder do míssil (15-40) - Dano causado pelo míssil especial | |
* - defense: Defesa (5-25) - Reduz o dano recebido | |
* - stealthChance: Chance de furtividade (0-20) - Probabilidade de evitar ataques | |
* - radar: Radar (0-10) - Capacidade de detectar projéteis inimigos | |
* - doubleShot: Tiro duplo (0-10) - Permite disparar em duas altitudes diferentes | |
* - nuclearPower: Poder nuclear (0-10) - Poder do míssil nuclear (dano massivo) | |
*/ | |
public class Team2Aircraft extends Aircraft { | |
private Random random = new Random(); | |
private int maxAltitude; // Armazena a altura máxima do campo | |
public Team2Aircraft() { | |
super( | |
// DISTRIBUA 100 PONTOS ENTRE ESSES ATRIBUTOS | |
5, // Velocidade (1-10) | |
5, // Taxa de fogo (1-10) | |
5, // Manobrabilidade (1-10) | |
15, // Dano do tiro normal (5-20) | |
20, // Dano do tiro supersônico (10-30) | |
25, // Dano do míssil (15-40) | |
15, // Defesa (5-25) | |
5, // Chance de furtividade (0-20) | |
2, // Radar (0-10) | |
2, // Tiro duplo (0-10) | |
1, // Poder nuclear (0-10) | |
"◀" // Símbolo da aeronave (não altere) | |
); | |
// IMPORTANTE: A soma de todos os atributos deve ser <= 100 | |
// Exemplo: 5+5+5+15+20+25+15+5+2+2+1 = 100 | |
// Verifica dinamicamente a altura do campo (será definida pelo BattleMain) | |
try { | |
String heightEnv = System.getProperty("battlefield.height", "3"); | |
maxAltitude = Integer.parseInt(heightEnv) - 1; | |
} catch (Exception e) { | |
maxAltitude = 2; // Valor padrão se não conseguir ler | |
} | |
} | |
/** | |
* Controla o movimento da aeronave. | |
* Valor padrão: Movimento aleatório baseado na velocidade | |
* Dica: Você pode personalizar para criar padrões de movimento mais inteligentes | |
*/ | |
@Override | |
public int move() { | |
// Retorna um número entre -speed/2 e +speed | |
return random.nextInt(speed + 1) - speed / 2; | |
} | |
/** | |
* Controla a mudança de altitude da aeronave. | |
* Valor padrão: Mudança aleatória entre subir, descer ou manter altitude | |
* Dica: Uma boa estratégia pode aumentar suas chances de esquiva | |
*/ | |
@Override | |
public int changeAltitude() { | |
int direction = random.nextInt(3) - 1; // -1 (descer), 0 (manter), 1 (subir) | |
this.posY = Math.max(0, Math.min(maxAltitude, posY + direction)); | |
return direction; | |
} | |
/** | |
* Tiro normal - mais frequente, menos dano | |
*/ | |
@Override | |
public Projectile shoot(int posX, int direction) { | |
return new Projectile(posX, this.posY, direction, 1, "<-"); | |
} | |
/** | |
* Tiro supersônico - mais rápido, mais dano | |
*/ | |
@Override | |
public Projectile shootSupersonic(int posX, int direction) { | |
return new Projectile(posX, this.posY, direction, 2, "<<"); | |
} | |
/** | |
* Míssil especial - muito dano, com cooldown | |
*/ | |
@Override | |
public Projectile specialMissile(int posX, int direction) { | |
if (missileCooldown == 0) { | |
missileCooldown = 3; // Espera 3 turnos para usar novamente | |
return new Projectile(posX, this.posY, direction, 1, "<="); | |
} | |
missileCooldown--; | |
return null; | |
} | |
/** | |
* Tiro duplo - ataca em duas altitudes diferentes | |
*/ | |
@Override | |
public Projectile doubleShot(int posX, int direction) { | |
// Define a segunda altitude para o tiro (diferente da atual) | |
int currentAlt = this.posY; | |
int secondAlt = (currentAlt + 1) % (maxAltitude + 1); | |
// Guarda essa altitude para ser usada pelo BattleMain | |
this.secondShotAltitude = secondAlt; | |
// Retorna o projétil principal | |
return new Projectile(posX, this.posY, direction, 1, "⇇"); | |
} | |
/** | |
* Míssil nuclear - dano massivo | |
*/ | |
@Override | |
public Projectile nuclearMissile(int posX, int direction) { | |
if (missileCooldown == 0) { | |
missileCooldown = 5; // Longo cooldown para o poder nuclear | |
return new Projectile(posX, this.posY, direction, 1, "<[=-"); | |
} | |
return null; | |
} | |
/** | |
* Radar - detecta projéteis inimigos | |
*/ | |
@Override | |
public void radarScan(ArrayList<Projectile> projectiles, int enemyPosX, int enemyPosY) { | |
// Implementação básica: apenas detecta projéteis próximos | |
// Em uma implementação mais avançada, você poderia usar essas informações | |
// para ajustar seu movimento e evitar projéteis | |
} | |
}''' | |
# Código base das classes Aircraft e Projectile | |
aircraft_code = """ | |
import java.util.ArrayList; | |
public abstract class Aircraft { | |
protected int health; // Agora definido externamente | |
protected int speed; | |
protected int fireRate; | |
protected int maneuverability; | |
protected int shotPower; | |
protected int supersonicPower; | |
protected int missilePower; | |
protected int defense; | |
protected int stealthChance; | |
protected int radar; | |
protected int doubleShot; | |
protected int doubleShotPower; | |
protected int nuclearPower; | |
protected int secondShotAltitude = -1; | |
protected int missileCooldown = 0; | |
protected int posY = 1; | |
protected String symbol; | |
protected static final int TOTAL_POINTS = 100; | |
public Aircraft(int speed, int fireRate, int maneuverability, int shotPower, int supersonicPower, | |
int missilePower, int defense, int stealthChance, int radar, int doubleShot, | |
int nuclearPower, String symbol) { | |
this.health = 100; // Valor padrão que será substituído | |
this.speed = speed; | |
this.fireRate = fireRate; | |
this.maneuverability = maneuverability; | |
this.shotPower = shotPower; | |
this.supersonicPower = supersonicPower; | |
this.missilePower = missilePower; | |
this.defense = defense; | |
this.stealthChance = stealthChance; | |
this.radar = radar; | |
this.doubleShot = doubleShot; | |
this.doubleShotPower = doubleShot; | |
this.nuclearPower = nuclearPower; | |
this.symbol = symbol; | |
validateAttributes(); | |
} | |
public void setInitialHealth(int health) { | |
this.health = health; | |
} | |
private void validateAttributes() { | |
int total = speed + fireRate + maneuverability + shotPower + supersonicPower + | |
missilePower + defense + stealthChance + radar + doubleShot + nuclearPower; | |
if (total > TOTAL_POINTS) { | |
throw new IllegalArgumentException("Erro: A soma dos atributos excede " + TOTAL_POINTS + " pontos! Total: " + total); | |
} | |
} | |
public abstract int move(); | |
public abstract int changeAltitude(); | |
public abstract Projectile shoot(int posX, int direction); | |
public abstract Projectile shootSupersonic(int posX, int direction); | |
public abstract Projectile specialMissile(int posX, int direction); | |
public abstract Projectile doubleShot(int posX, int direction); | |
public abstract Projectile nuclearMissile(int posX, int direction); | |
public abstract void radarScan(ArrayList<Projectile> projectiles, int enemyPosX, int enemyPosY); | |
public int getHealth() { | |
return health; | |
} | |
public void takeDamage(int damage) { | |
this.health -= Math.max(0, damage - (defense / 10)); | |
} | |
public boolean isAlive() { | |
return health > 0; | |
} | |
public int getPositionY() { | |
return posY; | |
} | |
public int getSecondShotAltitude() { | |
int alt = secondShotAltitude; | |
secondShotAltitude = -1; // Reset após uso | |
return alt; | |
} | |
} | |
""" | |
projectile_code = """ | |
public class Projectile { | |
int posX; | |
int posY; | |
int direction; | |
int speed; | |
String symbol; | |
int power = 0; // Poder do projétil, usado para dano personalizado | |
public Projectile(int posX, int posY, int direction, int speed, String symbol) { | |
this.posX = posX; | |
this.posY = posY; | |
this.direction = direction; | |
this.speed = speed; | |
this.symbol = symbol; | |
} | |
public Projectile(int posX, int posY, int direction, int speed, String symbol, int power) { | |
this(posX, posY, direction, speed, symbol); | |
this.power = power; | |
} | |
public void move() { | |
posX += direction * speed; | |
} | |
public boolean isOutOfBounds(int screenWidth) { | |
return (posX < 0 || posX >= screenWidth); | |
} | |
public int getPower() { | |
return power; | |
} | |
} | |
""" | |
def run_battle(code1, code2, screen_width, battlefield_height, p1_start_pos, p2_start_pos, team1_health, team2_health): | |
# Caminhos dos arquivos Java | |
aircraft_path = "combat_classes/Aircraft.java" | |
projectile_path = "combat_classes/Projectile.java" | |
class1_path = "combat_classes/Team1Aircraft.java" | |
class2_path = "combat_classes/Team2Aircraft.java" | |
main_path = "combat_classes/BattleMain.java" | |
# Gerar o código do BattleMain com os parâmetros configuráveis | |
battle_main_code = f""" | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import java.util.Random; | |
public class BattleMain {{ | |
public static void main(String[] args) {{ | |
// Definir a altura do campo como propriedade do sistema | |
System.setProperty("battlefield.height", "{battlefield_height}"); | |
Aircraft team1 = new Team1Aircraft(); | |
Aircraft team2 = new Team2Aircraft(); | |
// Definir a vida inicial de cada aeronave | |
team1.setInitialHealth({team1_health}); | |
team2.setInitialHealth({team2_health}); | |
Random random = new Random(); | |
int p1PosX = {p1_start_pos}; | |
int p2PosX = {p2_start_pos}; | |
int screenWidth = {screen_width}; | |
int battlefieldHeight = {battlefield_height}; | |
ArrayList<Projectile> projectiles = new ArrayList<>(); | |
// Inicializar as altitudes das naves em uma posição média do campo | |
team1.posY = battlefieldHeight / 2; | |
team2.posY = battlefieldHeight / 2; | |
while (team1.isAlive() && team2.isAlive()) {{ | |
System.out.println("\\n=== NOVO TURNO ==="); | |
System.out.flush(); | |
String[][] battlefield = new String[battlefieldHeight][screenWidth]; | |
for (int row = 0; row < battlefieldHeight; row++) {{ | |
for (int i = 0; i < screenWidth; i++) {{ | |
battlefield[row][i] = " "; | |
}} | |
}} | |
// Radar scan para detectar projéteis | |
team1.radarScan(projectiles, p2PosX, team2.getPositionY()); | |
team2.radarScan(projectiles, p1PosX, team1.getPositionY()); | |
// Movimento das aeronaves | |
p1PosX += team1.move(); | |
p2PosX += team2.move(); | |
p1PosX = Math.max(0, Math.min(screenWidth - 1, p1PosX)); | |
p2PosX = Math.max(0, Math.min(screenWidth - 1, p2PosX)); | |
// Mudança de altitude | |
team1.changeAltitude(); | |
team2.changeAltitude(); | |
// Garantir que a altitude não exceda o novo tamanho do campo de batalha | |
team1.posY = Math.min(team1.posY, battlefieldHeight - 1); | |
team2.posY = Math.min(team2.posY, battlefieldHeight - 1); | |
// Atirar para Time 1 | |
if (random.nextInt(10) < team1.fireRate) {{ | |
Projectile shot = null; | |
int shotType = random.nextInt(100); | |
// Escolha aleatória do tipo de tiro baseado na probabilidade | |
if (shotType < 5 && team1.nuclearPower > 0) {{ | |
// Tiro nuclear (baixa probabilidade) | |
shot = team1.nuclearMissile(p1PosX, 1); | |
if (shot != null) {{ | |
System.out.println("☢️ Time 1 lançou um MÍSSIL NUCLEAR!"); | |
}} | |
}} else if (shotType < 15 && team1.doubleShot > 0) {{ | |
// Tiro duplo | |
shot = team1.doubleShot(p1PosX, 1); | |
if (shot != null) {{ | |
System.out.println("➡️ Time 1 disparou um TIRO DUPLO!"); | |
// Adicionar o segundo projétil em uma altitude diferente | |
int secAlt = team1.getSecondShotAltitude(); | |
if (secAlt >= 0 && secAlt < battlefieldHeight) {{ | |
projectiles.add(new Projectile(p1PosX, secAlt, 1, 1, "->", team1.doubleShotPower)); | |
}} | |
}} | |
}} else if (shotType < 30) {{ | |
// Míssil especial | |
shot = team1.specialMissile(p1PosX, 1); | |
}} else if (shotType < 60) {{ | |
// Tiro supersônico | |
shot = team1.shootSupersonic(p1PosX, 1); | |
}} else {{ | |
// Tiro normal | |
shot = team1.shoot(p1PosX, 1); | |
}} | |
if (shot != null) {{ | |
// Garantir que a altitude do projétil não exceda o campo de batalha | |
shot.posY = Math.min(shot.posY, battlefieldHeight - 1); | |
projectiles.add(shot); | |
}} | |
}} | |
// Atirar para Time 2 | |
if (random.nextInt(10) < team2.fireRate) {{ | |
Projectile shot = null; | |
int shotType = random.nextInt(100); | |
// Escolha aleatória do tipo de tiro baseado na probabilidade | |
if (shotType < 5 && team2.nuclearPower > 0) {{ | |
// Tiro nuclear (baixa probabilidade) | |
shot = team2.nuclearMissile(p2PosX, -1); | |
if (shot != null) {{ | |
System.out.println("☢️ Time 2 lançou um MÍSSIL NUCLEAR!"); | |
}} | |
}} else if (shotType < 15 && team2.doubleShot > 0) {{ | |
// Tiro duplo | |
shot = team2.doubleShot(p2PosX, -1); | |
if (shot != null) {{ | |
System.out.println("⬅️ Time 2 disparou um TIRO DUPLO!"); | |
// Adicionar o segundo projétil em uma altitude diferente | |
int secAlt = team2.getSecondShotAltitude(); | |
if (secAlt >= 0 && secAlt < battlefieldHeight) {{ | |
projectiles.add(new Projectile(p2PosX, secAlt, -1, 1, "<-", team2.doubleShotPower)); | |
}} | |
}} | |
}} else if (shotType < 30) {{ | |
// Míssil especial | |
shot = team2.specialMissile(p2PosX, -1); | |
}} else if (shotType < 60) {{ | |
// Tiro supersônico | |
shot = team2.shootSupersonic(p2PosX, -1); | |
}} else {{ | |
// Tiro normal | |
shot = team2.shoot(p2PosX, -1); | |
}} | |
if (shot != null) {{ | |
// Garantir que a altitude do projétil não exceda o campo de batalha | |
shot.posY = Math.min(shot.posY, battlefieldHeight - 1); | |
projectiles.add(shot); | |
}} | |
}} | |
// Posicionar aeronaves no campo de batalha com cores | |
battlefield[team1.getPositionY()][p1PosX] = "\u001B[34m" + team1.symbol + "\u001B[0m"; // Azul para Time 1 | |
battlefield[team2.getPositionY()][p2PosX] = "\u001B[31m" + team2.symbol + "\u001B[0m"; // Vermelho para Time 2 | |
// Mover projéteis e verificar colisões | |
Iterator<Projectile> iterator = projectiles.iterator(); | |
while (iterator.hasNext()) {{ | |
Projectile p = iterator.next(); | |
p.move(); | |
// Verificar colisões com Time 1 | |
if (p.posX == p1PosX && p.posY == team1.getPositionY()) {{ | |
int damage = 0; | |
// Verificar se o projétil tem poder personalizado | |
if (p.getPower() > 0) {{ | |
damage = p.getPower(); | |
}} else if (p.symbol.contains("<[=-")) {{ // Míssil nuclear do Time 2 | |
damage = team2.nuclearPower * 2; | |
System.out.println("💥💥💥 MÍSSIL NUCLEAR do Time 2 atingiu o Time 1!"); | |
}} else if (p.symbol.contains("⇇")) {{ // Tiro duplo do Time 2 | |
damage = team2.doubleShotPower; | |
}} else if (p.symbol.equals("<=")) {{ | |
damage = team2.missilePower; | |
}} else if (p.symbol.equals("<<")) {{ | |
damage = team2.supersonicPower; | |
}} else {{ | |
damage = team2.shotPower; | |
}} | |
if (random.nextInt(100) >= team1.stealthChance) {{ | |
team1.takeDamage(damage); | |
System.out.println("💥 Aeronave do Time 1 atingida! -" + damage + " pontos"); | |
}} else {{ | |
System.out.println("👻 Aeronave do Time 1 esquivou!"); | |
if (team1.radar > 0) {{ | |
System.out.println("📡 Radar do Time 1 detectou o projétil!"); | |
}} | |
}} | |
iterator.remove(); | |
continue; | |
}} | |
// Verificar colisões com Time 2 | |
if (p.posX == p2PosX && p.posY == team2.getPositionY()) {{ | |
int damage = 0; | |
// Verificar se o projétil tem poder personalizado | |
if (p.getPower() > 0) {{ | |
damage = p.getPower(); | |
}} else if (p.symbol.contains("-]=>")) {{ // Míssil nuclear do Time 1 | |
damage = team1.nuclearPower * 2; | |
System.out.println("💥💥💥 MÍSSIL NUCLEAR do Time 1 atingiu o Time 2!"); | |
}} else if (p.symbol.contains("⇉")) {{ // Tiro duplo do Time 1 | |
damage = team1.doubleShotPower; | |
}} else if (p.symbol.equals("=>")) {{ | |
damage = team1.missilePower; | |
}} else if (p.symbol.equals(">>")) {{ | |
damage = team1.supersonicPower; | |
}} else {{ | |
damage = team1.shotPower; | |
}} | |
if (random.nextInt(100) >= team2.stealthChance) {{ | |
team2.takeDamage(damage); | |
System.out.println("💥 Aeronave do Time 2 atingida! -" + damage + " pontos"); | |
}} else {{ | |
System.out.println("👻 Aeronave do Time 2 esquivou!"); | |
if (team2.radar > 0) {{ | |
System.out.println("📡 Radar do Time 2 detectou o projétil!"); | |
}} | |
}} | |
iterator.remove(); | |
continue; | |
}} | |
// Remover projéteis fora dos limites | |
if (p.isOutOfBounds(screenWidth)) {{ | |
iterator.remove(); | |
continue; | |
}} | |
// Mostrar projéteis no campo de batalha com cores | |
if (p.posX >= 0 && p.posX < screenWidth && p.posY >= 0 && p.posY < battlefieldHeight) {{ | |
// Adicionar cores aos projéteis baseado na direção | |
if (p.direction > 0) {{ | |
battlefield[p.posY][p.posX] |