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