2D 游戏开发

2D 游戏开发

2D 项目设置

创建 2D 项目时,建议的初始设置:

# 项目设置 -> Application -> Config -> Name
# 项目设置 -> Application -> Run -> Main Scene

# 项目设置 -> Display -> Window -> Size
# Viewport Width: 1280
# Viewport Height: 720

角色移动

基础移动

extends CharacterBody2D

@export var speed: float = 200.0

func _physics_process(delta: float) -> void:
    var direction := Vector2.ZERO

    if Input.is_action_pressed("move_right"):
        direction.x += 1
    if Input.is_action_pressed("move_left"):
        direction.x -= 1
    if Input.is_action_pressed("move_down"):
        direction.y += 1
    if Input.is_action_pressed("move_up"):
        direction.y -= 1

    velocity = direction * speed
    move_and_slide()

使用输入映射

# 项目设置 -> Input Map
# 添加动作:ui_right, ui_left, ui_up, ui_down

@export var speed: float = 200.0

func _physics_process(delta: float) -> void:
    var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
    velocity = direction * speed
    move_and_slide()

角色朝向

func _physics_process(delta: float) -> void:
    var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")

    if direction.x > 0:
        $Sprite2D.flip_h = false
    elif direction.x < 0:
        $Sprite2D.flip_h = true

    velocity = direction * speed
    move_and_slide()

物理碰撞

碰撞形状

# CollisionShape2D + Shape2D
# 常用形状:RectangleShape2D, CircleShape2D, CapsuleShape2D

碰撞检测

# 使用 CharacterBody2D
velocity = direction * speed
move_and_slide()

if get_last_slide_collision():
    var collider = get_last_slide_collision().get_collider()
    print("Collided with: ", collider.name)

Area2D 检测

extends Area2D

signal body_detected(body: Node2D)

func _on_body_entered(body: Node2D) -> void:
    if body.is_in_group("player"):
        body_detected.emit(body)

摄像机跟随

extends Camera2D

@export var target: Node2D
@export var smooth_speed: float = 5.0

func _process(delta: float) -> void:
    if target:
        position = lerp(position, target.position, smooth_speed * delta)

限制摄像机范围

extends Camera2D

@export var limit_left: int = 0
@export var limit_right: int = 1920
@export var limit_top: int = 0
@export var limit_bottom: int = 1080

func _ready() -> void:
    limit_left = limit_left
    limit_right = limit_right
    limit_top = limit_top
    limit_bottom = limit_bottom

2D 动画

使用 AnimatedSprite2D

extends AnimatedSprite2D

func _ready() -> void:
    play("idle")

func _process(delta: float) -> void:
    var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")

    if direction != Vector2.ZERO:
        if animation != "run":
            play("run")
    else:
        if animation != "idle":
            play("idle")

瓦片地图 (TileMap)

extends TileMap

func _ready() -> void:
    # 绘制瓦片
    var coords := Vector2i(0, 0)
    set_cell(0, coords, 0, Vector2i(0, 0))

    # 获取瓦片数据
    var tile_data = get_cell_tile_data(0, coords)

平台跳跃游戏

重力与跳跃

extends CharacterBody2D

@export var speed: float = 200.0
@export var jump_force: float = -400.0
@export var gravity: float = 980.0

var can_jump: bool = true

func _physics_process(delta: float) -> void:
    # 应用重力
    velocity.y += gravity * delta

    # 水平移动
    var direction = Input.get_axis("ui_left", "ui_right")
    velocity.x = direction * speed

    # 跳跃
    if Input.is_action_just_pressed("ui_accept") and can_jump:
        velocity.y = jump_force
        can_jump = false

    # 移动并更新跳跃状态
    move_and_slide()
    can_jump = is_on_floor()

2D 坐标系统

常用工具节点