Godot02-Frogger游戏制作
1-视频教程:https://www.bilibili.com/video/BV1ugKB66ExJ
2-项目仓库地址:https://gitee.com/enzoism/godot_game_frogger
1-Frogger游戏开发
1-创建Game场景(类型:Node2D)->解决图片模糊问题
2-创建Player场景(类型:Node2D)->解决图片太小问题
3-Player人物挂载脚本(gdscript脚本)->编写人物移动脚本
4-_physics_process 和 _process对比 -> _process 不固定,取决于当前帧率(FPS)/ _physics_process固定,默认每秒 60 次,与帧率无关
5-使用键盘控制物物体移动-简单 ->Input.is_action_pressed(“right”)
6-使用键盘控制物物体移动-通用 ->Input.get_vector(“left”, “right”, “up”, “down”)
7-XXX
1-解决图片模糊问题
- 英文界面
- 中文界面
2-解决图片太小问题
3-人物移动脚本
extends Node2D var direction: Vector2 = Vector2(1, 1) var speed: int = 5 func _physics_process(_delta: float) -> void: position += direction * speed4-物体添加动作
5-物体添加键盘控制-简单
1-选中左侧-FroggerGame(类型:Node2D)
2-点击项目设置(添加键盘定义)
3-选中左侧-Player(类型:Node2D)
4-创建gdscript脚本->编写人物移动脚本
extends Node2D var direction: Vector2 = Vector2(1, 1) var speed: int = 5 func _physics_process(_delta: float) -> void: if Input.is_action_pressed("right"): direction = Vector2.RIGHT if Input.is_action_pressed("left"): direction = Vector2.LEFT position += direction * speed6-物体添加键盘控制-通用
extends CharacterBody2D # 移动方向,初始为右下对角线方向;每帧会根据输入被覆盖 var direction: Vector2 = Vector2(1, 1) # 移动速度(像素/秒) var speed: int = 200 # 物理帧回调:执行频率固定(默认 60 次/秒),与物理引擎同步 # 移动角色、调用 move_and_slide() 等物理相关操作应放在这里 func _physics_process(_delta: float) -> void: # 读取输入,返回归一化后的方向向量(无输入时为 (0,0),斜向移动不会更快) direction = Input.get_vector("left", "right", "up", "down") # 速度 = 方向 × 速率;注意这里没有乘 delta, # 因为 move_and_slide() 内部会按物理帧时长处理速度,无需手动乘 velocity = direction * speed # 执行移动并处理碰撞/滑动,内部会更新 position move_and_slide() # 检测"确认"动作是否在本物理帧刚刚按下(只在按下的那一帧触发一次) if Input.is_action_just_pressed("comfirm"): print("hello godot")7-人物运行视角-Camera2D
添加Camera2D,设置视角的边界
8-物体碰撞阻挡-刚体
- StaticBody2D:环境静态物(场景中不会移动的障碍物)
- CharacterBody2D:代码控制角色(场景中会移动的角色)
9-添加背景音乐-AudioStreamPlayer
2-知识整理
1-_physics_process 和 _process方法的对比
在 Godot 中,_process和_physics_process的核心区别在于执行频率是否固定以及是否与物理引擎同步。简单说,与物理、碰撞相关的逻辑放_physics_process,其余常规逐帧更新放_process。
核心对比
| 特性 | _process(delta) | _physics_process(delta) |
|---|---|---|
| 执行频率 | 不固定,取决于当前帧率(FPS) | 固定,默认每秒 60 次,与帧率无关 |
| 主要用途 | 常规逐帧更新:UI 动画、计时器、非物理的视觉特效等 | 物理相关运算:移动带有碰撞体的角色、施加力、射线检测等 |
| 与物理同步 | 不同步。在单线程游戏中,通常在一轮物理步骤之后执行 | 同步。在每一次物理步骤之前执行,确保物理状态稳定 |
delta含义 | 自上一帧渲染以来经过的秒数 | 自上一物理步以来经过的秒数(通常恒定) |
如何选择
使用_physics_process的场景
只要你的代码涉及物理引擎的计算,就必须用它。例如,用move_and_slide()控制CharacterBody2D/3D移动、对RigidBody施加力、或者需要精确检测碰撞的射线查询。因为它的时间步长固定,物理模拟的结果才能保持稳定和可复现。
使用_process的场景
用于那些不需要严格物理同步、且希望尽可能流畅更新的逻辑。例如,更新 UI 文本显示、让 2D 精灵做纯粹的视觉旋转(不参与碰撞)、或者处理输入缓冲(如果不需要在物理帧精确响应)。
关键注意事项
无论使用哪个,只要涉及基于时间的持续变化(如移动、旋转、渐变),都必须把变化量乘以delta,这样才能保证在不同帧率或物理配置下速度一致。例如:position.x += speed * delta。
2-三种刚体区别
在 Godot 中,这三个物理节点的核心区别在于控制权归属:StaticBody2D由引擎固定不动,RigidBody2D由物理引擎全权模拟,而CharacterBody2D由你通过代码手动控制移动与碰撞响应。
🧱 StaticBody2D:环境静态物
它不会被物理引擎移动,碰撞时自身不发生位移,主要用于构建游戏世界的固定环境。
- 典型用途:墙壁、地板、平台、障碍物。
- 特殊功能:虽然自身不动,但可通过
constant_linear_velocity属性模拟“移动”,让撞上它的物体受到类似传送带或移动平台的力。 - 注意:它不响应重力,也不会因被推动而改变位置。
🎮 CharacterBody2D:代码控制角色
它不受重力、摩擦力等物理属性自动影响,移动完全由你的代码决定。物理引擎只负责在它移动时检测碰撞,但不会自动处理碰撞后的滑动或反弹。
- 典型用途:玩家角色、敌人、需要精确手感控制的单位。
- 核心方法:在
_physics_process中调用move_and_slide()(自动沿墙滑动,适合平台游戏)或move_and_collide()(立即停止并返回碰撞信息,适合子弹反弹等自定义逻辑)。 - 注意:不要直接设置
position,否则可能穿墙或绕过碰撞检测。
🎢 RigidBody2D:全物理模拟体
它完全交由物理引擎接管,你不应直接设置其位置或速度,而应通过施加力(如apply_force、apply_impulse)来间接影响它。
- 典型用途:愤怒的小鸟式弹射物、可堆叠掉落的箱子、受爆炸冲击的碎片。
- 优点:碰撞反弹、旋转、重力下落等行为“免费”获得,无需写代码。
- 注意:直接改
position或linear_velocity可能引发异常行为;如需安全修改,应使用_integrate_forces()回调。
💡 快速选择建议
- 做墙、地面、固定障碍→
StaticBody2D - 做你控制的玩家或 AI 角色→
CharacterBody2D - 做被炸飞、会滚动的箱子→
RigidBody2D