一个开箱即用的竖屏短视频风格 Pygame 自动对战小游戏。默认不依赖任何外部素材:如果 assets/ 里没有图片,游戏会自动生成占位角色、手掌、点赞投射物和睡眠特效。
python -m pip install -r requirements.txt
python main.py要求 Python 3.10+。依赖只包含标准 pygame。
R: 立即重开Space: 暂停/继续F: 全屏切换Tab: 显示/隐藏 debug 面板M: 切换自动 AI 和手动模式G: 切换竞技场布局H: 显示接口/插件帮助1/2/3: Angry Guy 释放第 1/2/3 个技能8/9/0: Tired Guy 释放第 1/2/3 个技能W/A/S/D: 手动模式移动 Angry Guy方向键: 手动模式移动 Tired Guy
把自己的授权图片放进 assets/ 即可自动替换默认占位图:
assets/angry.pngassets/tired.pngassets/hand.pngassets/thumb.png
缺少任意图片时,游戏会继续使用对应的自动生成占位图。
状态立绘会优先从 assets/portraits/ 加载:
angry_idle.pngangry_rage.pngangry_low_hp.pngtired_idle.pngtired_heal_sleep.pngtired_counter_slow.png
Angry Guy 会在 Rage 和低血量时切换立绘;Tired Guy 会在回血/睡眠技能、受击反击时切换立绘。
游戏会在运行时合成简短音效,不需要额外音频文件。技能、受伤、回血、状态、碰墙反弹和 KO 都有声音。
可以在 configs/default_match.json 中调整:
"audio": {
"enabled": true,
"volume": 0.45
}如果当前系统没有可用音频设备,游戏会自动静音继续运行。
自动模式下角色采用老式 DVD 标志一样的反弹移动:保持方向在竞技场内弹跳,AI 只负责按节奏释放技能,不会直接朝敌人寻路。手动模式仍可用键盘移动角色做测试。
默认竞技场边界在世界坐标里固定不变,镜头会根据两个角色的距离缩放:靠近时放大,远离时缩小。边框作为世界物体参与镜头变换,不是固定贴在屏幕上的 UI 框。
"arena": {
"auto_switch_layouts": false
},
"camera": {
"close_zoom": 1.55,
"far_zoom": 0.78
}默认配置在 configs/default_match.json,可以调整窗口、竞技场颜色、角色血量、速度和技能列表。
示例:把插件技能 MeteorPunch 加给 Angry Guy:
"skills": ["SlapHand", "ThumbShot", "RageBurst", "MeteorPunch"]- 新建
plugins/my_skill.py - 继承
game.skills.BaseSkill - 实现
can_cast()和cast() - 在
register(registry)中注册 - 在
configs/default_match.json的角色skills列表中使用技能名
最小示例:
from game.skills import BaseSkill
from game.constants import RED
class BigBonk(BaseSkill):
def __init__(self):
super().__init__("BigBonk", cooldown=2.0, range=220, tags={"plugin"})
def can_cast(self, caster, target, world):
return super().can_cast(caster, target, world) and caster.position.distance_to(target.position) <= self.range
def cast(self, caster, target, world):
world.apply_damage(caster, target, 120, {"plugin", "bonk"})
world.spawn_floating_text("BONK", target.position + (0, -120), RED, 42)
world.play_screen_shake(12, 0.2)
def register(registry):
registry.register_skill("BigBonk", BigBonk)可扩展基类分布在这些模块:
game.skills.BaseSkillgame.effects.BaseEffectgame.projectiles.BaseProjectilegame.statuses.BaseStatusgame.registry.Registry
插件会自动扫描 plugins/*.py,每个插件只需要暴露 register(registry)。
world 提供常用 API:
spawn_effect(effect)spawn_projectile(projectile)spawn_floating_text(text, pos, color, size=None)apply_damage(source, target, amount, tags=None)apply_heal(source, target, amount)apply_status(source, target, status)play_screen_shake(amount, duration)query_enemies(caster)query_allies(caster)get_rng()schedule(delay, callback)emit(event_name, payload)
main.py
requirements.txt
README.md
configs/default_match.json
plugins/example_skills.py
assets/
game/
app.py
constants.py
audio.py
engine.py
scene.py
entities.py
components.py
skills.py
effects.py
projectiles.py
statuses.py
ui.py
registry.py
plugins.py
utils.py