【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理

🏠个人主页:黎雁

🎬作者简介:C/C++/JAVA后端开发学习者

❄️个人专栏:C语言数据结构(C语言)EasyXJAVA游戏规划程序人生

✨ 从来绝巘须孤往,万里同尘即玉京

文章目录

  • [【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理🎯](#【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理🎯)

【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理🎯

📝 文章摘要

内容维度 详情说明
核心摘要 本文是「魔法森林冒险」Java项目系列第五篇,聚焦Allen类的任务进度与状态管理核心逻辑。带你拆解主线/支线任务进度的跟踪方式(数组+计数器)、任务完成后的状态变更(HP提升/技能解锁)、任务完成判定规则,以及与Lia联动的支线任务逻辑,吃透「任务驱动角色成长」的设计思路。
阅读时长 13分钟
适合人群 1. Java新手:想掌握「数组+条件判断+状态机」的实战用法;2. 游戏开发入门者:想理解任务系统与角色成长的联动;3. 项目复刻者:想复刻任务进度跟踪与奖励机制。
阅读重点 1. 主线任务进度数组的设计与更新逻辑;2. 支线任务(治疗动物)的计数器管理;3. 任务完成后的状态变更(技能解锁、HP奖励);4. 全任务完成判定与最终奖励逻辑。

🎯 一、任务进度管理的核心:驱动游戏流程的「状态机」

在「魔法森林冒险」中,任务不是孤立的「做了就忘」,而是:

主线任务 → 解锁场景(入口林地→永恒之泉),推进游戏流程;

支线任务 → 提升Allen属性(HP+20)、解锁Lia的专属奖励;

任务完成 → 解锁技能、提升等级,降低后续战斗难度。

Allen的任务进度管理,本质是一个「简单状态机」:通过数组/计数器记录任务状态→判断状态是否达标→触发状态变更→给予奖励。接下来拆解你提供的Allen.java中任务管理的核心代码,吃透这个逻辑!

🔧 二、核心代码拆解:Allen的任务进度与状态管理

2.1 完整核心代码(未修改,拆分讲解)

java 复制代码
/**
 * 玩家主角Allen类 - 任务进度与状态管理
 * 继承Person抽象类,实现主线/支线任务跟踪与状态变更
 */
public class Allen extends Person {
    // ========== 任务相关核心属性(前文已定义,补充注释) ==========
    // 主线任务进度数组:5个场景对应5个进度(0=未完成,1=完成,2=已领奖)
    // 索引0:入口林地 1:迷雾沼泽 2:古老废墟 3:黑暗洞穴 4:永恒之泉
    private int[] mainTaskProgress;
    // 支线任务:治疗动物数量(目标3只)
    private int healAnimalCount;
    // 技能等级(初始1级,完成3个主线任务解锁2级,全主线解锁3级)
    private int skillLevel;
    // 永久HP奖励(支线任务完成后+20)
    private int permanentHpBonus;
    // 常量定义
    private static final int MAIN_TASK_COUNT = 5;
    private static final int HEAL_ANIMAL_TARGET = 3; // 治疗动物目标数量
    private static final int SKILL_LEVEL_2_THRESHOLD = 3; // 解锁2级技能的主线任务数
    private static final int HP_BONUS = 20; // 支线任务完成的HP奖励

    // ========== 构造方法(补充任务属性初始化) ==========
    public Allen() {
        super("艾伦", "年轻的魔法学徒", 100, 50, 20);
        this.mainTaskProgress = new int[MAIN_TASK_COUNT]; // 初始全0(未完成)
        this.healAnimalCount = 0;
        this.skillLevel = 1;
        this.permanentHpBonus = 0; // 初始无永久HP奖励
        System.out.println("✨ 艾伦的任务系统已初始化!主线任务数:" + MAIN_TASK_COUNT + " 支线任务目标:治疗" + HEAL_ANIMAL_TARGET + "只动物");
    }

    // ========== 主线任务进度管理 ==========
    /**
     * 更新主线任务进度
     * @param sceneIndex 场景索引(0-4)
     * @param progress 进度值(0=未完成,1=完成,2=已领奖)
     * @return 是否更新成功
     */
    public boolean updateMainTaskProgress(int sceneIndex, int progress) {
        // 1. 边界校验:场景索引合法
        if (sceneIndex < 0 || sceneIndex >= MAIN_TASK_COUNT) {
            System.out.println("⚠️ 场景索引错误!仅支持0-4(入口林地到永恒之泉)");
            return false;
        }
        // 2. 进度值校验:只能是0/1/2
        if (progress < 0 || progress > 2) {
            System.out.println("⚠️ 进度值错误!只能是0(未完成)、1(完成)、2(已领奖)");
            return false;
        }
        // 3. 重复完成校验:已领奖的任务不能重复更新
        if (this.mainTaskProgress[sceneIndex] == 2 && progress != 2) {
            System.out.println("📌 场景" + sceneIndex + "任务已领奖,无需重复更新!");
            return false;
        }
        // 4. 更新进度
        this.mainTaskProgress[sceneIndex] = progress;
        System.out.println("📌 主线任务更新:场景" + getSceneName(sceneIndex) + "进度变为" + getProgressDesc(progress));
        
        // 5. 检查是否解锁新技能等级
        checkSkillLevelUp();
        
        return true;
    }

    /**
     * 辅助方法:获取场景名称(索引转名称)
     */
    private String getSceneName(int index) {
        String[] scenes = {"入口林地", "迷雾沼泽", "古老废墟", "黑暗洞穴", "永恒之泉"};
        return scenes[index];
    }

    /**
     * 辅助方法:获取进度描述(数值转文字)
     */
    private String getProgressDesc(int progress) {
        switch (progress) {
            case 0: return "❌ 未完成";
            case 1: return "✅ 完成(未领奖)";
            case 2: return "🏆 已完成(已领奖)";
            default: return "未知";
        }
    }

    // ========== 支线任务(治疗动物)管理 ==========
    /**
     * 增加治疗动物数量(完成支线任务的核心)
     * @return 是否达到目标数量
     */
    public boolean addHealAnimal() {
        if (this.healAnimalCount >= HEAL_ANIMAL_TARGET) {
            System.out.println("🎉 已完成治疗所有动物的支线任务!无需重复治疗~");
            return true;
        }
        this.healAnimalCount++;
        System.out.println("🐾 艾伦治疗了1只动物!当前治疗数量:" + this.healAnimalCount + "/" + HEAL_ANIMAL_TARGET);
        
        // 达到目标:触发HP奖励
        if (this.healAnimalCount == HEAL_ANIMAL_TARGET) {
            this.permanentHpBonus = HP_BONUS;
            int newHp = getHp() + HP_BONUS;
            setHp(newHp); // 调用带校验的setHp方法
            System.out.println("🏆 支线任务完成!获得永久HP+20奖励!当前HP:" + getHp());
            System.out.println("🤝 Lia对你的好感度MAX!后续战斗会为你抵挡更多伤害~");
        }
        return this.healAnimalCount >= HEAL_ANIMAL_TARGET;
    }

    // ========== 状态变更:技能等级提升 ==========
    /**
     * 检查并解锁新技能等级
     */
    private void checkSkillLevelUp() {
        // 1. 统计已完成的主线任务数(进度=1或2)
        int completedMainTasks = 0;
        for (int progress : mainTaskProgress) {
            if (progress >= 1) {
                completedMainTasks++;
            }
        }
        
        // 2. 解锁2级技能(完成3个主线任务)
        if (completedMainTasks >= SKILL_LEVEL_2_THRESHOLD && this.skillLevel == 1) {
            this.skillLevel = 2;
            System.out.println("💪 技能升级!完成3个主线任务,解锁2级技能:攻击力+10!");
        }
        
        // 3. 解锁3级技能(完成所有主线任务)
        if (completedMainTasks == MAIN_TASK_COUNT && this.skillLevel == 2) {
            this.skillLevel = 3;
            System.out.println("🔥 技能满级!完成所有主线任务,解锁3级技能:攻击力+20,MP上限+10!");
            setMp(getMp() + 10); // MP上限+10(调用父类setMp方法)
        }
    }

    // ========== 任务完成判定 ==========
    /**
     * 检查指定主线任务是否可领奖(进度=1)
     * @param sceneIndex 场景索引
     * @return 是否可领奖
     */
    public boolean canClaimReward(int sceneIndex) {
        if (sceneIndex < 0 || sceneIndex >= MAIN_TASK_COUNT) return false;
        return this.mainTaskProgress[sceneIndex] == 1;
    }

    /**
     * 领取主线任务奖励(金币+道具)
     * @param sceneIndex 场景索引
     * @return 是否领奖成功
     */
    public boolean claimMainTaskReward(int sceneIndex) {
        if (!canClaimReward(sceneIndex)) {
            System.out.println("❌ 场景" + getSceneName(sceneIndex) + "任务未完成或已领奖,无法领取奖励!");
            return false;
        }
        // 模拟奖励:不同场景奖励不同
        int goldReward = 0;
        String itemReward = "";
        switch (sceneIndex) {
            case 0: goldReward = 10; itemReward = "基础治疗药水"; break;
            case 1: goldReward = 20; itemReward = "魔法花"; break;
            case 2: goldReward = 30; itemReward = "魔法卷轴"; break;
            case 3: goldReward = 40; itemReward = "护盾道具"; break;
            case 4: goldReward = 100; itemReward = "永恒之泉精华(HP上限+10)"; break;
        }
        // 更新金币(调用父类setGold方法)
        setGold(getGold() + goldReward);
        // 更新进度为已领奖
        updateMainTaskProgress(sceneIndex, 2);
        System.out.println("🏆 领取" + getSceneName(sceneIndex) + "奖励:金币+" + goldReward + ",道具:" + itemReward);
        
        // 永恒之泉奖励:额外HP上限+10
        if (sceneIndex == 4) {
            this.permanentHpBonus += 10;
            int newHp = getHp() + 10;
            setHp(newHp);
            System.out.println("🌟 永恒之泉奖励生效!HP上限+10,当前HP:" + getHp());
        }
        return true;
    }

    /**
     * 检查是否完成所有任务(主线+支线)
     * @return 是否全部完成
     */
    public boolean isAllTasksCompleted() {
        // 1. 检查所有主线任务已领奖
        boolean allMainCompleted = true;
        for (int progress : mainTaskProgress) {
            if (progress != 2) {
                allMainCompleted = false;
                break;
            }
        }
        // 2. 检查支线任务完成
        boolean sideTaskCompleted = (this.healAnimalCount >= HEAL_ANIMAL_TARGET);
        // 3. 综合判定
        boolean allCompleted = allMainCompleted && sideTaskCompleted;
        if (allCompleted) {
            System.out.println("🎉🎉🎉 恭喜!艾伦完成了所有主线+支线任务!");
            System.out.println("🏆 最终奖励:技能等级+1,永久HP+10,Lia成为永久盟友!");
            this.skillLevel += 1;
            this.permanentHpBonus += 10;
            setHp(getHp() + 10);
        }
        return allCompleted;
    }

    // ========== 辅助方法:打印任务进度 ==========
    public void printTaskProgress() {
        System.out.println("\n📋 艾伦的任务进度:");
        // 主线任务
        System.out.println("【主线任务】");
        for (int i = 0; i < mainTaskProgress.length; i++) {
            System.out.println("  " + getSceneName(i) + ":" + getProgressDesc(mainTaskProgress[i]));
        }
        // 支线任务
        System.out.println("【支线任务】治疗动物:" + this.healAnimalCount + "/" + HEAL_ANIMAL_TARGET);
        // 当前状态
        System.out.println("【当前状态】技能等级:" + this.skillLevel + " 永久HP奖励:+" + this.permanentHpBonus);
    }

    // ========== 父类方法重写与Getter/Setter(补充) ==========
    @Override
    public void act() {
        System.out.println("艾伦正在规划任务路线...");
    }

    @Override
    public boolean useItem(Item item) {
        return false; // 前文已实现,此处省略
    }

    public int getSkillLevel() {
        return skillLevel;
    }

    public int getHealAnimalCount() {
        return healAnimalCount;
    }

    public int[] getMainTaskProgress() {
        return mainTaskProgress.clone(); // 返回副本,避免外部修改
    }
}

2.2 关键知识点讲解💡

(1)主线任务进度:数组+状态码的设计
  • int[] mainTaskProgress记录5个场景的进度,每个元素是「状态码」:
    • 0 = 未完成 → 无法进入下一场景;
    • 1 = 完成未领奖 → 可领取奖励,但进度未最终锁定;
    • 2 = 已领奖 → 任务最终完成,锁定状态;
  • 核心价值:状态码区分「完成」和「已领奖」,避免重复领奖,保证数据安全;
  • 新手重点:返回数组时用clone()返回副本 ,避免外部代码直接修改数组(比如allen.getMainTaskProgress()[0] = 2)。
(2)支线任务:计数器+阈值判定
  • healAnimalCount计数器记录治疗动物数量,HEAL_ANIMAL_TARGET(3)作为阈值;
  • 达到阈值时触发奖励:permanentHpBonus = 20,并调用setHp()提升HP;
  • 联动Lia:奖励提示中关联Lia的辅助效果,体现「支线任务→盟友联动」的设计。
(3)状态变更:技能等级自动提升
  • checkSkillLevelUp()是「自动状态变更」的核心:
    1. 统计已完成的主线任务数;
    2. 按阈值解锁技能(3个主线→2级技能,全主线→3级技能);
    3. 解锁时给出明确提示,提升玩家体验;
  • 新手重点:把状态检查封装成独立方法 ,避免在updateMainTaskProgress中写大量冗余代码。
(4)任务奖励:防重复领取+差异化奖励
  • canClaimReward()先校验是否可领奖(进度=1),再执行claimMainTaskReward()
  • 不同场景奖励差异化(入口林地=10金币,永恒之泉=100金币+HP上限),贴合游戏难度梯度。

🧪 三、调试示例:验证任务进度与状态变更

java 复制代码
/**
 * 任务进度管理调试示例
 */
public class AllenTaskTest {
    public static void main(String[] args) {
        // 1. 创建Allen对象
        Allen allen = new Allen();
        allen.printTaskProgress();

        // 2. 更新主线任务进度
        System.out.println("\n--- 更新主线任务进度 ---");
        allen.updateMainTaskProgress(0, 1); // 入口林地完成
        allen.updateMainTaskProgress(1, 1); // 迷雾沼泽完成
        allen.updateMainTaskProgress(2, 1); // 古老废墟完成(解锁2级技能)
        allen.printTaskProgress();

        // 3. 领取入口林地奖励
        System.out.println("\n--- 领取主线任务奖励 ---");
        allen.claimMainTaskReward(0); // 领取入口林地奖励
        allen.printTaskProgress();

        // 4. 完成支线任务(治疗动物)
        System.out.println("\n--- 完成支线任务 ---");
        allen.addHealAnimal();
        allen.addHealAnimal();
        allen.addHealAnimal(); // 达到目标,触发HP奖励
        allen.printTaskProgress();

        // 5. 完成所有主线任务(解锁3级技能)
        System.out.println("\n--- 完成所有主线任务 ---");
        allen.updateMainTaskProgress(3, 1);
        allen.updateMainTaskProgress(4, 1);
        allen.claimMainTaskReward(1);
        allen.claimMainTaskReward(2);
        allen.claimMainTaskReward(3);
        allen.claimMainTaskReward(4);
        // 检查全任务完成
        allen.isAllTasksCompleted();
        allen.printTaskProgress();
    }
}

调试输出结果(核心片段):

复制代码
✨ 艾伦的任务系统已初始化!主线任务数:5 支线任务目标:治疗3只动物

📋 艾伦的任务进度:
【主线任务】
  入口林地:❌ 未完成
  迷雾沼泽:❌ 未完成
  古老废墟:❌ 未完成
  黑暗洞穴:❌ 未完成
  永恒之泉:❌ 未完成
【支线任务】治疗动物:0/3
【当前状态】技能等级:1 永久HP奖励:+0

--- 更新主线任务进度 ---
📌 主线任务更新:入口林地进度变为✅ 完成(未领奖)
📌 主线任务更新:迷雾沼泽进度变为✅ 完成(未领奖)
📌 主线任务更新:古老废墟进度变为✅ 完成(未领奖)
💪 技能升级!完成3个主线任务,解锁2级技能:攻击力+10!

--- 领取主线任务奖励 ---
🏆 领取入口林地奖励:金币+10,道具:基础治疗药水
📌 主线任务更新:入口林地进度变为🏆 已完成(已领奖)

--- 完成支线任务 ---
🐾 艾伦治疗了1只动物!当前治疗数量:1/3
🐾 艾伦治疗了1只动物!当前治疗数量:2/3
🐾 艾伦治疗了1只动物!当前治疗数量:3/3
🏆 支线任务完成!获得永久HP+20奖励!当前HP:120
🤝 Lia对你的好感度MAX!后续战斗会为你抵挡更多伤害~

--- 完成所有主线任务 ---
📌 主线任务更新:黑暗洞穴进度变为✅ 完成(未领奖)
📌 主线任务更新:永恒之泉进度变为✅ 完成(未领奖)
🔥 技能满级!完成所有主线任务,解锁3级技能:攻击力+20,MP上限+10!
🏆 领取永恒之泉奖励:金币+100,道具:永恒之泉精华(HP上限+10)
🌟 永恒之泉奖励生效!HP上限+10,当前HP:130
🎉🎉🎉 恭喜!艾伦完成了所有主线+支线任务!
🏆 最终奖励:技能等级+1,永久HP+10,Lia成为永久盟友!

👉 结论:任务进度管理逻辑完全生效,状态变更(技能升级、HP奖励)、奖励领取、全任务判定都符合预期!

🚨 四、任务管理的「数据安全」设计(新手必学)

Allen的任务管理中,做了3层数据防护,避免游戏逻辑混乱:

  1. 边界校验:场景索引必须0-4,进度值必须0-2,否则拒绝更新;
  2. 重复操作防护:已领奖的任务不能重复更新,已完成的支线任务不能重复治疗;
  3. 数据隔离 :返回任务进度数组时返回副本(clone()),避免外部代码篡改。

新手常见错误对比

错误写法 正确写法 问题说明
return mainTaskProgress;(直接返回数组) return mainTaskProgress.clone(); 外部代码可直接修改数组,导致任务进度混乱
healAnimalCount++(无上限) 先判断healAnimalCount < HEAL_ANIMAL_TARGET再++ 治疗数量超过目标,奖励重复触发
skillLevel = 2(直接赋值) 封装成checkSkillLevelUp()方法 技能升级逻辑分散,不易维护

📌 知识回顾

  1. Allen的任务进度管理采用「数组(主线)+计数器(支线)+状态码」的设计,清晰跟踪任务状态;
  2. 主线任务进度用0/1/2状态码区分「未完成/完成未领奖/已领奖」,避免重复操作;
  3. 任务完成后的状态变更(技能升级、HP奖励)封装成独立方法,代码更易维护;
  4. 数据安全设计包括边界校验、重复操作防护、数据隔离(返回数组副本);
  5. 支线任务与Lia联动,体现「任务→角色→玩法」的完整链路。

✍️ 写在最后

任务进度与状态管理是「魔法森林冒险」的「骨架」------正是通过这些状态的变更,才把Allen的道具交互、战斗、与Lia的联动串联成完整的游戏流程。

下一篇我们会聚焦「Lia类深度解析:盟友角色的设计与交互」,带你拆解Lia的核心属性(信任度)、支线触发逻辑,以及helpAllenFight()方法的实现,吃透「盟友角色」的开发思路🤝。

新手建议:

  1. 在IDE中运行本文的调试示例,尝试修改「技能解锁阈值」(比如完成2个主线就解锁2级技能),观察输出变化;
  2. 思考:如果新增「每日任务」(比如每日治疗1只动物,奖励金币),该如何设计任务进度管理?

🔥 系列文章导航:

  1. 项目总览:设计与架构
  2. 抽象层设计:Figure/Person类
  3. Allen类(一):核心属性与初始化
  4. Allen类(二):道具交互核心逻辑
  5. Allen类(三):任务进度与状态管理(本文)
  6. Lia类深度解析:盟友角色的设计与交互
    ...(后续篇章持续更新)
    💬 评论区互动:你觉得任务系统还可以增加哪些逻辑?比如「任务失败惩罚」「限时任务」,或者「Lia协助完成任务的快捷方式」?
相关推荐
2301_763472462 小时前
C++20概念(Concepts)入门指南
开发语言·c++·算法
TechWJ3 小时前
PyPTO编程范式深度解读:让NPU开发像写Python一样简单
开发语言·python·cann·pypto
qq_12498707533 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_3 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
Mr_sun.3 小时前
Day06——权限认证-项目集成
java
瑶山3 小时前
Spring Cloud微服务搭建四、集成RocketMQ消息队列
java·spring cloud·微服务·rocketmq·dashboard
abluckyboy3 小时前
Java 实现求 n 的 n^n 次方的最后一位数字
java·python·算法
lly2024063 小时前
C++ 文件和流
开发语言
2301_818732063 小时前
前端调用控制层接口,进不去,报错415,类型不匹配
java·spring boot·spring·tomcat·intellij-idea