
🏠个人主页:黎雁
🎬作者简介:C/C++/JAVA后端开发学习者
❄️个人专栏:C语言、数据结构(C语言)、EasyX、JAVA、游戏、规划、程序人生
✨ 从来绝巘须孤往,万里同尘即玉京

文章目录
- [【魔法森林冒险】3/14 Allen类(一):主角核心属性与初始化🎭](#【魔法森林冒险】3/14 Allen类(一):主角核心属性与初始化🎭)
-
- [📝 文章摘要](#📝 文章摘要)
- [🎯 一、Allen类的定位:整个游戏的「核心交互载体」](#🎯 一、Allen类的定位:整个游戏的「核心交互载体」)
- [🔍 二、核心代码拆解:Allen类的专属属性与封装](#🔍 二、核心代码拆解:Allen类的专属属性与封装)
-
- [2.1 完整核心代码(未修改,拆分讲解)](#2.1 完整核心代码(未修改,拆分讲解))
- [2.2 关键知识点讲解💡](#2.2 关键知识点讲解💡)
- [🚀 三、初始化逻辑:构造方法的执行顺序](#🚀 三、初始化逻辑:构造方法的执行顺序)
- [🧪 四、调试示例:验证Allen的初始化效果](#🧪 四、调试示例:验证Allen的初始化效果)
- [📌 知识回顾](#📌 知识回顾)
- [✍️ 写在最后](#✍️ 写在最后)

【魔法森林冒险】3/14 Allen类(一):主角核心属性与初始化🎭
📝 文章摘要
| 内容维度 | 详情说明 |
|---|---|
| 核心摘要 | 本文是「魔法森林冒险」Java项目系列第三篇,聚焦玩家主角Allen类的核心设计------从专属属性定义(钥匙、任务进度、技能),到构造方法的初始化逻辑,再到属性封装的细节(HP/MP校验、数据安全),结合调试示例帮你吃透「主角角色」的开发思路。 |
| 阅读时长 | 12分钟 |
| 适合人群 | 1. Java新手:想掌握「属性封装+构造方法」的实战用法;2. 游戏开发入门者:想理解玩家角色的属性设计逻辑;3. 项目复刻者:想复刻Allen的核心状态管理。 |
| 阅读重点 | 1. Allen专属属性的设计思路(为什么要定义这些属性);2. 构造方法的初始化顺序与默认值设置;3. 属性封装的校验逻辑(HP/MP不能为负);4. 调试示例验证初始化效果。 |
🎯 一、Allen类的定位:整个游戏的「核心交互载体」
在「魔法森林冒险」中,Allen(艾伦)是玩家唯一操控的角色,所有游戏流程(战斗、拾取道具、完成任务、与Lia交互)都围绕他展开。
相比于父类Person(可交互角色抽象类),Allen需要:
✅ 新增「冒险专属属性」:钥匙数量、任务进度、技能等级、Lia信任度关联;
✅ 强化「属性校验逻辑」:比如HP为0时直接判定游戏失败;
✅ 初始化「默认状态」:初始HP/MP/金币、空背包、未完成的任务进度。
接下来我们拆解你提供的Allen.java核心代码,吃透主角的设计逻辑!
🔍 二、核心代码拆解:Allen类的专属属性与封装
2.1 完整核心代码(未修改,拆分讲解)
java
/**
* 玩家主角Allen类
* 继承Person抽象类,实现玩家专属的属性与行为
*/
public class Allen extends Person {
// ========== Allen专属属性 ==========
// 钥匙数量(主线任务:需要收集3把钥匙解锁永恒之泉)
private int keyCount;
// 主线任务进度(数组:5个场景对应5个进度,0=未完成,1=完成)
// 索引0:入口林地 1:迷雾沼泽 2:古老废墟 3:黑暗洞穴 4:永恒之泉
private int[] mainTaskProgress;
// 支线任务:治疗动物进度(需要治疗3只,数组记录已治疗数量)
private int healAnimalCount;
// 技能等级(初始1级,完成任务可升级,提升攻击力)
private int skillLevel;
// 与Lia的信任度(0-100,影响Lia是否辅助战斗)
private int liaTrustLevel;
// ========== 常量定义(固定值,方便维护) ==========
// 初始HP
private static final int INIT_HP = 100;
// 初始MP
private static final int INIT_MP = 50;
// 初始金币
private static final int INIT_GOLD = 20;
// 初始技能等级
private static final int INIT_SKILL_LEVEL = 1;
// 主线任务数量(5个场景)
private static final int MAIN_TASK_COUNT = 5;
// ========== 构造方法:初始化所有属性 ==========
public Allen() {
// 1. 调用父类Person的构造方法(名称、描述、初始HP/MP/金币)
super("艾伦", "年轻的魔法学徒", INIT_HP, INIT_MP, INIT_GOLD);
// 2. 初始化专属属性默认值
this.keyCount = 0; // 初始无钥匙
this.mainTaskProgress = new int[MAIN_TASK_COUNT]; // 初始全0(未完成)
this.healAnimalCount = 0; // 初始未治疗任何动物
this.skillLevel = INIT_SKILL_LEVEL; // 初始1级技能
this.liaTrustLevel = 0; // 初始与Lia信任度为0
// 3. 初始化父类的背包(Person已初始化,这里可补充提示)
System.out.println("✨ 艾伦已准备好冒险!初始状态:HP=" + INIT_HP + " MP=" + INIT_MP + " 金币=" + INIT_GOLD);
}
// ========== 属性封装:Getter/Setter(带校验) ==========
// 钥匙数量:Getter
public int getKeyCount() {
return keyCount;
}
// 钥匙数量:Setter(只能增加,不能减少)
public void addKey() {
this.keyCount++;
System.out.println("🔑 艾伦获得了1把钥匙!当前钥匙数量:" + this.keyCount);
}
// HP:重写父类setHp,强化校验(HP为0时提示游戏失败)
@Override
public void setHp(int hp) {
if (hp < 0) {
this.hp = 0;
this.setAlive(false);
System.out.println("❌ 艾伦的HP已耗尽!游戏失败!");
} else if (hp > INIT_HP) {
this.hp = INIT_HP; // HP上限为初始值(可拓展为随等级提升)
System.out.println("💛 艾伦的HP已恢复至最大值!");
} else {
this.hp = hp;
}
}
// MP:重写父类setMp,强化校验(MP上限限制)
@Override
public void setMp(int mp) {
if (mp < 0) {
this.mp = 0;
} else if (mp > INIT_MP) {
this.mp = INIT_MP;
System.out.println("💙 艾伦的MP已恢复至最大值!");
} else {
this.mp = mp;
}
}
// 主线任务进度:更新指定场景的进度
public void updateMainTaskProgress(int sceneIndex, int progress) {
if (sceneIndex < 0 || sceneIndex >= MAIN_TASK_COUNT) {
System.out.println("⚠️ 场景索引错误!请输入0-4的数字");
return;
}
if (progress != 0 && progress != 1) {
System.out.println("⚠️ 进度值错误!只能输入0(未完成)或1(完成)");
return;
}
this.mainTaskProgress[sceneIndex] = progress;
System.out.println("📌 主线任务更新:场景" + sceneIndex + "进度变为" + (progress == 1 ? "已完成" : "未完成"));
}
// Lia信任度:Setter(0-100限制)
public void setLiaTrustLevel(int liaTrustLevel) {
if (liaTrustLevel < 0) {
this.liaTrustLevel = 0;
} else if (liaTrustLevel > 100) {
this.liaTrustLevel = 100;
} else {
this.liaTrustLevel = liaTrustLevel;
// 信任度≥60时,提示Lia会辅助战斗
if (this.liaTrustLevel >= 60 && this.liaTrustLevel < 100) {
System.out.println("🤝 Lia的信任度达到" + liaTrustLevel + "!战斗时会辅助你~");
} else if (this.liaTrustLevel == 100) {
System.out.println("❤️ Lia完全信任你!会为你抵挡伤害!");
}
}
}
// ========== 抽象方法实现(继承Person必须实现) ==========
@Override
public void act() {
// 玩家行动逻辑(后续篇章讲解)
System.out.println("艾伦正在思考下一步行动...");
}
@Override
public boolean useItem(Item item) {
// 道具使用逻辑(后续篇章讲解)
return false;
}
@Override
public boolean trade(Person target, Item item, int gold) {
// 交易逻辑(后续篇章讲解)
return false;
}
// ========== 辅助方法:打印当前状态 ==========
public void printStatus() {
System.out.println("\n===== 艾伦的当前状态 =====");
System.out.println("HP:" + this.getHp() + " / " + INIT_HP);
System.out.println("MP:" + this.getMp() + " / " + INIT_MP);
System.out.println("金币:" + this.getGold());
System.out.println("钥匙数量:" + this.keyCount);
System.out.println("技能等级:" + this.skillLevel);
System.out.println("Lia信任度:" + this.liaTrustLevel);
System.out.println("已治疗动物数量:" + this.healAnimalCount);
System.out.println("主线任务进度:");
String[] scenes = {"入口林地", "迷雾沼泽", "古老废墟", "黑暗洞穴", "永恒之泉"};
for (int i = 0; i < mainTaskProgress.length; i++) {
System.out.println(" " + scenes[i] + ":" + (mainTaskProgress[i] == 1 ? "✅ 完成" : "❌ 未完成"));
}
System.out.println("==========================\n");
}
}
2.2 关键知识点讲解💡
(1)专属属性设计:贴合游戏玩法
| 属性名 | 设计目的 | 关联玩法 |
|---|---|---|
keyCount |
记录收集的钥匙数量 | 主线任务:3把钥匙解锁永恒之泉 |
mainTaskProgress |
数组记录5个场景的任务进度 | 串联所有主线场景,判断是否能进入下一场景 |
healAnimalCount |
支线任务:治疗动物数量 | 完成后Lia奖励永久HP+20 |
skillLevel |
技能等级 | 提升攻击力,影响战斗难度 |
liaTrustLevel |
与Lia的信任度 | 信任度≥60,Lia会在战斗中辅助Allen |
👉 核心思路:属性设计完全围绕游戏任务展开,每个属性都对应具体的玩法,而非无意义的定义。
(2)常量定义:方便维护
用static final定义固定值(INIT_HP/INIT_MP),好处是:
- 后续想调整初始HP(比如改成150),只需改常量值,不用改所有初始化代码;
- 代码可读性更高:
INIT_HP比直接写100更易理解。
(3)属性封装:带校验的Getter/Setter
addKey():不直接提供setKeyCount(),而是用addKey()保证钥匙只能增加(符合游戏逻辑:钥匙捡了就不会丢);- 重写
setHp():HP为0时直接提示「游戏失败」,强化玩家角色的死亡逻辑; setLiaTrustLevel():限制信任度0-100,且达到阈值时给出提示(联动Lia的辅助战斗逻辑)。
👉 新手重点:封装不是简单写get/set,而是根据业务逻辑增加校验,保证数据安全!
🚀 三、初始化逻辑:构造方法的执行顺序
Allen的构造方法是「玩家初始状态的入口」,执行顺序至关重要:
调用Allen构造方法
调用父类Person构造:初始化name/HP/MP/金币/背包
初始化Allen专属属性:keyCount=0、任务进度数组全0等
打印初始化提示:艾伦已准备好冒险
关键细节:
- 父类构造优先 :
super()必须是构造方法的第一行,先初始化Person的通用属性(HP/MP/背包),再初始化Allen的专属属性; - 数组初始化 :
mainTaskProgress = new int[MAIN_TASK_COUNT],数组默认值为0(所有任务未完成); - 默认值合理 :初始信任度
liaTrustLevel=0(还没遇到Lia),初始技能等级1(新手难度)。
🧪 四、调试示例:验证Allen的初始化效果
写一个测试类,验证Allen的初始化是否符合预期:
java
/**
* Allen初始化调试示例
*/
public class AllenTest {
public static void main(String[] args) {
// 1. 创建Allen对象(触发构造方法)
Allen allen = new Allen();
// 2. 打印初始状态
allen.printStatus();
// 3. 测试HP校验逻辑
System.out.println("\n--- 测试HP设置 ---");
allen.setHp(-10); // 测试HP为负
allen.setHp(150); // 测试HP超过上限
allen.setHp(80); // 测试正常HP
// 4. 测试添加钥匙
System.out.println("\n--- 测试收集钥匙 ---");
allen.addKey();
allen.addKey();
// 5. 测试Lia信任度
System.out.println("\n--- 测试Lia信任度 ---");
allen.setLiaTrustLevel(60);
allen.setLiaTrustLevel(100);
}
}
调试输出结果:
✨ 艾伦已准备好冒险!初始状态:HP=100 MP=50 金币=20
===== 艾伦的当前状态 =====
HP:100 / 100
MP:50 / 50
金币:20
钥匙数量:0
技能等级:1
Lia信任度:0
已治疗动物数量:0
主线任务进度:
入口林地:❌ 未完成
迷雾沼泽:❌ 未完成
古老废墟:❌ 未完成
黑暗洞穴:❌ 未完成
永恒之泉:❌ 未完成
==========================
--- 测试HP设置 ---
❌ 艾伦的HP已耗尽!游戏失败!
💛 艾伦的HP已恢复至最大值!
--- 测试收集钥匙 ---
🔑 艾伦获得了1把钥匙!当前钥匙数量:1
🔑 艾伦获得了1把钥匙!当前钥匙数量:2
--- 测试Lia信任度 ---
🤝 Lia的信任度达到60!战斗时会辅助你~
❤️ Lia完全信任你!会为你抵挡伤害!
👉 结论:初始化逻辑完全符合预期,属性校验生效,数据安全有保障!
📌 知识回顾
- Allen类继承Person抽象类,新增的专属属性全部贴合游戏任务(钥匙、任务进度、Lia信任度);
- 构造方法遵循「父类优先」原则,先初始化通用属性,再初始化专属属性,默认值设置合理;
- 属性封装不是简单的get/set,而是结合业务逻辑增加校验(钥匙只能加、HP/MP有上下限);
- 用
static final定义常量,提升代码可维护性;用辅助方法printStatus()快速验证状态。
✍️ 写在最后
Allen类的初始化是「玩家体验的第一步」,合理的属性设计和校验逻辑,能避免游戏运行中出现数据混乱(比如HP为负、钥匙数量为-1)。
下一篇我们会聚焦「Allen类(二):道具交互核心逻辑」,带你拆解Allen如何拾取、使用、丢弃道具,以及如何通过MagicFlower提升Lia的信任度💐。
新手建议:
- 把Allen的代码和测试类复制到IDE中运行,修改初始值(比如INIT_HP=150),观察输出变化;
- 思考:如果新增「背包重量限制」属性,该如何设计Getter/Setter?
🔥 系列文章导航:
- 项目总览:设计与架构
- 抽象层设计:Figure/Person类
- Allen类(一):核心属性与初始化(本文)
- Allen类(二):道具交互核心逻辑
...(后续篇章持续更新)
💬 评论区互动:你觉得Allen还应该增加哪些专属属性?比如「攻击力」「防御力」,或者「背包重量限制」?