{"id":4157,"date":"2017-08-13T16:38:46","date_gmt":"2017-08-13T21:38:46","guid":{"rendered":"https:\/\/justinparrtech.com\/JustinParr-Tech\/?p=4157"},"modified":"2017-08-13T16:47:59","modified_gmt":"2017-08-13T21:47:59","slug":"simple-method-to-implement-a-virtual-joystick","status":"publish","type":"post","link":"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/","title":{"rendered":"Simple Method to Implement a Virtual Joystick"},"content":{"rendered":"<p>Many mobile games need arcade-like controls, and implementing a virtual joystick is a quick and easy solution.<\/p>\n<p>Here is a quick and simple way to implement a virtual joystick.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_81 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#background\" >Background<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#joystick\" >Joystick<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#button-array\" >Button Array<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#dpad\" >DPad<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#vpad-virtual-pad\" >VPad (Virtual Pad)<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#anatomy-of-a-vpad\" >Anatomy of a VPad<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#converting-a-touch-event-to-game-input\" >Converting a Touch Event to Game Input<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#virtual-analog-pad-vapad\" >Virtual Analog Pad (VAPad)<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#the-effects-of-clamping\" >The effects of Clamping<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#creating-acceleration\" >Creating Acceleration<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/simple-method-to-implement-a-virtual-joystick\/#conclusion\" >Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"background\"><\/span>Background<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>For arcade-like games played on mobile devices, you need arcade-like controls.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"joystick\"><\/span>Joystick<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Arcade games typically implement a joystick, allowing movement in 8 basic directions.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4159 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Arcade_Stick-295x300.png\" alt=\"\" width=\"295\" height=\"300\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Arcade_Stick-295x300.png 295w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Arcade_Stick.png 323w\" sizes=\"auto, (max-width: 295px) 100vw, 295px\" \/><\/p>\n<p>An arcade joystick has a &#8220;dead zone&#8221;, which has the effect of dampening trivial input.\u00a0 The dead zone is important, because it allows the player to be at rest without interpreting the player&#8217;s at-rest state as input.<\/p>\n<p>Outside the dead zone, the player can push the joystick up or down, and left or right.\u00a0 Up\/down and left\/right can be combined, such as UP+LEFT, to form 8 basic directions &#8211; the four cardinal directions, plus four diagonals.<\/p>\n<p>An arcade joystick allows smooth transitions, but also provides exclusivity, meaning that you can&#8217;t push &#8220;LEFT&#8221; and &#8220;RIGHT&#8221; at the same time, nor &#8220;UP&#8221; and &#8220;DOWN&#8221; at the same time.\u00a0 Likewise, any given diagonal is exclusive from all other diagonals.<\/p>\n<p>Exclusivity means that the game doesn&#8217;t require as much code in order to interpret the user&#8217;s input, because the user&#8217;s input is limited to one of 9 exclusive states (idle, plus the four cardinal states, plus the four diagonals).<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"button-array\"><\/span>Button Array<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The first handheld games used individual buttons in a &#8220;cross&#8221; configuration.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4160 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Button_Array-300x300.png\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Button_Array-300x300.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Button_Array-150x150.png 150w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Button_Array.png 360w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>This provided a dead zone in the center, where the player could rest their thumb, and each of the four cardinal directions had a unique button.<\/p>\n<p>Unfortunately, buttons are not as feasible or user friendly as a joystick:<\/p>\n<ul>\n<li>Buttons do not provide exclusivity.\u00a0 You CAN press LEFT and RIGHT at the same time, for example.<\/li>\n<li>No smooth transition.\u00a0 Shifting directions requires lifting your thumb and placing it in a new location.<\/li>\n<li>Diagonals don&#8217;t work well.\u00a0 Pressing a diagonal requires pushing two buttons at the same time.\u00a0 Although diagonals can be implemented as four more discreet buttons, this can result in the player inadvertently pressing two or more buttons at the same time, which the game sees as ambiguous.<\/li>\n<\/ul>\n<p>In addition to the physical limitations, software buttons follow a complex event lifecycle.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4161 size-large\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Button_Event_LifeCycle-600x280.png\" alt=\"\" width=\"600\" height=\"280\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Button_Event_LifeCycle-600x280.png 600w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Button_Event_LifeCycle-300x140.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Button_Event_LifeCycle.png 740w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<ul>\n<li>The button starts in an IDLE state.<\/li>\n<li>When pressed, the button generates a DOWN event.<\/li>\n<li>When released, the button generates an UP event.<\/li>\n<li>When a DOWN is followed by an UP, the button generates a CLICK event.<\/li>\n<li>After a CLICK event, the button returns to an IDLE state.<\/li>\n<\/ul>\n<p>Because of the complex event lifecycle, using a button array becomes even more complicated, because each DOWN and UP event must be individually tracked, and the game must react accordingly.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"dpad\"><\/span>DPad<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>In the early 80&#8217;s, Nintendo came up with the perfect solution:\u00a0 The DPad (&#8220;Digital&#8221; pad).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4163 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/DPad-300x300.png\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/DPad-300x300.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/DPad-150x150.png 150w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/DPad.png 312w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>The DPad has all of the advantages of an arcade joystick, with the simplicity and compact design of a button array:<\/p>\n<ul>\n<li>Exclusivity &#8211; LEFT and RIGHT are exclusive, as are UP and DOWN.\u00a0 Any diagonal is exclusive from all other diagonals, just like an arcade stick.<\/li>\n<li>Smooth transition &#8211; without lifting a thumb, the player can easily transition from any direction to any other direction.<\/li>\n<li>Diagonals &#8211; unlike a button array, the player can easily push two cardinal directions at once in order to move diagonally.<\/li>\n<li>Dead zone &#8211; allows the player to place the controls in an idle state without lifting the thumb.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4164 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/DPad_Explained-300x288.png\" alt=\"\" width=\"300\" height=\"288\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/DPad_Explained-300x288.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/DPad_Explained.png 336w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>As a physical input device, the DPad works well.\u00a0 Implemented as a virtual input device, however, it doesn&#8217;t translate very well.<\/p>\n<p>For example, a physical DPad has four physical buttons that determine 8 possible direction inputs, as well as an idle state.<\/p>\n<p>As we&#8217;ve seen, buttons don&#8217;t translate very well to the virtual world.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"vpad-virtual-pad\"><\/span>VPad (Virtual Pad)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Enter the Virtual Pad (VPad).\u00a0 A VPad is simply a picture of a DPad, where input to the game is a series of TOUCH events.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4165 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad-300x300.png\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad-300x300.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad-150x150.png 150w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad.png 408w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>The VPad provides all of the advantages of a DPad, plus it&#8217;s easy for a game to interpret the player&#8217;s input.<\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"anatomy-of-a-vpad\"><\/span>Anatomy of a VPad<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>A VPad, or Virtual Pad, is a picture that represents a DPad control, but responds to TOUCH events.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4166 size-large\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Event_LifeCycle-600x288.png\" alt=\"\" width=\"600\" height=\"288\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Event_LifeCycle-600x288.png 600w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Event_LifeCycle-300x144.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Event_LifeCycle-768x369.png 768w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Event_LifeCycle.png 1001w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Unlike a DPad, where each button has its own event lifecycle, there is only one type of event supported by a VPad &#8211; the TOUCH event.<\/p>\n<p>Each TOUCH event provides the X,Y location where the player placed their thumb.<\/p>\n<p>Once a TOUCH event has occurred, either the player can lift their thumb, or drag it to another location, resulting in a second TOUCH event with a new X,Y location.<\/p>\n<p>When the player lifts their thumb, the control returns to an idle state.<\/p>\n<p>In addition to the four cardinal directions and four diagonals, we can programmatically implement a dead zone as well, allowing the player to place the control in an idle state without lifting their thumb.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4167 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Explained-291x300.png\" alt=\"\" width=\"291\" height=\"300\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Explained-291x300.png 291w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Explained.png 418w\" sizes=\"auto, (max-width: 291px) 100vw, 291px\" \/><\/p>\n<p>More precisely, we can represent this structure as a grid:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4168 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Zones-300x292.png\" alt=\"\" width=\"300\" height=\"292\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Zones-300x292.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Zones.png 424w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>When a touch event occurs, the game simply needs to determine in what square the touch event occurred.\u00a0 The resulting input is +1, 0, or -1 for X, and +1, 0, or -1 for Y, indicating the state of each independent axis.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"converting-a-touch-event-to-game-input\"><\/span>Converting a Touch Event to Game Input<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>When a TOUCH event occurs, it returns an X,Y pair that ranges from (0,0), which is the upper-left coordinate of the VPad, up to the VPad&#8217;s width and height (ControlWidth,ControlHeight).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4170 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Touch-300x267.png\" alt=\"\" width=\"300\" height=\"267\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Touch-300x267.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Touch-600x535.png 600w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_Touch.png 625w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>So, X will range from 0 to ControlWidth, while Y will range from 0 to ControlHeight.<\/p>\n<p>Ideally, we want to convert this to a directionality for X (-1, 0, or +1) and a directionality for Y (-1, 0, or +1).<\/p>\n<p>Since there are 3 &#8220;X&#8221; sections and 3 &#8220;Y&#8221; sections (3&#215;3 grid), we can use the following formula to convert a TOUCH event to directionality:<\/p>\n<pre>XI = X * 3 \/ ControlWidth -1\r\nYI = Y * 3 \/ ControlHeight -1<\/pre>\n<p>For each X and Y value, we start by multiplying the X value by 3, and then dividing by the control&#8217;s width or height respectively.<\/p>\n<p>This returns a value in the range of 0 to 2.<\/p>\n<p>The last step is to subtract 1, shifting both ranges from -1 to +1.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"virtual-analog-pad-vapad\"><\/span>Virtual Analog Pad (VAPad)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Suppose you want to scale the player&#8217;s input.\u00a0 For example, if the player touches slightly right, the player&#8217;s avatar might walk.\u00a0 If the player touches the far right, the player&#8217;s avatar might run.\u00a0 This allows 5 possible states for X, and 5 possible states for Y:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4171 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5_Directions-300x300.png\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5_Directions-300x300.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5_Directions-150x150.png 150w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5_Directions.png 410w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>The resulting structure is a 5&#215;5 grid, where there are two possible magnitudes for each of the 8 basic directions, plus there are 8 additional directions (16 total).<\/p>\n<pre>XI = X * 5 \/ ControlWidth - 2\r\nYI = Y * 5 \/ ControlHeight - 2<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4172 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5-300x292.png\" alt=\"\" width=\"300\" height=\"292\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5-300x292.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5.png 428w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>This can be scaled up to any number of slices:<\/p>\n<pre>XI = X * GridWidth \/ ControlWidth - INT(GridWidth\/2)\r\nYI = Y * GridHeight \/ ControlHeight - INT(GridHeight\/2)<\/pre>\n<p>Compared to a VPad, which supports 8 basic directions and an idle state, a VAPad can be scaled up using any odd number, to support N*N possible states.<\/p>\n<pre>X States:  N\r\nY States:  N\r\nTotal States:  N * N\r\nTotal Directions:  N * 2 + (N-2) * 2\r\nSensitivity:  INT(N \/ 2)<\/pre>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"the-effects-of-clamping\"><\/span>The effects of Clamping<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Clamping limits the range of an output variable.<\/p>\n<p>For example, let&#8217;s say that we want a smaller dead zone without changing the range of inputs.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4173 size-medium\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5_Clamped-300x300.png\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5_Clamped-300x300.png 300w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5_Clamped-150x150.png 150w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/VPad_5x5_Clamped.png 411w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>A clamping function works like this:<\/p>\n<pre>XI = MIN( RangeX, MAX( -RangeX, X * GridWidth \/ ControlWidth - INT(GridWidth \/ 2) )\r\nYI = MIN( RangeY, MAX( -RangeY, Y * GridWidth \/ ControlWidth - INT(GridHeight \/ 2) )<\/pre>\n<p>Clamping makes the dead zone smaller.\u00a0 For example, if we start with a Grid size of 5 x 5, we can implement clamping at -1 to 1:<\/p>\n<pre>XI = MIN( 1, MAX( -1, X * 5 \/ ControlWidth - INT(5 \/ 2))\r\nYI = MIN( 1, MAX( -1, Y * 5 \/ ControlHeight - INT(5 \/ 2))<\/pre>\n<p>Clamping allows you to reduce the dead zone, and combine possible output states.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"creating-acceleration\"><\/span>Creating Acceleration<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>We can create a non-linear relationship between input and output.<\/p>\n<p>For example, we can use the same linear grid to feed an exponentiation function.<\/p>\n<pre>Capture the sign (in pseudocode):\r\nIF X=0\r\n  SX=0\r\nELSE\r\n  IF X&lt;0 \r\n    SX=-1\r\n  ELSE\r\n    SX=1\r\n\r\nIf your compiler supports the conditional operator (C, Java):\r\nSX = (X=0)?0:((X&lt;0)?-1:1)\r\n\r\nUse the Absolute value of X, then apply the sign.\r\nXI = ABS(X)^N * SX<\/pre>\n<p>Since there is no square root of a negative number, you must separate the sign of the value from its magnitude.<\/p>\n<p>Once the magnitude has been exponentiated, multiply by the sign in order to obtain directionality.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4175\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Acceleration_Table.png\" alt=\"\" width=\"321\" height=\"127\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Acceleration_Table.png 321w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Acceleration_Table-300x119.png 300w\" sizes=\"auto, (max-width: 321px) 100vw, 321px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4176 size-full\" src=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Acceleration_Chart.png\" alt=\"\" width=\"574\" height=\"340\" srcset=\"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Acceleration_Chart.png 574w, https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-content\/uploads\/Acceleration_Chart-300x178.png 300w\" sizes=\"auto, (max-width: 574px) 100vw, 574px\" \/><\/p>\n<p>Exponential scaling can provide the feeling of acceleration, where the player&#8217;s input is linear, but the magnitude is raised to some specific power.<\/p>\n<p>For example, if X is in the range of -5 to +5, and we raise that to the 1.7 power, the resulting output will be X in the range of -15 to +15.<\/p>\n<p>If the player touches (3,5), the resulting output is (3^1.7, 5^1.7) = (6,15), creating the impression of acceleration.<\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Using a VAPad provides a quick and simple way to allow the player to have responsive and intuitive controls in a mobile game.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many mobile games need arcade-like controls, and implementing a virtual joystick is a quick and easy solution. Here is a quick and simple way to implement a virtual joystick.<\/p>\n","protected":false},"author":16,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-4157","post","type-post","status-publish","format-standard","hentry","category-tech-support"],"_links":{"self":[{"href":"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-json\/wp\/v2\/posts\/4157","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-json\/wp\/v2\/comments?post=4157"}],"version-history":[{"count":8,"href":"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-json\/wp\/v2\/posts\/4157\/revisions"}],"predecessor-version":[{"id":4180,"href":"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-json\/wp\/v2\/posts\/4157\/revisions\/4180"}],"wp:attachment":[{"href":"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-json\/wp\/v2\/media?parent=4157"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-json\/wp\/v2\/categories?post=4157"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/justinparrtech.com\/JustinParr-Tech\/wp-json\/wp\/v2\/tags?post=4157"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}