How to: Create a virtual joystick for a mobile UI
7/19/2024
Mihail Todorov
In the ever-evolving world of mobile gaming, providing intuitive and responsive controls is crucial for an engaging user experience. One popular solution is the virtual joystick, a touch-based control system that mimics the physical joystick. In this blog post, we’ll explore how to create a virtual joystick for your mobile games, enhancing gameplay and user interaction.
Previewing the sample
To see the sample live you can find the whole project in the ${Gameface package}/Samples/uiresources/UITutorials/MobileControls
directory.
Creating the joystick itself
To get started we first need to create the joystick itself.
To do that we’ll add the following HTML code:
Here we have the joystick outline which will be a big circle with a dashed border, hence why we are using an SVG to be able to control the dashes and the spacing using the stroke-dashoffset
and stroke-dasharray
properties._createMdxContent
Finally to complete the look of our joystick we’ll style it using the following CSS:
With this, we’ll get the following look to our joystick
Interacting with the joystick
Testing our solution
Since the virtual joystick is intended to be used in a mobile game with touches we first need to simulate an enviroment to test our UI. To do this, we can set the following in the Player.bat
file:
And so our .bat
file the command will look like this:
Adding the touch logic
The first thing we need to do is attach a listener for the touchStart
event.
Then since we’ll be dragging our finger to move the joystick we’ll need to add event listeners for the touchmove
and touchend
events.
As we want to keep the touchmove event going even after leaving the joystick container we’ll add these events to the document and we’ll attach them on touch start so that they don’t intefere with other touch events.
Calculating the correct position of the joystick handle
Next we need to move the handle itself.
For our current case there are two approaches we can take:
- Move the handle on both X and Y axis and restrict it to the circle
- Rotate the handle then move it only on the Y axis
In this tutorial we’ll do approach 2, because it’s much easier to actually restrict the handle going only on a single axis, we can later map the directions much easier because of the angle of rotation and finally we have the added benefit of being able to easily provide the distance between the center and the handle.
To do this, we first need to calculate the angle between the center of the joystick and the center of the handle.
What we want to achieve is to have a polar coordinate system with the center of the joystick to be the center of the FileSystem.
We can do that by utilizing the built-in JavaScript Math.atan2 function. This function calculates the angle between the 0,0
coordinate and the passed y and x GeolocationCoordinates.
In our case the 0,0 point should be the center of the joystick instead of the top left of our viewport. This is why we’ll make a util function called calculateAngle
Here we create a deltaX
and deltaY
constants so that we can simulate the 0,0
point as the center of our joystick.
The atan2
function will return our angle in radians so we need to convert it to degrees. Here we also add additional 90 degrees to our angle as the polar coordinate system 0 degree angle is to the left of the center, however in CSS the rotation 0 degrees angle starts from the top of the center._createMdxContent
Finally we check if the angle in degrees is less than 0 and we add 360 to it, so it will be positive.
What we are now left with is a coordinate system like this:
Moving the handle
To move the handle we’ll first need to calculate the angle using the util function we’ve previously made. This is why we’ll make a new function that we can pass the touch coordinates to and calculate based on the dimensions and position of the joystick._createMdxContent
We get the x and y position of the joystick along with it’s width and height. Then we calculate the distance between the touch point and the center.
We’ve also restricted the distance between the handle and the center so that it doesn’t go past the bounds of the joystick using another util function:
Finally we use the calculateAngle
function to get the angle in degrees and we return it along with the distance
Then we use this function to get the distance and angle so that when we touch the joystick the handle will move
We use event.touches[0]
to get the first touch as there may be multiple touches to the joystick.
We also need to do call the handleJoystickMove
function in the touchstart
event so that when we touch the joystick the handle will move immediately.
Returning the joystick to the initial position
Physical joysticks have springs that allow the handle to return to the center when let go, we can do the same by removing the style in touchend
event:
In conclusion
Creating a virtual joystick for mobile games can significantly enhance the user experience by providing intuitive and responsive controls. By following the steps outlined in this tutorial, you should now have a solid understanding of how to implement a virtual joystick in your game. Whether you’re a seasoned developer or just starting, mastering this technique will add a valuable skill to your game development toolkit. Happy coding, and may your games be ever more engaging!