Приклади введення¶
Вступ¶
У цьому уроці ви дізнаєтеся, як використовувати систему вхідних подій Godot InputEvent для захоплення вводу гравця. Є багато різних типів введення, які ваша гра може використовувати - клавіатура, геймпад, миша і т. д. - і багато різних способів перетворити ці введення в дії у вашій грі. Цей документ покаже вам деякі з найбільш поширених сценаріїв, які ви можете використовувати як відправні точки для власних проектів.
Примітка
Детально робота системи вхідних подій Godot розглянута в Використання inputEvent.
Events versus polling¶
Іноді ви хочете, щоб ваша гра реагувала на певну вхідну подію - наприклад, натискання кнопки "стрибка". В інших ситуаціях ви можете хотіти, щоб щось відбувалося, коли натиснута клавіша, наприклад, рух. У першому випадку можна скористатися функцією _input()
, яка буде викликатися при виникненні вхідної події. Для другого випадку Godot надає синглтон Input, який можна використовувати для запиту стану вводу.
Приклади:
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()
.
Вхідні події¶
Вхідні події - це об'єкти, які успадковуються від InputEvent. Залежно від типу події об'єкт міститиме певні властивості, пов'язані з цією подією. Щоб побачити, як насправді виглядають події, додайте вузол і прикріпіть такий скрипт:
extends Node
func _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());
}
}
При натисканні клавіші, переміщенні мишку та виконанні іншого введення, ви можете бачити, що кожна подія прокручується у вікні виводу. Ось приклад виводу:
A
InputEventMouseMotion : 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=false
InputEventMouseButton : button_index=BUTTON_LEFT, pressed=false, position=(108, 107), button_mask=0, doubleclick=false
S
F
Alt
InputEventMouseMotion : button_mask=0, position=(108, 107), relative=(0, -1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)
Як бачите, результати дуже різні для різних типів введення. Події клавіш навіть друкуються як символи, за які вони відповідають. Для прикладу, розглянемо вхідну події клавіші мишки InputEventMouseButton. Вона успадковується від наступних класів:
InputEvent - базовий клас для всіх вхідних подій
InputEventWithModifiers - додає можливість перевірити, чи натиснуті модифікатори, такі як Shift, або Alt.
InputEventMouse - додає властивості події мишки, такі як
position
InputEventMouseButton - містить індекс клавіші, яка була натиснута, чи це було подвійне клацання і т. д.
Порада
Рекомендовано тримати посилання на клас відкритим під час роботи з подіями, щоб ви могли перевірити доступні властивості та методи типу події.
Ви можете зіткнутися з помилками, при спробі отримати доступ до тої властивості типу введення, якої він не містить , наприклад, викликати position
з InputEventKey
. Щоб уникнути цього, спочатку перевіряйте тип події:
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 (карта введення)¶
Карта введення InputMap є найбільш гнучким способом обробки різних вводів. Ви використовуєте її, створюючи іменовані вхідні дії, яким можна призначити будь-яку кількість вхідних подій, таких як натискання клавіш, або клацання мишкою. Новий проект Godot містить ряд уже визначених дій за замовчуванням. Щоб переглянути їх і додати власні, відкрийте вікно Проект -> Параметри проекту та перейдіть на вкладку Карта введення:

Захоплення дій¶
Визначивши дії, ви можете обробити їх у своїх скриптах, використовуючи is_action_pressed()
та is_action_released()
, передаючи назву дії, яку ви шукаєте:
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:
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");
}
}
}
Порада
Перегляньте @GlobalScope_KeyList, щоб ознайомитися зі списком констант сканкоду.
Попередження
Due to keyboard ghosting, not all key inputs may be registered at a given time if you press too many keys at once. Due to their location on the keyboard, certain keys are more prone to ghosting than others. Some keyboards feature antighosting at a hardware level, but this feature is generally not present on low-end keyboards and laptop keyboards.
As a result, it's recommended to use a default keyboard layout that is designed to work well on a keyboard without antighosting. See this Gamedev Stack Exchange question for more information.
Модифікатори клавіатури¶
Властивості модифікатора успадковуються від 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")
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;
}
}
}
Порада
Перегляньте @GlobalScope_KeyList, щоб ознайомитися зі списком констант сканкоду.
Події мишки¶
Події миші випливають з класу InputEventMouse і розділені на два типи: InputEventMouseButton та InputEventMouseMotion. Зауважте, що це означає, що всі події мишки міститимуть властивість position
.
Рух мишки¶
Події 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 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;
}
}
}
}
Сенсорні події¶
Якщо використовується сенсорний пристрій, можна генерувати сенсорні події. InputEventScreenTouch еквівалентний події клацання мишки, а InputEventScreenDrag працює так само, як і рух мишки.
Порада
Щоб перевірити сенсорні події на пристрої без сенсорного екрана, відкрийте вікно Параметри проекту та перейдіть до розділу Пристрої вводу/вказівки. Увімкніть "Emulate Touch From Mouse" ("Емулювати дотик від миші"), і ваш проект інтерпретуватиме клацання та рух мишки, як сенсорні події.