zoukankan      html  css  js  c++  java
  • [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    
    
    
    
    
  • 相关阅读:
    多表代换密码
    仿射变换
    LeetCode实战练习题目
    13.线性同余方程 扩展欧几里得算法
    12.扩展欧几里得算法
    11.快速幂求逆元
    10.快速幂
    9.筛法求欧拉函数
    8.欧拉函数
    7.最大公约数 欧几里得算法,也叫辗转相除法
  • 原文地址:https://www.cnblogs.com/xdblog/p/15500752.html
Copyright © 2011-2022 走看看