mcpField
G
godot-2d-gameplay

godot-2d-gameplay

github.com/pbzona开发248 次安装15 周前更新
代码仓库

关于 godot-2d-gameplay

godot-2d-gameplay 是在 Godot 项目既有规范内实现 2D 玩法的技能,面向开发移动、物理和战斗系统的开发者。它要求先检查项目,再按实际场景设计并验证,而非直接照搬代码片段。

主要功能

  1. 01检查 Godot 版本和项目配置
  2. 02沿用现有场景与输入规范
  3. 03按玩法职责选择物理节点
  4. 04构建移动与战斗交互
  5. 05验证碰撞、伤害和性能边界
  6. 06排查常见的 2D 玩法故障

适用场景

  1. 01实现平台跳跃或俯视角角色控制
  2. 02添加基于碰撞的攻击与伤害
  3. 03调试 TileMap 碰撞位置偏差
  4. 04检查不同物理条件下的玩法表现

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pbzona/godot-skills --skill godot-2d-gameplay

安装后在 Claude Code 中输入/godot-2d-gameplay确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
animation-combat-game-feel.md
movement-physics-tilemaps.md
verification-and-troubleshooting.md

详细介绍

Godot 2D 游戏玩法

在项目现有的场景、输入、物理和组件约定中实现游戏玩法。将代码片段视为可调整的模式,而不是可以原样粘贴的文件。

从项目现状着手

在提出节点或代码之前:

  1. 找到最近的 project.godot。读取 config/features;如果有可用的 Godot 可执行文件,则通过 godot --version 或项目文档中指定的二进制文件确认版本。
  2. 检查 application/run/main_scene、[input]、已命名的 2D 物理层、物理帧率、默认重力、窗口/拉伸设置和纹理过滤。
  3. 搜索现有的 .gd、.tscn 和 .tres 文件,查找玩家物体、TileMap 或 TileMapLayer、动画节点、伤害 API、组、自动加载项和测试工具。
  4. 沿用现有的节点名称、类型化脚本风格、信号命名、场景所有权和碰撞约定。
  5. 不要只为匹配示例而迁移可正常工作的 TileMap。对于新内容,仅当检查到的 Godot 版本支持 TileMapLayer 时才优先使用它。

如果不存在项目文件,请先询问目标 Godot 4.x 次要版本和最简场景约定,再生成特定于项目的文件。

选择物理控制方

  • 对于需要与世界碰撞并滑动的代码驱动角色,使用 CharacterBody2D。平台游戏使用贴地运动,俯视角角色使用浮空运动。
  • 对于由模拟驱动的对象,使用 RigidBody2D。离散撞击使用冲量,持续加速使用力;不要每帧覆盖其变换。
  • 对于脚本驱动、需要可预测地传递运动的平台和危险物,使用 AnimatableBody2D。
  • 对于仅检测重叠的传感器、拾取物、受击框和大多数简单弹体,使用 Area2D。它不提供扫掠式物体碰撞。
  • 在 _physics_process() 中处理物理移动和查询。除非必须与物理结果完全同步,否则在 _process() 中更新表现效果。

实现工作流

  1. 用可衡量的指标定义行为。 记录速度、加速度、停止距离、跳跃高度或滞空时间、攻击频率、无敌时间以及预期的碰撞对象。
  2. 先创建输入。 重用语义化的 Input Map 动作。绝不要在角色逻辑中硬编码按键。若同时支持键盘和控制器,请检查死区。
  3. 搭建灰盒物理场景。 在添加美术、动画、摄像机或战斗前,先使用基础碰撞形状和平面地板。
  4. 实现一种移动模式。 速度以像素/秒为单位;CharacterBody2D.move_and_slide() 会在内部应用物理时间步长。
  5. 分层构建世界。 根据实际职责,将地面、带碰撞的地形、装饰、前景和导航分开。
  6. 根据游戏状态驱动视觉效果。 在移动后选择动画,并避免动画轨道覆盖权威物理变换。
  7. 将战斗实现为明确的交互。 为攻击、受击框、生命值、阵营、冷却时间和死亡分别定义约定。使用信号提供反馈。
  8. 最后再加入游戏手感效果。 围绕已确认的事件叠加清晰易读的效果;绝不要用屏幕抖动或动画掩盖不可靠的碰撞。
  9. 在边界情况和高负载下验证。 测试斜坡、拐角、低天花板、同时受击、场景重载、对象池复用,以及预期的最高角色/弹体数量。

类型化平台游戏核心

此控制器使用基于速率的加速度、跳跃缓冲、土狼时间和短跳松键机制。请根据项目的比例调整数值。

extends CharacterBody2D

