本文介绍如何安装 PySTG、运行游戏、打开关卡编辑器,以及编写第一份弹幕脚本。
- Python 3.10 或更高版本。当前验证的版本是 Python 3.12。
- 支持 OpenGL 3.3 或更高版本的显卡。
- Windows 或 Linux。macOS 未验证。
git clone https://github.com/qwqpap/PythonSTG.git
cd PythonSTG
python -m pip install -r requirements.txtrequirements.txt 锁定一组互相兼容的版本,其中 numpy==1.26.4 和 numba==0.60.0 必须成对升级。只升级其中一个时,Numba 会报告 Numba needs NumPy x.x or less。
关卡编辑器、独立资产工具和开发脚本需要额外的依赖项:
python -m pip install -r requirements-dev.txt
python -m pip install -e .关卡编辑器以声明式 Python 为唯一真源,不打开旧 Scene/Pattern JSON。阶段进度和剩余验收见代码驱动编辑器实施 TODO。纹理、自机、敌人、背景、对话和 UI 等独立工具见编辑器工具指南。
在存储库根目录运行 python main.py。
python main.py # 默认 Stage 1
python main.py --stage=stage2 # 从指定关卡开始,可取 stage1、stage2、stage3
python main.py --stage=asset_preview # 资产预览:浏览所有弹型和敌人
python main.py --debug # 调试模式:菜单可跳转到任意波次、Boss 或符卡
python main.py --profile # 输出前 120 帧的逐帧耗时
python main.py --help # 列出全部选项--debug 是开发期最常用的开关:标记 DEBUG_BOOKMARK = True 的波次和符卡会出现在跳转菜单中,不需要每次从头打到 Boss。
安装开发依赖项后,在存储库根目录运行:
pystg-editor game_content/authoring/code_editor_democode_editor_demo 是可编辑的作者工程。试用时先复制到 game_content/authoring/ 下的新目录,再把命令参数换成副本路径。编辑器不会反向解析 game_content/stages/ 下的手写关卡。
打开工程后,从开始 Stage 查看引用的波次、敌人和 Boss。在程序流中选择节点,然后在 Inspector 中修改参数。只有在 运行 菜单中选择 运行当前单元(F5)、运行整个工程 或 运行当前关卡 时,编辑器才会保存、构建并启动真实游戏预览。预览运行期间修改源码后,状态栏显示“源码已改,需重新运行”。保存后重开、Undo/Redo 和完整创作流程的验收要求见 TODO;启动成功本身不代表这些验收通过。
生成文件位于 game_content/generated/<project_id>/,可以重新构建,不要手工修改或提交。
flowchart TB
root["PySTG"]
main["main.py<br/>游戏入口"]
src["src/<br/>引擎与编辑器代码"]
gameContent["game_content/stages/<br/>手写关卡内容"]
authoring["game_content/authoring/<br/>声明式作者工程"]
assets["assets/<br/>全局资源"]
tools["tools/<br/>独立资产工具与校验脚本"]
docs["docs/<br/>文档"]
root --> main
root --> src
root --> gameContent
root --> authoring
root --> assets
root --> tools
root --> docs
src --> core["core:配置、碰撞、窗口、输入"]
src --> game["game:子弹、关卡、玩家、Boss、激光、道具、音频"]
src --> render["render:渲染管线"]
src --> resource["resource:纹理和精灵管理"]
src --> ui["ui:HUD、菜单、对话框"]
gameContent --> stage1["stage1:完整参考实现"]
gameContent --> stage23["stage2 / stage3:波次、Boss 与对白"]
gameContent --> stageTest["stage_test:测试关"]
PySTG 把引擎和内容分开:
src/是引擎,提供子弹池、渲染、碰撞、激光和音频等底层能力。game_content/是内容,只描述发生什么:弹幕怎么飞、敌人怎么动、Boss 出什么招。
手写运行时脚本使用以下基类;声明式编辑器工程使用 src.authoring.dsl,两者目录和语法不同:
from src.game.stage.spellcard import SpellCard, NonSpell # 符卡 / 非符
from src.game.stage.wave_base import Wave # 道中波次
from src.game.stage.enemy_script import EnemyScript # 敌人脚本
from src.game.stage.stage_base import StageScript, BossDef # 整面流程
from src.game.stage.boss_base import nonspell, spellcard # Boss 阶段组合这些类通过 self.fire()、self.wait(N) 和 self.ctx 调用引擎,不直接导入引擎内部模块。
class MySpell(SpellCard):
name = "火符「示例」"
hp = 1000
time_limit = 45
async def run(self):
angle = 0
while True:
self.fire_circle(count=12, speed=2.0, start_angle=angle, color="red")
angle += 10
await self.wait(15) # 暂停 15 帧(约 0.25 秒)await self.wait(N) 让协程暂停 N 帧,引擎每帧推进一步。这是 PySTG 弹幕脚本的核心模式。
完整 API 见弹幕脚本开发指南。
| 路径 | 作用 |
|---|---|
game_content/stages/stage1/__init__.py |
关卡包入口 |
game_content/stages/stage1/stage_script.py |
整面流程,必需 |
game_content/stages/stage1/waves/ |
道中波次,例如 opening_wave.py、fairy_wave.py |
game_content/stages/stage1/spellcards/ |
Boss 符卡,例如 nonspell_1.py、spell_2.py |
game_content/stages/stage1/enemies/ |
可复用敌人定义 |
game_content/stages/stage1/dialogue/ |
对话脚本 |
game_content/stages/stage1/audio/ |
关卡私有音频,可覆盖全局同名音效 |
game_content/stages/stage1/images/ |
关卡私有图片资源 |
stage_script.py 控制整个关卡的流程:
class Stage1(StageScript):
id = "stage1"
name = "Stage 1"
bgm = "00.wav"
boss_bgm = "01.wav"
async def run(self):
await self.run_wave(OpeningWave) # 道中波次
await self.run_wave(FairyWave)
await self.play_dialogue([ # Boss 前对话
("Hinanawi_Tenshi", "left", "准备好了吗?"),
("Reiuji_Utsuho", "right", "来吧!"),
])
await self.run_boss(self.boss) # Boss 战对话立绘渲染参数位于 assets/ui/dialog_portrait_layout.json,可以使用编辑器调整:
python tools/dialog/dialog_portrait_editor.py写内容时先参考 game_content/stages/stage1/ 下的现有脚本,这是当前最完整的实现样例。