• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Android Touch Controls Object - Joystick/Swipes/Taps/Buttons

M

Maximus

Guest
GM Version: GM Studio
Target Platform: mobile platforms
Download: (see code examples below)
Links: NA

Description:

Object for handling multi touch inputs. Up to 2 fingers can be read at once. 1 Joystick and 1 other touch input that is recognised as either a swipe or a tap.


Information about object: obj_input
Sprite:
Solid: false
Visible: true
Depth: 0
Persistent: true
Parent:
Children:
Mask:
No Physics Object

Create Event:
execute code:
Code:
/// input init
disp_w = display_get_width();
disp_h = display_get_height();

// virtual buttons
vb_menu = false;
vb_menu_x1 = 0;
vb_menu_y1 = 0;
vb_menu_x2 = 128;
vb_menu_y2 = 128;

vb_restart = false;
vb_restart_x1 = disp_w - 128;
vb_restart_y1 = 0;
vb_restart_x2 = disp_w;
vb_restart_y2 = 128;

// joy input - left side of screen
// inputs
joy_x       = 0; // sqrt( joy_x^2 + joy_y^2 ) <= 1
joy_y       = 0;
// settings
joy_region  = 0.4 * disp_w;
joy_range   = 100;
// process variables
joy_range_inverse = 1/joy_range;
joy_active  = false;
joy_device  = 0;
joy_x_pos   = 0;
joy_y_pos   = 0;

// tap & swipe inputs - right side of display or anywhere if joy is active
// inputs
tap             = false;
swipe           = false;
swipe_dir       = 0;
swipe_spd       = 0; // pixels per step
// settings
max_tap_time    = 30;
max_tap_dist    = 30;
// process variables
touch_active    = false;
touch_device    = 0;
touch_startx    = 0;
touch_starty    = 0;
touch_timer     = 0;