@export_range(0.0, 2000.0, 1.0) var run_speed: float = 260.0
@export_range(0.0, 10000.0, 1.0) var ground_accel: float = 2200.0
@export_range(0.0, 10000.0, 1.0) var air_accel: float = 900.0
@export_range(0.0, 10000.0, 1.0) var gravity: float = 1800.0
@export_range(0.0, 5000.0, 1.0) var jump_speed: float = 560.0
@export_range(0.0, 5000.0, 1.0) var max_fall_speed: float = 1100.0
@export_range(0.0, 0.5, 0.01) var coyote_time: float = 0.10
@export_range(0.0, 0.5, 0.01) var jump_buffer_time: float = 0.12

var _coyote_left: float = 0.0
var _jump_buffer_left: float = 0.0

func _physics_process(delta: float) -> void:
    if Input.is_action_just_pressed(&"jump"):
        _jump_buffer_left = jump_buffer_time
    else:
        _jump_buffer_left = maxf(_jump_buffer_left - delta, 0.0)

    var axis: float = Input.get_axis(&"move_left", &"move_right")
    var accel: float = ground_accel if is_on_floor() else air_accel
    velocity.x = move_toward(velocity.x, axis * run_speed, accel * delta)

    if is_on_floor():
        _coyote_left = coyote_time
    else:
        _coyote_left = maxf(_coyote_left - delta, 0.0)
        velocity.y = minf(velocity.y + gravity * delta, max_fall_speed)

    if _jump_buffer_left > 0.0 and _coyote_left > 0.0:
        velocity.y = -jump_speed
        _jump_buffer_left = 0.0
        _coyote_left = 0.0

    if Input.is_action_just_released(&"jump") and velocity.y < 0.0:
        velocity.y *= 0.45

    move_and_slide()

在调用 move_and_slide() 前,不要将 velocity 乘以 delta。如果必须精确控制跳跃高度,请根据目标高度和到达顶点所需时间推导重力和起跳速度,而不是分别调整两者。

设计规则

  • 为了保证可玩性,碰撞尺寸应依据实际碰撞需求设定,而不是精灵图的透明区域。保持角色脚部稳定,并适当放宽战斗受击框。
  • 将碰撞层视为接口。为每个图层命名,并记录哪些遮罩会使用它。
  • 仅在语义状态变化时切换动画。空中状态和动作状态的优先级应高于待机/奔跑状态。
  • 只在权威接收方处应用一次伤害。反馈监听器可以闪烁、抖动、生成粒子、更新 UI 或播放音频,但不得再次造成伤害。
  • 冷却时间应使用计时器或累积游戏时间增量。墙上时钟时间戳不会自然遵循暂停或时间缩放。
  • 仅在性能分析或规模确有需要时才使用对象池。池化节点需要明确的生成/回收重置逻辑,处理计时器、监控状态、速度、所有权和处理状态;仅设置可见性并不算完整的生命周期管理。

验证门槛

完成前:

  • 运行仓库现有的测试命令;如果有兼容的 Godot 二进制文件,还要运行无头解析/导入检查。
  • 确认所有引用的 Input Map 操作都已存在。
  • 启用可见碰撞形状,并在运行中的场景里检查瓦片碰撞、物体形状和 Area2D 遮罩。
  • 验证在已配置的物理帧率下,以及窗口或摄像机缩放发生变化后,移动是否正常。
  • 验证伤害值会被限制、死亡信号只发出一次、不会攻击友方目标,并且无敌状态不会永久持续。
  • 对于对象池,观察 Remote 场景树和性能分析器:对象数量应趋于稳定,复用对象的行为应与全新实例一致。
  • 报告已更改的文件、已测试的场景、运行的命令,以及因缺少资源或 Godot 可执行文件而无法完成的检查。

常见故障模式

  • **俯视角斜向移动更快:**使用 Input.get_vector() 或限制向量长度。
  • **角色速度随帧率变化:**在物理处理过程中进行移动,并且只在计算速率时使用 delta,不要将其用于最终的 CharacterBody 速度。
  • **楼层状态始终为 false:**检查 up_direction、运动模式、遮罩、碰撞形状,以及 move_and_slide() 调用前后的顺序。
  • **瓦片碰撞看起来有偏移:**对比 TileSet 瓦片尺寸、图集区域尺寸、图层变换和碰撞多边形。
  • **动画闪烁:**多个分支调用了 play(),或状态优先级不明确。先确定唯一状态,再应用一次。
  • **一次攻击造成多次命中:**禁用或消耗命中框、跟踪每次激活时被击中的目标,或添加接收方无敌状态。
  • **快速子弹穿透目标:**使用扫掠物体/射线查询、缩短物理移动距离,或改用形状投射,而不要依赖最终位置的重叠检测。
  • **抖动后摄像机未复位:**让偏移量逐渐衰减至零,并在效果结束时明确重置偏移量。

参考资料

评论

支持 Markdown