第 12 课 · 期末项目

文字冒险游戏

期末大阅兵:把一学期学的 print、变量、if、循环、random、字符串全部装进一个游戏,做出属于你自己的文字冒险《神秘城堡冒险》!

120 分钟完整闭环 5 个知识点 3 段示范代码 难度 ★★★
🏠 学期课件主页 ← 上一课:字符串魔法已是最后一课 →
01

本课导览

先看这节课教什么、怎么分配 120 分钟,老师心里有底,课堂节奏就不乱。

第12课期末项目
🎯 趣味项目:文字冒险游戏
综合运用游戏设计状态变量def 小帮手调试
🎯教学目标(学完这节课,学生能…)
  • 综合运用本学期所学的所有知识点(输出、变量、运算、输入、判断、循环、随机、字符串);
  • 学会设计一个有分支剧情的互动游戏:描述场景 → 玩家选择 → 根据选择走向不同结局;
  • 理解「状态变量」的作用(生命值、金币、是否有钥匙),体会游戏数值的联动;
  • 初步认识 def 函数:把重复动作打包成「小帮手」,喊一声就来;
  • 完成一个可运行、可展示的文字冒险游戏作品,并学会基本的调试方法(找 bug 三步走)。
🔑 教学重点
  • 游戏骨架:场景 → 选择 → 分支 → 下一场景 → … → 结局
  • 用 health / gold / has_key 三个状态变量撑起剧情
🧗 教学难点 / 易卡点
  • 多分支嵌套时,else 到底配哪个 if(缩进看辈分)
  • 角色被暗箭击中后 health 变化、后续剧情要跟着变
  • 游戏很长,敲错一行找半天——学会分段测试
🧰课前准备(老师 / 学生)
  • 老师:本课建议 2 课时(教案建议)——第 1 课时搭框架跑通主线,第 2 课时学生自主加剧情、做展示;准备一枚印章/贴纸做「冒险家评级章」。
  • 学生:把「我的作品」文件夹整理好,今天的大作品保存为「第12课_神秘城堡.py」;这将是期末作品展的主角。
  • 分组建议:同桌两人一组互相测试对方设计的关卡,记录「别人玩不懂的地方」。
⏱️120 分钟教学流程(建议时间轴,可按班级情况微调)
时间环节做什么 / 师生互动要点
0–5候课 · 设备检查开机 → 打开编辑器 → 整理作品文件夹,准备迎接大项目。
5–12学期回顾 · 快问快答快问抢答过一遍:print 干嘛?变量?if 三件套?for/while?random?字符串切片?
12–22情景导入 · 拆解游戏聊「你玩过哪些选剧情游戏」→ 把游戏拆成:场景、选择、分支、状态、结局五个零件。
22–35知识讲解游戏设计思路 → 状态变量(血/金币/钥匙)→ def 把状态栏打包成小帮手。
35–55搭积木(示例1~3)最小冒险骨架(选路→结局)→ def 状态栏 → 完整主项目代码带读 + 上机敲。
55–80主项目跑通 + 测试完整运行《神秘城堡》,三条大门选择 × 三条通道 × 多个结局都试一遍;投屏找茬。
80–95课堂练习 A/B练习 1 完整通关记录结局;练习 2 加一个新场景或分支;互相测试。
95–105挑战练习 C加「战斗系统」让怪物也会还手;学有余力的同学设计第二关。
105–115作品展示 · 互评同桌互玩对方的游戏,填写「冒险家互评卡」(好玩吗?卡不卡?哪里看不懂?);老师盖评级章。
115–120总结 · 保存作品齐读结课口诀;保存「第12课_神秘城堡.py」;预告下学期:真正的函数和更多数据容器!

时间轴把 2 小时切成 8 段:复习→导入→讲解→示范→上机→练习→检测→小结,每段都有明确产出。

02

情景导入 · 复习热身

先用 5 分钟把上节课的记忆叫醒,再用故事和类比把新知识挂到孩子已有的经验上。

🔁上节回顾 · 快问快答(建议 5 分钟)

问 1:一学期下来,让电脑「开口说话」用什么函数?
→ print()。 我们学的第一句咒语。

问 2:if-elif-else、for、while、break 分别是干嘛的?
→ if 做选择、elif 多选一、for 定次数循环、while 条件循环、break 跳出循环。 选择 + 循环 = 程序的两大引擎。

问 3:random.randint(1, 6) 和 s[::-1] 各是什么?
→ 掷 1~6 的骰子;把字符串 s 反转。 一个是运气大师,一个是字符串魔法。

