示例工程【免费下载链接】godot-demo-projectsDemonstration and Template Projects项目地址https://gitcode.com/GitHub_Trending/go/godot-demo-projects点击查看免费下载导读本文以 2d/physics_platformer 官方演示项目为蓝本完整讲解如何用RigidBody2D刚体构建 2D 平台跳跃游戏的角色控制器。与常见的CharacterBody2D运动体方案不同刚体角色天然融入物理引擎可以实现跷跷板、骑乘敌人、被移动平台带动等真实交互代价是所有移动逻辑必须写在_integrate_forces()回调中手动修改刚体速度。读完本文你将掌握刚体角色控制器的参数体系、地板判定与速度传导、敌人 AI 与子弹交互、物理关卡搭建等完整实战方案并了解该项目在 project.godot 中的配套物理设置。项目概览一个完全基于物理的角色平台跳跃演示Physics Platformer项目名 Physics-Based Platformer 2D见 project.godot是 godot-demo-projects 仓库 2D 分类下的官方演示核心卖点正如其 README 所述玩家与敌人全部使用RigidBody2D动态角色控制器它们能完美地与物理交互——场景里有可踩踏的跷跷板seesaw玩家甚至可以跳到敌人头上骑着它移动。该演示使用 GDScript 编写渲染器为 Compatibilityrenderer/rendering_methodgl_compatibility关卡主场景为 stage.tscn窗口分辨率 800×480。场景中通过实例化instancing把 player/player.tscn、enemy/enemy.tscn、coin/coin.tscn 以及各种平台道具组合到同一关卡充分体现了场景独立编辑、关卡统一实例化的工程组织方式stage.tscn 开头的 Label 提示文字也明确说明了这一点。为什么用 RigidBody2D 而不是 CharacterBody2DREADME 明确指出刚体角色控制器比CharacterBody2D更强大但更难以处理因为它要求手动修改刚体的速度。维度RigidBody2D本演示CharacterBody2D移动方式在_integrate_forces()中读写PhysicsDirectBodyState2D的线性速度move_and_slide()直接移动并自动处理碰撞物理交互原生参与刚体模拟可被推、可压在跷跷板上、可被移动平台带动运动体与刚体交互需额外配置move_and_slide默认不推动刚体旋转控制默认会翻滚需lock_rotation默认不旋转重力处理需要手动叠加get_total_gravity()自动受重力影响除非gravity_scale 0适用场景强调真实物理反馈的玩法跷跷板、骑乘、弹射传统平台跳跃、追求精确控制的角色从 player.tscn 可以看到刚体角色的关键配置mass 1.5、physics_material_override摩擦为 0避免地面摩擦拖慢移动、lock_rotation true锁定旋转防止倒地翻滚、custom_integrator true由脚本接管积分逻辑配合_integrate_forces、contact_monitor truemax_contacts_reported 4开启接触监控用于地板检测。核心机制一切移动都在 _integrate_forces() 中完成README 强调所有移动必须与物理引擎同步在_integrate_forces()内部进行。这是刚体角色控制器与传统脚本控制的本质区别——你不能在_process/_physics_process里直接设置刚体位置或速度因为物理引擎每帧会基于受力重新求解刚体状态直接赋值会被覆盖且造成物理不同步。player/player.gd 展示了标准写法func _integrate_forces(state: PhysicsDirectBodyState2D) - void: var velocity : state.get_linear_velocity() var step : state.get_step() # 本帧物理步长 # 1. 读取输入 var move_left : Input.is_action_pressed(move_left) var move_right : Input.is_action_pressed(move_right) var jump : Input.is_action_pressed(jump) # 2. 计算目标水平速度地面/空中分别处理 # 3. 手动叠加重力 velocity state.get_total_gravity() * step # 4. 写回刚体 state.set_linear_velocity(velocity)核心要点通过state而非节点属性读写速度state.get_linear_velocity()/state.set_linear_velocity()配合custom_integrator true脚本完全接管移动积分手动叠加重力state.get_total_gravity()返回项目级重力矢量本项目为 900乘以step后累加这是 README 所说手动修改速度最直接的一步使用step而非deltastate.get_step()是物理步长项目配置 120 ticks/s 时为 1/120 秒确保速度换算与物理引擎完全一致call_deferred处理场景变更生成子弹、生成敌人等会修改场景树的操作通过_shot_bullet.call_deferred()/_spawn_enemy_above.call_deferred()延迟执行避免在物理回调中修改场景造成冲突。玩家控制详解参数体系与手感调校玩家控制器由一系列常量集中定义手感参数位于 player/player.gd常量值作用WALK_ACCEL1000.0地面水平加速度WALK_DEACCEL1000.0地面水平减速度松键减速WALK_MAX_VELOCITY200.0地面最大水平速度AIR_ACCEL250.0空中水平加速度远小于地面体现空中操控差的手感AIR_DEACCEL250.0空中水平减速度JUMP_VELOCITY380.0跳跃初速度向上为负STOP_JUMP_FORCE450.0松键跳衰减力实现可变跳高度MAX_SHOOT_POSE_TIME0.3射击姿势动画保持时长MAX_FLOOR_AIRBORNE_TIME0.15地板判定容忍时间跳跃缓冲/物理误差补偿地面与空中的差异化处理在_integrate_forces()中代码根据是否在地板上分支处理水平移动player/player.gd地面移动按住方向键时按WALK_ACCEL * step累加速度并钳制在 ±WALK_MAX_VELOCITY未按键时用WALK_DEACCEL逐步衰减到 0空中移动同样结构但使用小得多的AIR_ACCEL/AIR_DEACCEL250 vs 1000使玩家在空中转向迟缓、更真实跳跃在地面且按下跳跃时一次性赋予velocity.y -JUMP_VELOCITY-380向上若跳跃中松键则通过STOP_JUMP_FORCE * step向上加速度持续抵消上升速度实现按住跳得高、轻点跳得矮的可变跳跃可变跳跃状态机jumping、stopping_jump两个布尔配合管理跳起、衰减、下落三个阶段的转换并伴随sound_jump.play()播放跳跃音效player/player.gd。地板检测基于接触法线的判定刚体没有is_on_floor()可用因此玩家通过遍历接触点、检查碰撞法线方向来判断是否站在地板上player/player.gdfor contact_index in state.get_contact_count(): var collision_normal : state.get_contact_local_normal(contact_index) if collision_normal.dot(Vector2(0, -1)) 0.6: found_floor true floor_index contact_index法线与竖直向上方向(0, -1)的点积大于 0.6即法线基本朝上就视为地板接触。配合MAX_FLOOR_AIRBORNE_TIME 0.15秒的空中宽容期airborne_time 0.15仍算站在地面可以补偿物理引擎的微小误差和人类反应延迟——这正是 README 与代码注释共同强调的刚体角色实现技巧player/player.gd。移动平台与地板速度传导这是一个刚体角色特有的关键细节当玩家站在移动平台上时必须把平台的水平速度叠加到玩家速度上否则会被平台甩下。代码用floor_h_velocity变量实现player/player.gd# 每帧先移除上一帧传导的平台速度再重新计算 velocity.x - floor_h_velocity floor_h_velocity 0.0 ... if found_floor: floor_h_velocity state.get_contact_collider_velocity_at_position(floor_index).x velocity.x floor_h_velocitystate.get_contact_collider_velocity_at_position(floor_index)直接读取所站碰撞体的水平速度并叠加到自己身上于是玩家能稳稳站在平台上随其移动。项目中的移动平台本身是CharacterBody2D见 platform/moving_platform.tscn由 stage.tscn 中的AnimationPlayerautoplay move 动画时长 6 秒驱动3 块平台在关卡中按设定路径往复运动。敌人 AI状态机 射线 子弹交互敌人同样是RigidBody2Denemy/enemy.gd其 AI 展示了刚体角色如何配合RayCast2D做寻路与转向状态机WALKING / DYINGenum State { WALKING, DYING, }WALKING设置velocity.x direction * WALK_SPEEDWALK_SPEED 50enemy/enemy.gd并根据两类检测翻转方向接触法线检测遍历接触点若水平法线分量绝对值大于 0.9说明撞墙则反向enemy/enemy.gd悬空检测左右各挂一个RayCast2Drc_left/rc_right当行进方向前方脚下没有碰撞体not rc_left.is_colliding()而另一侧有碰撞时判定即将掉下平台边缘立即掉头enemy/enemy.gd同时翻转 Sprite 的scale.x实现朝向切换DYING播放 explode 动画通过_pre_explode()移除 3 个碰撞形状防止后续碰撞并播放爆炸音效最终_die()调用queue_free()释放enemy/enemy.gd。子弹交互与死亡旋转在_integrate_forces中敌人检测接触对象是否为Bulletenemy/enemy.gdvar collider : state.get_contact_collider_object(collider_index) if collider is Bullet and not (collider as Bullet).disabled: _bullet_collider.call_deferred(collider, state, collision_normal) break命中后enemy/enemy.gd状态切到DYING根据碰撞法线水平分量的符号设置刚体角速度state.set_angular_velocity(signf(collision_normal.x) * 33.0)让敌人被子弹击中后旋转着倒地——这是 RigidBody2D 独有的物理反馈将physics_material_override.friction设为 1 增大摩擦帮助停稳调用collider.disable()让子弹熄火并播放命中音效。子弹本身也是RigidBody2Dplayer/bullet.gd发射时赋予初速度Vector2(400.0 * speed_scale, -40)向右 400、略向上speed_scale根据朝向取 ±1并在_shot_bullet()中通过add_collision_exception_with(bullet)让子弹与玩家互不碰撞player/player.gd。子弹带有Timer与disable()逻辑被命中后播放 shutdown 动画并标记disabled true避免重复触发。收集物与物理交互金币、跷跷板、单向平台金币Area2D 检测刚体玩家金币使用Area2Dcoin/coin.gd而非刚体通过body_entered信号检测func _on_body_enter(body: Node2D) - void: if not taken and body is Player: ($AnimationPlayer as AnimationPlayer).play(taken)taken标志防止重复触发动画 taken 播放后金币消失。关卡中摆放了 40 个金币实例见 stage.tscn 的Coins节点沿平台与跳跃路线分布作为收集目标。跷跷板PinJoint2D 的真实物理反馈这是 README 特别点名的亮点交互。跷跷板场景 background/seesaw.tscn 由三部分组成Plank木板RigidBody2Dmass 5.10204带矩形碰撞体Pillar支柱StaticBody2D固定在地面PinJoint2D销钉关节node_a指向木板、node_b指向支柱把两者铰接成可转动的杠杆。当玩家跳到木板一端刚体物理自动产生力矩让另一端翘起——完全无需手写任何跷跷板逻辑这正是刚体角色与物理完美交互的直观体现。同理玩家也可以跳到敌人头上骑乘敌人移动时会把玩家一起带走。单向平台one_way_collisionplatform/one_way_platform.tscn 中CollisionShape2D开启one_way_collision true实现经典的只能从下往上穿过、落到上面站住的单向平台效果用于设计从下方跳入的路线。TileMap 关卡与物理层地面由TileMapLayerGodot 4 中TileMap的图层节点铺成tileset 定义在 tileset.tres。其中每个图块的physics_layer_0/polygon_0/points都显式给出了碰撞多边形如(-16, -12, 16, -12, 16, 16, -16, 16)这类 32×32 内的矩形区域见 tileset.tres并通过flip_h/flip_v/transpose组合出全方向图块上下左右与角块保证铺出的地面处处有真实碰撞。如果想修改基础图块关卡内提示文字建议打开 tileset_edit.tscn 在 TileSet 编辑器中调整再回到 stage.tscn 查看效果。项目物理配置为刚体角色调优的全局参数project.godot 中的物理设置是整套刚体方案能否跑顺的前提[physics] common/physics_ticks_per_second120 2d/default_gravity900 common/physics_interpolationtruephysics_ticks_per_second 120物理步长提升到 120Hz默认 60使快速移动的刚体角色碰撞检测更精确、运动更平滑代价是 CPU 开销更高——这正是_integrate_forces中step对应 1/120 秒的原因2d/default_gravity 9002D 重力加速度调得比默认值大配合JUMP_VELOCITY 380得到干脆利落的跳跃手感跳跃高度 ≈ v²/(2g) ≈ 80pxcommon/physics_interpolation true开启物理插值让 120Hz 的物理结果在低刷新率屏幕上渲染更平滑是刚体角色画面流畅性的关键开关。输入映射同样在 project.godot 定义jumpW / 空格实际为物理键 W 方向键上 手柄 A、move_leftA 左方向键 手柄、move_rightD 右方向键 手柄、shoot空格 鼠标左键 手柄、spawnR 手柄 Y可在头顶生成一个敌人供测试。此外 player.tscn 还提供了 4 个TouchScreenButtonLeft/Right/Jump/Fire映射到同名 action支持触屏移动端操作并跟随visibility_mode自动显示。运行与体验在 Godot 4.x项目config/features标注 4.7project.godot中导入2d/physics_platformer目录直接运行主场景 stage.tscn 即可移动A/D 或方向键左右跳跃W / 上方向键按住跳更高射击空格或鼠标左键生成敌人R 键在头顶生成一只敌人方便随时测试骑乘与击杀。观察点跳到移动平台上随其升降踩跷跷板一端看另一端翘起跳到敌人头上骑着它巡逻开枪击杀敌人看其旋转倒地动画。关卡自带滚动视差背景background/parallax_bg.tscn 使用多层云、前景贴图滚动背景音乐为循环播放的audio/music.ogg。音乐资源按 README 说明背景音乐 Pompy 由 Hubert Lamontagnemadbr创作音效文件跳跃、射击、命中、爆炸、金币均位于 2d/physics_platformer/audio 目录通过AudioStreamPlayer/AudioStreamPlayer2D挂载到对应场景节点上播放可在编辑器中替换为自有资源。参考资料演示 README2d/physics_platformer/README.md玩家控制器2d/physics_platformer/player/player.gd、2d/physics_platformer/player/player.tscn敌人 AI2d/physics_platformer/enemy/enemy.gd子弹2d/physics_platformer/player/bullet.gd关卡组装与物理道具2d/physics_platformer/stage.tscn、2d/physics_platformer/background/seesaw.tscn、2d/physics_platformer/platform/one_way_platform.tscn、2d/physics_platformer/platform/moving_platform.tscn项目与瓦片配置2d/physics_platformer/project.godot、2d/physics_platformer/tileset.tres如果你希望角色拥有脚踏实地的精确操控感可以继续对比仓库中同样位于 2d 分类下使用CharacterBody2D的 kinematic_character 与 platformer 演示两者对照即可直观理解两种角色控制器在手感与物理交互上的取舍。赞分享示例工程【免费下载链接】godot-demo-projectsDemonstration and Template Projects项目地址https://gitcode.com/GitHub_Trending/go/godot-demo-projects点击查看免费下载相关推荐Godot 4.7 3D 平台跳跃示例深度解析基于 CharacterBody3D 构建 Platformer 3D 完整项目Godot 4.7 3D 平台跳跃示例深度解析基于 CharacterBody3D 构建 Platformer 3D 完整项目 这篇技术指南以本仓库 3d/p示例工程Godot-demo-projects中的着色器示例2D与3D特效实现教程Godot demo projects中的着色器示例2D与3D特效实现教程 引言告别特效实现困境 你是否还在为Godot引擎中着色器 Shader 的复杂语示例工程GraphiQL 本地测试环境搭建指南从 test 目录到 Cypress 端到端验证GraphiQL 本地测试环境搭建指南从 test 目录到 Cypress 端到端验证 GraphiQL 是浏览器端交互式 GraphQL IDE在持续迭代示例工程上一篇猫抓资源嗅探插件网页视频音频一键下载的完整指南下一篇rofi-sensible-terminal 终端启动器使用指南原理、配置与自定义创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考