# Star Field

## Description

This examples demonstrates how it's possible to utilise a large amount of sprites to create a simple star field effect. Even though there are a lot of sprites the program will still run fast as behind the scenes AGK is taking measures to ensure optimal performance.

## External media

This example program relies on several images:

star.png (has been inverted so it's easier to see in the documentation)

space.jpg

## Overview

The process involved is as follows:

- load a background image
- load an image for the stars
- create a large group of sprites and position them at random locations
- within the main loop update the position of all sprites

## Background image

The code begins with two simple calls to load an image that will cover the whole screen and then creating a sprite from it:

    LoadImage ( 1, "space.jpg" )
    CreateSprite ( 1, 1 )

    agk::LoadImage ( 1, "space.jpg" );
    agk::CreateSprite ( 1, 1 );

## Making stars

To represent a collection of stars several hundred sprites will be created and positioned at random locations on screen. This will be handled with a simple loop. Here's what happens for each sprite:

- create a sprite and position it at a random location on screen
- create a random size value and apply this as the scale of the sprite
- provide a random colour for the sprite
- store a random speed value that will be used in the main loop

The code for this is as follows:

    LoadImage ( 2, "star.png" )

    for i = 2 to 1000
        CreateSprite ( i, 2 )
        SetSpritePosition ( i,  Random ( 0, 320 ), Random ( 0, 480 ) )

        size = Random ( 3, 10 ) / 10.0
        SetSpriteScale ( i, size, size )

        SetSpriteColor ( i, Random ( 100, 255 ), Random ( 100, 255 ), Random ( 100, 255 ), Random ( 100, 255 ) )

        speed [ i ] = Random ( 1, 30 ) / 10.0
    next i

    agk::LoadImage ( 2, "star.png" );

    for ( int i = 2; i < 1000; i++
    {
        agk::CreateSprite ( i, 2 );
        agk::SetSpritePosition ( i, agk::Random ( 0, 320 ), agk::Random ( 0, 480 ) );

        size = agk::Random ( 3, 10 ) / 10.0f;
        agk::SetSpriteScale ( i, size, size );

        agk::SetSpriteColor ( i, agk::Random ( 100, 255 ), agk::Random ( 100, 255 ), agk::Random ( 100, 255 ), agk::Random ( 100, 255 ) );

        speed [ i ] = agk::Random ( 1, 30 ) / 10.0f;
    }

## Main Loop

At this point our stars have been created and positioned on screen, it's now time to bring them to life by moving them from right to left, and once they have gone off the left side of the screen reposition them on the right side. This has the effect of our stars continually scrolling from right to left:

    do
        for i = 2 to 1000
            SetSpriteX ( i, GetSpriteX ( i ) - speed [ i ] );

            if ( GetSpriteX ( i ) < -20 )
                SetSpritePosition ( i, Random ( 330, 400 ), Random ( 0, 480 ) )
                speed [ i ] = Random ( 1, 30 ) / 10.0
            endif
        next i

        sync ( )
    loop

    void app::Loop ( void )
    {
        for ( int i = 2; i < 1000; i++ )
        {
            agk::SetSpritePositionX ( i, agk::GetSpriteX ( i ) - speeds [ i ] );

            if ( agk::GetSpriteX ( i ) < -20 )
    	{
    	    agk::SetSpritePosition ( i, agk::Random ( 330, 400 ), agk::Random ( 0, 480 ) );
    	    speed [ i ] = agk::Random ( 1, 30 ) / 10.0f;
    	}
        }

        agk::Sync ( );
    }

## Full code listing

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

    dim speed [ 1000 ] as float

    SetVirtualResolution ( 320, 480 )

    LoadImage ( 1, "space.jpg" )
    CreateSprite ( 1, 1 )

    LoadImage ( 2, "star.png" )

    for i = 2 to 1000
        CreateSprite ( i, 2 )
        SetSpritePosition ( i, Random ( 0, 320 ), Random ( 0, 480 ) )

        size = Random ( 3, 10 ) / 10.0
        SetSpriteScale ( i, size, size )

        SetSpriteColor ( i, Random ( 100, 255 ), Random ( 100, 255 ), Random ( 100, 255 ), Random ( 100, 255 ) )

        speed [ i ] = Random ( 1, 30 ) / 10.0
    next i

    do
        for i = 2 to 1000
            SetSpriteX ( i, GetSpriteX ( i ) - speed [ i ] )

            if ( GetSpriteX ( i ) < -20 )
                SetSpritePosition ( i, Random ( 330, 400 ), Random ( 0, 480 ) )
                speed [ i ] = Random ( 1, 30 ) / 10.0
            endif
        next i

        sync ( )
    loop

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

        agk::LoadImage ( 1, "space.jpg" );
        agk::CreateSprite ( 1, 1 );

        agk::LoadImage ( 2, "star.png" );

        for ( int i = 2; i < 1000; i++
        {
            agk::CreateSprite ( i, 2 );
            agk::SetspritePosition ( i, agk::Random ( 0, 320 ), agk::Random ( 0, 480 ) );

            size = agk::Random ( 3, 10 ) / 10.0f;
            agk::SetSpriteScale ( i, size, size );

            agk::SetSpriteColor ( i, agk::Random ( 100, 255 ), agk::Random ( 100, 255 ), agk::Random ( 100, 255 ), agk::Random ( 100, 255 ) );

            speed [ i ] = agk::Random ( 1, 30 ) / 10.0f;
        }
    }

    void app::Loop ( void )
    {
        for ( int i = 2; i < 1000; i++ )
        {
            agk::SetSpritePositionX ( i, agk::GetSpriteX ( i ) - speeds [ i ] );

            if ( agk::GetSpriteX ( i ) < -20 )
    	{
    	    agk::SetSpritePosition ( i, agk::Random ( 330, 400 ), agk::Random ( 0, 480 ) );
    	    speed [ i ] = agk::Random ( 1, 30 ) / 10.0f;
    	}
        }

        agk::Sync ( );
    }

## Conclusion

This concludes the example for creating a simple star field effect using AGK.