Input examples

简介

在本教程中,您将学习如何使用Godot的:ref:`输入事件<class_InputEvent>`系统捕获玩家输入。您的游戏可以使用多种不同类型的输入——键盘,游戏手柄,鼠标等等。还有许多不同的方法,将这些输入转化为游戏中的动作。本文将向您展示一些最常见的场景,您可以将其作为您自己项目的起点。

注解

要详细了解Godot的输入事件系统是如何工作的,请见:ref:文档_输入事件

事件和轮询

有时候,你想让游戏对某个输入事件做出反应——例如按下“跳跃”按钮。对于其他情况,可能希望只要按下键就会发生一些事情,比如移动。在第一种情况下,您可以使用“_input()”函数,它将在发生输入事件时调用。在第二种情况下,Godot提供了:ref:`输入<class_Input>`单例,您可以使用它来查询输入的状态。

示例:

# 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 ()”捕捉单个事件。

输入事件

输入事件是继承自:ref:`输入事件<class_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)

如你所见,对于不同类型的输入,结果是非常不同的。按键事件甚至被打印为按键符号。例如,让我们考虑:ref:鼠标按钮输入事件<class_InputEventMouseButton>。它继承自以下类:

  • InputEvent - the base class for all input events
  • :ref:`带有修饰符的输入事件<class_InputEventWithModifiers>`加入了检查是否按下修饰符的功能,例如“Shift”或“Alt”。
  • InputEventMouse - adds mouse event properties, such as position
  • :ref:`鼠标按钮输入事件<class_InputEventMouseButton>`包含按下的按钮的索引,无论是双击,或是其他。

小技巧

在处理事件时,打开类引用是一个好主意,这样可以检查事件类型的可用属性和方法。

You can encounter errors if you try to access a property on an input type that doesn’t contain it - calling position on InputEventKey for example. To avoid this, make sure to test the event type first:

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

InputMap

:ref:`事件表<class_InputMap>`是处理各种输入的最灵活的方法。您可以通过创建命名的输入*动作*来使用它,可以为它分配任意数量的输入事件,例如按键或鼠标点击。一个新的Godot项目已经包含许多默认定义操作。看看它们,然后添加你自己的,打开项目->项目设置,并选择事件表选项卡:

../../_images/inputs_inputmap.png

Capturing actions

一旦你定义了动作,可以在脚本中使用“is_action_pressed()”和“is_action_released ()”处理它们。通过名称查找响应的动作:

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

键盘事件

键盘事件在:参考:‘输入事件键位 <类_输入事件键位>’中捕获。虽然建议使用输入行为,在某些情况下,您可能希望特别关注关键事件。对于这个示例,我们检查“T”键:

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

小技巧

详见:参考:“@全局范围_键位列表<枚举_@全局范围_键位列表>”获取扫描代码常量列表。

键盘修饰符

修饰符属性继承自:参考:‘带有修饰符的输入事件<类_带有修饰符的输入事件>’。这允许您使用布尔属性检查修饰符组合。假设您希望在按下“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")

小技巧

详见:参考:“@全局范围_键位列表<枚举_@全局范围_键位列表>”获取扫描代码常量列表。

鼠标事件

鼠标事件继承自:参考:’鼠标输入事件<类_鼠标输入事件>’类,并被分成两种类型::参考:’鼠标按钮输入事件<类_鼠标按钮输入事件>’和:参考:“鼠标行为输入事件<类_鼠标行为输入事件>”。注意,这意味着所有鼠标事件将包含一个“位置”(position)属性。

鼠标按钮

捕获鼠标按钮与处理按键事件非常相似。@全局作用域_按钮列表 包含每个可能按钮的“按钮_*”常量列表,它将在事件的“按钮_索引”属性中报告。注意,鼠标滚轮也可以算作一个按钮——准确地说,是两个按钮,“按钮_滚轮_上”和“按钮_滚轮_下”都是独立的事件。

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")

鼠标行为

:ref:`鼠标移动输入事件<class_InputEventMouseMotion>`事件在鼠标移动时发生。可以通过“相对”属性找到移动的距离。

下面是一个使用鼠标事件拖放:ref:`精灵<class_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

Touch events

如果使用触摸屏设备,可以生成触摸事件。:ref:`触摸屏幕输入事件<class_InputEventScreenTouch>`相当于鼠标点击事件,并且:ref:`拖拽屏幕输入事件<class_InputEventScreenDrag>`的工作原理与鼠标移动非常相似。

小技巧

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