What's / Where's the issue with my Code. ?

ari484ari484 Posts: 23Member
edited August 30 in Programming

I was making this TOUCHSCREEN JOYSTICK. I used the codes from @TwistedTwigleg RandomMomentania tutorial...and made slight changes according to my needs.

So 1st of all the PROBLEM --

( I am trying to position the joystick at the lower centre of the Viewport, but it seem to be slightly shifted towards the right)
( Also, clearly the Joystick inner ring is supposed to be positioned at the joystick centre )

Heres the CODE --

extends TextureRect



# The radius of the circle that joystick_ring can stay within.
export (float) var radius = 50;

# The results/axes-value for the joystick. Works exactly like a controller's joystick.
var joystick_vector = Vector2();

# The touch ID for the finger/mouse being used for this joystick. (null ID = mouse)
var joystick_touch_id = null;

# The inner ring/part/circle of the joystick
var joystick_ring;

# A boolean for tracking whether this joystick is active or not (currently being used or not)
var joystick_active = false;



func _ready():

    # Get the inner ring    
    joystick_ring = get_node("Joystick_Ring");

    # Move the Joystick to the Lower centre of Viewport.
    rect_global_position = Vector2( get_viewport().size.x/2, get_viewport().size.y/1.2 ) - rect_size/2 ;

    # Move the joystick_ring to the center of the joystick.
    joystick_ring.rect_global_position = get_center_of_joystick() - (joystick_ring.rect_size/2);

    # Reset the joystick vector to zero (since the joystick is in the center)
    joystick_vector = Vector2(0, 0);




func get_center_of_joystick():
    # Return the center position of the joystick texture w.r.t its parent.
    return (rect_global_position + get_rect().size/2 ) ;




func _input(event):


    # If the event is a press/touch...
    if event is InputEventScreenTouch or event is InputEventMouseButton:

        # We need to figure out if this is a press, or a release
        var event_is_press = true;

        # Figure out if this is a press or a release based on the type of input event.
        # (They happen to have the same property in this case, but it is good habit to
        # not assume they will, and therefore treat them separately)
        if event is InputEventScreenTouch:
            event_is_press = event.pressed;
        elif event is InputEventMouseButton:
            event_is_press = event.pressed;

        # If the event is a press...
        if (event_is_press == true):

            if(joystick_active == false):

                # We need to figure out where the event happened and get the event's ID
                var event_position = Vector2();
                var event_ID = null;

                # Get the event position and ID
                if event is InputEventScreenTouch:
                    event_position = event.position;
                    event_ID = event.index;
                elif event is InputEventMouseButton:
                    event_position = get_global_mouse_position();
                    event_ID = null;

                # If the event is within the radius of the joystick.
                if ( ( get_center_of_joystick() - event_position).length() <= radius):

                    joystick_active = true

                    # Set the joystick event ID.
                    joystick_touch_id = event_ID;


                    # Calculate the new joystick vector value, using some math to make a vector pointing from the
                    # center of the joystick to the event's position, and then divide it by the joystick radius to 
                    # get  :'( a normalized vector.
                    joystick_vector = (get_center_of_joystick() - event_position).normalized();

                    # Set the joystick's position
                    joystick_ring.rect_global_position = event_position - (joystick_ring.rect_size/2);





        # If the event is a release...
        else:

            if (joystick_active == true):

                # We need to figure out if the event has the Index we are bound to
                var event_ID = null;

                # Get the event ID
                if event is InputEventScreenTouch:
                    event_ID = event.index;
                elif event is InputEventMouseButton:
                    event_ID = null;

                # Figure out if it is this joystick's event
                if (joystick_touch_id == event_ID):

                    # Reset everything, and if we are using a portion of the screen, then become
                    # invisible
                    joystick_ring.rect_global_position = get_center_of_joystick() - (joystick_ring.rect_size/2);
                    joystick_vector = Vector2(0, 0);

                    joystick_active = false

                    joystick_touch_id = null;




    # If the event is a motion event... (mouse/finger is moving on/across the screen)
    if event is InputEventScreenDrag or event is InputEventMouseMotion:

        if (joystick_active == true):   
            # We need to figure out if the event has the Index we are bound to
            # and we need to get the position of the event
            var event_ID = null;
            var event_position = Vector2();

            # Get the event ID and position
            if event is InputEventScreenDrag:
                event_ID = event.index;
                event_position = event.position;
            elif event is InputEventMouseMotion:
                event_ID = null;
                event_position = get_global_mouse_position();

            # If this event is this joystick's event.
            if (event_ID == joystick_touch_id):

                # Check to see if the event position is within the joystick's radius.
                # If it is, update the position of the inner ring , update joystick_vector with the new values,
                # and emit the Joystick_Updated signal.
                if ( (get_center_of_joystick() - event_position).length() <= radius):
                    joystick_ring.rect_global_position = event_position - (joystick_ring.rect_size/2);

                    joystick_vector = (get_center_of_joystick() - event_position).normalized();


                # If the event position is NOT within the joystick radius, we need to calculate the values
                # differently, but within the radius of the joystick (even though the event is outside it)
                #
                # We calculate the joystick vector using a normalized vector,
                # We use a normalized direction from the center to the event position and multiply it by the 
                # joystick's radius so that it is on the edge of the joystick,
                # and emit the Joystick_Updated signal.
                else:
                    joystick_vector = (get_center_of_joystick() - event_position).normalized()

                    joystick_ring.rect_global_position =get_center_of_joystick() -(joystick_ring.rect_size/2)
                    joystick_ring.rect_global_position -= joystick_vector * radius;
Tagged:

Tags :

Answers

  • TwistedTwiglegTwistedTwigleg Posts: 892Admin

    Hey @ari484!

    I copied and pasted your code into the starter project in the touch screen joystick tutorial, and it works fine for me.

    I changed the code that centers the joystick slightly (see below) but other than that I didn't change anything. I tried using a aspect ratio like in the picture you posted, and it sill seems to be working fine.

    Here is the code I changed, which seemed to fix the offset issue:

    # Move the Joystick to the Lower centre of Viewport.
    rect_global_position = Vector2( get_viewport().size.x/2 - rect_size.x/2, get_viewport().size.y/1.4 );
    

    I think the problems you are having is because of how your joystick TexturedRect nodes are set up. Are either of the joystick nodes scaled? If so, is the Expand property checked with a Stretch Mode that works for your game assets?

    If possible, can you upload the project, or message me with the project? That way I could better be help debug and find a solution to the problem.

  • ari484ari484 Posts: 23Member

    @TwistedTwigleg it's still not working..
    Here's the link to the Project ---- https://drive.google.com/open?id=1ToKwY1xENxLEjUuSMkLc5xPvJP0d0azr

  • TwistedTwiglegTwistedTwigleg Posts: 892Admin
    Answer ✓

    I think I fixed it!

    The problem was the Scale property, which for some reason breaks the script (not sure why though. I will need to look into it in the future). I changed the Scale property values back to 1 and that seems to have fixed it and positioned it correctly, but it was too small to use.

    So I changed the stretch mode to Scale and changed the size property of the TextureRect nodes and now it seems to work correctly and at a usable size.

    Here is a link to the project :)
    https://drive.google.com/open?id=1Ew6tFo3dS8bt7kDmE78po601fnpn9dz2

Sign In or Register to comment.