📖情景故事 · 今天学什么

期末了,老师宣布:这次不考试,每人设计一个「文字冒险游戏」——你用文字讲故事,玩家用选择决定命运!

小刚兴奋地设计了一座神秘城堡:大门前有三条路,大厅有三条通道,每个选择都可能捡到金币、碰到怪物、或者找到金钥匙……

可他发现游戏越来越长:又是血量又是金币又是钥匙,代码像迷宫一样绕。老师说:别急,先把游戏拆成零件——场景、选择、分支、状态、结局,一个一个装。

小刚把「报状态」做成了一个小帮手 def,喊一次就报一次血量和金币;把选择用 if-elif-else 一条条排好。终于,他的《神秘城堡冒险》跑通了!

今天,你也要当一次游戏设计师:把一学期的本领全部装进你的冒险世界,做出属于你的结局!

💡生活类比:把新知识挂在旧经验上
🎬

文字冒险 = 会分叉的故事书

读到关键处停下:选 1 翻到某页,选 2 翻到另一页——故事走向由读者决定。

分支剧情
🧩

游戏 = 五个零件拼装

场景(print)、选择(input)、分支(if)、状态(变量)、结局——拆开做,再拼起来。

模块化设计
❤️

状态变量 = 游戏的血条

health 是血量、gold 是金币、has_key 是钥匙——程序用变量记住「你现在怎么样」。

数值联动
🧰

def = 打包小帮手

把「报状态」这段动作包成函数,起个名字,以后喊 show_status() 它就立刻执行。

函数初体验
🗝️本课核心口诀(板书 / 齐读)
核 心 口 诀场景选择加分支,状态结局五零件;
先拆后拼写代码,跑通就是小作家!
03

知识讲解

分小块讲透语法点,每一块都配生活类比 + 要点小结,讲完立刻口头小试。

📚知识点回顾——一学期学了什么

文字冒险游戏是全明星阵容:一学期学的每个知识点都能在游戏里找到用武之地。

print:打印场景描述、分隔线 = 40 个等号;变量:health(生命)、gold(金币)、has_key(钥匙);运算:health - 30、gold + 20。

input + 类型转换:读玩家的选择;if-elif-else:每个选择分支出不同剧情;random:怪物战输赢看运气(random.randint)。

while + break:可以给游戏加「再来一次」的循环;字符串操作:拼接输出 + str()、用 = 号打印漂亮的分隔线。

输出/变量/运算/输入/判断/循环/随机/字符串全用上每个知识点都能在游戏里找到位置学以致用的大阅兵
💡 做游戏不是为了炫技,而是把零散的知识串成一条线——这比背十个语法都管用。
🧩游戏设计思路——先拆零件,再拼装

文字冒险游戏的核心循环:描述场景 → 玩家做选择 → 根据选择进入不同场景 → 继续选择,直到游戏结束。

先画一张「剧情地图」:城堡大门(3 个选项)→ 大厅(3 条通道)→ 最终房间(有钥匙 / 没钥匙两种结局)。把分支画成树状图再写码。

状态变量是游戏的「记性」:health 记住你剩多少血、gold 记住你有多少钱、has_key 记住你有没有钥匙——它们会随选择变化,并影响后面的剧情。

每个分支都用 if-elif-else 处理:1/2/3 各走各的路,else 接住乱输入的情况。分支多不怕,一个一个写清楚就行。

先画剧情地图再写代码状态变量 = 游戏的记性if-elif-else 分管每个选择
💡 第一版只做一条主线跑通,再慢慢加分支。游戏是做出来的,不是想出来的——先跑起来最重要。
🧰def 小帮手——把重复动作打包(初识函数)

游戏里要多次「报状态」(血量、金币、钥匙)。同样的代码写三遍太啰嗦,Python 允许你用 def 把它打包成一个「小帮手」,起个名字随叫随到。

写法:def 名字(): 下面缩进写打包的动作。定义好之后,在别处写 名字() 就会执行整段动作。

本例:def show_status(): 里打印生命值/金币/钥匙。需要报状态时,写一句 show_status() 就全部打印出来。

函数是编程里极其重要的概念,下学期会正式系统学习。今天先混个脸熟:看到 def 知道它是「打包动作的小帮手」即可。

def 名字(): + 缩进 = 打包动作名字() = 喊小帮手来干活下学期正式学,今天先认识
💡 show_status() 里 print 的 health 是外面的变量——函数能「看到」它,但要记住:现在只需会用,不求甚解。
🔍调试三步走——敲错别怕

这么长的游戏,敲错一行怎么办?别慌,用「调试三步走」:

