Exemples d’entrée

Introduction

Dans ce tutoriel, vous apprendrez comment utiliser le système InputEvent de Godot pour capturer les entrées du joueur. Il existe de nombreux types d’entrée différents que votre jeu peut utiliser - clavier, manette de jeu, souris, etc. - et de nombreuses façons de transformer ces entrées en actions dans votre jeu. Ce document vous présentera certains des scénarios les plus courants, que vous pourrez utiliser comme point de départ pour vos propres projets.

Note

Pour un aperçu détaillé du fonctionnement du système d’événements d’entrée de Godot, voir InputEvent.

Événements comparés aux sondages

Parfois, vous voulez que votre jeu réponde à un certain événement d’entrée - en appuyant sur le bouton « sauté », par exemple. Pour d’autres situations, vous pourriez vouloir que quelque chose se produise tant qu’une touche est enfoncée, comme un mouvement. Dans le premier cas, vous pouvez utiliser la fonction _input(), qui sera appelée à chaque fois qu’un événement d’entrée se produit. Dans le second cas, Godot fournit le singleton Input, que vous pouvez utiliser pour interroger l’état d’une entrée.

Exemples :

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;
    }
}

Cela vous donne la flexibilité de combiner le type de traitement des entrées que vous effectuez.

Pour le reste de ce tutoriel, nous allons nous concentrer sur la capture d’événements individuels dans _input().

Événement d’entrée

Les événements d’entrée sont des objets qui héritent de InputEvent. Selon le type d’événement, l’objet contiendra des propriétés spécifiques liées à cet événement. Pour voir à quoi ressemblent réellement les événements, ajoutez un nœud et attachez le script suivant :

extends Node

func _input(event):
    print(event.as_text())
public override void _Input(InputEvent inputEvent)
{
    GD.Print(inputEvent.AsText());
}

Lorsque vous appuyez sur les touches, déplacez la souris et effectuez d’autres entrées, vous verrez chaque événement défiler dans la fenêtre de sortie. Voici un exemple de la sortie :

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)

Comme vous pouvez le voir, les résultats sont très différents pour les différents types de saisie. Les événements de touches sont même imprimés en tant que symboles de touches. Par exemple, considérons InputEventMouseButton. Il hérite des classes suivantes :

  • InputEvent - la classe de base pour tous les événements d’entrée
  • InputEventWithModifiers - adds the ability to check if modifiers are pressed, such as Shift or Alt.
  • InputEventMouse - ajoute les propriétés des événements de la souris, comme position
  • InputEventMouseButton - contient l’index du bouton qui a été pressé, si c’était un double-clic, etc.

Astuce

C’est une bonne idée de garder la référence de la classe ouverte lorsque vous travaillez avec des événements afin de pouvoir vérifier les propriétés et les méthodes disponibles du type d’événement.

Vous pouvez rencontrer des erreurs si vous essayez d’accéder à une propriété sur un type d’entrée qui ne la contient pas - en appelant position sur InputEventKey par exemple. Pour éviter cela, assurez-vous de tester d’abord le type d’événement :

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

La InputMap est la façon la plus flexible de gérer une variété d’entrées. Vous utilisez ceci en créant des actions d’entrée nommées, auxquelles vous pouvez attribuer un nombre quelconque d’événements d’entrée, tels que des pressions de touches ou des clics de souris. Un nouveau projet Godot comprend un certain nombre d’actions par défaut déjà définies. Pour les voir, et pour ajouter les vôtres, ouvrez Projet -> Paramètres du projet et sélectionnez l’onglet InputMap :

../../_images/inputs_inputmap.png

Capturer les actions

Une fois que vous avez défini vos actions, vous pouvez les traiter dans vos scripts en utilisant is_action_pressed() et is_action_released() en passant le nom de l’action que vous recherchez :

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!");
    }
}

Événements clavier

Keyboard events are captured in InputEventKey. While it’s recommended to use input actions instead, there may be cases where you want to specifically look at key events. For this example, let’s check for the 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.Scancode == KeyList.T)
        {
            GD.Print("T was pressed");
        }
    }
}

Astuce

Voir @GlobalScope_KeyList pour une liste des constantes du scancode.

Modificateurs de clavier

Modifier properties are inherited from InputEventWithModifiers. This allows you to check for modifier combinations using boolean properties. Let’s imagine you want one thing to happen when the T is pressed, but something different when it’s 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;
        }
    }
}

Astuce

Voir @GlobalScope_KeyList pour une liste des constantes du scancode.

Événements souris

Les événements souris proviennent de la classe InputEventMouse, et sont séparés en deux types : InputEventMouseButton et InputEventMouseMotion. Notez que cela signifie que tous les événements souris contiendront une propriété position.

Boutons de la souris

La capture des boutons de la souris est très similaire à la gestion des événements touches. @GlobalScope_ButtonList contient une liste de constantes BUTTON_* pour chaque bouton possible, qui sera rapportée dans la propriété button_index de l’événement. Notez que la molette de défilement compte aussi comme un bouton - deux boutons, pour être précis, avec les deux BUTTON_WHEEL_UP et BUTTON_WHEEL_DOWN étant des événements séparés.

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 as 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;
        }
    }
}

Mouvement de la souris

InputEventMouseMotion les événements se produisent à chaque fois que la souris bouge. Vous pouvez trouver la distance du mouvement avec la propriété relative.

Voici un exemple d’utilisation des événements de la souris pour glisser-déposer un nœud 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
public override void _Input(InputEvent inputEvent)
{
    var 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 = !dragging;
        }
        // Stop dragging if the button is released.
        if (dragging && !mouseEvent.Pressed)
        {
            dragging = false;
        }
    }
    else
    {
        if (inputEvent is InputEventMouseMotion motionEvent)
        {
            // While dragging, move the sprite with the mouse.
            sprite.Position = motionEvent.Position;
        }
    }
}

Événements tactiles

Si vous utilisez un appareil avec un écran tactile, vous pouvez générer des événements tactiles. InputEventScreenTouch est équivalent à un événement de clic de souris, et InputEventScreenDrag fonctionne à peu près de la même manière qu’un mouvement de souris.

Astuce

Pour tester vos événements tactiles sur un appareil sans écran tactile, ouvrez Paramètres de projet et allez à la section « Input Devices/Pointing ». Activez « Emulate Touch From Mouse » et votre projet interprétera les clics et les mouvements de la souris comme des événements tactiles.