Reading the Values of a Virtual Joystick

TheOnlyWRT

Member
Hey guys!!

So I am working on an iOS app and am trying to program in a virtual joystick. I watched one tutorial video to make a joystick object, but it seems that the code is not quite working. When i drag around the inner circle, the value does not change (i drew it to make sure). Here is the code of the VStick Object.

CREATE:
Code:
//where the tap begins
tapX = device_mouse_x_to_gui(0);
tapY = device_mouse_y_to_gui(0);


//the other circle
circleX = 0;
circleY = 0;

//the mac distance the inner circle can be drawn
maxDistance = 150;

//the alarm to read input
alarm[0] = 2;
STEP:
Code:
circleX = device_mouse_x_to_gui(0);
circleY = device_mouse_y_to_gui(0);

x = tapX;
y = tapY;


if(!device_mouse_check_button(0, mb_left)){

    checkVStickDirection();
    objectPlayer.vstickDirection = -1;
    instance_destroy();

}
ALARM 0:
Code:
checkVStickDirection();

alarm[0] = 2;
SCRIPT "checkVStickDirection()"
Code:
/// @description  checkVStickDirection()
/// @function  checkVStickDirection




//up direction
if((point_direction(xstart, ystart, x, y) > 45) && (point_direction(xstart, ystart, x, y) < 135)){

    objectPlayer.vstickDirection = 0;

}

//down direction
if((point_direction(xstart, ystart, x, y) > 135) && (point_direction(xstart, ystart, x, y) < 225)){

    objectPlayer.vstickDirection = 1;

}

//left direction
if((point_direction(xstart, ystart, x, y) > 225) && (point_direction(xstart, ystart, x, y) < 315)){

    objectPlayer.vstickDirection = 2;

}

//right direction
if((point_direction(xstart, ystart, x, y) > 315) && (point_direction(xstart, ystart, x, y) < 45)){

    objectPlayer.vstickDirection = 3;

}
might i add that i also need this to check if it is both down AND left, or down AND right. So i hope with that code i can figure out how to get this working, thanks a ton!
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
There is an official tutorial that comes with GMS 1.4 that explains how to create a virtual joystick... might be worth checking out. ;)
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Just open GMS and go to the Tutorials section. It should be listed there (I think there are three different tutorials for devices covering virtual keys, swipes and virtual joysticks).
 

TheOnlyWRT

Member
So the only tutorial i see in GMS2 is the gesture events. I downloaded it and it wont open.... so is there a different tutorial?
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Ah, you're using GMS 2... In that case, not yet... They are still being ported from 1.4 to 2, BUT you get 1.4 Pro when you get 2.1 and can install them together. The code for the 1.4 tutorials is exactly the same for 2 as it is for 1, so you should be okay.
 

TheOnlyWRT

Member
The only problem is that im on a Mac and 1.4 doesnt have a Mac IDE. Is there perhaps a download project for that tutorial?
 

TheOnlyWRT

Member
also, in case there isnt a project, ive been messing with the code i posted earlier and ive got it to read input. BUT, up is up, down is left, left is down, and right doesnt work at all.....

heres the new code (-1 is neutral):
Code:
/// @param x2
/// @param y2
x1 = argument0;
y1 = argument1;
x2 = argument2;
y2 = argument3;
distance = point_distance(x1, y1, x2, y2);
angle = point_direction(x1, y1, x2, y2);

if(angle >= 360){

    angle = 0;

}



if(distance >= 50){

    //up direction
    if((angle >= 45) && (angle <= 135)){

        objectPlayer.vstickDirection = 0;

    }
   
    else
    //left direction
    if((angle >= 135) && (angle <= 225)){

        objectPlayer.vstickDirection = 2;

    }
   
    else
    //down direction
    if((angle >= 225) && (angle <= 315)){

        objectPlayer.vstickDirection = 1;

    }

    else
    //right direction
    if((angle >= 315) && (angle <= 45)){

        objectPlayer.vstickDirection = 3;

    } else {
   
        objectPlayer.vstickDirection = -1;
       
    }

} else {

    objectPlayer.vstickDirection = -1;

}
 
Last edited:

TheOnlyWRT

Member
ok, so i just implemented the tutorial in my project and the vstick works well, but now i have just 1 question .

1) the tutorial cycled through the 5 devices to check for a touch. My game needs multi touch because i have 3 buttons that the player touches a lot to control other things. How can i use this multi touch code for the buttons?

i have seen a few tutorials use the a for loop to go through all possible devices, and i tried that, and it didnt work. Heres the other code for the buttons:
Code:
for(i=0;i<=4;i++){

    if(device_mouse_check_button(i, mb_left) && point_in_rectangle(_mouseX, _mouseY, _x, _y, _x2, _y2)){

        return true
    
    } else return false;

}

Thanks a ton again!!
 
Last edited:

Nocturne

Friendly Tyrant
Forum Staff
Admin
ok, so i just implemented the tutorial in my project and the vstick works well, but now i have just 1 question .
Yay! :)

1) the tutorial cycled through the 5 devices to check for a touch. My game needs multi touch because i have 3 buttons that the player touches a lot to control other things. How can i use this multi touch code for the buttons?
Do you need to detect the three touches all at the same time? Or is it three touches on three different buttons? What are you wanting to do exactly?

As for the code you posted, what isn't working? What are you expecting to happen? As it stands it looks okay and it should detect any one of 5 touches within the given area and then return true/false... More info on how your buttons are set up would help (like, do you use the Draw GUI event or the regular draw event for the buttons?).
 

