+3 votes

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 physicsprocess()

in Engine by (78 points)

2 Answers

+2 votes
Best answer

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()
by (78 points)

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")
0 votes

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.

by (318 points)
edited by

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.

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

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

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

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

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.