第一步:看报错信息——它告诉你第几行出错了(看行号!),多半是冒号、引号、缩进的问题。

第二步:分段测试——刚写完场景 1 就运行一次,确认没问题再写场景 2。别攒到最后一次运行,那时 bug 藏得最深。

第三步:加「探针」——在怀疑的地方临时加一句 print("到这里了"),看程序到底走没走到那一段。找出问题后把探针删掉。

看报错行号写完一段测一段print 探针找位置
💡 找 bug 不是笨功夫,是程序员的日常。今天学会调试,比多背十个语法更有用!
04

示范代码 · 动手做

老师先带读代码、讲注释,再让学生亲手敲一遍——敲错正好学习调试。

Python示例 1 · 示例 1:最小冒险骨架——两个选择两种结局
# 第12课:最小文字冒险骨架
print("你站在魔法森林的岔路口。")
print("1. 走左边的亮光小路")
print("2. 走右边的黑森林")
choice = input("你的选择?(1/2):")

if choice == "1":
    print("你走进亮光小路,发现了一座糖果屋!")
    print("结局:甜蜜的冒险!")
else:
    print("黑森林里传来狼叫声……你赶紧跑回了家。")
    print("结局:平安回家")
运 行 结 果
你站在魔法森林的岔路口。
1. 走左边的亮光小路
2. 走右边的黑森林
你的选择?(1/2):1
你走进亮光小路,发现了一座糖果屋!
结局:甜蜜的冒险!
✍ 亲手敲一遍,两个选项各走一次。数一数这个骨架用到了哪些学过的知识。

🤔 想一想:如果玩家输入 3,程序走哪条路?(else 接住了「没想到的情况」——这也是一种保护。)

Python示例 2 · 示例 2:def 小帮手——状态栏
# 把"报状态"打包成小帮手
health = 100
gold = 0
has_key = False

def show_status():
    # 以后喊 show_status(),就执行下面三行
    print("生命值:" + str(health))
    print("金币:" + str(gold))
    print("钥匙:" + ("有" if has_key else "没有"))

print("--- 第一次报状态 ---")
show_status()     # 喊小帮手来干活

gold = gold + 50  # 捡到金币
print("--- 捡到50金币后 ---")
show_status()     # 再喊一次,数值变了
运 行 结 果
--- 第一次报状态 ---
生命值:100
金币:0
钥匙:没有
--- 捡到50金币后 ---
生命值:100
金币:50
钥匙:没有
✍ 敲一遍并运行。试着把 has_key 改成 True 再运行,看钥匙那行怎么变。

🤔 想一想:def show_status(): 下面的代码什么时候执行?(只在喊 show_status() 的时候执行,定义本身不执行。)

Python示例 3 · 主项目:神秘城堡冒险(完整版)
# 第12课主项目:文字冒险游戏《神秘城堡冒险》
# 用到的本领:print、变量、运算、input、if-elif-else、random、字符串拼接
import random

print("=" * 40)
print("    神秘城堡冒险")
print("=" * 40)

health = 100      # 生命值
gold = 0          # 金币
has_key = False   # 是否找到金钥匙

def show_status():
    # 报状态小帮手:血量、金币、钥匙
    print("\n--- 你的状态 ---")
    print("生命值:" + str(health))
    print("金币:" + str(gold))
    print("钥匙:" + ("有" if has_key else "没有"))

# ===== 场景1:城堡大门 =====
print("\n【场景1:城堡大门】")
print("1. 检查石像  2. 推门进去  3. 绕到城堡后面")
choice1 = input("你的选择?(1/2/3):")

if choice1 == "1":
    print("你发现石像手里握着一把金钥匙!")
    has_key = True
elif choice1 == "2":
    print("大门纹丝不动,突然暗箭射来!")
    health = health - 30
    print("你忍痛退后,在石像底座下找到了钥匙。")
    has_key = True
else:
    print("你绕到城堡后面,在花园宝箱里找到了20金币!")
    gold = gold + 20