// touch intputs
for (var i = 4; i > -1; i--)
{
   mouse[i]            = false;
    mouse_pressed[i]    = false;
    mouse_released[i]   = false;
    mouse_rx[i]         = 0; //mouse x rel to room
    mouse_ry[i]         = 0;
    mouse_gx[i]         = 0; //mouse x rel to gui
    mouse_gy[i]         = 0;
}
Step Event:
execute code:
Code:
/// input step
vb_menu = false;
vb_restart = false;
// iterate through mouse devices (potential touch inputs) and collect input data
for (var i = 0; i < 5; i++)
{
   if device_mouse_check_button(i, mb_any)
    {
        // set mouse inputs
        mouse_pressed[i]    = !mouse[i];
        mouse[i]            = true;
        mouse_released[i]   = false;
        mouse_rx[i]         = device_mouse_x(i); // mouse x relative to room
        mouse_ry[i]         = device_mouse_y(i);
        mouse_gx[i]         = device_mouse_x_to_gui(i); // mouse x relative to gui
        mouse_gy[i]         = device_mouse_y_to_gui(i);
        //if (mouse_pressed[i]) {show_debug_message("mouse: " + string(i) + " pressed");}
    
        // check virtual buttons
        if !(joy_active || touch_active)
        {
            // menu button
            if (!vb_menu)
            {
                vb_menu     = point_in_rectangle(   mouse_gx[i], mouse_gy[i],
                                                    vb_menu_x1, vb_menu_y1,
                                                    vb_menu_x2, vb_menu_y2  );
            }
            // restart room button
            if (!vb_restart)
            {
            vb_restart  = point_in_rectangle(   mouse_gx[i], mouse_gy[i],
                                                vb_restart_x1, vb_restart_y1,
                                                vb_restart_x2, vb_restart_y2  );

            //use point_in_circle, etc for diferent shaped buttons
            }
        }
        // check joy input
        if (!joy_active && (mouse_pressed[i] && (mouse_gx[i] < joy_region)))
        {
            joy_active  = true
            joy_device  = i;
            joy_startx  = mouse_gx[i];
            joy_starty  = mouse_gy[i];
            joy_x_pos   = 0;
            joy_y_pos   = 0;
        }
        // check swipes and arbitrary taps
        else if (!touch_active && !(joy_active && (joy_device == i)))
        {
            touch_active = true;
            touch_device = i;
            touch_timer  = 0;
            touch_startx = mouse_gx[i];
            touch_starty = mouse_gy[i];
        }
    }
    else
    {
        mouse_released[i]   = mouse[i];
        mouse[i]            = false;
        mouse_pressed[i]    = false;
        //if (mouse_released[i]) {show_debug_message("mouse: " + string(i) + " released");}
    }
}
// virtual button actions
if (vb_menu)
{
    //todo...
}
if (vb_restart)
{
    room_restart();
}
// get joystick input
if (joy_active)
{
    if (mouse[joy_device])
    {
        var _dir, _dist;
        _dir        = degtorad(point_direction(joy_startx, joy_starty, mouse_gx[joy_device], mouse_gy[joy_device]));
        _dist       = min(joy_range, point_distance(joy_startx, joy_starty, mouse_gx[joy_device], mouse_gy[joy_device]));
        joy_x_pos   = cos(_dir) * _dist;
        joy_y_pos   = -sin(_dir) * _dist;
        joy_x       = joy_range_inverse * joy_x_pos;
        joy_y       = -joy_range_inverse * joy_y_pos;
    }
    else
    {
        joy_x       = 0;
        joy_y       = 0;
        joy_x_pos   = 0;
        joy_y_pos   = 0;
        joy_active  = false;
    }
}
// get tap / swipe input
tap = false;
swipe = false;
if (touch_active)
{
    if (!mouse[touch_device])
    {
        var _dist;
        _dist = point_distance(touch_startx, touch_starty, mouse_gx[touch_device], mouse_gy[touch_device]);
        // was that a tap?
        if ((touch_timer < max_tap_time) && (_dist < max_tap_dist))
        {
            tap = true;
            //show_debug_message("tap detected - x: " + string(touch_startx) + ", y: " + string(touch_starty));
        }
        else // it was a swipe
        {
            swipe       = true;
            swipe_spd   = _dist / touch_timer;
            swipe_dir   = point_direction(touch_startx, touch_starty, mouse_gx[touch_device], mouse_gy[touch_device]);
            //show_debug_message("swipe detected - speed: " + string(swipe_spd) + ", direction: " + string(swipe_dir));
        }
        touch_active = false;
    }
    touch_timer++;
}
Draw GUI Event:
execute code:
Code:
// draw joystick
if (joy_active)
{
   draw_circle_colour(joy_startx, joy_starty, 128, c_gray, c_dkgray, false);
    draw_circle_colour(floor(joy_startx + joy_x_pos), floor(joy_starty + joy_y_pos), 128, c_silver, c_gray, false);
    //draw_sprite(spr_joy_base, 0, joy_startx, joy_starty);
    //draw_sprite(spr_joy_stick, 0, floor(joy_startx + joy_x_pos), floor(joy_starty + joy_y_pos));
}
// draw touch input
if (touch_active)
{
    draw_circle(mouse_gx[touch_device], mouse_gy[touch_device], 64, false);
}
// draw virtual buttons
draw_rectangle(vb_menu_x1, vb_menu_y1, vb_menu_x2, vb_menu_y2, false);
draw_rectangle(vb_restart_x1, vb_restart_y1, vb_restart_x2, vb_restart_y2, false);

init room creation code:
Code:
global.input = instance_create(0,0,obj_input);
Note: object is persistent so make sure to only create it once, or turn of the persistent flag and create it in every room you need it or you will get multiple copies building up.

player create:
Code:
input = global.input;
player step:
Code:
key_atk = input.tap;
move_x = input.joy_x;
move_y = input.joy_y;
if (input.swipe && input.swipe_spd > 20)
{
    switch ( floor( ((input.swipe_dir + 45) mod 360) /90) )
    {
        case 0: // right
            break;
        case 1: // up
            break
        case 2: // left
            break;
        case 3: // down
            break;
            
    }
}
 
Last edited by a moderator:
Top