从控制台到策略深度:我用Java手搓了一个深渊RPG

从控制台到策略深度:我用Java手搓了一个深渊RPG

Lovien Lv1

《从控制台到策略深度:我用 Java 设计了一个 30 层地牢 RPG》

1. 项目概述

这是一个基于 Java 控制台的回合制地牢探险游戏。玩家从第 1 层一路挑战到第 30 层,通过战斗、掉落与策略选择逐步成长,最终迎战深渊破坏神。

游戏包含以下核心内容:

  • 角色创建与属性分配
  • 回合制战斗(玩家选技能,敌人随机行动)
  • Buff 系统(中毒、流血、眩晕、狂暴、圣光免疫等)
  • 掉落与背包(消耗品、装备、技能书)
  • 装备与套装加成(冒险者 / 狂战士 / 圣骑士)
  • 奇遇房间(泉水、商店、洞穴随机事件)
  • 存档 / 读档继续冒险

2. 项目结构

为了便于后续平滑升级到 2D 图形界面(GUI),项目采用“流程控制”和“核心实体”分离的组织方式,包结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
com.LuoHe
├── ui
│ ├── App.java
│ ├── Login.java
│ └── FightingGame.java
├── domain
│ ├── Character.java
│ ├── HeroCharacter.java
│ ├── EnemyCharacter.java
│ ├── Skill.java
│ ├── User.java
│ ├── Item.java
│ ├── Equipment.java
│ ├── Consumable.java
│ └── SkillBook.java
├── factory
│ └── EnemyFactory.java
└── manager
└── SaveManager.java

2.1 com.LuoHe.domain(核心实体与底层规则)

  • Character:角色基类,包含血蓝、攻防、Buff 容器与回合结算方法
  • HeroCharacter / EnemyCharacter:玩家与敌人,继承自 Character
  • Item:物品基类
    • Equipment:装备(武器 / 防具 / 饰品),提供属性加成与套装信息
    • Consumable:消耗品(回血 / 回蓝)
    • SkillBook:技能书(学习技能)
  • Skill:技能对象(名称、MP 消耗、描述)
  • User:账号对象(用于登录注册与账号持久化)

2.2 com.LuoHe.ui(控制层与展示层)

  • App:程序入口
  • Login:登录注册模块(账号校验与读写)
  • FightingGame:关卡推进、战斗循环、控制台输出与交互入口

2.3 简单工厂模式:EnemyFactory

深渊共有 30 层,如果把怪物生成逻辑直接写在主循环中,会导致流程类过度膨胀。项目将敌人生成抽离为:

  • EnemyFactory.createEnemy(stage)

主流程只传入层数,工厂内部负责:

  • 普通怪随机抽取与数值强化
  • Boss/精英的定点投放
  • 对应的提示信息输出(如“区域霸主”“终极警告”等)

3. 战斗系统

本项目采用经典的回合制战斗:每层生成一个敌人,玩家与敌人轮流行动,直到一方生命值归零。

战斗流程为:开战展示 → 回合循环 → 玩家行动 → 敌人行动 → 胜负结算 → 战后处理

3.1 开战:生成敌人并进入战斗回合

进入某一层后:

  • 普通层:随机普通怪,并按层数强化属性
  • Boss/精英层(5 的倍数):生成固定敌人并输出警告提示

同时输出关卡与敌人信息,例如:

  • “第 N 层战斗开始!对手:xxx”
  • 敌我双方血条 / 蓝条展示

3.2 回合循环:直到一方死亡

每层战斗内部使用:

  • while (player.isAlive() && enemy.isAlive())

并用 round++ 推进回合数。每一回合分为两段:

(1)玩家回合

  • 回合前状态结算:player.updateBuffs()
  • 若玩家存在 buffs.containsKey("眩晕"):跳过行动
  • 否则执行玩家行动:playerRound(player, enemy)

(2)敌人回合

  • 回合前状态结算:enemy.updateBuffs()
  • 若敌人眩晕:跳过行动
  • 否则敌人行动:enemyRound(player, enemy)

每次行动后都会做胜负检查,任何一方死亡则退出战斗循环。

3.3 状态结算:回合开始统一处理 Buff

每个角色在自己回合开始时都会调用:

  • updateBuffs():触发中毒、流血、生命回溯、专注等效果
  • Buff 回合数减少,为 0 时移除并提示“状态消失”

3.4 玩家行动:技能菜单 + 输入校验 + 执行效果

