当前位置:首页>python>从零开始:我用纯 Python 写了一个文字 RPG 游戏

从零开始:我用纯 Python 写了一个文字 RPG 游戏

  • 2026-10-11 05:39:42
从零开始:我用纯 Python 写了一个文字 RPG 游戏

从零开始:我用纯 Python
写了一个文字 RPG 游戏

零外部依赖 · 2400 行代码 · 7 张地图 · 5 个主线任务

Python 3.14tkinter零依赖回合制战斗数据驱动

📖 本文目录

一、缘起:为什么要用纯 Python 写游戏?
二、沉浸式剧情体验(含截图)
三、游戏架构深度解析
四、数据驱动设计——把游戏内容写成配置文件
五、回合制战斗系统(含截图)
六、地图系统——从 txt 文件到开放世界
七、技术实现亮点
八、完整游戏内容一览
九、扩展与展望
结语

一、缘起:为什么要用纯 Python 写游戏?

作为一个从小玩着《仙剑奇侠传》《轩辕剑》长大的一代,我一直对 RPG 游戏有着特殊的情结。那些仗剑走天涯的江湖梦、扣人心弦的剧情线、在迷宫中探索的紧张感——这些体验塑造了我对游戏的审美。

工作后,我成了一名 Python 开发者。某天深夜,一个念头突然冒了出来:能不能用 Python 标准库,从零写一个完整的 RPG?不用 Pygame,不用 Unity,不用任何第三方依赖——就用 Python 自带的 tkinter,能做成什么样?

这个项目的核心信条:零外部依赖,只靠 Python 标准库。不是做不到,而是想看看 Python 标准库的边界在哪里。

项目名称叫 WordRpg,中文名"我之传说"——既是"文字 RPG"的谐音,也寓意每个玩家在游戏中书写自己的传说。

0

外部依赖

2,400

源码行数

17

Python 文件

7

互联地图

12+3

敌人与 Boss

5

主线任务

💡 技术选型:Python 3.14 + tkinter + dataclasses + random。仅此而已,四个标准库模块撑起一个完整 RPG。

✦ ✦ ✦

二、沉浸式剧情体验

RPG 的灵魂在于故事。WordRpg 设计了 7 个性格鲜明的 NPC,每个 NPC 拥有多段对话——根据玩家当前的任务进度动态切换。这种上下文感知的对话系统让游戏世界显得真实而生动。

▲ NPC对话界面—对话内容随任务进展动态变化

村庄中的 NPC 各司其职:老村长指引剧情方向、公会会长发布任务、铁匠和药铺提供装备与补给。当玩家完成某个任务后再去对话,NPC 的台词会自然过渡到下一阶段,营造出"世界在变化"的沉浸感。

对话状态机设计:每个 NPC 持有一组按 quest state 索引的对话段(unavailable / active / done / completed),引擎自动匹配当前最合适的对话。只需一份数据字典,无需 if-else 硬编码。

✦ ✦ ✦

三、游戏架构深度解析

分层设计——逻辑与界面彻底分离

很多人写 GUI 程序容易犯的一个错误是把界面代码和业务逻辑混在一起。WordRpg 从第一天起就严格执行分层架构:

wordRpg/
├── main.py
├── config.py
│
├── game/
│   ├── engine.py
│   ├── player.py
│   ├── combat.py
│   ├── classes.py
│   ├── enemy.py
│   ├── quest.py
│   ├── shop.py
│   ├── npc.py
│   ├── map_.py
│   └── map_manager.py
│
├── ui/
│   ├── main_window.py
│   ├── title_screen.py
│   ├── game_view.py
│   ├── combat_view.py
│   ├── dialog_view.py
│   └── shop_view.py
│
└── assets/maps/

关键约束:game/ 目录下不允许出现任何 import tkinter。这意味着整个游戏逻辑是纯 Python 数据结构,可以用单元测试直接验证,也可以在将来替换为其他 GUI 框架。

main.py——7 行代码的启动哲学

