今日速览

  • Godot 有 4 种碰撞体:Area2D(检测/感应)、StaticBody2D(静态环境)、RigidBody2D(物理模拟)、CharacterBody2D(代码控制移动),选错类型是新手最常见的坑。
  • 角色移动永远不要直接改 position,要用 move_and_collide()(碰撞即停)或 move_and_slide()(自动滑行),且必须写在 _physics_process() 里。
  • 物理以固定频率运行(默认 60Hz),与渲染帧率不同步,相关计算要传 delta,否则换设备就飘。
  • 碰撞体必须挂 CollisionShape2D 子节点才有碰撞;缩放形状要用尺寸手柄,别用 Scale 属性(会导致碰撞异常)。
  • 碰撞层(layer)表示”我在哪层”,掩码(mask)表示”我扫描哪些层”,共 32 层,可在项目设置里命名。

核心学习内容

1. 四大碰撞体怎么选

  • Area2D:只管”检测和影响”,不参与物理反弹。适合触发器:拾取金币、陷阱范围、敌人警戒区。通过 body_entered / body_exited 信号通知。
  • StaticBody2D:不动的环境物(墙壁、地板、平台),引擎不会让它动,但能挡住别人。
  • RigidBody2D:完整物理模拟,靠施加力(apply_impulse、重力)驱动,适合可推动的箱子、弹跳球。
  • CharacterBody2D:角色或需要精确操控的物体(移动平台、子弹)。引擎不管它,重力和移动全在代码里算,换来的是完全可控的手感——2D 平台跳跃游戏的主角几乎都用它。

判断口诀:会当障碍物 → StaticBody2D;只想要触发事件 → Area2D;要真实物理反馈 → RigidBody2D;要角色手感 → CharacterBody2D。

2. move_and_slide vs move_and_collide

  • move_and_collide(velocity * delta):沿向量移动,撞到就停,返回 KinematicCollision2D(能拿到碰撞法线、碰撞体),适合子弹反弹、精确判定。
  • move_and_slide():读取节点自带的 velocity 属性,自动处理贴墙滑行、落地归零垂直速度,配合 is_on_floor() / is_on_wall() 实现跳跃落地判定,平台跳跃和俯视角游戏的主力。
  • 关键配置:up_direction(哪边算地面,默认 (0,-1))、motion_mode(GROUNDED 区分地面/墙,FLOATING 全当墙)、floor_max_angle(45° 内算地板)。
  • 注意:官方强调 move_and_slide() 是 move_and_collide() 的特例,复杂需求(如自定义反弹)要用后者。

3. 碰撞层与掩码:让子弹不打自己人

这是 2D 物理里最强也最容易被忽略的功能。collision_layer = 我属于哪几层;collision_mask = 我会和哪些层发生碰撞。经典配置(官方示例):1=walls、2=player、3=enemies、4=coins;玩家 mask 勾 1/3/4(撞墙、撞敌人、捡金币),敌人和金币互不理会。层名在 项目设置 > Layer Names > 2D Physics 里起名,代码里用 set_collision_mask_value(3, true) 或 @export_flags_2d_physics 操作,比手算 16 进制位掩码直观得多。

4. 新手必踩的坑

  • 碰撞形状被 Scale 缩放 → 碰撞和视觉对不上,形状一律用尺寸手柄调整。
  • 物理代码写在 _process() 而不是 _physics_process() → 帧率不稳时手感飘忽、穿墙。
  • 直接改 CharacterBody2D 的 position → 会穿墙,必须走 move 系列方法。
  • 物理引擎不保证确定性:同场景两次运行结果可能不同,别把存档逻辑建立在物理结果上。

🎯 DeepSeek 提示词

① 生成平台跳跃角色脚本(最常用)

你是一名资深 Godot 4 游戏开发者。请用 GDScript 为我的 2D 平台跳跃游戏编写一个 CharacterBody2D 角色脚本,需求如下:
- 支持左右移动(速度 300 px/s)、跳跃(跳跃速度 500)、重力(980),均用 @export 暴露参数;
- 用 move_and_slide() 移动,支持 is_on_floor() 判断落地,只能在地面起跳;
- 附带输入映射说明(建议使用 ui_left/ui_right/ui_up 或自定义 action);
- 代码加中文注释,输出完整可直接粘贴到 Godot 4.2+ 的脚本。
约束:不要用 RigidBody2D,不要直接改 position,物理逻辑放 _physics_process。

使用说明:粘贴到角色的 GDScript 即得可跑的基础移动;想要冲刺、二段跳、 coyote time(土狼时间)等,在提示词里追加一句”加入 X 功能”即可迭代。

② 碰撞层方案设计

你是 Godot 物理系统专家。我的俯视角 2D 游戏里有:玩家、敌人、子弹、墙壁、可破坏箱子、触发机关的地板。请帮我:
1. 给出 2D Physics 碰撞层的分配表(第几层给谁用,共 32 层);
2. 列出每个对象的 collision_layer 和 collision_mask 应勾选的层(用层名表示);
3. 写一小段 GDScript 示例,演示在代码里用 set_collision_mask_value 动态开启"子弹可穿透箱子"的效果。
要求:敌人和敌人之间不能互相碰撞,子弹只撞墙壁和敌人,玩家子弹不误伤玩家。

使用说明:把”我的游戏有 X、Y、Z”换成你的实际对象清单,DeepSeek 会输出可直接照着配的层表 + 代码,省掉自己推位掩码的时间。

③ 碰撞 Bug 排查模板(debug 必备)

你是 Godot 4 调试专家。我的游戏出现这个 bug:玩家角色从高处落到地板上时偶尔会轻微抖动/陷进地板半格,跳到墙上时偶尔会卡住。相关代码:
{粘贴你的 _physics_process 代码}
我的 Physics 设置:默认 60Hz,地板是 StaticBody2D + RectangleShape2D。
请按以下格式回答:① 最可能的 3 个原因(按概率排序)② 每个原因对应的修复代码 ③ 如何用 print 或调试工具验证。

使用说明:把报错现象、代码、项目设置填进去,DeepSeek 会给出排好序的排查清单。遇到”穿墙、抖动、卡地形”这类问题直接套用,比盲目改参数高效。

学习心得

碰撞系统是”手感”的地基:选对碰撞体类型 + 用对移动方法 + 配好层掩码,平台跳跃和俯视角游戏的核心机制就立起来了。结合第 8 天的存档和第 8 天(第二篇)的手感优化,角色已经能”动得舒服、存得可靠”。对用 DeepSeek 做 Steam 游戏的目标来说,这套物理知识最大的价值是能看懂并验证 AI 生成的代码——提示词 ① 生成的脚本你拿到手,知道 move_and_slide 和层掩码的原理,就不会被 AI 代码牵着走,出 bug 也能用提示词 ③ 快速定位。

明日关注

  • RigidBody2D 物理:施加力、扭矩、物理材质(摩擦/弹性)怎么调出”有手感”的物理交互
  • Area2D 触发器实战:金币拾取 + 伤害区域 + 事件信号接线完整流程
  • 用 DeepSeek 生成一套”俯视角 8 方向移动 + 碰撞层”脚本,并亲自跑通验证

本文由自动化学习流水线每日生成,坚持即学即记。