Sites


Godot Game Engine

Managing input

There are many ways to receive input in Godot Engine, but all of them come from the same source, the input event. In this section, we discuss the basics of how to use input in your game, and the various 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, which is in Godot the InputEventstructure (found incore/os/input_event.h).

Every node in the scene can receive the raw input events that come into the game, following these steps.

  • First, override the builtin_input(event) method in your script attached to the node:
 func _input(event):
  if (event.type == InputEvent.MOUSE_BUTTON):
    # do something here with the mouse button
  • Then, when you want to start processing events (using the_input(event) method that you wrote), call this method:
 set_process_input(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 meant for your node or not.

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

Querying the state of the input devices

Catching input events is nice, but sometimes we do not 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 incore/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 is used in _process(), for example:

 export var char_speed = 100 # pixels/second

func _process(delta):
  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*delta)
  elif (Input.is_joy_button_pressed(0, JOY_DPAD_RIGHT)): # DPad right on joystick 0
    character_move.x = char_speed*delta
  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 (especially 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 Map tab, you will see a list of actions.
  3. Add an action: write jump as the action name in text 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 the space bar. Repeat those steps to add arestart action.
     
You can then use those input actions directly in the script attached to the bat node:
 const gravity = 10
var dead = false
var speed = 100
var impulse_cur = 0
 func _input(event):
  if (event.is_action("jump") and event.is_pressed() and !event.is_echo()):
    impulse()
 func impulse():
impulse_cur = impulse_force
 func _process(delta):
var dir = Vector2()
if (!dead):
dir.x = speed*delta
dir.y = -(impulse_cur - gravity)*delta
if (impulse_cur > 0):
impulse_cur -= gravity*delta
set_pos(get_pos() + dir)
You will need to set the used global variables to use this script plainly. Look at full source file if needed.

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

Add the same to restart the game with this code in the 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 that we have walk_left and walk_right actions for a character, assigned to the arrow keys and pad keys left and right:

 export var char_speed = 100 # pixels/second

func _process(delta):
  var character_walk = Vector2(0, 0)
  if Input.is_action_pressed("walk_left"):
    character_move.x = -(char_speed*delta)
  elif Input.is_action_pressed("walk_right"):
    character_move.x = char_speed*delta
  else:
    character_move.x = 0
  # apply character move to your character's position

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 have shown in the examples, both methods are useful in some cases, and cumbersome 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 will not tell you about the state change (because is_key_pressed, will be false), but you will 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 is not advised to attempt to discern events from the information you get from Input (i.e. by comparing the state of a key in the current frame with the previous frame), because Input is just a helper that uses the input events to maintain a state. It will complicate your code, and you will 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.