TheOnlyWRT

Member
The buttons are drawn with the draw GUI event. I spent all afternoon trying to get this to work, and i noticed that everyone used a for loop to search for all possible touches. The buttons work perfect if i am not using the vstick, and the vstick works perfectly if i dont touch any of the three buttons (only one button is touched at a time). Here is the code for detecting a button touch:

Code:
/// @description  spriteClicked(sprite, x, y)
/// @function  spriteClicked
/// @param sprite
/// @param x
/// @param y


//variables
var sprite = argument0;
var _width = sprite_get_width(sprite);
var _height = sprite_get_height(sprite);
var spriteX = argument1;
var spriteY = argument2;

_x = (spriteX - (_width/2));
_y = (spriteY - (_height/2));
_x2 = _x + (_width);
_y2 = _y + (_height);

for(var i=0;i<=4;i++){

    _mouseX = device_mouse_x_to_gui(i);

}

for(var o=0;o<=4;o++){

    _mouseY = device_mouse_y_to_gui(o);

}

/*
if(device_mouse_check_button(device, mb_left)){

    if(point_in_rectangle(_mouseX, _mouseY, _x, _y, _x2, _y2)) return true; else return false;

}
*/

for(var p=0;p<=4;p++){

    if(device_mouse_check_button(p, mb_left)){

        if(point_in_rectangle(_mouseX, _mouseY, _x, _y, _x2, _y2)) return true; else return false;

    }

}
I also read somewhere that every time i use device_to_ functions i need to do a for loop to detect all possible touches.

EDIT: with that new code, the buttons stopped working..... even when i dont use the vstick......
 
Last edited:

Nocturne

Friendly Tyrant
Forum Staff
Admin
Okay, try this instead of the code you have (keep the first part for defining x/y position from the sprite):

Code:
var _mouseX, _mouseY;
for(var i = 0; i <5; i++)
{
if(device_mouse_check_button(i, mb_left))
    {
    _mouseX = device_mouse_x_to_gui(i);
    _mouseY = device_mouse_y_to_gui(i);
    if(point_in_rectangle(_mouseX, _mouseY, _x, _y, _x2, _y2))
        {
        return true;
        }
    else return false;
    }
}
On a side note, I would suggest that if you have thumbstick controls and buttons active onscreen at the same time then you should consider using virtual keys instead of mouse/touch buttons... Using virtual keys means that you don't have to loop through the fingers on the screen and they also don't interfere with the mouse/touch functions. Oh, and they are also defined in GUI space so it makes them easier to position and use them. ;)
 
T

TimothyAllen

Guest
The problem is you are loop until you find a touch. You then check that touch to see if its on a button. BUT you return and break from the loop if its not on the button, causing you to miss any other touches that might be accuring. You should continue the loop if its not in the button.

To fix, simply move the "return false" outside the for loop.
 

TheOnlyWRT

Member
Okay, try this instead of the code you have (keep the first part for defining x/y position from the sprite):

Code:
var _mouseX, _mouseY;
for(var i = 0; i <5; i++)
{
if(device_mouse_check_button(i, mb_left))
    {
    _mouseX = device_mouse_x_to_gui(i);
    _mouseY = device_mouse_y_to_gui(i);
    if(point_in_rectangle(_mouseX, _mouseY, _x, _y, _x2, _y2))
        {
        return true;
        }
    else return false;
    }
}
On a side note, I would suggest that if you have thumbstick controls and buttons active onscreen at the same time then you should consider using virtual keys instead of mouse/touch buttons... Using virtual keys means that you don't have to loop through the fingers on the screen and they also don't interfere with the mouse/touch functions. Oh, and they are also defined in GUI space so it makes them easier to position and use them. ;)
That worked perfectly!!! Thanks a ton once again!
 
T

TimothyAllen

Guest
That worked perfectly!!! Thanks a ton once again!
Im going to take a guess and said that it will NOT work if you do this:
1. touch (with right hand) and hold screen anywhere (not on joystick)
2. while still touching with right hand, use the joystick with your left hand.
3. you can now use your right hand to try and touch a button while still using the joy stick... probably wont work.
 

TheOnlyWRT

Member
Im going to take a guess and said that it will NOT work if you do this:
1. touch (with right hand) and hold screen anywhere (not on joystick)
2. while still touching with right hand, use the joystick with your left hand.
3. you can now use your right hand to try and touch a button while still using the joy stick... probably wont work.
what makes you say that? And now for some reason, if i use the joystick first, the buttons dont work, but if im holding a button then i use the joystick, the multitouch works just fine......... I havent changed the code at all....
 
Last edited:
T

TimothyAllen

Guest
well I dont know that what i described will cause the bug... but in your loop, you are only looping until you find the FIRST touch. You then evaluate it to see if it is on a button... if its not you return and check no other touches. So unless the first touch is the touch you are looking for, you will miss button presses.
 

TheOnlyWRT

Member
wait, i fixed it using this code:

Code:
//the variable clicked is defined earlier
var _mouseX, _mouseY;
for(var i = 0; i <5; i++){

    if(device_mouse_check_button(i, mb_left)){
   
        _mouseX = device_mouse_x_to_gui(i);
        _mouseY = device_mouse_y_to_gui(i);
       
        if(point_in_rectangle(_mouseX, _mouseY, _x, _y, _x2, _y2)){
       
            clicked =  true;
            break;
        }
    } else clicked = false;
}

return clicked;
 
Top