How to create dual joysticks for a touch screen

0 favourites
  • 8 posts
From the Asset Store
Surena Touch
$2.50 USD
A wrap from official Touch plugin to export touch/mouse input to other plugins.
  • I need dual joysticks for a touch screen for an upcoming hobby project. I couldn't find a lot of documentation to do it and found it wasn't as easy as I originally thought. So I figured it out myself. I thought I would share how I did that the best I can.

    GitHub link for repo of prototype: https://github.com/mepis/Construct2/tree/master/Dual%20Joysticks

    The article I wrote for my blog sharing the exact same thing : http://kurie.us/how-to-make-dual-joysticks-in-construct-2/#more-127

    Capx example file: http://www.kurie.us/Downloads/construct2/DualJoysticksV1.0.zip

    I'm a bit lazy, so the rest is mostly a copy and paste job from my blog. If anyone has any questions or needs a better explanation, please let me know. I'll be happy to help how ever I can when I have the time.

    First, I assume a couple of things with this prototype:

    No more than two touch points will ever be used at the same time, or if there are, the first two touch points will be either joystick.

    There will be times when either joystick is initiated separately. As such, different touch combinations and events needed to be handled. This will explain the convoluted events used. I found them to work most accurately in this specific order.

    I built this prototype with a couple of idealisms in mind:

    The joysticks must disappear when not in use. I wanted to free up screen real estate when it wasn’t used.

    The joysticks will be created when the screen is touched and destroyed when touch has ended. The joysticks will be created at the point that the finger touches the screen. I’ve always found joystick control on touch screens to be annoying. Not everyone has the same sized fingers. I tend to miss buttons easily or I get annoyed about the amount of screen real estate used up by touch controls. I wanted to solve both of these issues the best I could.

    A couple of points to keep in mind:

    The graphics don’t matter and only exist as a point of reference. As such, each graphic can be removed, changed, shrunk in size, or blown up according to needs. All interactions are based around the points in which the finger first touches the screen, not the objects on the screen.

    The global variables event sheet contains two variables that should be altered per game and target device: XThreshold and YThreshold. This will adjust how quickly the left joystick reacts to movement from its zero point.

    The outside ring around the left joystick only acts as a point of reference for the player. It allows the player a point of reference where to zero out the joystick. This can be removed though it’s suggested to have some graphic to signify the center of the joystick.

    First, let’s go through the layout.

    Only one object on this example has any behaviors. The red triangle, or the player, has 8-way movement attached to it. I use this to make life easier to move the player around the screen. The joystick will interact with this behavior later on.

    It’s important to note that the ‘LTP’ and ‘RTP’ are two giant, clear objects that cover the entire windows. ‘LTP’ stands for ‘left touch panel’ while ‘RTP’ stands for ‘right touch panel’. Both objects are used to listen for and register touch. The left touch panel will be used for the left joystick that controls movement while the right touch panel will be used for the right joystick that will be used for rotation.

    The left joystick is a two piece system per say. The smaller black dot acts as a visual representation of the thumb pad while the larger black ring acts as a pseudo boundary for the thumb pad. The boundary acts as a point of reference for the player to indicate where to return to so that movement can be stopped. The black thumb pad will follow the finger and move in all directions.

    The red circle only rotates. It’s best to visualize this as a knob of sorts. The player can rotate this knob left and right. The player direction will match the angle at which this joystick is rotated.

    Finally, the event sheet.

    First, let me explain what’s going on here. The event sheet is broken into three groups, or functions. The first is for debugging labels. This can be ignored. It was only used in the process of making this to see the numbers of the inputs. The next two groups, or functions, control either the left joystick or the right joystick. I had to create three screen shoots (all below) to display the entire event sheet.

    Let’s start with this screenshot. First, ignore the debugging group and focus on the Touch Controls group. Within the Touch Controls group is a separate group for the left joystick and the right joystick. Both the groups for the left and right joysticks are designed almost the same with adjustments only for the type movements they provide.

    Let’s look at the left joystick first. First, I check to see if the player is touching the screen. If they aren’t, the joystick is destroyed and cleared from the screen. The right joystick is the same. I also set the touchID variable for the left joystick to -1. This is important because the code checks for existing touchIDs later on. Zero is a valid touchID so we can’t have the variables default to zero. Otherwise it causes confusion later on when the joysticks are created.

    Next, I check to see if the player is touching the screen, specifically the corresponding touch panel for the joystick (Eg. left touch panel for left joystick and right touch panel for the right joystick).

    Next I check for movement logic. This is a bit more complicated to explain. When the player touches the screen, the game needs a point of reference for finger movement. For example, the game needs to know if the player moved their thumb up or down. Notice the argument ‘Touch.XforID(leftTouchID)’. This is also very important. It checks for the X and Y coordinates of the specific touchID.

    So, I store the X and Y values of the first touch in a couple of variables to reference. Then, for each step thereafter, I check the position of the finger on the screen to see where it is in relation to the initial touch point. If the finger moved in the right direction (up, down, left, right), the 8-way movement behavior is called to move the player around the screen.

    Next, I check for either creation or destruction of the joystick. I save this for last. Please note, we are still technically in a ‘if-else’ type of statement. Otherwise, if the player is touching the left touch panel, check for everything I wrote above and the next paragraph.

    This part gets a little silly. All three of the first conditions do the same thing. They check to see if the player is touching the screen, and if they are, they create the joystick. They check against different touchIDs though. If a touchID of the other joystick is a specific value, this code checks the touchID value of this joystick for a specific value. This needs to be done to clear up some confusion when the code goes to create a joystick. If both touchIDs for both the left and right joystick are the same value, weird things happen. As such, I need to assign touchIDs very specifically and that all depends on the current value of the other joystick.

    Both joysticks go through this process. Both joysticks check the other’s values before assigning their own.

    The final step is register and move the graphic for the joystick.

    The right joystick follows the exact same logic and has almost the exact same wording and conditions. It should be pretty easy to follow if you understand the above explanations.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • hahahah

    You just make the problem more complicat

    i give you some tips...

    using two DragDrop

    like this http://hkfcp.com/gg

    and then

    all problems gone <img src="{SMILIES_PATH}/icon_e_wink.gif" alt=";)" title="Wink">

    [test @ iPhone ios7 Safari]

    i never detect touch using touch.x touch.y etc...

    ill use dragdrop and check object.x .y

  • When you have time, is there anyway you could provide a quick example file with how it corresponds to creating movement or controlling movement of another object? I was having a hard time finding documentation to do this. I get how drag and drop works to click and hold an object to move it. What I was not getting, or how to make it possible, was how to drag an object, such as a joystick or squares in your link, to make another object, like the player, move in the corresponding direction?

    I'll admit that there may very well be an easier way, but not one that i understand at this moment. I wanted two joysticks, one to control movement and one to control player rotation. I wanted the joystick to disappear when not in use. I also wanted them to adjust to where the player places their finger on the screen. I didn't want the joysticks to stay in a static position on the screen.

    Edit: To better explain my dilemma from your example, all I'm seeing is two squares with drag and drop behaviors attached to them. How does clicking and dragging correspond to measurement movement to make another object move in a specific direction.

  • I remember using the D&D behaviour first time I tried Dual Analog. I found the D&D Behaviour had three kill points.

    1. D&D picks up at the point of contact.

    Once at the point of contact forcing the D&D object to centre in the point of contact produced errors.

    So if you want Analog Tapping D&D loses out.

    2. Ashley says D&D is not meant for this and may produce problems.

    3. I had D&D set up in away that worked flawlessly. However if wanted to put my D&D objects into folders to clean the root folder. It broke all D&D objects. Go figure.

    Long solution. I fought to do it the hardway and then wrote a tutorial on the subject. mepis I think you did a pretty good job and I noticed mine works similar.

    My tutorial is at the top of the mobile filter

    https://www.scirra.com/tutorials/398/to ... ontrollers

  • Thanks I actually looked at you tutorial. I'll admit though, I skimmed it and didn't read it thoroughly. I only looked at the code to see what it was doing. I don't remember why, but it didn't do something the way I wanted. You did a damn fine job on that tut!

    With that said, Ashley or Tom, is there anyway that Scirra can add in an option to take a snapshot of the entire event sheet or group like we can with just snippets?

    At any rate, the more documentation the better. It'll help everyone in the future.

    I did run into a problem though with the snippets above. If they layout size is larger than the window size then the controls won't track and move on the layout properly. It was easy enough to fix though. I had to use the pin behavior on the joystick graphics when created and pin them to the invisible touch pads. I also have to keep realigning the initial x and y values for the left joystick to the center of the ring graphic.

    These are two different tools for two different jobs. If the window size and layout size are the same, I would recommend using the snippets in the OP. I say this because the having to constantly re-align the initial x and y values use extra compute cycles, albeit very few. if the layoutsize is larger than than the window size, the stuff in the paragraph above has to be done.

    I'll update the OP and my blog and the GitHub repo in a day or two when I'm feeling a bit more productive.

  • When you have time, is there anyway you could provide a quick example file with how it corresponds to creating movement or controlling movement of another object? I was having a hard time finding documentation to do this. I get how drag and drop works to click and hold an object to move it. What I was not getting, or how to make it possible, was how to drag an object, such as a joystick or squares in your link, to make another object, like the player, move in the corresponding direction?

    I'll admit that there may very well be an easier way, but not one that i understand at this moment. I wanted two joysticks, one to control movement and one to control player rotation. I wanted the joystick to disappear when not in use. I also wanted them to adjust to where the player places their finger on the screen. I didn't want the joysticks to stay in a static position on the screen.

    Edit: To better explain my dilemma from your example, all I'm seeing is two squares with drag and drop behaviors attached to them. How does clicking and dragging correspond to measurement movement to make another object move in a specific direction.

    DO NOT MAKE Problem Complex!!!!!!!!!!!!!!!!!!!!

    http://www.mediafire.com/download/r5nb8 ... idemo.capx

    HERE IS A DEMO MADE BY 1 MIN

    THIS IS A SUPER EASY JOB

    Please do not put any problems complicate

    this is my game

    [attachment=0:eb3ispu9]sendhelp3.png[/attachment:eb3ispu9]

    var nowthis = this ;

    nowthis.addEventListener(Event.ENTER_FRAME,RotationEvent);

    function RotationEvent(me:Event):void{

    var TmpA : Point = new Point(nowthis['TestObj'].x,nowthis['TestObj'].y);

    var TmpB : Point = new Point(nowthis.mouseX,nowthis.mouseY);

    nowthis['TestObj'].rotation = PointRotation(TmpA,TmpB);

    }

    function PointRotation(PointA,PointB) {

    var Pa = new Point(PointA.x,PointA.y);

    var Pb = new Point(PointB.x,PointB.y);

    var Dx = Pb.x - Pa.x;

    var Dy = Pb.y - Pa.y;

    var DRoation = Math.atan2(Dy,Dx);

    var WRotation = DRoation/Math.PI*180;

    return WRotation;

    }

  • fongka2 Thanks for the demo. In the next day or so I'll take a look at it. I understand what your code is saying and it seems like a good, viable usage. I completely agree, there's no need to make the problem more complex if it doesn't need to be.

    Also, would you mind if I saved your demo and added it to my GitHub account and whatnot? I'd like to have a documentation source for others in the future that might stumble on this post. I didn't see a lot of documentation on the subject past a couple of forum posts and jayderyu 's tutorial.

  • fongka2 Thanks for the demo. In the next day or so I'll take a look at it. I understand what your code is saying and it seems like a good, viable usage. I completely agree, there's no need to make the problem more complex if it doesn't need to be.

    Also, would you mind if I saved your demo and added it to my GitHub account and whatnot? I'd like to have a documentation source for others in the future that might stumble on this post. I didn't see a lot of documentation on the subject past a couple of forum posts and jayderyu 's tutorial.

    Sure ofcoz

    all of this forum's code i guess = free to use/free to copy

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)