0 votes

Hi.
after adding touchscreen controller to scene, 2 issues appeared:
1. after releasing touchscreen controller, character keeps moving and does not stop and it affects on keyboard input key as well (i could fixed this with "isactionjust_released" command for keyboard's input keys, but it wasn't a general solution for this problem)
2. character change its direction in U turn and not instantly.

how should i fix these problems? (especially first one), Thank You.

(I used controller codes from godot's templates made by Jakub Grzesik)

codes for moving KinematicBody2D:

func _physics_process(delta):
        if Input.is_action_pressed("ui_right"):
           velocity.x += 1
        if Input.is_action_pressed("ui_left"):
           velocity.x -= 1
        if Input.is_action_pressed("ui_down"):
           velocity.y += 1
        if Input.is_action_pressed("ui_up"):
           velocity.y -= 1

  velocity += outer_velocity

  if velocity.length() > 0:
     velocity = velocity.normalized()*speed*delta
  motion = move_and_collide(velocity)
  if (motion):
     motion = move_and_slide(velocity * 60)

#### Touch Controller Function
func analog_force_change(inForce, inStick):
    if(inStick.get_name()=="Directions"):
        if inForce.length() < 0.1:
            outer_velocity = Vector2(0,0) 
        else:
            outer_velocity.x = inForce.x
            outer_velocity.y = -inForce.y
        #Convert outer velocity to 0 , 1 , -1 

        outer_velocity.x = int(round(outer_velocity.x))
        outer_velocity.y = int(round(outer_velocity.y))

        outer_velocity.x = stepify(outer_velocity.x, 1)
        outer_velocity.y = stepify(outer_velocity.y, 1)
        #print(outer_velocity)

Touchscreen Controller code:

extends Node2D

const INACTIVE_IDX = -1;
export var isDynamicallyShowing = false
export var listenerNodePath = "/root/PvPD/Player01D"
export var padname = ""

var ball
var bg 
var animation_player
var parent
var listenerNode

var centerPoint = Vector2(0,0)
var currentForce = Vector2(0,0)
var halfSize = Vector2()
var ballPos = Vector2()
var squaredHalfSizeLength = 0
var currentPointerIDX = INACTIVE_IDX;

func _ready():
    set_process_input(true)
    bg = get_node("Back")
    ball = get_node("Ball")
    animation_player = get_node("DirectionAnim")
    parent = get_parent()
    halfSize = bg.texture.get_size()/2
    squaredHalfSizeLength = halfSize.x * halfSize.y

    if (listenerNodePath != "" && listenerNodePath!=null):
        listenerNodePath = get_node(listenerNodePath)
    elif listenerNodePath=="":
        listenerNodePath = null

#   isDynamicallyShowing = isDynamicallyShowing and parent extends Control
    if isDynamicallyShowing:
        modulate.a = 0
#       hide()

func get_force():
    return currentForce

func _input(event):

    var incomingPointer = extractPointerIdx(event)
    #print(incomingPointer)

    if incomingPointer == INACTIVE_IDX:
        return

    if need2ChangeActivePointer(event):
        if (currentPointerIDX != incomingPointer) and event.is_pressed():
            currentPointerIDX = incomingPointer;
            showAtPos(Vector2(event.position.x, event.position.y));

    var theSamePointer = currentPointerIDX == incomingPointer
    if isActive() and theSamePointer:
        process_input(event)

func need2ChangeActivePointer(event): #touch down inside analog 
    if event is InputEventMouseButton or event is InputEventScreenTouch:
        if isDynamicallyShowing:
            #print(get_parent().get_global_rect())
            return get_parent().get_global_rect().has_point(Vector2(event.position.x, event.position.y))
        else:
            var length = (global_position - Vector2(event.position.x, event.position.y)).length_squared();
            return length < squaredHalfSizeLength
    else:
        return false

func isActive():
    return currentPointerIDX != INACTIVE_IDX

func extractPointerIdx(event):
    var touch = event is InputEventScreenTouch
    var drag = event is InputEventScreenDrag
    var mouseButton = event is InputEventMouseButton
    var mouseMove = event is InputEventMouseMotion

    #print(event)
    if touch or drag:
        return 1
    elif mouseButton or mouseMove:
        #plog("SOMETHING IS VERYWRONG??, I HAVE MOUSE ON TOUCH DEVICE")
        return 0
    else:
        return INACTIVE_IDX

func process_input(event):
    calculateForce(event.position.x - global_position.x, event.position.y - global_position.y)
    updateBallPos()

    var isReleased = isReleased(event)
    if isReleased:
        reset()


func reset():
    currentPointerIDX = INACTIVE_IDX
    calculateForce(0, 0)

    if isDynamicallyShowing:
        hide()
    else:
        updateBallPos()

func showAtPos(pos):
    if isDynamicallyShowing:
        animation_player.play("FadeIn", 0.2)
        global_position = pos

func hide():
    animation_player.play("FadeOut", 0.2) 

func updateBallPos():
    ballPos.x = halfSize.x * currentForce.x #+ halfSize.x
    ballPos.y = halfSize.y * -currentForce.y #+ halfSize.y
    ball.position = Vector2(ballPos.x, ballPos.y)

func calculateForce(var x, var y):
    #get direction
    currentForce.x = (x - centerPoint.x)/halfSize.x
    currentForce.y = -(y - centerPoint.y)/halfSize.y
    #print(currentForce.x, currentForce.y)
    #limit 
    #print(currentForce.length_squared())
    if currentForce.length_squared()>1:
        currentForce=currentForce/currentForce.length()

    sendSignal2Listener()

func sendSignal2Listener():
    if (listenerNodePath != null):
        listenerNodePath.analog_force_change(currentForce, self)

func isPressed(event):
    if event is InputEventMouseMotion:
        return (InputEventMouse.button_mask == 1)
    elif event is InputEventScreenTouch:
        return event.is_pressed()

func isReleased(event):
    if event is InputEventScreenTouch:
        return !event.is_pressed()
    elif event is InputEventMouseButton:
        return !event.is_pressed()
in Engine by (75 points)
edited by

1 Answer

0 votes

If anybody wants to have both input key and touch controller in his code and something like this happen to him/her, should write physicsprocess like this:

func _physics_process(delta):
        if outer_velocity == Vector2(0,0) && l_fist == false && r_fist == false:
           velocity = Vector2(0,0)
        if Input.is_action_pressed("ui_right"):
           velocity.x += 1
        if Input.is_action_pressed("ui_left"):
           velocity.x -= 1
        if Input.is_action_pressed("ui_down"):
           velocity.y += 1
        if Input.is_action_pressed("ui_up"):
           velocity.y -= 1
        else:
           velocity += outer_velocity

  if velocity.length() > 0:
     velocity = velocity.normalized()*speed*delta
  motion = move_and_collide(velocity)
  if (motion):
     motion = move_and_slide(velocity * 60)

#### Touch Controller Function
func analog_force_change(inForce, inStick):
    if(inStick.get_name()=="Directions"):
        if inForce.length() < 0.1:
           outer_velocity = Vector2(0,0) 
        else:
            outer_velocity.x = inForce.x
            outer_velocity.y = -inForce.y

        #Convert outer velocity to 0 , 1 , -1 

       outer_velocity.x = int(round(outer_velocity.x))
        outer_velocity.y = int(round(outer_velocity.y))

        outer_velocity.x = stepify(outer_velocity.x, 1)
        outer_velocity.y = stepify(outer_velocity.y, 1)
        #print(outer_velocity)

:)

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

Categories