# Collision between two sprites

## Description

This example creates two sprites, places them on screen and moves one sprite towards the other. When they collide both sprites change colour.

## Overview

The process involved is as follows:

- load images and create sprites
- assign collision shapes

Within our main loop:

- move one sprite across the screen
- find out whether a collision takes place - when this happens turn the colour of both sprites to green

## Load images and create sprites

Two images are going to be loaded and attached to two sprites which will then be positioned on screen:

    imageA = LoadImage ( "blue.png" )
    imageB = LoadImage ( "purple.png" )

    spriteA = CreateSprite ( imageA )
    spriteB = CreateSprite ( imageB )

    SetSpritePosition ( spriteA, 0, 200 )
    SetSpritePosition ( spriteB, 200, 200 )

    imageA = agk::LoadImage ( "blue.png" );
    imageB = agk::LoadImage ( "purple.png" );

    spriteA = agk::CreateSprite ( imageA );
    spriteB = agk::CreateSprite ( imageB );

    agk::SetSpritePosition ( spriteA, 0.0f, 200.0f );
    agk::SetSpritePosition ( spriteB, 200.0f, 200.0f );

Here’s a breakdown of the code:

- The image “blue.png” is loaded and its ID number stored in “imageA”.
- The image “purple.png” is loaded and its ID number stored in “imageB”.
- A sprite is created that uses “imageA” and its ID number is stored in “spriteA”.
- A sprite is created that uses “imageB” and its ID number is stored in “spriteB”.
- “spriteA” is positioned at 0, 200
- “spriteB” is positioned at 200, 200

## Assign collision shapes

Prior to performing collision between sprites it is necessary to specify how those sprites are to be represented by the collision system. The options available are boxes, circles and polygons. Which is the best shape or most appropriate fit is dependent on the sprite. In many cases having your sprites represented by bounding boxes or circles might be perfectly acceptable. In cases where much finer collision detection is required then having your sprite represented by a polygon shape may be more suitable, at the expense of speed.

Setting the collision shape of a sprite is handled by the command SetSpriteShape. This command takes two parameters with the first being the ID number of the sprite and the second the shape type. Possible values for this are:

- 0 - no shape
- 1 - circle
- 2 - box
- 3 - polygon

Given that our sprites are boxes it makes sense to select the box shape so our code is:

    SetSpriteShape ( spriteA, 2 )
    SetSpriteShape ( spriteB, 2 )

    agk::SetSpriteShape ( spriteA, 2 );
    agk::SetSpriteShape ( spriteB, 2 );

If we used circles then the collision will still work, but perhaps not be entirely accurate. In another example we’ll look at this in more detail and understand the relationship between a sprite and its collision shape.

## Moving a sprite

Within our main loop we’re going to move “spriteA” across the screen towards the right. At some point it’s going to collide with “spriteB”. Once it does then we can change the colour of both sprites to get a visual clue that the collision has been registered within our code.

To move “spriteA” towards the right of the screen we call SetSpritePosition:

    SetSpritePosition ( spriteA, GetSpriteX ( spriteA ) + 1, 200 )

    agk::SetSpritePosition ( spriteA, agk::GetSpriteX ( spriteA ) + 1.0f, 200.0f );

The first parameter is the ID number of our sprite (that was initially placed at 0, 200). The second parameter is the X coordinate. In this instance we retrieve the current X position of our sprite and then add 1 to it, thereby moving it over to the right. As we’re not altering the final parameter (the Y position) we simply pass in 200 so it remains at 200 on the Y axis.

## Checking for a collision

To find out whether two sprites have collided requires a call to GetSpriteCollision. This command takes two parameters - the ID numbers of the two sprites you are checking. It then returns a value of 1 if a collision has occurred and value of 0 if no collision has taken place.

    if GetSpriteCollision ( spriteA, spriteB ) = 1

    endif

    if ( agk::GetspriteCollision ( spriteA, spriteB ) == true )
    {

    }

## Registering a collision