整个应用的入口只有极少的有效代码,却完成了从窗口创建到游戏启动的全部编排:

main.py (完整文件 20 行)

def main():
    root = MainWindow()
    engine = Engine(root)
    root.engine = engine
    engine.build_scenes()
    root.switch_to("title")
    root.mainloop()

这里运用了依赖注入和组合模式:Engine 不负责创建 MainWindow,MainWindow 也不负责创建 Engine——它们在 main() 中完成组装,彼此通过接口协作。

场景切换——60 行实现完整路由

游戏包含 5  个场景(标题、主游戏、战斗、对话、商店),切换逻辑精炼在一个方法中。每个场景是 tk.Frame 子类,拥有统一的 on_enter()  生命周期钩子。切换时引擎销毁当前场景、挂载目标场景、触发钩子——就像现代前端框架(Vue/React)的路由机制,只不过我们用的是 1999  年的 tkinter。

config.py——单一配置源的威力

把所有可调参数放进一个文件,是保持项目健康度的关键决策:

配置类别
内容
窗口尺寸
1100x720
瓦片属性
11 种瓦片的行走性、颜色、中文名、遇敌率
颜色系统
17 种主题色:深蓝底色 + 金色高亮
升级公式
全部成长曲线(EXP/HP/MP/ATK/DEF/SPD)
字体体系
5 级字号,统一使用微软雅黑

设计师友好:想调整遇敌率?改一个数字。想换配色?改 17 行颜色值。想调升级曲线?改 5 个常量。一切都集中在一个文件中,无需翻找分散的逻辑代码。

✦ ✦ ✦

四、数据驱动设计——把游戏内容写成配置文件

WordRpg 最核心的设计思想是数据驱动。游戏中的每一个实体——职业、技能、敌人、任务、商品、NPC 对话——都是用 Python 字典或 dataclass 声明的纯粹数据,与运行逻辑完全分离。

  • 添加新内容无需改代码:往字典里加一条数据即可
  • 内容可以独立维护:策划人员可以独立编辑数据文件
  • 逻辑可复用:一套战斗引擎,驱动所有敌人和技能

职业与技能

三个职业各自拥有 3 个专属技能,全部定义在一个字典中。添加新职业只需加一条数据条目。

敌人与 Boss

12 种普通敌人 + 3 个 Boss,属性、等级范围、所属地图全部声明式定义。战斗引擎读取数据结构驱动战斗逻辑。

对话状态机——NPC 的"记忆"

NPC 的对话不再是一成不变的复读机。每个 NPC 的 dialogues 按任务状态分组,随着玩家推进任务,对话自动升级。

数据驱动 vs. 硬编码:如果要用传统 if-else 方式实现同样的 NPC 对话逻辑,7 个 NPC x 5 个对话状态 x 分支条件,代码量将膨胀 3~5 倍。数据字典将复杂度从"控制流"降级为"查表"。

✦ ✦ ✦

五、回合制战斗系统

战斗是 RPG 的核心玩法之一。WordRpg 实现了完整的回合制战斗系统,支持攻击、技能、防御、逃跑四种行动,以及完整的 Buff 管理和技能冷却机制。

▲ 回合制战斗——HP 条、战斗日志、技能选择

战斗流程

玩家回合:
     攻击 - 伤害 = max(1, atk - enemy.def/2 +/- random)
     技能 - 消耗 MP,触发效果,有冷却
     防御 - 获得 defend_up Buff
     逃跑 - 概率 = player.spd / (player.spd + enemy.spd)

     敌人回合:反击 - 同等伤害公式

     回合结算:_tick_buffs() + tick_cooldowns()

3 个职业 x 3 个技能 = 9 种独特技能效果,通过统一的效果标识符调度,添加新技能无需新增分支逻辑。

设计心得:把"效果"抽象为字符串标识("attack_up"、"heal"),战斗引擎只负责解析效果标识并执行对应逻辑。添加一个新技能 = 定义效果标识 + 配数值。不开新分支,不写新函数。

✦ ✦ ✦

六、地图系统——从 txt 文件到开放世界

