input_examples.rst 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. .. _doc_input_examples:
  2. Input examples
  3. ==============
  4. Introduction
  5. ------------
  6. In this tutorial, you'll learn how to use Godot's :ref:`InputEvent <class_InputEvent>`
  7. system to capture player input. There are many different types of input your
  8. game may use - keyboard, gamepad, mouse, etc. - and many different ways to
  9. turn those inputs into actions in your game. This document will show you some
  10. of the most common scenarios, which you can use as starting points for your
  11. own projects.
  12. .. note:: For a detailed overview of how Godot's input event system works,
  13. see :ref:`doc_inputevent`.
  14. Events versus polling
  15. ---------------------
  16. Sometimes you want your game to respond to a certain input event - pressing
  17. the "jump" button, for example. For other situations, you might want something
  18. to happen as long as a key is pressed, such as movement. In the first case,
  19. you can use the ``_input()`` function, which will be called whenever an input
  20. event occurs. In the second case, Godot provides the :ref:`Input <class_Input>`
  21. singleton, which you can use to query the state of an input.
  22. Examples:
  23. .. tabs::
  24. .. code-tab:: gdscript GDScript
  25. # input event - runs when the input happens
  26. func _input(event):
  27. if event.is_action_pressed("jump"):
  28. jump()
  29. # polling - runs every frame
  30. func _physics_process(delta):
  31. if Input.is_action_pressed("move_right"):
  32. # move as long as the key/button is pressed
  33. position.x += speed * delta
  34. This gives you the flexibility to mix-and-match the type of input processing
  35. you do.
  36. For the remainder of this tutorial, we'll focus on capturing individual
  37. events in ``_input()``.
  38. Input events
  39. ------------
  40. Input events are objects that inherit from :ref:`InputEvent <class_InputEvent>`.
  41. Depending on the event type, the object will contain specific properties
  42. related to that event. To see what events actually look like, add a Node and
  43. attach the following script:
  44. .. tabs::
  45. .. code-tab:: gdscript GDScript
  46. extends Node
  47. func _input(event):
  48. print(event.as_text())
  49. As you press keys, move the mouse, and perform other inputs, you'll see each
  50. event scroll by in the output window. Here's an example of the output:
  51. ::
  52. A
  53. InputEventMouseMotion : button_mask=0, position=(551, 338), relative=(-85, 47), speed=(0, 0)
  54. InputEventMouseButton : button_index=BUTTON_LEFT, pressed=true, position=(551, 338), button_mask=1, doubleclick=false
  55. InputEventMouseButton : button_index=BUTTON_LEFT, pressed=false, position=(551, 338), button_mask=0, doubleclick=false
  56. S
  57. F
  58. InputEventMouseMotion : button_mask=0, position=(547, 338), relative=(-1, 0), speed=(0, 0)
  59. InputEventMouseMotion : button_mask=0, position=(542, 338), relative=(-4, 0), speed=(0, 0)
  60. As you can see, the results are very different for the different types of
  61. input. Key events are even printed as their key symbols. For example, let's consider :ref:`InputEventMouseButton <class_InputEventMouseButton>`.
  62. It inherits from the following classes:
  63. - :ref:`InputEvent <class_InputEvent>` - the base class for all input events
  64. - :ref:`InputEventWithModifiers <class_InputEventWithModifiers>` - adds the ability to check if modifiers are pressed, such as ``Shift`` or ``Alt``.
  65. - :ref:`InputEventMouse <class_InputEventMouse>` - adds mouse event properties, such as ``position``
  66. - :ref:`InputEventMouseButton <class_InputEventMouseButton>` - contains the index of the button that was pressed, whether it was a double-click, etc.
  67. .. tip:: It's a good idea to keep the class reference open while you're working
  68. with events so you can check the event type's available properties and
  69. methods.
  70. You can encounter errors if you try to access a property on an input type that
  71. doesn't contain it - calling ``position`` on ``InputEventKey`` for example. To
  72. avoid this, make sure to test the event type first:
  73. .. tabs::
  74. .. code-tab:: gdscript GDScript
  75. func _input(event):
  76. if event is InputEventMouseButton:
  77. print("mouse button event at ", event.position)
  78. InputMap
  79. --------
  80. The :ref:`InputMap <class_InputMap>` is the most flexible way to handle a
  81. variety of inputs. You use this by creating named input *actions*, to which
  82. you can assign any number of input events, such as keypresses or mouse clicks.
  83. A new Godot project includes a number of default actions already defined. To
  84. see them, and to add your own, open Project -> Project Settings and select
  85. the InputMap tab:
  86. .. image:: img/inputs_inputmap.png
  87. Capturing actions
  88. ~~~~~~~~~~~~~~~~~
  89. Once you've defined your actions, you can process them in your scripts using
  90. ``is_action_pressed()`` and ``is_action_released()`` by passing the name of
  91. the action you're looking for:
  92. .. tabs::
  93. .. code-tab:: gdscript GDScript
  94. func _input(event):
  95. if event.is_action_pressed("my_action"):
  96. print("my_action occurred!")
  97. Keyboard events
  98. ---------------
  99. Keyboard events are captured in :ref:`InputEventKey <class_InputEventKey>`.
  100. While it's recommended to use input actions instead, there may be cases where
  101. you want to specifically look at key events. For this example, let's check for
  102. the "T" key:
  103. .. tabs::
  104. .. code-tab:: gdscript GDScript
  105. func _input(event):
  106. if event is InputEventKey and event.pressed:
  107. if event.scancode == KEY_T:
  108. print("T was pressed")
  109. .. tip:: See :ref:`@GlobalScope_KeyList <enum_@GlobalScope_KeyList>` for a list of scancode
  110. constants.
  111. Keyboard modifiers
  112. ~~~~~~~~~~~~~~~~~~
  113. Modifier properties are inherited from
  114. :ref:`InputEventWithModifiers <class_InputEventWithModifiers>`. This allows
  115. you to check for modifier combinations using boolean properties. Let's imagine
  116. you want one thing to happen when the "T" key is pressed, but something
  117. different when it's "Shift+T":
  118. .. tabs::
  119. .. code-tab:: gdscript GDScript
  120. func _input(event):
  121. if event is InputEventKey and event.pressed:
  122. if event.scancode == KEY_T:
  123. if event.shift:
  124. print("Shift+T was pressed")
  125. else:
  126. print("T was pressed")
  127. .. tip:: See :ref:`@GlobalScope_KeyList <enum_@GlobalScope_KeyList>` for a list of scancode
  128. constants.
  129. Mouse events
  130. ------------
  131. Mouse events stem from the :ref:`InputEventMouse <class_InputEventMouse>` class, and
  132. are separated into two types: :ref:`InputEventMouseButton <class_InputEventMouseButton>`
  133. and :ref:`InputEventMouseMotion <class_InputEventMouseMotion>`. Note that this
  134. means that all mouse events will contain a ``position`` property.
  135. Mouse buttons
  136. ~~~~~~~~~~~~~
  137. Capturing mouse buttons is very similar to handling key events. :ref:`@GlobalScope_ButtonList <enum_@GlobalScope_ButtonList>`
  138. contains a list of ``BUTTON_*`` constants for each possible button, which will
  139. be reported in the event's ``button_index`` property. Note that the scrollwheel
  140. also counts as a button - two buttons, to be precise, with both
  141. ``BUTTON_WHEEL_UP`` and ``BUTTON_WHEEL_DOWN`` being separate events.
  142. .. tabs::
  143. .. code-tab:: gdscript GDScript
  144. func _input(event):
  145. if event is InputEventMouseButton:
  146. if event.button_index == BUTTON_LEFT and event.pressed:
  147. print("Left button was clicked at ", event.position)
  148. if event.button_index == BUTTON_WHEEL_UP and event.pressed:
  149. print("Wheel up")
  150. Mouse motion
  151. ~~~~~~~~~~~~
  152. :ref:`InputEventMouseMotion <class_InputEventMouseMotion>` events occur whenever
  153. the mouse moves. You can find the move's distance with the ``relative``
  154. property.
  155. Here's an example using mouse events to drag-and-drop a :ref:`Sprite <class_Sprite>`
  156. node:
  157. .. tabs::
  158. .. code-tab:: gdscript GDScript
  159. extends Node
  160. var dragging = false
  161. var click_radius = 32 # Size of the sprite
  162. func _input(event):
  163. if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
  164. if (event.position - $Sprite.position).length() < click_radius:
  165. # Start dragging if the click is on the sprite.
  166. if !dragging and event.pressed:
  167. dragging = true
  168. # Stop dragging if the button is released.
  169. if dragging and !event.pressed:
  170. dragging = false
  171. if event is InputEventMouseMotion and dragging:
  172. # While dragging, move the sprite with the mouse.
  173. $Sprite.position = event.position
  174. Touch events
  175. ------------
  176. If you are using a touchscreen device, you can generate touch events.
  177. :ref:`InputEventScreenTouch <class_InputEventScreenTouch>` is equivalent to
  178. a mouse click event, and :ref:`InputEventScreenDrag <class_InputEventScreenDrag>`
  179. works much the same as mouse motion.
  180. .. tip:: To test your touch events on a non-touchscreen device, open Project
  181. Settings and go to the "Input Devices/Pointing" section. Enable "Emulate
  182. Touch From Mouse" and your project will interpret mouse clicks and
  183. motion as touch events.