mirror of
https://github.com/stan220/godot-docs.git
synced 2026-09-08 17:28:58 +00:00
Add input examples tutorial
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
@@ -6,5 +6,6 @@ Inputs
|
||||
:name: toc-learn-features-inputs
|
||||
|
||||
inputevent
|
||||
input_examples
|
||||
mouse_and_input_coordinates
|
||||
custom_mouse_cursor
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
.. _doc_input_examples:
|
||||
|
||||
Input Examples
|
||||
==============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
In this tutorial, you'll learn how to use Godot's :ref:`InputEvent <class_InputEvent>`
|
||||
system to capture player input. There are many different types of input your
|
||||
game may use - keyboard, gamepad, mouse, etc. - and many different ways to
|
||||
turn those inputs into actions in your game. This document will show you some
|
||||
of the most common scenarios, which you can use as starting points for your
|
||||
own projects.
|
||||
|
||||
.. note:: For a detailed overview of how Godot's input event system works,
|
||||
see :ref:`doc_inputevent`.
|
||||
|
||||
Events versus polling
|
||||
---------------------
|
||||
|
||||
Sometimes you want your game to respond to a certain input event - pressing
|
||||
the "jump" button, for example. For other situations, you might want something
|
||||
to happen as long as a key is pressed, such as movement. In the first case,
|
||||
you can use the ``_input()`` function, which will be called whenever an input
|
||||
event occurs. In the second case, Godot provides the :ref:`Input <class_Input>`
|
||||
singleton, which you can use to query the state of an input.
|
||||
|
||||
Examples:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
# input event - runs when the input happens
|
||||
func _input(event):
|
||||
if event.is_action_pressed("jump"):
|
||||
jump()
|
||||
|
||||
# polling - runs every frame
|
||||
func _physics_process(delta):
|
||||
if Input.is_action_pressed("move_right"):
|
||||
# move as long as the key/button is pressed
|
||||
position.x += speed * delta
|
||||
|
||||
This gives you the flexibility to mix-and-match the type of input processing
|
||||
you do.
|
||||
|
||||
For the remainder of this tutorial, we'll focus on capturing individual
|
||||
events in ``_input()``.
|
||||
|
||||
Input events
|
||||
------------
|
||||
|
||||
Input events are objects that inherit from :ref:`InputEvent <class_InputEvent>`.
|
||||
Depending on the event type, the object will contain specific properties
|
||||
related to that event. To see what events actually look like, add a Node and
|
||||
attach the following script:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends Node
|
||||
|
||||
func _input(event):
|
||||
print(event.as_text())
|
||||
|
||||
As you press keys, move the mouse, and perform other inputs, you'll see each
|
||||
event scroll by in the output window. Here's an example of the output:
|
||||
|
||||
::
|
||||
|
||||
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)
|
||||
|
||||
As you can see, the results are very different for the different types of
|
||||
input. Key events are even printed as their key symbols. For example, let's consider :ref:`InputEventMouseButton <class_InputEventMouseButton>`.
|
||||
It inherits from the following classes:
|
||||
|
||||
- :ref:`InputEvent <class_InputEvent>` - the base class for all input events
|
||||
- :ref:`InputEventWithModifiers <class_InputEventWithModifiers>` - adds the ability to check if modifiers are pressed, such as ``Shift`` or ``Alt``.
|
||||
- :ref:`InputEventMouse <class_InputEventMouse>` - adds mouse event properties, such as ``position``
|
||||
- :ref:`InputEventMouseButton <class_InputEventMouseButton>` - contains the index of the button that was pressed, whether it was a double-click, etc.
|
||||
|
||||
.. tip:: It's a good idea to keep the class reference open while you're working
|
||||
with events so you can check the event type's available properties and
|
||||
methods.
|
||||
|
||||
You can encounter errors if you try and access a property on an input type that
|
||||
doesn't contain it - calling ``position`` on ``InputEventKey`` for example. To
|
||||
avoid this, make sure to test the event type first:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventMouseButton:
|
||||
print("mouse button event at ", event.position)
|
||||
|
||||
|
||||
InputMap
|
||||
--------
|
||||
|
||||
The :ref:`InputMap <class_InputMap>` is the most flexible way to handle a
|
||||
variety of inputs. You use this by creating named input *actions*, to which
|
||||
you can assign any number of input events, such as keypresses or mouse clicks.
|
||||
A new Godot project includes a number of default actions already defined. To
|
||||
see them, and to add your own, open Project -> Project Settings and select
|
||||
the InputMap tab:
|
||||
|
||||
.. image:: img/inputs_inputmap.png
|
||||
|
||||
Capturing actions
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once you've defined your actions, you can process them in your scripts using
|
||||
``is_action_pressed()`` and ``is_action_released()`` by passing the name of
|
||||
the action you're looking for:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("my_action"):
|
||||
print("my_action occurred!")
|
||||
|
||||
Keyboard events
|
||||
---------------
|
||||
|
||||
Keyboard events are captured in :ref:`InputEventKey <class_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" key:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventKey and event.pressed:
|
||||
if event.scancode == KEY_T:
|
||||
print("T was pressed")
|
||||
|
||||
.. tip:: See :ref:`@GlobalScope_KeyList <enum_@GlobalScope_KeyList>` for a list of scancode
|
||||
constants.
|
||||
|
||||
Keyboard modifiers
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Modifier properties are inherited from
|
||||
:ref:`InputEventWithModifiers <class_InputEventWithModifiers>`. This allows
|
||||
you to check for modifier combinations using boolean properties. Let's imagine
|
||||
you want one thing to happen when the "T" key is pressed, but something
|
||||
different when it's "Shift+T":
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
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")
|
||||
|
||||
.. tip:: See :ref:`@GlobalScope_KeyList <enum_@GlobalScope_KeyList>` for a list of scancode
|
||||
constants.
|
||||
|
||||
Mouse events
|
||||
------------
|
||||
|
||||
Mouse events stem from the :ref:`InputEventMouse <class_InputEventMouse>` class, and
|
||||
are separated into two types: :ref:`InputEventMouseButton <class_InputEventMouseButton>`
|
||||
and :ref:`InputEventMouseMotion <class_InputEventMouseMotion>`. Note that this
|
||||
means that all mouse events will contain a ``position`` property.
|
||||
|
||||
Mouse buttons
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Capturing mouse buttons is very similar to handling key events. :ref:`@GlobalScope_ButtonList <enum_@GlobalScope_ButtonList>`
|
||||
contains a list of ``BUTTON_*`` constants for each possible button, which will
|
||||
be reported in the event's ``button_index`` property. Note that the scrollwheel
|
||||
also counts as a button - two buttons, to be precise, with both
|
||||
``BUTTON_WHEEL_UP`` and ``BUTTON_WHEEL_DOWN`` being separate events.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
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")
|
||||
|
||||
Mouse motion
|
||||
~~~~~~~~~~~~
|
||||
|
||||
:ref:`InputEventMouseMotion <class_InputEventMouseMotion>` events occur whenever
|
||||
the mouse moves. You can find the move's distance with the ``relative``
|
||||
property.
|
||||
|
||||
Here's an example using mouse events to drag-and-drop a :ref:`Sprite <class_Sprite>`
|
||||
node:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
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
|
||||
|
||||
Touch events
|
||||
------------
|
||||
|
||||
If you are using a touchscreen device, you can generate touch events.
|
||||
:ref:`InputEventScreenTouch <class_InputEventScreenTouch>` is equivalent to
|
||||
a mouse click event, and :ref:`InputEventScreenDrag <class_InputEventScreenDrag>`
|
||||
works much the same as mouse motion.
|
||||
|
||||
.. tip:: To test your touch events on a non-touchscreen device, open Project
|
||||
Settings and go to the "Input Devices/Pointing" section. Enable "Emulate
|
||||
Touch From Mouse" and your project will interpret mouse clicks and
|
||||
motion as touch events.
|
||||
Reference in New Issue
Block a user