# Joysticks

Certain games may require more complex input than simple touches or clicks. For example, a game on Windows may need to use the keyboard to handle input, but how does this translate across to other devices? One possible solution is to use the AGK joystick commands. This set of commands will automatically utilise the most appropriate input mechanism. For example, on Windows and Mac keyboard input may be utilised in your game, whereas on mobile devices a virtual joystick may get displayed on screen. The priority is to use a real joystick if possible and then fall back to a keyboard, and if no keyboard is present use a virtual joystick. Here's what a virtual joystick looks like:

A directional pad is provided on the left and optional buttons can be added into the system, as shown on the right.

What this means is that your game can use different inputs dependent on the device and use the same few commands to deal with the input regardless of what is driving it. AGK will seamlessly handle this transition for you and simplify the whole process of dealing with different types of input

## Overview

This example will show a sprite being controlled by a real joystick or keyboard on Windows and Mac and by a virtual joystick on mobile devices.

The process of dealing with this is as follows:

- set up a virtual resolution
- create a sprite
- set the location of the virtual joystick for those platforms that use it
- within our main loop update the position of the sprite based on input from the joystick commands

## Initial set up

To begin with a virtual resolution is set of 320 x 480. This is followed by the creation of a sprite that is positioned near the center of the screen:

    SetVirtualResolution ( 320, 480 )

    CreateSprite ( 1, LoadImage ( "green.png" ) )
    SetSpritePosition ( 1, 160, 200 )

    void app::Begin ( void )
    {
        agk::SetVirtualResolution ( 320, 480 );

        agk::CreateSprite ( 1, agk::LoadImage ( "green.png" ) );
        agk::SetSpritePosition ( 1, 160, 200 );
    }

## Virtual joystick

AGK needs to know the location of the joystick on screen for those platforms that rely on it. To specify the location call the command SetJoystickScreenPosition. This command takes three parameters: X position on screen, Y position on screen and a size parameter that controls how large the joystick is on screen. To position our joystick close to the bottom of the screen with dimensions of 64 x 64 call:

    SetJoystickScreenPosition ( 50, 300, 64 )

    agk::SetJoystickScreenPosition ( 50, 300, 64 );

The ideal location to place this is within your initial set up code and prior to the main loop.

Windows and Mac platforms will emulate the joystick functionality using the keyboard, therefore no virtual joystick will be placed on screen, instead it will be hidden from view. It is only on platforms such as iOS and Samsung Bada that the virtual joystick will be displayed. If a real joystick is present on Windows or Mac then this will take precedence over the keyboard.

## Obtaining joystick input

Two commands are provided that return values in the range of -1 to 1 indicating input from the virtual joystick, real joystick or keyboard. These commands are named GetJoystickX and GetJoystickY, both of which take no parameters and return a floating point value.

The example program will take input from the joystick and apply it to the sprite, thus moving it around the screen:

    do
        x# = GetJoystickX ( )
        y# = GetJoystickY ( )

        SetSpritePosition ( 1, GetSpriteX ( 1 ) + x#, GetSpriteY ( 1 ) + y# )

        Sync ( )
    loop

    void app::Loop ( void )
    {
        float x = agk::GetJoystickX ( );
        float y = agk::GetJoystickY ( );

        agk::SetSpritePosition ( 1, agk::GetSpriteX ( 1 ) + x, agk::GetSpriteY ( 1 ) + y );

        agk::Sync ( );
    }

## Visibility of the virtual joystick

The call to SetJoystickScreenPosition will ensure a virtual joystick is displayed on screen for mobile platforms. Behind the scenes AGK will take no action on Windows and Mac platforms, however, on mobile platforms it will create a virtual joystick with an ID number of 1 by internally calling the command AddVirtualJoystick. If you require more control of this virtual joystick you can directly alter it using the virtual joystick command set and handle tasks such as adding buttons and controlling the visiblity.

To test whether a virtual joystick has been created make a call to the command GetVirtualJoystickExists and pass in the ID number 1. If this command returns true then the virtual joystick has been created and you are therefore running on a mobile device. The code that follows demonstrates how to check whether the virtual joystick is in use and proceeds to hide it from view:

    if ( GetVirtualJoystickExists ( 1 ) = 1 )
        SetVirtualJoystickVisible ( 1, 0 )
    endif

    if ( agk::GetVirtualJoystickExists ( 1 ) == 1 )
        agk::SetVirtualJoystickVisible ( 1, 0 );

The command SetVirtualJoystickVisible takes in the ID number of the joystick, followed by 0 to indicate that the joystick should be hidden. This code could be used at the start of the game to hide the virtual joystick on mobile devices, later when the game is ready this code could be used to display it:

    if ( GetVirtualJoystickExists ( 1 ) = 1 )
        SetVirtualJoystickVisible ( 1, 1 )
    endif

    if ( agk::GetVirtualJoystickExists ( 1 ) == 1 )
        agk::SetVirtualJoystickVisible ( 1, 1 );

## Full code listing

Everything is now in place to run our program. The final listing makes a few alterations including printing out the input from the joystick on screen, along with ensuring the sprite cannot move out of the boundaries of the screen.

On Windows and Mac platforms use the keys w, s, a and d to move the sprite around, while on mobile platforms use the on screen virtual joystick.

    SetVirtualResolution ( 320, 480 )

    CreateSprite ( 1, LoadImage ( "green.png" ) )
    SetSpritePosition ( 1, 160, 200 )

    SetJoystickScreenPosition ( 50, 300, 64 )

    do
        x# = GetJoystickX ( )
        y# = GetJoystickY ( )

        Print ( x# )
        Print ( y# )

        SetSpritePosition ( 1, GetSpriteX ( 1 ) + x#, GetSpriteY ( 1 ) + y# )

        if ( GetSpriteX ( 1 ) < 10 )
            SetSpriteX ( 1, 10 )
        endif

        if ( GetSpriteX ( 1 ) > 260 )
            SetSpriteX ( 1, 260 )
        endif

        if ( GetSpriteY ( 1 ) < 10 )
            SetSpriteY ( 1, 10 )
        endif

        if ( GetSpriteY ( 1 ) > 430 )
            SetSpriteY ( 1, 430 )
        endif

        Sync ( )
    loop

    void app::Begin ( void )
    {
    agk::SetVirtualResolution ( 320, 480 );

    agk::CreateSprite ( 1, agk::LoadImage ( "green.png" ) );
    agk::SetSpritePosition ( 1, 160, 200 );

    agk::SetJoystickScreenPosition ( 50, 300, 64 );
    }

    void app::Loop ( void )
    {
        float x = agk::GetJoystickX ( );
        float y = agk::GetJoystickY ( );

        agk::Print ( x );
        agk::Print ( y );

        agk::SetSpritePosition ( 1, agk::GetSpriteX ( 1 ) + x, agk::GetSpriteY ( 1 ) + y );

        if ( agk::GetSpriteX ( 1 ) < 10 )
            agk::SetSpriteX ( 1, 10.0f );

        if ( agk::GetSpriteX ( 1 ) > 260 )
            agk::SetSpriteX ( 1, 260.0f );

        if ( agk::GetSpriteY ( 1 ) < 10 )
            agk::SetSpriteY ( 1, 10.0f );

        if ( agk::GetSpriteY ( 1 ) > 430 )
            agk::SetSpriteY ( 1, 430.0f );
    }

## Conclusion

With only a few lines of code it has been possible to move a sprite around with a real joystick or keyboard on Windows and Mac platforms, while introducing a virtual joystick for mobile platforms.