WordRpg 的地图系统可能是最有趣的部分——每张地图就是一个纯文本文件,用中文字符画出来的。

七大区域

区域
等级
特色
风息村
安全区
NPC 聚集、商店、泉水
绿地平原
Lv 1-2
新手练级区
幽暗森林
Lv 3
高遇敌率
炙热沙漠
Lv 4-5
沙地减速
镜月湖畔
Lv 4-5
Boss 隐士
冰晶峡谷
Lv 6-8
雪地滑行
远古遗迹
Lv 8-12
最终 Boss

用字符画地图

每张地图是一个 22 行 x 35 列的 .map 文件,使用单中文字符标记瓦片类型。

游戏瓦片图例子:

草地(遇敌率 8%) 墙壁 小路(遇敌率 2%) 传送阵 泉水(满血复活)
店 公 宿 药 老 卫 = NPC 和商店标记

✦ ✦ ✦

渐进解锁与传送网络

游戏世界不是一开始就全部开放的。玩家必须击败特定 Boss 才能解锁下一区域。地图之间通过传送阵实现双向传送,配置由 PORTAL_MAP 字典管理。

✦ ✦ ✦

七、技术实现亮点

数据流:单向绑定
视图层只读 Engine 的状态,所有修改通过 Engine 暴露的方法完成。UI 从不直接修改 Player/MapManager,状态变化可追踪可预测。
装备聚合模型
玩家属性 = 基础属性 + 装备加成。total_atk 等属性实时聚合,换装即生效。
加权随机遇敌
基于瓦片 encounter_rate + 敌人级别加权随机,不会出现新手区遇 Boss 的情况。
纯 Canvas 像素风渲染
tkinter Canvas 逐格绘制,24x24px 每格。颜色字体全部由 config.py 控制,换皮肤只需改颜色常量。

✦ ✦ ✦

八、完整游戏内容一览

类别
数量
详情
职业
3
战士 射手 法师
技能
9
每职业 3 个,含伤害/治疗/Buff
普通敌人
12
史莱姆、哥布林、狼、蝙蝠、骷髅...
Boss
3
森林巨魔、冰晶守护者、遗迹魔王
主线任务
5
从"初出茅庐"到"遗迹之谜"
NPC
7
村长、公会会长、铁匠、旅店老板...
商店
3
铁匠铺、旅店、药铺
地图区域
7
从风息村到远古遗迹

游戏操作

按键
功能
W A S D
上下左右移动
E
交互(对话/商店/关闭)
Q
查看任务日志
I
查看背包

✦ ✦ ✦

九、扩展与展望

存档/读档系统
使用 json 或 shelve 序列化玩家状态,支持多存档位。
单元测试覆盖
game/ 层是纯逻辑,非常适合用 pytest 做全面测试。
地图编辑器
可视化拖拽生成 .map 文件,现在全靠手写 :)
音效与动画
增加音效反馈和战斗动画效果。
打包分发
PyInstaller 打包为单文件 exe,让不装 Python 的朋友也能玩。
Web 移植
game/ 层不含 GUI 代码,理论上可替换前端为 HTML5 Canvas。

✦ ✦ ✦

结语

写 WordRpg 这段经历让我重新认识了一个道理:限制往往是创造力的催化剂。

零外部依赖的约束,迫使我更深入地思考 Python 标准库的能力边界;不用 Pygame 等成熟框架,反而让我对游戏引擎的底层设计有了更深刻的理解——场景管理、状态机、数据驱动、事件路由,这些概念在任何规模的游戏中都是相通的。

如果你对这份代码感兴趣,不妨也试试用纯标准库做个什么项目。你可能会惊讶于 Python 标准库的强大——2400 行代码,零依赖,一个完整的 RPG 世界。

python main.p

如果你喜欢这篇文章,欢迎点赞、在看、转发
也欢迎在评论区交流你的纯 Python 项目经验

下载源码和游戏:搜索公众号 “码来的小朋友 ”,并且输入 “02我之传说”

最新文章

随机文章