Sites


Initiation à Godot

Manage Input

Manage Input

There are many ways to receive input in Godot Engine, but all of them come from the same source, the Input Event. We will discuss the basics of how to use input in your game, and a couple of alternatives.

Catching Input Events

Input Events are the way we get input from every OS on every platform. Whenever the state of the input device changes, we receive an event describing that change. Of course every OS and platform has a different way of describing these changes, and it's the job of the engine to put that into a standardized structure, we use the InputEvent structure (found in core/os/input_event.h).

Every Node in the scene can receive the raw Input Events that come into the game, following these steps.

  • First, add this method to your script in the Node:
func _input(event):
  if event.type == InputEvent.MOUSE_BUTTON:
    # do something here with the mouse button
  • Second, when you want to receive events, call this method:
set_input_event(true)

Some Nodes will want to receive input all the time, some will want to turn it on and off. It's up to you to decide, but remember that other Nodes will be receiving events at the same time, so you need to decide if a specific event is meat for your Node or not.

Check the InputEvent reference for a description of all the events you can receive.

Querying the state of the Input Devices

Catching Input Events is nice, but some times we don't want to keep track of the events, we just want to know what is the state of a button or position of the mouse at a certain moment. For this we use the helper class called Input (found in core/os/input.h). The Input class is a global singleton in GDScript, and can be used at many points in your script, but usually it's used in _process(), for example:

export var char_spped = 100 # 100 pixels per second

func _process(time):
  var character_walk = Vector2(0, 0)
  if Input.is_joy_button_pressed(0, JOY_DPAD_LEFT): # dpad left on joystick 0
    character_move.x = -(char_speed * time)
  elif Input.is_joy_button_pressed(0, JOY_DPAD_RIGHT):
    character_move.x = char_speed * time
  else:
    character_move.x = 0
  # apply character move to your character's position
Check the Input class reference for the full API 

Input Actions

When making a game with multiple input devices (for example joystick and keyboard), we want to avoid writing code to detect specific keyboard keys and joystick buttons, because it becomes too cumbresome and difficult to modify (also if we want to customize the input events). For this we use actions. An action represents an abstract event, and we can query any input event to check if it represents that action. To create an action: 

  1. In the Editor, go to  Scene > Project Settings
  2. On the top, go into the Input tab, you'll see a list of actions.
  3. Add an action : write jumpas the action name on top field and click add.
  4. For your new action, press the + icon, to add events. Add a Key, and a joystick button by pressing them. In our case we use space bar. Repeat for a restart game action.
     
  5. On your script, add this to your _input() method:
func _input(event):
  if event.is_action("jump") && event.is_pressed() && !event.is_echo():
    impulse()
func impulse():
impulse_cur = impulse_force
func stop():
set_process(false)
set_process_input(false)

func _process(time):
var dir = Vector2()
if !dead:
dir.x = speed * time
dir.y = -(impulse_cur - gravity) * time
if impulse_cur > 0:
impulse_cur -= gravity * time
set_pos(get_pos() + dir)
you’ll need to set the used variable to use this script plainly. Look at full source file if needed

Now your bat will jump when the jump event is pressed (but not when it's released, or when you get an echo pressed event from the keyboard).

Add the same to restart the game with this code in main_scene script :

func _input(event):
if event.is_action("restart") && event.is_pressed() && !event.is_echo():
restart()
func restart():
points = 0 bat.reset()
ui.reset() bat.start()
emit_signal("game_reset")
set_process(true)
spawn_ofs = 1000
get_node("animation").play("game_restart")
 

Similarily, you can query the state of an action on _process(). For example, imagine we could have walk_left and walk_right actions for a character, assigned to the arrow keys and pad keys left and right:

export var char_spped = 100 # 100 pixels per second

func _process(time):
  var character_walk = Vector2(0, 0)
  if Input.is_action_pressed("walf_keft"):
    character_move.x = -(char_speed * time)
  elif Input.is_action_pressed("walk_right"):
    character_move.x = char_speed * time
  else:
    character_move.x = 0
  # apply character move to your character's position
Check the InputEvent reference and the Input class reference for what you can do with actions.

Catching Input Events vs Querying Input States

By now you might be asking yourself, «what input method should I use? Both have benefits and drawbacks!». Short answer: use both!. As we've shown in the examples, both methods are useful in some case, and cumbresome in others. For example, for shooting, you want to know when the button is pressed, and ignore everything else, but for walking you want to know the state of the keys. Keep in mind a few tips:

  • Input events is the way we get information from the OS on all platforms, and the Input class is a helper implemented on top of the Events. So if you need raw data about input, check the events.
  • Sometimes, a key can be pressed and released within the same frame. In this case, Input won't tell you about the state change (because is_key_pressed, will be false), but you'll still receive the event for the press and release actions.
  • If you need to run the code that responds to events and to key states at the same time (for example both inside _process() as opposed to some on _input() and some on process() ), you can put your input events in a queue and process the queue in your _process method. It's not advisable to attempt to discern events from the information you get from Input (ie by comparing the state of a key in the current frame with the previous frame), because Input is just a helpers that uses the Input Events to maintain a state. It'll complicate your code, and you'll lose information along the way. Trust both methods to get the best out of your code!

Il y a une erreur de communication avec le serveur Booktype. Nous ne savons pas actuellement où est le problème.

Vous devriez rafraîchir la page.