Reading the Values of a Virtual Joystick

Discussion in 'Programming' started by TheOnlyWRT, Aug 29, 2017.

  1. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    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!
     
  2. Nocturne

    Nocturne Friendly Tyrant Forum Staff Admin

    Joined:
    Apr 13, 2016
    Posts:
    6,861
    There is an official tutorial that comes with GMS 1.4 that explains how to create a virtual joystick... might be worth checking out. ;)
     
  3. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    Really? I had no idea! Is there a link?
     
  4. Nocturne

    Nocturne Friendly Tyrant Forum Staff Admin

    Joined:
    Apr 13, 2016
    Posts:
    6,861
    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).
     
  5. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    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?
     
  6. Nocturne

    Nocturne Friendly Tyrant Forum Staff Admin

    Joined:
    Apr 13, 2016
    Posts:
    6,861
    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.
     
  7. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    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?
     
  8. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    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: Aug 29, 2017
  9. Nocturne

    Nocturne Friendly Tyrant Forum Staff Admin

    Joined:
    Apr 13, 2016
    Posts:
    6,861
  10. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
  11. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    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: Aug 30, 2017
  12. Nocturne

    Nocturne Friendly Tyrant Forum Staff Admin

    Joined:
    Apr 13, 2016
    Posts:
    6,861
    Yay! :)

    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?).
     
  13. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    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: Aug 30, 2017
  14. Nocturne

    Nocturne Friendly Tyrant Forum Staff Admin

    Joined:
    Apr 13, 2016
    Posts:
    6,861
    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. ;)
     
  15. TimothyAllen

    TimothyAllen Member

    Joined:
    Aug 7, 2016
    Posts:
    429
    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.
     
  16. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    That worked perfectly!!! Thanks a ton once again!
     
  17. TimothyAllen

    TimothyAllen Member

    Joined:
    Aug 7, 2016
    Posts:
    429
    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.
     
  18. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    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: Aug 31, 2017
  19. TimothyAllen

    TimothyAllen Member

    Joined:
    Aug 7, 2016
    Posts:
    429
    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.
     
  20. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    okay, that may be the reason.... how would you recommend that i fix that?
     
  21. TheOnlyWRT

    TheOnlyWRT Member

    Joined:
    Jul 5, 2017
    Posts:
    185
    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;
    
     
    Nocturne likes this.
  22. Nabil Kabour

    Nabil Kabour Member

    Joined:
    Aug 6, 2018
    Posts:
    92
    Hey I want to create virtual joysticks too. But the link has expired. Can you please share with me? Or where can I find the tutorials I'm looking online but can't find much.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice