《天外飞仙》教学方案
教学方案:涵盖每节课的教学目标、教学方法、课堂活动、可能出现的问题及解决方案
一、总体教学策略
1.1 教学方法
| 方法 | 应用场景 | 占比 |
|---|---|---|
| 讲授法 | 概念讲解、代码设计思路 | 30% |
| 演示法 | 实时编码、运行效果展示 | 40% |
| 发现法 | 故意留Bug让学生发现问题 | 10% |
| 对比法 | 好代码 vs 坏代码、优化前后对比 | 10% |
| 实践法 | 每节课的课后练习 | 10% |
1.2 教学节奏
每集视频结构:
📺 开场(1分钟) → 复习回顾(2分钟) → 新知识点(5分钟) → 编码实战(10分钟) → 运行验证(3分钟) → 作业布置(1分钟) → 下集预告(1分钟)1.3 学习效果评估
- 过程评估:每集结尾有 1 个思考题
- 阶段性评估:第5集/第10集各有 1 个小测验
- 终极项目:学生基于框架修改数值/增加新功能
二、每节课详细教学方案
第1集:开发环境搭建与 Swing 基础
教学目的:
- 学生能独立配置 JDK 11 + IntelliJ IDEA
- 学生理解 JFrame 和 JPanel 的关系
- 学生能创建并运行第一个 Swing 程序
教学过程:
| 环节 | 时间 | 内容 | 教学方法 |
|---|---|---|---|
| 导入 | 1min | 展示成品游戏运行效果,引起兴趣 | 演示法 |
| JDK安装 | 3min | 下载JDK 11 → 安装 → 配置 JAVA_HOME → 验证 java -version | 演示法 |
| IDEA配置 | 3min | 新建项目 → 设置 JDK → 创建包结构 | 演示法 |
| 编码实战 | 10min | 写 Main.java:JFrame 窗口 + 居中 + 标题 | 演练法 |
| 运行验证 | 3min | 运行 → 看到空白窗口 | 演示法 |
关键代码片段:
publicclassMain{publicstaticfinalintGAME_WIDTH=240;publicstaticfinalintGAME_HEIGHT=320;publicstaticfinalStringTITLE="天外飞仙";publicstaticvoidmain(String[]args){SwingUtilities.invokeLater(()->{JFrameframe=newJFrame(TITLE);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setResizable(false);frame.pack();DimensionscreenSize=Toolkit.getDefaultToolkit().getScreenSize();intx=(screenSize.width-frame.getWidth())/2;inty=(screenSize.height-frame.getHeight())/2;frame.setLocation(x,y);frame.setVisible(true);});}}常见问题:
- ❌ javac 不是内部命令 → 检查 JAVA_HOME 配置
- ❌ 窗口中文乱码 → file.encoding=UTF-8 或使用汉字显示
- ❌ 窗口未居中 → pack() 后再获取大小
课后作业:
- 修改窗口大小为 320×480,观察比例变化
- 设置窗口背景色为深蓝色
第2集:游戏循环与双缓冲渲染
教学目的:
- 理解游戏循环的基本结构
- 掌握 Runnable + Thread 的使用
- 理解双缓冲渲染的原理
教学过程:
| 环节 | 时间 | 内容 | 教学方法 |
|---|---|---|---|
| 复习 | 1min | 回顾JFrame窗口 | 问答法 |
| 概念 | 3min | 游戏循环 vs Web/App 的事件驱动模型差异 | 讲授法 |
| 编码 | 8min | GamePanel 类:实现 Runnable,run() 循环,60fps控制 | 演示法 |
| 编码 | 5min | 双缓冲:BufferedImage → Graphics2D | 演示法 |
| 调试 | 3min | 演示无双缓冲时的闪烁问题 | 发现法 |
| 输入 | 3min | 实现 KeyListener 接口 | 演示法 |
难点解析:
Thread.sleep(targetTime - elapsed)为什么不是固定 sleep 30ms?
→ 因为渲染时间不固定,需要动态计算剩余时间repaint()vspaintComponent()的关系
→ repaint 让 AWT 线程调度重绘,最终调用 paintComponent
常见问题:
- ❌ 画面闪烁 → 没用双缓冲,检查 buffer 绘制流程
- ❌ 键盘没反应 → 没调 setFocusable(true) 或 addKeyListener
- ❌ 窗口卡死 → Thread 里死循环阻塞了 EDT
课后作业:
- 修改帧率为 60fps,观察 CPU 占用变化
- 添加 WASD 四方向移动测试
第3集:玩家角色类与属性系统
教学目的:
- 掌握 Java 面向对象设计玩家模型
- 理解 RPG 属性体系设计
教学过程:
| 环节 | 时间 | 内容 | 教学方法 |
|---|---|---|---|
| 复习 | 1min | GamePanel 框架 | 问答法 |
| 概念 | 5min | RPG 属性设计:HP/MP/ATK/DEF 的数值规划 | 讲授法 |
| 编码 | 6min | Player 类:字段、构造方法、getter | 演示法 |
| 编码 | 4min | levelUp() 升级方法设计 | 演示法 |
| 编码 | 4min | gainExp() 经验值累进逻辑 | 演示法 |
| 渲染 | 4min | 状态栏绘制:HP条、MP条 | 演示法 |
设计决策讲解:
初始HP=100: 敌人攻击约8-12 → 能扛8-12次攻击 药品恢复50HP → 战斗中可以使用1-2次 升级+15~25HP → 提升空间明显有成就感课后作业:
- 给 Player 添加「内力恢复速度」字段(战斗中每回合回复)
- 修改升级公式为更平滑的曲线
第4集:场景地图与移动逻辑
教学目的:
- 理解场景数据设计
- 掌握链式调用 API 设计
教学过程:
| 环节 | 时间 | 内容 | 教学方法 |
|---|---|---|---|
| 复习 | 2min | Player 类和状态栏 | 问答法 |
| 设计 | 5min | Scene 类字段设计,7个场景的数据规划 | 讲授法 |
| 编码 | 8min | Scene.java 的静态配置 | 演示法 |
| 编码 | 5min | renderOverworld() + drawSceneBackground() | 演示法 |
| 编码 | 3min | 上下移动逻辑 + 边界检查 | 演示法 |
| 验证 | 2min | 运行效果 | 演示法 |
场景设计表:
| 场景 | 等级 | 安全区 | 商店 | 客栈 | NPC | 敌人 |
|---|---|---|---|---|---|---|
| 清风镇 | 1 | ✅ | ✅ | ✅ | ✅ | 无 |
| 幽暗森林 | 1 | ❌ | ❌ | ❌ | ❌ | 野狼、山贼 |
| 青石山路 | 2 | ❌ | ❌ | ❌ | ❌ | 山贼、毒蛇 |
| 古寺 | 2 | ✅ | ❌ | ✅ | ✅ | 黑衣僧人 |
| 死亡沼泽 | 3 | ❌ | ❌ | ❌ | ❌ | 女剑客 |
| 魔教总坛 | 4 | ❌ | ❌ | ❌ | ❌ | 白发老者、魔教教主 |
| 凌霄峰 | 5 | ❌ | ❌ | ❌ | ❌ | 天外飞仙幻象 |
课后作业:
- 添加更多场景,扩展地图
- 给场景添加图片变体(白天/夜晚)
第5集:战斗系统核心(上)
教学目的:
- 掌握状态机在游戏中的应用
- 理解回合制战斗流程
教学过程:
| 环节 | 时间 | 内容 | 教学方法 |
|---|---|---|---|
| 复习 | 2min | 场景移动+遇敌 | 问答法 |
| 概念 | 5min | 状态机:GameState 枚举,状态跳转图 | 讲授法 |
| 设计 | 3min | BattleSystem 类的职责设计 | 讲授法 |
| 编码 | 8min | BattleSystem 核心方法(攻击、伤害计算) | 演示法 |
| 编码 | 5min | Enemy 类 + 敌人配置 | 演示法 |
| 编码 | 3min | 遇敌→进入战斗的状态转换 | 演示法 |
状态机图:
TITLE → STORY → OVERWORLD →↔ BATTLE → BATTLE_ANIM → LEVEL_UP → OVERWORLD ↓ ↓ MENU GAME_OVER (→ TITLE) ↓ SHOP / INN / NPC_DIALOG伤害公式讲解:
damage = max(1, baseAtk - target.def / 2 + random(5))为什么 def 要除以 2?→ 防止高防御导致完全无伤害
为什么加 random(5)?→ 增加战斗随机性,避免公式化
课后作业:
- 增加「暴击」机制(10%概率 1.5倍伤害)
- 添加战斗背景音乐提示
第6集:战斗系统核心(下)
教学目的:
- 掌握复杂的多级状态处理
- 学会防御性编程
教学过程:
| 环节 | 时间 | 内容 | 教学方法 |
|---|---|---|---|
| 复习 | 2min | 战斗框架 review | 问答法 |
| 实战 | 10min | handleBattleInput 完整实现(phase 0-4) | 演示法 |
| 编码 | 5min | renderBattle() + renderBattleUI() | 演示法 |
| 调试 | 5min | Bug 演示:IndexOutOfBoundsException → 修复 | 发现法 |
| 验证 | 3min | 完整战斗测试 | 演示法 |
Bug 分析:
Exception in thread "Thread-0" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 0 at game.GamePanel.handleBattleInput(GamePanel.java:384) 原因:进入 battlePhase=4 时,敌人已被全部杀死,alive=enpty list but battleCursor 还是之前的索引 修复:在 phase 1/4 入口加 if (alive.isEmpty()) { battlePhase = 0; return; }课后作业:
- 添加防御命令的效果显示
- 修复逃跑后光标重置的问题
第7集:武功招式与物品装备系统
教学目的:
- 掌握枚举的高级用法
- 理解游戏数值设计
教学过程:
| 环节 | 时间 | 内容 | 教学方法 |
|---|---|---|---|
| 复习 | 2min | 战斗系统完善 | 问答法 |
| 概念 | 5min | Skill 枚举体系:Type(Target) 组合 | 讲授法 |
| 编码 | 6min | Skill.java + 12种武功配置 | 演示法 |
| 编码 | 5min | Item + 装备系统(品质、效果) | 演示法 |
| 编码 | 4min | 武功到物品的图片映射(itemNameToImgKey/skillNameToImgKey) | 演示法 |
| 渲染 | 3min | 菜单显示武功列表和装备信息 | 演示法 |
武功设计表:
| 武功名 | 类型 | 等级需求 | MP消耗 | 威力 |
|---|---|---|---|---|
| 基础拳法 | 物理·单体 | 1 | 0 | 15 |
| 小还丹术 | 治疗·单体 | 2 | 10 | 40 |
| 铁砂掌 | 物理·单体 | 3 | 5 | 30 |
| 金钟罩 | 增益·自身 | 3 | 8 | 0 |
| 八卦掌 | 物理·单体 | 4 | 6 | 35 |
| 混元一气功 | 魔法·单体 | 4 | 12 | 50 |
| 天山剑法 | 物理·单体 | 5 | 10 | 45 |
| 凌波微步 | 增益·自身 | 6 | 10 | 0 |
| 飞花逐月 | 物理·单体 | 7 | 15 | 60 |
| 太极剑法 | 物理·单体 | 8 | 18 | 70 |
| 万剑归宗 | 魔法·全体 | 9 | 28 | 90 |
| 天外飞仙 | 魔法·全体 | 10 | 35 | 120 |
课后作业:
- 添加新的武功(如「降龙十八掌」)
- 实现装备的出售功能
第8集:商店客栈与 NPC 对话
教学目的:
- 实现多种交互状态
- 掌握渲染与输入在不同状态间的隔离
教学过程:
| 环节 | 时间 | 内容 | 教学方法 |
|---|---|---|---|
| 复习 | 2min | 武功装备系统 | 问答法 |
| 编码 | 6min | 商店界面:renderShop() + handleShopInput() | 演示法 |
| 编码 | 4min | 客栈界面:回血逻辑 | 演示法 |
| 编码 | 3min | NPC 对话:showDialog() 渲染 | 演示法 |
| 编码 | 3min | 全局菜单:状态/武功/装备/背包四面板 | 演示法 |
| 编码 | 3min | 菜单内装备切换逻辑(穿装备/卸装备) | 演示法 |
交互流程:
大地图中按 Enter → 有商店?→ 商店状态 → 有客栈?→ 客栈状态 → 有NPC对话?→ 对话状态 → 以上都没有?→ 无反应(或提示) 大地图中按 X/Esc → 菜单状态 菜单中按 X/Esc → 返回大地图课后作业:
- 添加客栈砍价功能(随机折扣)
- 限制玩家银两为负数的逻辑
第9集:剧情流程与胜利条件
教学目的:
- 学会用状态变量推进剧情
- 实现完整的游戏闭环
教学过程:
| 环节 | 时间 | 内容 | 教学方法 |
|---|---|---|---|
| 复习 | 2min | 所有交互回顾 | 问答法 |
| 设计 | 5min | 剧情节点触发表 | 讲授法 |
| 编码 | 5min | triggerStoryEvents() 方法实现 | 演示法 |
| 编码 | 5min | renderVictory/GameOver/LevelUp 效果 | 演示法 |
| 编码 | 3min | Boss 战配置 | 演示法 |
| 验证 | 5min | 完整游戏流程测试 | 演示法 |
剧情节点:
storyProgress=0: 初始状态 → 击败魔教教主(Scene[5]) → storyProgress=1(获得古玉线索) → 到达凌霄峰(Scene[6]) → storyProgress=2 → 击败天外飞仙幻象(Scene[6] Boss战) → VICTORY(通关)课后作业:
- 添加更多支线任务(如帮村民找回失物)
- 通关后添加二周目继承机制
第10集:AI 美术资源生成与打包发布
教学目的:
- 学会使用 AI 工具辅助游戏开发
- 掌握游戏项目的打包部署
教学过程:
| 环节 | 时间 | 内容 | 教学方法 |
|---|---|---|---|
| 复习 | 2min | 全流程回顾 | 问答法 |
| 概念 | 5min | 提示词工程:是什么、怎么写、注意事项 | 讲授法 |
| 编码 | 8min | generate_assets.js 代码逐行解读 | 演示法 |
| 实操 | 5min | 设置 API KEY → 运行 → 查看生成效果 | 演示法 |
| 编码 | 3min | 图片加载失败的回退策略 | 演示法 |
| 打包 | 3min | run_game.bat 一键编译 | 演示法 |
提示词结构模板:
[主体描述] + [环境/背景] + [风格] + [构图] + [画质关键词]提示词示例拆解:
"Ancient Chinese riverside town, Song dynasty architecture, wooden buildings with tiled roofs, willow trees by a peaceful river, misty mountains in background, warm sunlight, traditional Chinese painting style, 4K" ├─ 朝代风格限定 ─┼─ 具体元素列举 ───────┼─ 环境氛围 ─┼─ 艺术风格 ─┼─ 画质课后作业:
- 用 AI 生成新的敌人造型
- 修改 generate_assets.js 使用不同的画风
三、课后练习合集
| 集 | 基础练习 | 进阶练习 |
|---|---|---|
| 1 | 修改窗口大小、背景色 | 添加标题文字 |
| 2 | 修改帧率、添加按键移动 | 双缓冲 vs 无缓冲对比 |
| 3 | 修改初始属性值 | 添加内力自动回复 |
| 4 | 添加新场景 | 场景昼夜切换 |
| 5 | 添加暴击、闪避 | 战斗背景音乐 |
| 6 | 防御命令效果显示 | 逃跑成功后遇敌重置 |
| 7 | 添加新武功 | 物品出售功能 |
| 8 | 客栈砍价 | 商店限购功能 |
| 9 | 添加支线任务 | 二周目继承 |
| 10 | 用不同画风生成 | 集成到网页版 |
四、常见 Bug 解决方案速查
| Bug | 位置 | 原因 | 修复 |
|---|---|---|---|
| IndexOutOfBounds -1 | handleBattleInput phase 1/4 | alive为空列表 | 加 if (alive.isEmpty()) return |
| IndexOutOfBounds 0 | handleBattleInput phase 3 | consumables列表为空 | 加 if (consumables.isEmpty()) return |
| 图片不显示 | loadAssets | 路径不区分大小写 | 统一小写文件名 |
| 窗口闪烁 | render() | 没用双缓冲 | 检查 buffer 绘制流程 |
| 键盘输入延迟 | keyPressed | EDT 线程阻塞 | 检查循环中的耗时操作 |
| 中文乱码 | paintComponent | 字体不支持中文 | 使用微软雅黑等中文字体 |