输入示例

介绍

在本教程中,您将学习如何使用Godot's InputEvent 系统捕获播放器输入。游戏可以使用多种不同类型的输入-键盘、游戏板、鼠标等-以及在游戏中将这些输入转化为动作的多种不同方法。本文档将向您展示一些最常见的场景,您可以将这些场景用作自己项目的起点。

注解

有关Godot的输入事件系统如何工作的详细概述,请参见 InputEvent .

事件与轮询

有时你希望你的游戏对某个输入事件做出响应-例如,按下“跳转”按钮。对于其他情况,您可能希望只要按下某个键(如移动),就会发生一些事情。在第一种情况下,您可以使用 _input() 函数,每当发生输入事件时将调用该函数。在第二种情况下,Godot提供 Input singleton,可用于查询输入的状态。

实例:

# input event - runs when the input happens
func _input(event):
    if event.is_action_pressed("jump"):
        jump()

# polling - runs every frame
func _physics_process(delta):
    if Input.is_action_pressed("move_right"):
        # move as long as the key/button is pressed
        position.x += speed * delta

这使您能够灵活地混合和匹配所做的输入处理类型。

在本教程的其余部分中,我们将重点捕获 _input() .

输入事件

输入事件是从继承的对象 InputEvent . 根据事件类型,对象将包含与该事件相关的特定属性。要查看事件的实际外观,请添加一个节点并附加以下脚本:

extends Node

func _input(event):
    print(event.as_text())

当您按下键、移动鼠标并执行其他输入时,您将在输出窗口中看到每个事件滚动。以下是输出示例:

A
InputEventMouseMotion : button_mask=0, position=(551, 338), relative=(-85, 47), speed=(0, 0)
InputEventMouseButton : button_index=BUTTON_LEFT, pressed=true, position=(551, 338), button_mask=1, doubleclick=false
InputEventMouseButton : button_index=BUTTON_LEFT, pressed=false, position=(551, 338), button_mask=0, doubleclick=false
S
F
InputEventMouseMotion : button_mask=0, position=(547, 338), relative=(-1, 0), speed=(0, 0)
InputEventMouseMotion : button_mask=0, position=(542, 338), relative=(-4, 0), speed=(0, 0)

如您所见,对于不同类型的输入,结果是非常不同的。关键事件甚至打印为其关键符号。例如,让我们考虑 InputEventMouseButton . 它继承自以下类:

小技巧

在处理事件时,最好保持类引用打开,这样可以检查事件类型的可用属性和方法。

如果试图访问不包含属性的输入类型的属性,则可能会遇到错误-调用 positionInputEventKey 例如。要避免这种情况,请确保首先测试事件类型:

func _input(event):
    if event is InputEventMouseButton:
        print("mouse button event at ", event.position)

InputMap

这个 InputMap 是处理各种输入的最灵活的方法。您可以通过创建命名输入来使用它 行动 ,可以为其分配任意数量的输入事件,如按键或鼠标单击。一个新的godot项目包括一些已经定义的默认操作。要查看它们并添加您自己的,请打开“项目”->“项目设置”,然后选择“输入地图”选项卡:

../../_images/inputs_inputmap.png

捕获操作

一旦定义了操作,就可以在脚本中使用 is_action_pressed()is_action_released() 通过传递要查找的操作的名称:

func _input(event):
    if event.is_action_pressed("my_action"):
        print("my_action occurred!")

键盘事件

键盘事件捕获在 InputEventKey . 虽然建议使用输入操作,但在某些情况下,您可能希望专门查看关键事件。对于这个例子,让我们检查一下“T”键:

func _input(event):
    if event is InputEventKey and event.pressed:
        if event.scancode == KEY_T:
            print("T was pressed")

小技巧

@GlobalScope_KeyList 获取scancode常量列表。

键盘修改器

修饰符属性继承自 InputEventWithModifiers . 这允许您使用布尔属性检查修饰符组合。假设您希望在按下“T”键时发生一件事,但在按下“SHIFT+T”键时会发生不同的事情:

func _input(event):
    if event is InputEventKey and event.pressed:
        if event.scancode == KEY_T:
            if event.shift:
                print("Shift+T was pressed")
            else:
                print("T was pressed")

小技巧

@GlobalScope_KeyList 获取scancode常量列表。

鼠标事件

鼠标事件源于 InputEventMouse 类,并分为两种类型: InputEventMouseButtonInputEventMouseMotion . 注意,这意味着所有鼠标事件都将包含 position 财产。

鼠标按钮

捕获鼠标按钮与处理关键事件非常相似。 @GlobalScope_ButtonList 包含的列表 BUTTON_* 每个可能按钮的常量,将在事件的 button_index 属性。请注意,滚动轮也算作一个按钮-准确地说,两个按钮都有 BUTTON_WHEEL_UPBUTTON_WHEEL_DOWN 是独立的事件。

func _input(event):
    if event is InputEventMouseButton:
        if event.button_index == BUTTON_LEFT and event.pressed:
            print("Left button was clicked at ", event.position)
        if event.button_index == BUTTON_WHEEL_UP and event.pressed:
            print("Wheel up")

鼠标移动

InputEventMouseMotion 每当鼠标移动时都会发生事件。你可以用 relative 财产。

下面是一个使用鼠标事件拖放 Sprite 节点:

extends Node

var dragging = false
var click_radius = 32  # Size of the sprite

func _input(event):
    if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
        if (event.position - $Sprite.position).length() < click_radius:
            # Start dragging if the click is on the sprite.
            if !dragging and event.pressed:
                dragging = true
        # Stop dragging if the button is released.
        if dragging and !event.pressed:
            dragging = false

    if event is InputEventMouseMotion and dragging:
        # While dragging, move the sprite with the mouse.
        $Sprite.position = event.position

触摸事件

如果您使用的是触摸屏设备,则可以生成触摸事件。 InputEventScreenTouch 相当于鼠标单击事件,并且 InputEventScreenDrag 其工作原理与鼠标运动基本相同。

小技巧

要在非触摸屏设备上测试触摸事件,请打开项目设置并转到“输入设备/指向”部分。启用“从鼠标模拟触摸”,您的项目将鼠标单击和运动解释为触摸事件。