Godot 主要 2D 节点对象详解
Godot 引擎采用“万物皆节点”的设计哲学,其 2D 游戏开发的核心在于对各种 2D 节点的理解和运用。这些节点提供了从基础绘制、运动控制到物理模拟、用户界面等一系列功能,它们通过层级结构(场景树)组织起来,共同构建出完整的游戏世界。本篇将详细介绍 Godot 中最常用的一些 2D 节点及其核心功能与典型应用。
核心概念:
- 节点 (Node): Godot 中最小的功能单元,所有对象都是节点。
- 场景树 (SceneTree): 节点以树形结构组织起来,形成一个场景。
- 2D 节点基类:
Node2D是所有可见 2D 节点的基类,提供了位置、旋转、缩放等基本变换属性。
一、2D 节点基类:Node2D
Node2D 是所有需要在 2D 场景中拥有位置、旋转和缩放的节点的基类。它本身不渲染任何东西,但提供了所有 2D 对象的通用变换属性和方法。
1.1 核心属性
position(Vector2): 节点在父节点坐标系中的二维位置。rotation(float): 节点相对于其父节点的旋转角度(弧度制)。rotation_degrees(float): 节点旋转角度(角度制,更易读)。scale(Vector2): 节点在 X 和 Y 方向上的缩放因子。global_position(Vector2): 节点在世界坐标系中的位置。global_rotation(float): 节点在世界坐标系中的旋转角度。global_scale(Vector2): 节点在世界坐标系中的缩放因子。transform(Transform2D): 包含position,rotation,scale的组合变换矩阵。
1.2 典型应用
- 作为其他 2D 节点的父节点,用于组织和分组对象。
- 作为仅拥有位置、旋转、缩放属性的空对象,用于定位或作为其他组件的参照点。
- 继承创建自定义 2D 节点。
二、可见 2D 节点:CanvasItem 及其子类
CanvasItem 是所有 2D 可见节点的基类,它引入了绘图、Z 索引、可见性、材质、混合模式等与渲染相关的属性。
2.1 Sprite
Sprite 是 Godot 中最常用的显示 2D 图像的节点。
- 核心功能: 显示一张纹理 (Texture)。
- 关键属性:
texture(Texture2D): 要显示的图像资源。flip_h(bool): 水平翻转图像。flip_v(bool): 垂直翻转图像。offset(Vector2): 图像相对于节点原点的偏移量。modulate(Color): 调制精灵的颜色,可用于着色或制作闪烁效果。region_enabled(bool),region_rect(Rect2): 如果设置为true,则只显示纹理的指定区域,常用于图集 (atlas)。
- 典型应用:
- 游戏角色、敌人、道具、背景元素等静态或简单动画的图像显示。
- UI 元素的图标或背景图。
1 | # 示例: 动态改变 Sprite 的纹理和颜色 |
2.2 AnimatedSprite2D
AnimatedSprite2D 用于播放帧动画,它将一个 SpriteFrames 资源中的多个动画序列进行播放。
- 核心功能: 播放动画序列。
- 关键属性:
sprite_frames(SpriteFrames): 包含所有动画帧和动画序列的资源。可以在编辑器中创建和管理。animation(StringName): 当前正在播放的动画名称。frame(int): 当前显示的动画帧索引。playing(bool): 控制动画是否播放。speed_scale(float): 动画播放速度的缩放因子。
- 核心方法:
play(name: StringName = "", custom_speed: float = 1.0, from_end: bool = false): 播放指定名称的动画。stop(): 停止当前动画。
- 信号:
animation_finished(当动画播放完毕且未循环时发出)。 - 典型应用:
- 玩家角色(行走、跳跃、攻击等)的复杂帧动画。
- 敌人、NPC 的动画行为。
- 各种特效动画(爆炸、拾取物品)。
1 | # 示例: 播放动画 |
2.3 TextureRect (UI 节点,但常用于显示图像)
TextureRect 是一种 UI 控件节点,它也用于显示纹理,但与 Sprite 的主要区别在于其对布局和 UI 属性的支持。
- 核心功能: 显示纹理,并遵循 UI 布局规则。
- 关键属性:
texture(Texture2D): 要显示的图像。expand_mode(ExpandMode): 定义纹理如何适应节点的尺寸(如EXPAND_FIT_WIDTH_PROPORTIONAL)。stretch_mode(StretchMode): 定义纹理如何拉伸以填充TextureRect的边界。flip_h,flip_v: 翻转图像。
- 典型应用:
- UI 背景、图标、血条填充。
- 作为
Control节点的一部分,利用其布局容器进行尺寸和位置管理。
2.4 ParallaxBackground 和 ParallaxLayer
用于创建视差滚动效果,常用于游戏背景。
ParallaxBackground: 视差背景的容器,通常作为Viewport的子节点或根节点的子节点。ParallaxLayer: 包含实际背景元素的层。每个ParallaxLayer都有自己的滚动速度。motion_scale(Vector2): 决定该层相对于相机移动的速度。Vector2(0.5, 0.5)表示移动速度是相机的一半。motion_offset(Vector2): 层的偏移量,用于循环背景。
- 典型应用:
- 制作多层深度感的背景,例如,近景移动快,远景移动慢。
1 | # Scene Tree Structure Example |
三、碰撞与物理节点:CollisionObject2D 及其子类
CollisionObject2D 是所有 2D 物理对象的基类,它提供了碰撞检测和物理模拟所需的基础功能。其子类通常需要一个或多个 CollisionShape2D 或 RectangleShape2D 等形状节点作为子节点来定义它们的碰撞区域。
3.1 Area2D
Area2D 节点用于检测与其他物理对象(RigidBody2D, KinematicBody2D, StaticBody2D, TileMap)的重叠(overlap),但不参与物理模拟本身。
- 核心功能: 触发器、范围检测、拾取物品。
- 信号:
body_entered(body: Node2D):当一个PhysicsBody2D进入Area2D时发出。body_exited(body: Node2D):当一个PhysicsBody2D离开Area2D时发出。area_entered(area: Area2D):当另一个Area2D进入时发出。
- 典型应用:
- 玩家进入一个区域,触发对话或事件。
- 拾取物品(如金币、药水)。
- 检测子弹是否击中敌人(子弹本身可能是
KinematicBody2D或RigidBody2D,而敌人上的命中框可能是Area2D)。 - 陷阱区域、传送门。
1 | # 示例: 拾取金币 |
3.2 StaticBody2D
StaticBody2D 是一个不动的物理对象,它不参与物理模拟,但会与其他物理对象产生碰撞。
- 核心功能: 游戏世界的固定几何体。
- 典型应用:
- 地面、墙壁、平台、固定障碍物。
- 任何不应移动或响应力的环境元素。
- 注意: 如果需要有碰撞但没有物理模拟的地图,通常使用
TileMap更高效。
3.3 KinematicBody2D
KinematicBody2D 是一个由代码控制移动的物理对象。它受物理引擎的碰撞检测影响,但不受重力、摩擦力等物理力的影响。开发者需要手动计算其移动和处理碰撞响应。
- 核心功能: 玩家角色、可移动平台、由 AI 控制的敌人。
- 核心方法:
move_and_slide(linear_velocity: Vector2, up_direction: Vector2 = Vector2(0, -1), stop_on_slope: bool = false, max_slides: int = 4, floor_max_angle: float = 0.785398, infinite_inertia: bool = true): 根据给定的速度移动物体,并处理碰撞和滑动。常用于平台游戏中的角色移动。move_and_collide(linear_velocity: Vector2, test_only: bool = false, collide_with_bodies: bool = true, collide_with_areas: bool = false, recovery_as_collision: bool = false): 移动物体并返回第一个碰撞信息,但不会滑动。
- 典型应用:
- 玩家角色: 精确控制玩家的跳跃、行走、冲刺等行为,同时与其他物体发生碰撞。
- 移动平台: 按照预设路径移动,并与玩家或其他物体发生碰撞。
- 子弹: 精准移动并检测碰撞。
1 | # 示例: KinematicBody2D 玩家移动 |
3.4 RigidBody2D
RigidBody2D 是一个完全由物理引擎模拟的物理对象。它受重力、摩擦力、弹力以及外部力(如冲量、施加的力)的影响。
- 核心功能: 模拟真实物理行为的对象。
- 关键属性:
mode(Mode):RigidBody2D的行为模式:MODE_RIGID(完全物理模拟)、MODE_STATIC(像StaticBody2D一样不动)、MODE_KINEMATIC(像KinematicBody2D一样由代码控制,但依然响应物理碰撞)、MODE_CHARACTER(特殊的KinematicBody2D模式)。mass(float): 物体的质量。friction(float): 摩擦系数。bounce(float): 弹力系数 (0-1)。linear_velocity(Vector2): 线性速度。angular_velocity(float): 角速度。gravity_scale(float): 对重力的敏感度。
- 核心方法:
apply_central_force(force: Vector2): 在中心点施加一个持续的力。apply_force(force: Vector2, position: Vector2): 在指定位置施加一个持续的力。apply_central_impulse(impulse: Vector2): 在中心点施加一个瞬时冲量。apply_impulse(impulse: Vector2, position: Vector2): 在指定位置施加一个瞬时冲量。_integrate_forces(state: Physics2DDirectBodyState): 用于在物理引擎计算之前,自定义RigidBody2D的行为,比直接设置linear_velocity更安全。
- 典型应用:
- 弹球、箱子、可破坏的方块等受物理定律影响的对象。
- 爆炸碎片、掉落的道具。
1 | # 示例: RigidBody2D 小球被点击后施加一个冲量 |
四、地图节点:TileMap
TileMap 节点允许你在 2D 网格上快速绘制基于瓷砖的地图,并能自动生成碰撞体、导航区域等。
- 核心功能: 快速构建关卡地图。
- 关键资源:
TileSet(TileSet): 包含所有瓷砖及其属性(纹理、碰撞形状、导航形状等)的资源。
- 核心方法:
set_cell(layer: int, coords: Vector2i, tile_id: int, alternative_tile: int = 0): 在指定层和坐标设置瓷砖。get_cell_tile_data(layer: int, coords: Vector2i): 获取指定位置的瓷砖数据。map_to_world(map_coords: Vector2i, use_center: bool = true): 将地图坐标转换为世界坐标。world_to_map(world_coords: Vector2): 将世界坐标转换为地图坐标。
- 典型应用:
- 平台游戏的地面、墙壁、背景。
- 俯视角游戏的地图。
- 自动生成碰撞体,方便与物理节点交互。
1 | # 示例: TileMap 动态修改瓷砖 |
五、相机节点:Camera2D
Camera2D 用于控制 2D 场景的视图。一个场景可以有多个 Camera2D,但通常只有一个是激活的。
- 核心功能: 控制屏幕显示哪个区域,以及如何缩放。
- 关键属性:
current(bool): 如果设置为true,则此相机是当前激活的相机。zoom(Vector2): 相机的缩放因子(Vector2(1,1)为 1:1 像素比)。offset(Vector2): 相机相对于其position的额外偏移量。limit_left,limit_top,limit_right,limit_bottom(int): 限制相机移动的世界坐标边界。smoothing_enabled(bool),smoothing_speed(float): 启用平滑跟随目标。follow_viewport_enabled(bool): 当父节点是Viewport时,启用此属性可以让相机自动跟随Viewport的大小变化。process_callback(ProcessCallback): 相机更新的模式 (IDLE或PHYSICS)。
- 典型应用:
- 跟随玩家角色移动。
- 实现缩放效果(如瞄准、视野变化)。
- 提供固定区域的俯视视角。
- 在分屏游戏中为不同玩家提供单独的视图。
1 | # 示例: Camera2D 跟随玩家 |
六、其他重要 2D 节点
Line2D: 绘制 2D 线条。Polygon2D: 绘制自定义的多边形。Light2D: 用于 2D 光照和阴影效果。CanvasModulate: 全局调制整个 2D 渲染的颜色。Node2D家族的各种碰撞形状节点:RectangleShape2D,CircleShape2D,CapsuleShape2D等,它们必须作为CollisionObject2D的子节点来定义碰撞区域。RayCast2D: 用于从一点发射射线,检测碰撞。常用于检测前方是否有障碍物或地面。
七、总结
Godot 2D 节点的设计理念是模块化和组合性。每个节点都专注于特定的功能,通过将它们组合成场景树,开发者可以灵活地构建出各种复杂的游戏逻辑和视觉效果。
掌握 Node2D 的基本变换,理解 Sprite 和 AnimatedSprite2D 的图像显示,区分 Area2D、StaticBody2D、KinematicBody2D 和 RigidBody2D 的物理行为,并熟练运用 TileMap 和 Camera2D 进行世界构建和视图控制,是成功开发 Godot 2D 游戏的关键。随着经验的积累,你将能更深入地利用这些节点,并通过继承和自定义来创造出更独特和强大的游戏元素。
