Skip to content

FishCodeTech/ShenRen-Fight

Repository files navigation

Angry Guy vs Tired Guy - Pygame Auto Battle

一个开箱即用的竖屏短视频风格 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.png
  • assets/tired.png
  • assets/hand.png
  • assets/thumb.png

缺少任意图片时,游戏会继续使用对应的自动生成占位图。

状态立绘会优先从 assets/portraits/ 加载:

  • angry_idle.png
  • angry_rage.png
  • angry_low_hp.png
  • tired_idle.png
  • tired_heal_sleep.png
  • tired_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"]

新增技能

  1. 新建 plugins/my_skill.py
  2. 继承 game.skills.BaseSkill
  3. 实现 can_cast()cast()
  4. register(registry) 中注册
  5. 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.BaseSkill
  • game.effects.BaseEffect
  • game.projectiles.BaseProjectile
  • game.statuses.BaseStatus
  • game.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

About

神人大乱斗 skills

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages