Godot detect key pressed once

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Godot_PHTTP

Hello, I´m a beginner at Godot and to English. I have a project where I have a pigeon that flaps to right and to left. I want the pigeon to flap once, and not constantly when the left/right key is pressed. How can I achieve that?

Here is my script:

extends RigidBody2D

func _ready():
set_process_input(true)
pass

func _input(event):
if event is InputEventKey and event.pressed:
if event.scancode == KEY_RIGHT || event.scancode == KEY_D:
apply_impulse(Vector2(20, -20), Vector2(20, -20))

if event is InputEventKey and event.pressed:
	if event.scancode == KEY_LEFT || event.scancode == KEY_A: 
		 apply_impulse(Vector2(-20, -20), Vector2(-20, -20))

I´v tried different tutorials and posts, but what I want to do doesn´t show up anywhere, so that´s why I post this. (Sorryif it´s an obious solution, I´m new to Godot and GDscript).

Thanks in advance.

X

:bust_in_silhouette: Reply From: dethland

I think I get your problem. Try to use the button_relased to trigger the action of your character.

Something similar to below:

If Input.is_action_just_released:
   #your code here
   pass
:bust_in_silhouette: Reply From: Skelteon

First, I’d recommend using Input Map to set your custom actions. It will make your code much more readable.

Second, you could either use a dictionary to keep track of all button presses, or a single boolean for each key to see if it was being held last frame.

Assuming you use Input Map and set up an action called “left” that has 2 keys (left_arrow and A), you could do something like

var left_held = false

func _input(event):
  if event.is_action_pressed("left"):
    if not left_held:
      apply_impulse(Vector2(-20, -20), Vector2(-20, -20))
    left_held = true
  elif event.is_action_released("left"):
    left_held = false

If you wanted to use a dictionary, it would look like:

var buttons = {
  "left" = false,
  "right" = false
}

func _input(event):
  # same code as before but update the dictionary instead of boolean variables
:bust_in_silhouette: Reply From: AlexTheRegent

You also need to check echo property of InputEventKey class.

if event is InputEventKey and event.pressed and event.echo == false:
  # do your stuff

Also check out Input class, it has many functions to handle user input with ease.
Of particular interest are next functions:
Input.is_action_just_pressed
Input.is_action_pressed
Input.is_action_just_released
and many others. You will also need to read this tutorial to understand how to use input maps.