if health > 0:
    show_status()

    # ===== 场景2:城堡大厅 =====
    print("\n【场景2:城堡大厅】")
    print("三条通道:左(奇怪的声音)、中(亮光)、右(很黑)")
    choice2 = input("走哪条路?(左/中/右):")

    if choice2 == "左":
        print("你发现一个睡觉的怪物,旁边有个宝箱。")
        action = input("1.偷拿宝箱 2.攻击怪物 3.悄悄离开:")
        if action == "1":
            if random.randint(1, 3) == 1:
                print("怪物醒了!抓伤了你!")
                health = health - 40
            print("你拿到了50金币和一瓶药水!")
            gold = gold + 50
            health = health + 20
            if health > 100:
                health = 100   # 生命值最多100
        elif action == "2":
            if random.randint(1, 2) == 1:
                print("你打败了怪物!获得80金币!")
                gold = gold + 80
            else:
                print("怪物太强,你被打退了!")
                health = health - 50
        # 选3悄悄离开:什么也不发生
    elif choice2 == "中":
        print("你发现了图书馆,书桌上放着一本魔法书。")
        read = input("1.读书 2.搜索书架 3.离开:")
        if read == "1":
            if random.randint(1, 2) == 1:
                print("魔法书把你传送到宝藏室!获得100金币!")
                gold = gold + 100
            else:
                print("魔法书把你传送到陷阱!")
                health = health - 20
        elif read == "2":
            print("你在书架暗格里找到了30金币!")
            gold = gold + 30
    else:
        print("太黑了!你撞到了墙!")
        health = health - 10
        print("你摸索到机关,暗门里有40金币!")
        gold = gold + 40

    if health > 0:
        show_status()

        # ===== 场景3:城堡深处 =====
        print("\n【场景3:城堡深处】")
        if has_key:
            print("你用金钥匙打开了宝藏室的大门!")
            gold = gold + 200
            print("获得200金币!通关成功!")
            print("最终金币:" + str(gold) + ",剩余生命:" + str(health))
            if gold >= 300:
                print("评级:S级 - 传奇冒险家!")
            elif gold >= 200:
                print("评级:A级 - 优秀冒险家!")
            else:
                print("评级:B级 - 合格冒险家!")
        else:
            print("没有钥匙,你只能带着金币从侧门离开。")
            print("游戏结束。金币:" + str(gold))
    else:
        print("你倒下了……游戏结束。")
else:
    print("你被暗箭击倒了……游戏结束。")

print("\n感谢游玩《神秘城堡冒险》!")
运 行 结 果
========================================
    神秘城堡冒险
========================================

【场景1:城堡大门】
1. 检查石像  2. 推门进去  3. 绕到城堡后面
你的选择?(1/2/3):1
你发现石像手里握着一把金钥匙!

--- 你的状态 ---
生命值:100
金币:0
钥匙:有

【场景2:城堡大厅】
三条通道:左(奇怪的声音)、中(亮光)、右(很黑)
走哪条路?(左/中/右):中
你发现了图书馆,书桌上放着一本魔法书。
1.读书 2.搜索书架 3.离开:1
魔法书把你传送到陷阱!

--- 你的状态 ---
生命值:80
金币:0
钥匙:有

【场景3:城堡深处】
你用金钥匙打开了宝藏室的大门!
获得200金币!通关成功!
最终金币:200,剩余生命:80
评级:A级 - 优秀冒险家!

感谢游玩《神秘城堡冒险》!
✍ 完整敲一遍(很长,敲完一段就运行一次,别等全敲完)。把大门 3 个选择 × 大厅 3 条路都试一遍,看你能打出几个不同的结局。

🤔 想一想:想让「没有钥匙也能通关」吗?想想:把 final 的 if has_key 分支改一改,能不能设计一个「翻窗偷宝」的第三条结局?

05

易错提醒

把最容易翻车的写法先亮出来,见一次、错一次、就会了。

易错点 1

长代码缩进错位——else 配错了 if

✗ 错误写法
if choice1 == "1":
    ...
else:
    ...
    else:  # 多了一个没配对的else
✓ 正确写法
elif choice1 == "2":
    ...
else:
    ...
为什么:缩进决定 if 和 else 的配对。每层 if 的 else 必须和它同一缩进。写长代码时先在心里数清楚:这个 else 是配哪个 if 的?
易错点 2

状态变量没更新或更新错

✗ 错误写法
health = health - 30  # 写完忘了用
✓ 正确写法
health = health - 30  # 后面 show_status() 才能显示新值
为什么:变量是游戏的记性:捡了金币要 gold = gold + 20、掉血要 health = health - 30,剧情才会「记住」你的经历。漏写一行,后面评级就算错。
易错点 3

数字忘加 str() 就拼接

✗ 错误写法
print("金币:" + gold)  # 报错
✓ 正确写法
print("金币:" + str(gold))
为什么:字符串拼接 + 的两边都必须是字符串。gold 是数字,先 str(gold) 转文字。这是全学期最容易反复踩的坑。
06

课堂练习(分层)

基础题人人过关,进阶题鼓励尝试,挑战题给学有余力的孩子。参考答案给老师做巡视对照。

