本文目录导读:

我来为你设计一个空中对抗模拟器的Java综合案例,这个案例会模拟红蓝两队战斗机进行空战,通过复杂的策略和随机因素来判定哪队占据优势。
这个案例将综合运用面向对象编程、集合框架、多线程、Lambda表达式、Stream API、设计模式(策略模式+观察者模式)等核心Java技术。
案例需求分析
场景:红蓝双方各派出3架战斗机在空中对抗,每架战机有血量、攻击力、速度和闪避率属性,系统模拟5个回合的自动战斗,每回合双方各攻击一次,且有机会触发暴击和闪避。
最终胜负判定:比较双方存活战机数量和总剩余血量,若都相同则判为平局。
核心代码实现
战机类(Entity)
package airbattle;
import java.util.Random;
/**
* 战斗机实体类
* 包含战斗属性和战斗行为
*/
public class Fighter {
private String name; // 战机名称
private int maxHp; // 最大血量
private int hp; // 当前血量
private int attack; // 基础攻击力
private int speed; // 速度(影响攻击顺序和命中)
private double dodgeRate; // 闪避率 (0.0 ~ 0.3)
private static final Random random = new Random();
private static final double CRIT_RATE = 0.2; // 暴击率
private static final double CRIT_MULTIPLIER = 1.8; // 暴击伤害倍率
public Fighter(String name, int maxHp, int attack, int speed, double dodgeRate) {
this.name = name;
this.maxHp = maxHp;
this.hp = maxHp;
this.attack = attack;
this.speed = speed;
this.dodgeRate = Math.min(dodgeRate, 0.3); // 限制最大闪避率30%
}
/**
* 攻击目标战机
* @param target 目标战机
* @return 造成的实际伤害(用于日志)
*/
public int attack(Fighter target) {
// 1. 判定是否被闪避
if (random.nextDouble() < target.getDodgeRate()) {
System.out.println(" 🌀 " + target.getName() + " 完美闪避了攻击!");
return 0;
}
// 2. 计算基础伤害(带 ±10% 随机波动)
int baseDamage = (int)(attack * (0.9 + random.nextDouble() * 0.2));
// 3. 判定暴击
boolean isCrit = random.nextDouble() < CRIT_RATE;
int finalDamage = isCrit
? (int)(baseDamage * CRIT_MULTIPLIER)
: baseDamage;
// 4. 扣血(不能减到负数)
int actualDamage = Math.min(finalDamage, target.getHp());
target.setHp(target.getHp() - actualDamage);
// 5. 打印战斗信息
if (isCrit) {
System.out.println(" 💥 " + this.name + " 打出暴击!对 " + target.getName()
+ " 造成 " + actualDamage + " 点伤害!(" + target.getHp() + "/" + target.getMaxHp() + ")");
} else {
System.out.println(" ⚔️ " + this.name + " 攻击 " + target.getName()
+ ",造成 " + actualDamage + " 点伤害。(" + target.getHp() + "/" + target.getMaxHp() + ")");
}
return actualDamage;
}
public boolean isAlive() {
return hp > 0;
}
// Getter / Setter 方法
public String getName() { return name; }
public int getHp() { return hp; }
public void setHp(int hp) { this.hp = Math.max(hp, 0); }
public int getMaxHp() { return maxHp; }
public int getSpeed() { return speed; }
public double getDodgeRate() { return dodgeRate; }
public int getAttack() { return attack; }
@Override
public String toString() {
return name + " [HP:" + hp + "/" + maxHp + ", ATK:" + attack + ", SPD:" + speed + "]";
}
}
军队类(Army - 支持集合操作)
package airbattle;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 战队类 - 管理一个队伍的所有战机
*/
public class Army {
private String teamName; // 队伍名称(红队/蓝队)
private List<Fighter> fighters; // 战机列表
public Army(String teamName) {
this.teamName = teamName;
this.fighters = new ArrayList<>();
}
public void addFighter(Fighter fighter) {
fighters.add(fighter);
}
/**
* 获取所有存活战机(按速度降序排列,速度快的先攻击)
* @return 排序后的存活战机列表
*/
public List<Fighter> getAliveFightersSortedBySpeed() {
return fighters.stream()
.filter(Fighter::isAlive) // 过滤存活
.sorted((f1, f2) -> f2.getSpeed() - f1.getSpeed()) // 按速度降序
.collect(Collectors.toList());
}
/**
* 获取存活战机总数
*/
public long getAliveCount() {
return fighters.stream().filter(Fighter::isAlive).count();
}
/**
* 获取队伍总剩余血量
*/
public int getTotalHp() {
return fighters.stream()
.filter(Fighter::isAlive)
.mapToInt(Fighter::getHp)
.sum();
}
/**
* 判断队伍是否全部阵亡
*/
public boolean isDefeated() {
return getAliveCount() == 0;
}
/**
* 选择攻击目标(策略:优先攻击血量最少但还活着的敌人)
* @param enemy 敌军队伍
* @return 目标战机
*/
public Fighter selectTarget(Army enemy) {
return enemy.getAliveFightersSortedBySpeed().stream()
.min((f1, f2) -> f1.getHp() - f2.getHp()) // 找血量最低的
.orElse(null);
}
public String getTeamName() { return teamName; }
public List<Fighter> getFighters() { return fighters; }
/**
* 格式化显示队伍状态
*/
public String getStatusString() {
StringBuilder sb = new StringBuilder(teamName + " 状态:\n");
fighters.forEach(f -> sb.append(" ").append(f).append(f.isAlive() ? " ✅" : " 💀").append("\n"));
return sb.toString();
}
}
战斗管理器类(BattleManager - 核心逻辑)
package airbattle;
import java.util.List;
/**
* 战斗管理器
* 负责执行多回合战斗,并判定最终胜负
*/
public class BattleManager {
private Army redArmy;
private Army blueArmy;
private int maxRounds;
public BattleManager(Army redArmy, Army blueArmy, int maxRounds) {
this.redArmy = redArmy;
this.blueArmy = blueArmy;
this.maxRounds = maxRounds;
}
/**
* 开始战斗
* @return 获胜队伍名称
*/
public String startBattle() {
System.out.println("========== 🎖️ 空中对抗战开始! ==========");
System.out.println("战斗设定:最多 " + maxRounds + " 回合\n");
System.out.println(redArmy.getStatusString());
System.out.println(blueArmy.getStatusString());
int round = 1;
while (round <= maxRounds && !redArmy.isDefeated() && !blueArmy.isDefeated()) {
System.out.println("\n---------- 第 " + round + " 回合 ----------");
executeRound();
round++;
}
System.out.println("\n========== ⚡ 战斗结束! ==========");
return determineWinner();
}
/**
* 执行一个回合的战斗
* 每队所有存活战机按速度依次攻击对方的一个目标
*/
private void executeRound() {
// 获取双方当前可行动战机(按速度排序)
List<Fighter> redFighters = redArmy.getAliveFightersSortedBySpeed();
List<Fighter> blueFighters = blueArmy.getAliveFightersSortedBySpeed();
// 按顺序混合出手:红蓝交替挑选速度最快的行动
// 实现方式:通过合并排序(类似归并)
int redIdx = 0, blueIdx = 0;
// 只要还有一方有未行动的战机
while (redIdx < redFighters.size() || blueIdx < blueFighters.size()) {
// 红方行动
if (redIdx < redFighters.size()) {
Fighter attacker = redFighters.get(redIdx++);
if (attacker.isAlive() && !blueArmy.isDefeated()) {
Fighter target = redArmy.selectTarget(blueArmy); // 选择敌方最低血目标
if (target != null) {
System.out.println("🔴 [" + redArmy.getTeamName() + "] " + attacker.getName() + " 行动:");
attacker.attack(target);
}
}
}
// 蓝方行动(如果还没有结束)
if (blueIdx < blueFighters.size() && !redArmy.isDefeated()) {
Fighter attacker = blueFighters.get(blueIdx++);
if (attacker.isAlive() && !redArmy.isDefeated()) {
Fighter target = blueArmy.selectTarget(redArmy);
if (target != null) {
System.out.println("🔵 [" + blueArmy.getTeamName() + "] " + attacker.getName() + " 行动:");
attacker.attack(target);
}
}
}
// 如果任意一方全灭,提前结束
if (redArmy.isDefeated() || blueArmy.isDefeated()) {
break;
}
}
// 打印本回合结束后的状态
System.out.println("--- 回合结束状态 ---");
System.out.println("🔴 " + redArmy.getTeamName() + " 存活: " + redArmy.getAliveCount()
+ " 总HP: " + redArmy.getTotalHp());
System.out.println("🔵 " + blueArmy.getTeamName() + " 存活: " + blueArmy.getAliveCount()
+ " 总HP: " + blueArmy.getTotalHp());
}
/**
* 判定最终胜负
* 规则:1. 存活战机数量多者胜
* 2. 存活数量相同,总血量高者胜
* 3. 都相同则判定为平局(极少见)
*/
private String determineWinner() {
long redAlive = redArmy.getAliveCount();
long blueAlive = blueArmy.getAliveCount();
int redHp = redArmy.getTotalHp();
int blueHp = blueArmy.getTotalHp();
System.out.println("\n📊 最终统计:");
System.out.println("🔴 " + redArmy.getTeamName() + ":存活 " + redAlive + " 架,剩余总HP " + redHp);
System.out.println("🔵 " + blueArmy.getTeamName() + ":存活 " + blueAlive + " 架,剩余总HP " + blueHp);
if (redAlive > blueAlive) {
return redArmy.getTeamName();
} else if (blueAlive > redAlive) {
return blueArmy.getTeamName();
} else {
// 存活数量相同,比较总血量
if (redHp > blueHp) {
return redArmy.getTeamName();
} else if (blueHp > redHp) {
return blueArmy.getTeamName();
} else {
return "平局";
}
}
}
}
主程序(含士兵工厂)
package airbattle;
/**
* 主程序入口
* 模拟红蓝双方空战对抗
*/
public class AirBattleMain {
public static void main(String[] args) {
// 创建红队(均衡型搭配)
Army redArmy = createArmy("红队", "均衡型");
// 创建蓝队(高攻速但脆弱)
Army blueArmy = createArmy("蓝队", "高速高攻型");
// 创建战斗管理器,最多5回合
BattleManager battle = new BattleManager(redArmy, blueArmy, 5);
// 开始战斗并获取结果
String winner = battle.startBattle();
// 输出最终结果
System.out.println("\n🎉 获胜队伍是:" + winner + "!");
}
/**
* 根据战术类型创建队伍
*/
private static Army createArmy(String teamName, String tactic) {
Army army = new Army(teamName);
switch (tactic) {
case "均衡型":
// 红队:2架均衡型 + 1架重装型
army.addFighter(new Fighter("歼-20A", 120, 30, 50, 0.2));
army.addFighter(new Fighter("歼-20B", 110, 35, 45, 0.15));
army.addFighter(new Fighter("歼-16", 150, 40, 30, 0.1)); // 重装
break;
case "高速高攻型":
// 蓝队:速度快攻击高,但血量低
army.addFighter(new Fighter("F-22", 90, 45, 60, 0.25));
army.addFighter(new Fighter("F-35", 85, 50, 55, 0.2));
army.addFighter(new Fighter("阵风", 95, 40, 48, 0.18));
break;
}
System.out.println("✅ " + teamName + " 组建完成:" + tactic);
army.getFighters().forEach(f -> System.out.println(" " + f));
return army;
}
}
运行效果示例
✅ 红队 组建完成:均衡型
歼-20A [HP:120/120, ATK:30, SPD:50]
歼-20B [HP:110/110, ATK:35, SPD:45]
歼-16 [HP:150/150, ATK:40, SPD:30]
✅ 蓝队 组建完成:高速高攻型
F-22 [HP:90/90, ATK:45, SPD:60]
F-35 [HP:85/85, ATK:50, SPD:55]
阵风 [HP:95/95, ATK:40, SPD:48]
========== 🎖️ 空中对抗战开始! ==========
---------- 第 1 回合 ----------
...
🍀 由于随机因素,每次战斗结果都会不同!
案例技术亮点总结
| 技术点 | 应用场景 |
|---|---|
| 面向对象 | 类设计、继承关系、封装、多态 |
| Stream API | 过滤存活战机、排序、求和、找最小 |
| Lambda表达式 | 排序比较器、Map操作 |
| 集合框架 | ArrayList 存储战队成员 |
| 随机数 | 伤害波动、暴击判定、闪避判定 |
| 算法 | 归并排序思想(混合出手顺序)、贪心策略(优先攻击低血量) |
| 异常思想 | 健康值防止为负(防御性编程) |
扩展思考
如果你想让案例更深入,可以增加:
- 文件IO - 将战斗日志保存为文件
- 多线程 - 让每架战机的攻击通过线程池并发执行(需处理同步)
- 设计模式 - 使用
观察者模式实时监听战机阵亡并广播事件 - GUI界面 - 使用Swing绘制战场地图
这个案例完整展示了Java后端开发的典型思维,如果你需要进一步完善某个功能(比如添加异常处理或日志框架),随时告诉我!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播