玩家回合由 playerRound(player, enemy) 实现,流程如下:

  1. 动态打印技能菜单(遍历 player.skillList
  2. 输入技能编号并校验范围
  3. 校验 MP 是否足够
  4. 扣除 MP:player.useMP(skill.getMpCost())
  5. 根据技能名称执行效果(switch(skill.getName())

技能一览(示例):

技能 消耗 效果
—:
普通攻击 0 MP 造成 100% 物理伤害
碎甲重击 15 MP 150% 伤害,30% 概率附加【眩晕】
嗜血打击 20 MP 120% 伤害,吸取伤害的一部分生命
狂暴姿态 25 MP 附加【狂暴】3 回合(攻 +50%,防 -30%)
圣光术 30 MP 净化负面状态,并附加【圣光免疫】2 回合
雷霆万钧 40 MP 200% 伤害,50% 概率附加【眩晕】
绝境反击 50 MP 血量越低伤害越高,附加【狂暴】1 回合

3.5 敌人行动:普通攻击或技能随机选择

敌人回合由 enemyRound(player, enemy) 实现:

  • 随机执行普通攻击技能攻击
  • 技能由敌人 skill 字段决定,并可能附加中毒、流血、眩晕等状态

3.6 伤害计算:统一公式入口

伤害计算封装为统一方法:

  • calculateDamage(attack, defence)

所有技能最终都走该入口,保证伤害结算规则一致。

3.7 胜利结算:金币、掉落、战后恢复、进入营地

当敌人被击败后会进行:

  1. 胜场 +1(用于统计)
  2. 掉落金币(随机 + 层数加成)
  3. 概率掉落道具(Boss 层或随机触发)
  4. 战后恢复生命值(当前版本为固定区间恢复)
  5. 输出战报与当前胜场
  6. 进入营地 enterCamp(player, stage) 进行整理、存档或继续下一层

4. Buff 系统

项目引入了 中毒、流血、眩晕、狂暴、专注 等异常状态。所有状态保存在:

  • Map<String, Integer> buffs(状态名 → 剩余回合数)

并在每回合开始前调用 updateBuffs() 结算。

核心结算框架如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Iterator<Map.Entry<String,Integer>> iterator = buffs.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String,Integer> entry = iterator.next();
String buffName = entry.getKey();
int duration = entry.getValue();

// ... 触发中毒扣血、专注回蓝等具体逻辑 ...

duration--;
if (duration <= 0) {
iterator.remove();
} else {
entry.setValue(duration);
}
}

5. 掉落、背包与装备

5.1 基于多态的背包交互

EquipmentConsumableSkillBook 都继承自 Item,背包只需要:

  • List<Item> inventory

交互时通过 instanceof 分流:

  • 消耗品:直接使用(回血 / 回蓝)
  • 装备:替换装备栏并处理属性变化
  • 技能书:学习新技能并加入 skillList

5.2 套装共鸣系统

使用 HashMap 动态统计当前装备栏中的套装件数:

1
2
3
4
5
6
7
Map<String, Integer> counts = new HashMap<>();
for (Equipment equip : equips) {
if (equip != null && equip.getSuitName() != null) {
String name = equip.getSuitName();
counts.put(name, counts.getOrDefault(name, 0) + 1);
}
}

随后根据件数触发对应的套装加成(攻击、生命、魔法、防御等)。

5.3 血量过渡算法(换装时的细节处理)

当装备改变 MaxHP/MaxMP 时:

  • 上限增加:当前 HP/MP 等额增加
  • 上限减少:对溢出部分进行截断,保证当前值不超过上限

6. 奇遇系统

为了避免连续战斗的单调感,项目用取模规则:

  • stage % 5 == 4

在每个 Boss 关卡前一层(4、9、14、19、24、29)设置“安全屋奇遇”。玩家三选一:

  1. 治愈泉水:回满生命与魔法
  2. 地精商店:花金币购买道具/装备
  3. 未知探险:随机触发陷阱扣血、捡金币、或获得高价值装备

7. 存档读档

项目实现了双重存档机制

7.1 账号密码持久化

注册、锁定等账号数据通过 IO 将 ArrayList<User> 写入 users.dat,下次启动可直接登录。

7.2 游戏进度持久化

让核心实体(如 CharacterItemSkill 等)实现 Serializable 接口。玩家在营地选择“存档并退出”时:

  • ObjectOutputStream 序列化玩家对象(包含背包、装备、Buff、技能等完整状态)

再次登录时通过反序列化读取并继续冒险。


8.源码与运行

GitHub:https://github.com/changAn221/Text-RPG-Dungeon.git