A组 · 基础(人人必做)课堂完成,老师巡回指导
  1. 运行《神秘城堡冒险》,把大门 3 个选择都试一遍,把每次得到的金币、生命值变化记在练习本上。 (提示:第 1 条路拿钥匙;第 2 条路掉血但也能拿钥匙;第 3 条路只有金币。)
  2. 在游戏开头加上玩家姓名:先 input 问「冒险家,你叫什么名字?」,之后 print("欢迎你," + name + "!")。 (提示:name = input(...) 在游戏开始处;注意 name 也要拼进欢迎语。)
B组 · 进阶(鼓励尝试)课堂完成,老师巡回指导
  1. 给游戏增加一个新场景:比如在场景 2 和场景 3 之间加一个「护城河上的吊桥」,2 个选择各给不同结果。 (提示:照着场景 2 的格式写:print 描述 → print 选项 → input → if-elif-else。)
  2. 给「悄悄离开」也写点剧情:原来选 3 什么都不发生,现在让它捡到 5 金币或遇到小惊喜。 (提示:在 action == "3" 分支里补代码(现在它没有 elif)。)
C组 · 挑战(学有余力)课堂完成,老师巡回指导
  1. 给游戏加简单的「战斗系统」:打怪物时让怪物也有攻击力,玩家和怪物轮流扣血,直到一方倒下(提示:用 while True + break)。 (提示:先定义 monster_health = 30,循环里玩家打一次、怪物打一次。)
  2. 设计「第二关」:通关后问「要进入地下墓穴吗?」,做一个全新的场景链(至少 2 个场景、3 个选择)。 (提示:把第一关的代码结构复制改造即可。)
07

闯关小测

收尾前 10 分钟,用口答 / 举手抢答把今天的关键点过一遍。

闯关 1先举手回答,再对答案

文字冒险游戏的核心循环是什么?

答案:描述场景 → 玩家选择 → 根据选择进入不同场景 → 继续选择直到结束。

💡 场景、选择、分支三件套。

闯关 2先举手回答,再对答案

游戏里 health、gold、has_key 这样的变量叫「什么变量」?

答案:状态变量——记录玩家当前的状态(血、钱、道具)。

💡 程序的「记性」。

闯关 3先举手回答,再对答案

def show_status(): 定义好后,想让它执行要怎么写?

答案:写一句 show_status()。

💡 喊小帮手来干活。

闯关 4先举手回答,再对答案

写长游戏时,防止 bug 最好的习惯是什么?

答案:写完一段就运行测试一段,别等全部写完。

💡 分段测试,bug 无处藏身。

闯关 5先举手回答,再对答案

print("金币:" + str(gold)) 为什么 gold 要套 str()?

答案:因为 + 两边都要字符串,gold 是数字要先转文字。

💡 全学期最经典的坑之一。

08

小结 · 作业与预告

用一句话带走今天的内容;作业分层布置,作品记得保存进成长档案。

🖍️本课小结(一句话 + 板书核心词)
一句话带走期末大阅兵:把一学期学的 print、变量、if、循环、random、字符串全部装进一个游戏,做出属于你自己的文字冒险《神秘城堡冒险》!
场景→选择→分支→结局状态变量 health/gold/has_keydef = 打包小帮手if-elif-else 管分支random 定成败str() 拼数字写完一段测一段
必做 · 人人过关
  1. 必做题:修改游戏——在开始时让玩家输入名字,并在游戏过程中(至少开头和通关时)显示这个名字。
  2. 把《神秘城堡冒险》保存为「第12课_神秘城堡.py」放进作品文件夹,这就是你的期末作品展主角(老师检查)。
选做 · 鼓励挑战
  1. 选做题:增加至少 2 个新场景和 3 个新选择,让游戏更丰富,并画一张「剧情地图」交给老师。
  2. 选做题:给自己游戏里的每个选择设计成都有「意外惊喜或意外风险」(用 random.randint 控制好坏),让玩家想多玩几遍。
思考 · 烧脑一下
  1. 思考题:这个游戏用到了哪些本学期知识点?在练习本上列一张清单,标出每个知识点在代码里的位置。
  2. 想一想:如果想让玩家输错选项(比如输入 5)时不退出、而是重新选,该怎么做?(提示:while True + continue,第 10 课学过。)
👉 下节课预告:恭喜完成小学三年级上学期 Python 课程!下学期将进入《6年Python+AI精英培养课程》第02章「数据集合与函数封装」——正式学习列表、字典和真正的函数,做出更厉害的程序!