1. 程式人生 > 其它 >[GODOT]可複用移動元件(載具類)

[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