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    
    
    
    
    
  • 相关阅读:
    MKMapVIew学习系列2 在地图上绘制出你运行的轨迹
    WPF SDK研究 Intro(6) WordGame1
    WPF SDK研究 Intro(3) QuickStart3
    WPF SDK研究 Layout(1) Grid
    WPF SDK研究 目录 前言
    WPF SDK研究 Intro(7) WordGame2
    WPF SDK研究 Layout(2) GridComplex
    对vs2005创建的WPF模板分析
    WPF SDK研究 Intro(4) QuickStart4
    《Programming WPF》翻译 第6章 资源
  • 原文地址:https://www.cnblogs.com/xdblog/p/15500752.html
Copyright © 2011-2022 走看看