Godot制作2D游戏(1)——人物控制

393 阅读1分钟

概述

我打算将今年使用godot引擎制作游戏到的知识做简单的总结和汇总,这是第一章,关于人物移动控制的。

平台跳跃移动

因为是跳跃平台,所以存在重力,移动时有惯性的影响。从静止到运动速度有加速的过程。

核心代码:

@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D

const RUN_SPEED := 160
# 运动加速度 在地面到达运动速度时间为0.2秒
const ACCELERATION := RUN_SPEED / .2
# 运动加速度 在空中到达运动速度的时间0.1秒
const AIR_ACCELERATION := RUN_SPEED / .1

var gravity := ProjectSettings.get("physics/2d/default_gravity") as float

_physics_process(delta:float)->void:
    move(gravity,delta)
    
func move(g: float, delta: float) -> void:
  var onFloor = is_on_floor()
  	
  if Input.is_action_just_pressed("ui_accept") and onFloor:
      velocity.y = JUMP_VELOCITY
  var direction = Input.get_axis("ui_left", "ui_right")
  var acceleration := ACCELERATION if onFloor else AIR_ACCELERATION
  # 将玩家的移动速度逐渐调整到目标速度,速度变化步进值acceleration * delta
  velocity.x = move_toward(velocity.x, direction * RUN_SPEED, acceleration * delta)
  velocity.y += g * delta
  
  # 人物动画逻辑
  if !onFloor:
        sprite.play('jump')
    else:
        if direction:
                sprite.scale.x = direction
                sprite.play('run')
        else:
                sprite.play('idle')
  move_and_slide()

向鼠标位置移动

与跳跃平台不同的是没有重力的影响,所以没有y方向的重力加速度的计算。不考虑惯性,所以速度的变化是直接的,没有加速的过程。

@onready var playerAni=$AnimatedSprite2D

const SPEED:=600
func move(_delta):
    var mousePos=get_global_mouse_position()
    dir=(mousePos-position).normalized()
    playerAni.flip_h=dir.x<0
    if canMove and !stop:
        velocity=dir*SPEED
        playerAni.play("run")
        move_and_slide()
     else:
        playerAni.play("idle")
    pass

上下左右移动

@onready var animation = $AnimationPlayer

const SPEED:=100

func move():
    var direction=Input.get_vector('ui_left','ui_right','ui_up','ui_down')
    velocity=direction*SPEED
    move_and_slide()
    updateAnimation()
    
# 更新动画
func updateAnimation():
    if velocity.length() == 0: animation.stop(); return
    var dir = '向下'
    if velocity.y < 0: dir = '向上'
    if velocity.x < 0: dir = '向左'
    elif velocity.x > 0: dir = '向右'

    animation.play(dir + '走')

八方移动

@onready var animation=$AnimatedSprite2D

const SPEED:=100
var state

func move():
    direction=Input.get_vector('ui_left','ui_right','ui_up','ui_down')
    state = '移动' if direction != Vector2.ZERO else '空闲'

    velocity=direction*SPEED
    move_and_slide()
    animation(direction)
    
func animation(dir):
    if state== '空闲': return animation.play(state)
     
    var direction_map = { 
         Vector2(0, -1): '上', 
         Vector2(1, 0): '右', 
         Vector2(0, 1): '下', 
         Vector2(-1, 0): '左', 
         Vector2(1, -1): '右上', 
         Vector2(1, 1): '右下', 
         Vector2(-1, -1): '左上', 
         Vector2(-1, 1): '左下', 
    }
    # 归一化方向以匹配映射
    var norm_dir = Vector2(dir.x, dir.y).normalized().round()
    var dire = direction_map.get(norm_dir, '下') # 默认为下
    ani.play(dire + '移动')