The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

0 votes

So I tried to make dynamic analog for mobile game. I try to get start position and end position drag from TouchScreenButton, and then calculate it for my Character movement. First it is worked, but after I create new TouchScreenButton for other thing the problem come.

Here is the code

var startpos = Vector2()
var endpos = Vector2()
var pos = Vector2()

func _input(event):
    if event is InputEventScreenTouch:
        if $MoveAnalog/Move.is_pressed():
            startpos = event.position

        if $MoveAnalog/Action.is_pressed():
            dash = true

    if event is InputEventScreenDrag:
        if $MoveAnalog/Move.is_pressed():
            endpos = event.position
            pos = (endpos - startpos).normalized()

The problem is when I moving and I press the Action button, my startpos move into $MoveAnalog/Action event position.

How do I make the startpos to not detect or move to $MoveAnalog/Action?

Godot version 3.4
in Engine by (29 points)
edited by

Is there any reason on that you don't use pressed() and released() signals from TouchScreenButon like below?

var pos = Vector2.ZERO
var speed = Vector2.ZERO
onready var character = $Character_Node_Here
onready var buttonpos = $TouchScreenButton.position

func _ready() -> void:
    set_process(true)

func _process(delta: float) -> void:
    if speed != Vector2.ZERO:
        speed = get_global_mouse_position() - buttonpos
        character.position += delta * 50 * Vector2(speed / 10)
    pass

func _on_TouchScreenButton_pressed() -> void: # pressed signal connected
    speed = get_global_mouse_position() - buttonpos
    print("pressed")

func _on_TouchScreenButton_released() -> void: # released signal connected
    speed = Vector2.ZERO
    print("released")

I was trying from the signal and it is same. And I need some code from the event function.

This is my character movement if you want to see it

var vec = Vector2()
var startpos = Vector2()
var endpos = Vector2()
var pos = Vector2()

func _physics_process(delta):

    touch_move()

    if vec == Vector2():
        animstate.travel("Idle")
    else:
        animstate.travel("Walk")
        anim.set("parameters/Walk/blend_position", vec)
        anim.set("parameters/Idle/blend_position", vec)
        anim.set("parameters/Attack/blend_position", vec)
        anim.set("parameters/Jump/blend_position", vec)
        move_and_slide(vec * speed)

func touch_move():
    if pos.x > 0.5:
        vec.x = 10
    if pos.x < -0.5:
        vec.x = -10
    if pos.y > 0.5:
        vec.y = 10
    if pos.y < -0.5:
        vec.y = -10

func _input(event):
    if event is InputEventScreenTouch:
        if $MoveAnalog/Move.is_pressed():
            startpos = event.position

        if $MoveAnalog/Action.is_pressed():
            dash = true

    if event is InputEventScreenDrag:
        if $MoveAnalog/Move.is_pressed():
            endpos = event.position
            pos = (endpos - startpos).normalized()

The reason why I made the movement like that is because I want to make my movement locked to 8 direction only

1 Answer

+1 vote
Best answer

Sorry I couldn't answer well that time.

Scene sctructure

Control <- script attached
    Control
        MoveButton - emit pressed & released signals connected to script
    Control2
        DashButton - emit pressed & released signals connected to script
    Character

For every control node, in Inspector dock, go to Mouse > Filter and set the field as Ignore

Source code is here.
*adding explanation

extends Control

# global_pos = current MoveButton touch position
# pos = normalized character direction.
# vec = variable for storing movement speed
var global_pos = Vector2.ZERO
var pos = Vector2.ZERO
var vec = Vector2.ZERO

# dash = dashmode, move = movemode
# If you want to add more buttons, you can use button_queue for more touch inputs
# touches = total touch points in screen (limited to 10 in _unhandled_input func)
# button_index = store which button is pressed with which index. If touch index is 3 and you pressed move button, button_index[3] = 0
var dash: bool = false
var move: bool = false
var button_queue = []
var touches = []
var button_index = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1]

# Character Sprite and calculated center of each Buttons.
onready var character = $Character
onready var btn_pos = [$Control.rect_position+Vector2(32,32), $Control2.rect_position+Vector2(32,32)]#[$Control/MoveButton.position, $Control2/DashButton.position]


func _ready() -> void:
    set_process(true)

func _process(delta: float) -> void:
    # only runs when move is true
    if move == true:
        pos = (global_pos - btn_pos[0]).normalized()
        vec = Vector2.ZERO
        if pos.y < 0:
            if abs(pos.x*2.0) < abs(pos.y):
                vec.y = -1
            elif abs(pos.x*2.0) >= abs(pos.y) && abs(pos.y*2.0) >= abs(pos.x):
                vec.y = -1
                if pos.x < 0:
                    vec.x = -1
                else:
                    vec.x = 1
            else:
                if pos.x < 0:
                    vec.x = -1
                else:
                    vec.x = 1
        else:
            if abs(pos.x*2.0) < abs(pos.y):
                vec.y = 1
            elif abs(pos.x*2.0) >= abs(pos.y) && abs(pos.y*2.0) >= abs(pos.x):
                vec.y = 1
                if pos.x < 0:
                    vec.x = -1
                else:
                    vec.x = 1
            else:
                if pos.x < 0:
                    vec.x = -1
                else:
                    vec.x = 1
        # you can change this part to increase/decrease/normalize speed of character
        character.position += vec if dash == false else vec * 2
    pass

func _on_TouchScreenButton_pressed() -> void: # pressed signal connected
    move = true
    button_queue.append(0)

func _on_TouchScreenButton_released() -> void: # released signal connected
    move = false

func _on_TouchScreenButton2_pressed() -> void: # pressed signal connected
    dash = true

func _on_TouchScreenButton2_released() -> void: # released signal connected
    dash = false

func _unhandled_input(event):
    if event is InputEventScreenTouch:
        if event.is_pressed():
            if touches.size() <= 10: # Ignore more than 10 stimultanous touches
                touches.append(event.index)
                if not button_queue.empty(): # check button queue if button is pressed
                    button_index[event.index] = button_queue[0]
                    button_queue.remove(0)
        else: # released
            for i in range(0, touches.size()):
                if touches[i] == event.index:
                    touches.remove(i)
                    break
    if event is InputEventScreenDrag: # dragging while button is pressed
        if button_index[event.index] == 0:
            global_pos = event.position

Above code can:

  1. get up to 10 touch inputs stimultanously
  2. move and dash character 8 direction
  3. you can still use events. And also you can manipulate anything you want.

functions connected to signals will always run faster than unhandledinput function

by (236 points)
selected by
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 Frequently asked questions and 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 [email protected] with your username.