用 Python 做一个「中文脚本 + Qt 界面 + SDL 渲染」的小游戏引擎:HappyQQ Game Maker 入门与实战
更新时间:2025-08-11
你为什么要读这篇文章?
如果你:
-
想用中文写几句“在屏幕画一个红色矩形”就能跑起来; -
想把 SDL 的高性能渲染塞进 PySide6 的窗口里; -
想让 Lua 脚本随时调用你准备好的绘图 API; -
想把整个工程一键打包成 Windows 下的 EXE;
那么 HappyQQ Game Maker(下文简称 hqqgm)这个骨架项目刚好能帮你起步。它不是商业级引擎,而是一份“看得懂、改得动、能打包”的教学示例。
1. 项目到底是什么?
一句话:
hqqgm = PySide6 主窗口 + SDL3 渲染区 + Lua 逻辑 + 中文脚本解释器 + PyInstaller 打包示例。
模块 | 作用 | 对应文件 |
---|---|---|
Qt 应用 | 创建主窗口、菜单、按钮 | app.py |
SDL 嵌入 | 把 Qt 子窗口句柄交给 SDL 渲染 | sdl_embed.py |
Lua 桥接 | 把 Python 函数暴露给 Lua | lua_bridge.py |
中文解释器 | 把“清屏蓝色”翻译成 Python 调用 | mini_interpreter.py |
资源目录 | 存放图片、字体等 | assets/ |
2. 五分钟跑起来
先确保你用的是 Python 3.11(3.10 也行,3.9 以下没试过)。
2.1 安装
# Windows PowerShell
py -3.11 -m venv .venv
. .venv\Scripts\Activate.ps1
python -m pip install -U pip
pip install -e .
说明
-e .
会把当前目录以「可编辑」模式装进虚拟环境,后续改代码不用重装。
2.2 运行默认示例
python -m hqqgm
第一次启动会看到一个带黑框的 Qt 窗口,标题栏实时显示 FPS,按 Esc 直接退出。
2.3 跑中文脚本演示
python -m hqqgm --demo-interpreter
你会看到控制台里逐行解释并执行中文指令,例如:
清屏蓝色
画矩形 100 100 200 200 红色
2.4 把中文脚本编译成 Python
python -m hqqgm --compile .\example.cn.txt --out .\example.gen.py
生成的 example.gen.py
里会有一个 run(api)
函数,你可以:
-
在 IDE 里直接运行; -
随主程序一起打包; -
发给不会 Python 的同事,他只改中文脚本即可。
3. 目录结构深度解读
src/
└── hqqgm/
├── __init__.py
├── __main__.py # 命令行入口,支持 --demo-interpreter 等参数
├── app.py # Qt 侧:主窗口、菜单、信号槽
├── sdl_embed.py # SDL 侧:窗口句柄、Renderer、纹理缓存
├── lua_bridge.py # Lua 侧:Runtime、API 注册、错误处理
├── mini_interpreter.py # 中文解析:分词 → 语法树 → Python 代码
└── assets/ # 放图片、ttf、wav,代码里用相对路径读取
小技巧
在assets/
里建子目录fonts
、images
、sounds
,代码里统一用Path(__file__).with_suffix('') / "assets" / ...
读取,打包时 PyInstaller 能自动收集。
4. SDL 如何嵌进 Qt?技术拆解
4.1 核心思路
Qt 负责窗口和事件循环;SDL 只做渲染。
具体做法:
-
在 Qt 里放一个 QWidget
(例如SdlWidget
)。 -
拿到该控件的 WinId(Windows 下是 HWND,X11 下是 Window)。 -
调用 SDL_CreateWindowFrom(void * winId)
,把原生窗口句柄包装成 SDL 窗口。 -
再 SDL_CreateRenderer
,之后正常SDL_RenderPresent
。
4.2 关键代码片段(伪代码)
# sdl_embed.py
from PySide6.QtCore import QTimer
import sdl3 as sdl
class SdlWidget(QWidget):
def __init__(self):
super().__init__()
self.setAttribute(Qt.WA_OpaquePaintEvent)
self.timer = QTimer(self)
self.timer.timeout.connect(self.render)
def showEvent(self, event):
self.sdl_window = sdl.SDL_CreateWindowFrom(int(self.winId()))
self.renderer = sdl.SDL_CreateRenderer(self.sdl_window, None, 0)
self.timer.start(16) # 约 60 FPS
def render(self):
sdl.SDL_SetRenderDrawColor(self.renderer, 0, 0, 0, 255)
sdl.SDL_RenderClear(self.renderer)
# 这里调用 Lua 或解释器产生的绘图命令
sdl.SDL_RenderPresent(self.renderer)
注意
在 macOS 上需要NSView
而非NSWindow
,代码需#ifdef Q_OS_MAC
。示例仓库目前只演示 Windows。
5. Lua 与 Python 如何互通?
5.1 安装 lupa
pip install lupa
5.2 注册 API
# lua_bridge.py
from lupa import LuaRuntime
lua = LuaRuntime(unpack_returned_tuples=True)
def draw_rect(x, y, w, h, color):
# 真正调用 SDL 绘图
...
lua.globals()['draw_rect'] = draw_rect
5.3 Lua 脚本示例
-- game.lua
draw_rect(50, 50, 100, 100, "red")
运行:
with open("game.lua") as f:
lua.execute(f.read())
6. 中文脚本解释器怎么工作?
6.1 设计目标
让不会 Python 的人也能写逻辑:
循环 100 次
清屏黑色
画圆 随机位置 半径=5 颜色=随机
延迟 16
结束
6.2 翻译流程
-
分词:按空格、换行、标点切词。 -
语法:目前只支持“动词 + 参数”的结构。 -
生成:把“画圆”翻译成 api.draw_circle(...)
。
6.3 实际效果
中文指令 | 生成 Python |
---|---|
清屏蓝色 | api.clear(color="blue") |
画矩形 10 20 30 40 红色 | api.draw_rect(10,20,30,40,color="red") |
7. 打包成 EXE:一步搞定
7.1 PyInstaller 方法
pip install pyinstaller
pyinstaller -F -w -n HappyQQGameMaker src/hqqgm/__main__.py
参数解释:
-
-F
单文件; -
-w
不弹出终端; -
-n
生成的 exe 名称。
7.2 常见坑
问题 | 解决 |
---|---|
SDL 动态库找不到 | 在 pyinstaller 命令后加 --add-binary "path_to_sdl3.dll;." |
Qt 插件缺失 | 用 pyinstaller --onedir 先测试,再根据需要精简 |
路径写死 | 用 sys._MEIPASS 判断运行环境是否为打包后 |
8. FAQ:你可能想问的 10 个问题
问题 | 回答 |
---|---|
能在 Linux/macOS 跑吗? | 逻辑代码可以,SDL 嵌入部分需改窗口句柄获取方式。 |
Python 3.9 行不行? | 没试过,建议 3.10+。 |
能加载图片吗? | 可以,SDL_image 扩展已适配,示例未演示。 |
中文脚本能做 if/else 吗? | 目前仅支持顺序+循环,分支语法待扩展。 |
Lua 能调用 Qt 的信号吗? | 通过 lua.globals() 注入 Python 函数即可。 |
能嵌入网页吗? | 思路一样,把 QWebEngineView 当控件即可。 |
性能如何? | 60 FPS 画几千个矩形无压力,复杂场景需批处理。 |
可以商用吗? | MIT 许可证,随便用,记得保留版权声明。 |
有调试器吗? | 用 VSCode 打断点即可,SDL 渲染线程注意线程安全。 |
能打包成安卓吗? | 需要 Qt for Android + SDL Android 模板,工作量较大。 |
9. 下一步可以做什么?
-
完善中文语法:支持变量、函数、事件监听。 -
热重载:文件改动后自动重新解释并执行。 -
场景树:像 Godot 那样节点式管理精灵。 -
音频模块:SDL_mixer 直接对接 Lua。 -
可视化编辑器:拖拽节点自动生成中文脚本。
10. 小结
HappyQQ Game Maker 不是让你“一周做出原神”,而是告诉你:
-
SDL 与 Qt 可以共存,窗口句柄就是桥梁; -
Lua 与 Python 互通只需 lupa; -
中文脚本解释器其实就是“翻译官”,技术难度不高,体验提升巨大; -
打包成 EXE 只需一条 PyInstaller 命令,真正的门槛是路径管理。
把这份骨架克隆下来,删掉你不想要的,加上你需要的,就能变成自己的工具。祝你玩得开心,写游戏也开心。
(完)