输入示例
前言
输入事件 系统捕获玩家输入. 您的游戏可以使用多种不同类型的输入——键盘, 游戏手柄, 鼠标等等. 还有许多不同的方法, 将这些输入转化为游戏中的动作. 本文将向您展示一些最常见的场景, 您可以将其作为您自己项目的起点. 注解 使用 InputEvent。
事件和轮询
_input() 函数, 只要有输入事件发生就会调用该函数. 在第二种情况下,Godot提供了 Input 单例, 你可以用它来查询一个输入的状态.
示例:
GDScript
C#
func _input(event): if event.is_action_pressed("jump"): jump()func _physics_process(delta): if Input.is_action_pressed("move_right"): # Move as long as the key/button is pressed. position.x += speed * delta
public override void _Input(InputEvent inputEvent){ if (inputEvent.IsActionPressed("jump")) { Jump(); }}public override void _PhysicsProcess(float delta){ if (Input.IsActionPressed("move_right")) { // Move as long as the key/button is pressed. position.x += speed * delta; }}
这使您能够灵活地混合和匹配所执行输入的处理类型.
_input () 捕捉单个事件.
输入事件
输入事件 的对象. 根据事件类型, 对象将包含与该事件相关的特定属性. 为了了解事件的实际情况, 添加一个节点并附加以下脚本: GDScript C#
extends Nodefunc _input(event): print(event.as_text())
using Godot;using System;public class Node : Godot.Node{ public override void _Input(InputEvent inputEvent) { GD.Print(inputEvent.AsText()); }}
当你按下按键, 移动鼠标, 并执行其他输入, 您会在输出窗口中看到每个事件滚动. 下面是输出的一个例子:
AInputEventMouseMotion : button_mask=0, position=(108, 108), relative=(26, 1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)InputEventMouseButton : button_index=BUTTON_LEFT, pressed=true, position=(108, 107), button_mask=1, doubleclick=falseInputEventMouseButton : button_index=BUTTON_LEFT, pressed=false, position=(108, 107), button_mask=0, doubleclick=falseSFAltInputEventMouseMotion : button_mask=0, position=(108, 107), relative=(0, -1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)
鼠标按钮输入事件 . 它继承自以下类:
- InputEvent - 所有输入事件的基类
- InputEventWithModifiers - 增加了检查是否按下修饰按键, 如 Shift 或 Alt .
- InputEventMouse - 增加鼠标事件属性, 如
position - 鼠标按钮输入事件 包含按下的按钮的索引, 无论是双击, 或是其他.
小技巧
在处理事件时, 打开类引用是一个好主意, 这样可以检查事件类型的可用属性和方法.
InputEventKey调用Position. 要避免这种情况, 请确保首先测试事件类型: GDScript C#func _input(event): if event is InputEventMouseButton: print("mouse button event at ", event.position)
public override void _Input(InputEvent inputEvent){ if (inputEvent is InputEventMouseButton mouseEvent) { GD.Print("mouse button event at ", mouseEvent.Position); }}
InputMap
事件表 是处理各种输入的最灵活的方法. 您可以通过创建命名的输入 动作 来使用它, 可以为它分配任意数量的输入事件, 例如按键或鼠标点击. 一个新的Godot项目已经包含许多默认定义操作. 看看它们, 然后添加你自己的, 打开项目->项目设置, 并选择事件表选项卡:捕捉动作
is_action_pressed()和is_action_released ()处理它们. 通过名称查找响应的动作: GDScript C#func _input(event): if event.is_action_pressed("my_action"): print("my_action occurred!")
public override void _Input(InputEvent inputEvent){ if (inputEvent.IsActionPressed("my_action")) { GD.Print("my_action occurred!"); }}
键盘事件
InputEventKey 中被捕获. 虽然建议使用输入动作来代替, 但在某些情况下, 你可能会想专门查看按键事件. 对于当前示例, 来检查一下 T : GDScript C#func _input(event): if event is InputEventKey and event.pressed: if event.scancode == KEY_T: print("T was pressed")
小技巧 全局范围_键位列表 获取扫描代码常量列表.public override void _Input(InputEvent inputEvent){ if (inputEvent is InputEventKey keyEvent && keyEvent.Pressed) { if ((KeyList)keyEvent.Keycode == KeyList.T) { GD.Print("T was pressed"); } }}
键盘修饰键
InputEventWithModifiers ,可使用布尔属性检查修饰键的组合。试想,如果需要在按下 T 时发生一件事,而按下 Shift + T 时发生不同的事: GDScript C#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")
小技巧 全局范围_键位列表 获取扫描代码常量列表.public override void _Input(InputEvent inputEvent){ if (inputEvent is InputEventKey keyEvent && keyEvent.Pressed) { switch ((KeyList)keyEvent.Scancode) { case KeyList.T: GD.Print(keyEvent.Shift ? "Shift+T was pressed" : "T was pressed"); break; } }}
鼠标事件
鼠标输入事件 , 并被分成两种类型 : 鼠标按钮输入事件 和 鼠标移动输入事件 . 注意, 这意味着所有鼠标事件将包含一个 位置(position) 属性.鼠标按钮
@全局作用域按钮列表 包含每个可能按钮的 BUTTON* 常量列表, 它将在事件的button_index(按钮_索引)属性中报告. 注意, 鼠标滚轮也可以算作一个按钮——准确地说, 是两个按钮,BUTTON_WHEEL_UP(按钮_滚轮_向上)和BUTTON_WHEEL_DOWN(按钮_滚轮_向下)都是独立的事件. GDScript C#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")
public override void _Input(InputEvent inputEvent){ if (inputEvent is InputEventMouseButton mouseEvent && mouseEvent.Pressed) { switch ((ButtonList)mouseEvent.ButtonIndex) { case ButtonList.Left: GD.Print("Left button was clicked at ", {mouseEvent.Position}); break; case ButtonList.WheelUp: GD.Print("Wheel up"); break; } }}
鼠标行为
InputEventMouseMotion 只要鼠标移动就会发生事件. 可以通过relative属性找到移动的距离. 精灵 节点的例子: GDScript C#extends Nodevar dragging = falsevar 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 not dragging and event.pressed: dragging = true # Stop dragging if the button is released. if dragging and not event.pressed: dragging = false if event is InputEventMouseMotion and dragging: # While dragging, move the sprite with the mouse. $Sprite.position = event.position
using Godot;using System;public class Node2D : Godot.Node2D{ private bool dragging = false; private int clickRadius = 32; // Size of the sprite. public override void _Input(InputEvent inputEvent) { Sprite sprite = GetNodeOrNull<Sprite>("Sprite"); if (sprite == null) { return; // No suitable node was found. } if (inputEvent is InputEventMouseButton mouseEvent && (ButtonList)mouseEvent.ButtonIndex == ButtonList.Left) { if ((mouseEvent.Position - sprite.Position).Length() < clickRadius) { // Start dragging if the click is on the sprite. if (!dragging && mouseEvent.Pressed) { dragging = true; } } // Stop dragging if the button is released. if (dragging && !mouseEvent.Pressed) { dragging = false; } } else { if (inputEvent is InputEventMouseMotion motionEvent && dragging) { // While dragging, move the sprite with the mouse. sprite.Position = motionEvent.Position; } } }}
触摸事件
触摸屏幕输入事件 相当于鼠标点击事件, 并且 拖拽屏幕输入事件 的工作原理与鼠标移动非常相似. 小技巧 要在非触摸屏设备上测试触摸事件, 打开项目设置, 进入”输入设备(Input Devices)/指向(Pointing)”部分. 启用” 模拟鼠标触摸”, 您的项目将把鼠标单击和移动解释为触摸事件.
