How to differentiate between InputEventScreenTouch and InputEventScreenDrag?

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

I’m building a 2d game where the player can move up and down the y axis.

I want to create 3 movement types:

  1. Ascend
  2. Dive
  3. Boost up

The first is a simple movement that happens when InputScreenTouch is registered.
The second and third are dependent on whether the player swipes up or swipe down, which I am assuming is the purpose of “InputEventScreenDrag”.

I’d appreciate any clue as to how I am able to differentiate between the different events and to use it to move the character.

The character is KinematicBody2d and position is changed within _physics_process()

:bust_in_silhouette: Reply From: hinasis

InputEventScreenDrag is an event that is a complete action.
It has two parameters you need for what you want to do, position and relative, well I think relative is enough for this.
The relative parameter is a position relative to position and position is the start point of the the “swipe” action. So you can check, in your case, if the relative.y is positive or negative, if it’s negative it’s a “swipe up”, and positive a “swipe down”.

I could be giving you incorrect information, because I haven’t tried it, but it’s what it looks like. The docs are missing information.

It’s probable that there is a better way to catch touch gestures, but I can’t find it.
I mean, ScreenDrag can be a very slow movement, not just a swipe. May be it’s something related to the speed paramenter.

Yeah thanks

I’m really confused. I get that InputEventScreenDrag has speed, position and relative but I am not even sure how to handle the input if I am also looking for InputEventScreenTouch. The second the screen is touched InputEventScreenTouch must be registered right, so how do I differentiate it.

Also there is very little info regarding speed, is it measured in pixels per second or per frame, what constitutes fast or slow.

As you said the Docs are missing a lot of info.

alfandango | 2018-07-20 23:45

Do you mean something like:

func ready():
	your_character.connect("input_event",self,"on_input_event")

func on_input_event(viewport,event,shape_idx):
	if event is InputEventScreenTouch && event.pressed:
		#blabla
	if event is InputEventScreenDrag:
		#blabla

Every event pass through it, so you won’t miss any event, touch or drag.

Note: I think the next code works without the signal connection, I’m still a rookie:

func _input_event(viewport,event,shape_idx):
	if event is InputEventScreenTouch && event.pressed:
		#blabla
	if event is InputEventScreenDrag:
		#blabla

hinasis | 2018-07-21 04:44

You’ve blown my mind a little here.

Where did you see the your_character.connect("input_event",self,"on_input_event") ? I haven’t seen any documentation on Input handling using such a method.

You’re second snippet may have given me an idea

alfandango | 2018-07-21 07:44

Haha, I said I’m a rookie.
You said your character is a KinematicBody2D that comes from CollisionObject2D that handles its input with the virtual method _input_event() and emits the input_eventsignal, and you are supposed to use that signal outside the node, as I do in most cases delegating inputs to a parent. But here you can just override the method.
I’m confused too! Sorry

hinasis | 2018-07-21 14:08

appreciate the help, I got it to work! :smiley:

alfandango | 2018-07-21 21:02

:bust_in_silhouette: Reply From: alfandango

So it seems the engine is quite intuitive.

Using KinematicBody2d I was able to create different movements depending on whether the user swipes up, swipes down or just taps the screen (in simulation)

func _input(event):
	if event is InputEventScreenDrag:
		if event.speed.y < -10:
			self.state = BOOST
                    self.character_on_input_press_position = self.position
			self.get_tree().set_input_as_handled()
		elif event.speed.y > 10:
			self.state = DIVE
			self.character_on_input_press_position = self.position
			self.get_tree().set_input_as_handled()
	elif event is InputEventScreenTouch:
		if event.pressed:
			self.state = FLY
			self.character_on_input_press_position = self.position
			self.get_tree().set_input_as_handled()

This doesn’t work for me. If Drag is triggered, so is Touch:

if event is InputEventScreenDrag:
	if event.speed.y < -0.2:
		print("swipe up")
		emit_signal("up")
		self.get_tree().set_input_as_handled()
		return
	elif event.speed.y > 0.2:
		print("swipe down")
		emit_signal("down")
		self.get_tree().set_input_as_handled()
		return
elif event is InputEventScreenTouch:
	if event.pressed:
		calculate_touch(get_node("../player").get_global_mouse_position(), event)
	if not event.pressed:
		emit_signal("none")

ishfwilf | 2019-05-25 11:08