The final part of our code is to provide a visual notification that the collision has taken place. A simple way of doing this is to turn the colour of both sprites to green. This is achieved by calling the command SetSpriteColor. This command takes four parameters:

- ID number of the sprite
- red component going from 0 - 255
- green component going from 0 - 255
- blue component going from 0 - 255
- alpha component going from 0 - 255

    if GetSpriteCollision ( spriteA, spriteB ) = 1
        SetSpriteColor ( spriteA, 0, 255, 0, 255 )
        SetSpriteColor ( spriteB, 0, 255, 0, 255 )
    endif

    if ( agk::GetspriteCollision ( spriteA, spriteB ) == true )
    {
        agk::SetSpriteColor ( spriteA, 0, 255, 0, 255 );
        agk::SetSpriteColor ( spriteB, 0, 255, 0, 255 );
    }

The code above sets the red channel to 0, full on green with a value of 255, blue set to 0 and alpha set to 255.

## Main loop

The final main loop is as follows:

    do
        SetSpritePosition ( spriteA, GetSpriteX ( spriteA ) + 1, 200 )

        if GetSpriteCollision ( spriteA, spriteB ) = 1
            SetSpriteColor ( spriteA, 0, 255, 0, 255 )
            SetSpriteColor ( spriteB, 0, 255, 0, 255 )
        endif

        Sync ( )
    loop

    void app::Loop ( void )
    {
        agk::SetSpritePosition ( spriteA, agk::GetSpriteX ( spriteA ) + 1.0f, 200.0f );

        if ( agk::GetspriteCollision ( spriteA, spriteB ) == true )
        {
            agk::SetSpriteColor ( spriteA, 0, 255, 0, 255 );
            agk::SetSpriteColor ( spriteB, 0, 255, 0, 255 );
        }

        agk::Sync ( );
    }

## Full code listing

Everything is now in place. Here's the final code for our program:

    SetVirtualResolution ( 320, 480 )

    CreateSprite ( LoadImage ( "background2.jpg" ) )

    imageA = LoadImage ( "blue.png" )
    imageB = LoadImage ( "purple.png" )

    spriteA = CreateSprite ( imageA )
    spriteB = CreateSprite ( imageB )

    SetSpritePosition ( spriteA, 0, 200 )
    SetSpritePosition ( spriteB, 200, 200 )

    SetSpriteShape ( spriteA, 2 )
    SetSpriteShape ( spriteB, 2 )

    do
        SetSpritePosition ( spriteA, GetSpriteX ( spriteA ) + 1, 200 )

        if GetSpriteCollision ( spriteA, spriteB ) = 1
            SetSpriteColor ( spriteA, 0, 255, 0, 255 )
            SetSpriteColor ( spriteB, 0, 255, 0, 255 )
        endif

        Sync ( )
    loop

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

        agk::CreateSprite ( agk::LoadImage ( "background2.jpg" ) );

        imageA = agk::LoadImage ( "blue.png" );
        imageB = agk::LoadImage ( "purple.png" );

        spriteA = agk::CreateSprite ( imageA );
        spriteB = agk::CreateSprite ( imageB );

        agk::SetSpritePosition ( spriteA, 0.0f, 200.0f );
        agk::SetSpritePosition ( spriteB, 200.0f, 200.0f );

        agk::SetSpriteShape ( spriteA, 2 );
        agk::SetSpriteShape ( spriteB, 2 );
    }

    void app::Loop ( void )
    {
        agk::SetSpritePosition ( spriteA, agk::GetSpriteX ( spriteA ) + 1.0f, 200.0f );

        if ( agk::GetspriteCollision ( spriteA, spriteB ) == true )
        {
            agk::SetSpriteColor ( spriteA, 0, 255, 0, 255 );
            agk::SetSpriteColor ( spriteB, 0, 255, 0, 255 );
        }

        agk::Sync ( );
    }

## Conclusion

This concludes the example of checking for collision between sprites. It’s a very simple process and by utilising these command it’s possible to let AGK take care of all collision problems.