[GODOT]可复用移动组件(载具类)

介绍

本篇实现了一个可复用的移动组件,将本组件作为移动目标的子节点,即可完成移动控制。请注意该脚本可提供的移动方式是载具类型的,移动方式为 前进 后退 左转 右转。

Tallk is cheap, show me your code!

# 为载具类目标提供可移动功能 此节点的父节点将会在此节点的驱动下进行移动
# 移动方式为 前进 后退 左转 右转
# 按键适配: ui_forward ui_backward ui_left ui_right 
# 打开 handle_input 选项,接受用户输入控制物体, 
# 关闭 handle_input 选项,则通过控制  go_command turn_command 控制前后和转向
extends Node2D
###################常量、枚举区###############
enum GO_COMMAND {
    E_FORWARD = 1,
    E_BACKWARD = -1,
    E_NONE = 0,
}

enum TURN_COMMAND{
    E_TURN_LEFT = -1,
    E_TURN_RIGHT = 1,
    E_NONE = 0,
}

###################导出区#######################################
#是否需要手动操控 如果为真 用户输入则会影响此物体的移动
#如果为假 则可以通过控制  go_command turn_command 控制前后和转向
export var handle_input := false
#移动加速度
export var acceleration: float = 500
#转向速度
export var turn_speed: float = PI
#最大移动速度
export var max_speed := 500.0
#无指令时的自然减速
export var stop_speed := 300.0

#前后行进命令
export var go_command = GO_COMMAND.E_NONE
#左右行进命令
export var turn_command = TURN_COMMAND.E_NONE

###################变量区#######################################
#移动速度
onready var speed:float = 0.0
#控制目标 父节点
onready var parent_node = $".."

###################System Function############################
func _ready():
    pass # Replace with function body.

func _process(delta):
    # 决定是否处理用户输入
    if handle_input :
        if Input.is_action_just_pressed("ui_up") :
            go_command = GO_COMMAND.E_FORWARD
        elif Input.is_action_just_pressed("ui_down") :
            go_command = GO_COMMAND.E_BACKWARD
        elif Input.is_action_just_released("ui_up") or Input.is_action_just_released("ui_down") :
            go_command = GO_COMMAND.E_NONE


        if Input.is_action_just_pressed("ui_left"):
            turn_command = TURN_COMMAND.E_TURN_LEFT
        elif Input.is_action_just_pressed("ui_right"):
            turn_command = TURN_COMMAND.E_TURN_RIGHT
        elif  Input.is_action_just_released("ui_left") or Input.is_action_just_released("ui_right") :
            turn_command = TURN_COMMAND.E_NONE


func _physics_process(delta):
    var turn_add = turn_speed * delta * turn_command
    parent_node.rotation += turn_add
    var speed_add = acceleration* delta * go_command;
    speed += speed_add
    #减速
    if speed > 0 :
        if speed >= max_speed :
            speed = max_speed
        speed -= stop_speed*delta
        if speed < 0 :
            speed = 0
    elif speed < 0:
        if -speed >= max_speed :
            speed = -max_speed
        speed += stop_speed*delta
        if speed > 0 :
            speed = 0
    #行进
    parent_node.position += speed * Vector2.RIGHT.rotated(parent_node.rotation) * delta

使用示例

使用按键控制

添加到子节点中。

勾选 Handle Input, 调整参数

此时你就得到了一个可以用 wasd 控制的目标啦。

使用代码控制

脚本导出了两个枚举,分别表示前进后退指令和左转右转命令。

我们使用它来完成一个随机移动的目标。

别忘了取消勾选,这样目标就不会响应键盘控制了:

添加以下脚本到目标上:

extends Area2D
# 作为测试目标的坦克 可以随机移动

enum GO_COMMAND {
    E_FORWARD = 1,
    E_BACKWARD = -1,
    E_NONE = 0,
}

enum TURN_COMMAND{
    E_TURN_LEFT = -1,
    E_TURN_RIGHT = 1,
    E_NONE = 0,
}


#在0.2 到 0.5s 内随机进行一个动作
export var action_time_range := [0.2, 0.5]

onready var go_commands := GO_COMMAND.keys()
onready var turn_commands := TURN_COMMAND.keys()
onready var next_action_time := 0.0

var go_command:int = GO_COMMAND.E_NONE
var turn_command:int = TURN_COMMAND.E_NONE

# Called when the node enters the scene tree for the first time.
func _ready():
    pass # Replace with function body.

func _process(delta):
    #时间扣光了 就开始随机动作
    if next_action_time <= 0 :
        go_command = GO_COMMAND[go_commands[randi()%go_commands.size()]]
        turn_command = TURN_COMMAND[turn_commands[randi()%turn_commands.size()]]
        #发出运动指令
        $Moveable.go_command = go_command
        $Moveable.turn_command = turn_command
        #随机一个动作时间
        next_action_time = rand_range(action_time_range[0], action_time_range[1])
    else :
        next_action_time  -= delta    



posted @ 2021-11-02 19:55  Smalldy  阅读(175)  评论(0编辑  收藏  举报