19. Functions: Intro screen, initialization

We can create a welcome screen for our game, in which a ghost follows our character continuously. Instead of doing it inside "Main", we can create a new "function", which takes all the necessary steps:

public static void Intro()
{
    Image pac = new Image("pac01r.bmp");
    Image ghost = new Image("ghostGreen.bmp");
    int x = -40;
    do
    {
        SdlHardware.ClearScreen();
        SdlHardware.DrawHiddenImage(ghost, x-50, 300);
        SdlHardware.DrawHiddenImage(pac,x,300);
        SdlHardware.ShowHiddenScreen();
        x += 8;
        if (x > 850) x = -40;      
        SdlHardware.Pause(20);
    }
    while (!SdlHardware.KeyPressed(SdlHardware.KEY_SPC));
}
 

This function is called "Intro", and it has a few local variables: an image for our character, an image for a ghost and a x coordinate. It does not need anything else from the main program, except that we have entered the graphics mode (using SdlHarware.Init) before calling this function.

In fact, we can create also an Init function, to enter graphics mode and (soon) initialize all the variables. Right now it could be simply like this:

public static void Init()
{
    bool fullScreen = false;
    SdlHardware.Init(800, 600, 24, fullScreen);
}
 

So the structure for our program now would be:

Init();
...
Intro();
do
{
    // Game loop
} ...
 


There is still too much initialization code out of "init", and too much repetitive code, but we will fix both things very soon. Now our full program would be:

/*
  First mini-graphics-game skeleton
  Version I: functions Init and Intro
*/
 
using System;
 
public class Game02i
{
    public static void Init()
    {
        bool fullScreen = false;
        SdlHardware.Init(800, 600, 24, fullScreen);
    }
 
    public static void Intro()
    {
        Image pac = new Image("pac01r.bmp");
        Image ghost = new Image("ghostGreen.bmp");
        int x = -40;
        do
        {
            SdlHardware.ClearScreen();
            SdlHardware.DrawHiddenImage(ghost, x-50, 300);
            SdlHardware.DrawHiddenImage(pac,x,300);
            SdlHardware.ShowHiddenScreen();
            x += 8;
            if (x > 850) x = -40;      
            SdlHardware.Pause(20);
        }
        while (!SdlHardware.KeyPressed(SdlHardware.KEY_SPC));
    }
 
 
    public static void Main()
    {
        Init();
 
        Image dotImage = new Image("dot.bmp");
        Image enemyImage = new Image("ghostGreen.bmp");
        Image pacImage = new Image("pac01r.bmp");
        Image wallImage = new Image("wall.bmp");
 
        int x = 32, y = 32;
        int pacSpeed = 4;
 
        int amountOfEnemies = 4;
        float[] xEnemy = { 150, 400, 500, 600 };
        float[] yEnemy = { 100, 200, 300, 400 };
        float[] incrXEnemy = { 5f, 3f, 6f, 4.5f };
 
        string[] map = {
            "-----------------",
            "-.......-.......-",
            "-.--.--.-.--.--.-",
            "-...............-",
            "-.--.-.---.-.--.-",
            "-....-..-..-....-",
            "----.--...--.----",
            ".................",
            "----.-.-.-.-.----",
            "-....-.-.-.-....-",
            "-.--.-.---.-.--.-",
            "-...............-",
            "-.--.-.---.-.--.-",
            "-....-.....-....-",
            "-----------------"
        };
 
        // Data for the dots
        // First: count how many
        int amountOfDots = 0;
        for (int row = 0; row < 15; row++)
        {
            for (int column = 0; column < 17; column++)
            {
                if (map[row][column] == '.')
                    amountOfDots++;
            }
        }
        int[] xDot = new int[amountOfDots];
        int[] yDot = new int[amountOfDots];
        bool[] visible = new bool[amountOfDots];
        // Now, assign their coordinates
        int currentDot = 0;
        for (int row = 0; row < 15; row++)
        {
            for (int column = 0; column < 17; column++)
            {
                if (map[row][column] == '.')
                {
                    xDot[currentDot] = column * 32;
                    yDot[currentDot] = row * 32;
                    visible[currentDot] = true;
                    currentDot++;
                }
            }
        }
 
 
        int score = 0;
        bool gameFinished = false;
 
        Intro();
 
        // Game Loop
        while (!gameFinished)
        {
            // Draw
            SdlHardware.ClearScreen();
            //Console.Write("Score: {0}",score);
 
            // Background map
            for (int row = 0; row < 15; row++)
            {
                for (int column = 0; column < 17; column++)
                {
                    if (map[row][column] == '-')
                        SdlHardware.DrawHiddenImage(wallImage, column * 32, row * 32);
                }
            }
 
            for (int i = 0; i < amountOfDots; i++)
            {
                if (visible[i])
                    SdlHardware.DrawHiddenImage(dotImage, xDot[i], yDot[i]);
            }
 
            SdlHardware.DrawHiddenImage(pacImage, x, y);
 
            for (int i = 0; i < amountOfEnemies; i++)
                SdlHardware.DrawHiddenImage(enemyImage,
                    (int)xEnemy[i], (int)yEnemy[i]);
 
            SdlHardware.ShowHiddenScreen();
 
            // Read keys and calculate new position
            if (SdlHardware.KeyPressed(SdlHardware.KEY_RIGHT))
            {
                bool canMove = true;
                for (int row = 0; row < 15; row++)
                {
                    for (int column = 0; column < 17; column++)
                    {
                        if (map[row][column] == '-')
                            if ((x + pacSpeed > column * 32 - 32) &&
                                (x + pacSpeed < column * 32 + 32) &&
                                (y > row * 32 - 32) &&
                                (y < row * 32 + 32)
                                )
                            {
                                canMove = false;
                            }
                    }
                }
                if (canMove)
                    x += pacSpeed;
            }
 
            if (SdlHardware.KeyPressed(SdlHardware.KEY_LEFT))
            {
                bool canMove = true;
                for (int row = 0; row < 15; row++)
                {
                    for (int column = 0; column < 17; column++)
                    {
                        if (map[row][column] == '-')
                            if ((x - pacSpeed > column * 32 - 32) &&
                                (x - pacSpeed < column * 32 + 32) &&
                                (y > row * 32 - 32) &&
                                (y < row * 32 + 32)
                                )
                            {
                                canMove = false;
                            }
                    }
                }
                if (canMove)
                    x -= pacSpeed;
            }
 
            if (SdlHardware.KeyPressed(SdlHardware.KEY_DOWN))
            {
                bool canMove = true;
                for (int row = 0; row < 15; row++)
                {
                    for (int column = 0; column < 17; column++)
                    {
                        if (map[row][column] == '-')
                            if ((x > column * 32 - 32) &&
                                (x < column * 32 + 32) &&
                                (y + pacSpeed > row * 32 - 32) &&
                                (y + pacSpeed < row * 32 + 32)
                                )
                            {
                                canMove = false;
                            }
                    }
                }
                if (canMove)
                    y += pacSpeed;
            }
 
            if (SdlHardware.KeyPressed(SdlHardware.KEY_UP))
            {
                bool canMove = true;
                for (int row = 0; row < 15; row++)
                {
                    for (int column = 0; column < 17; column++)
                    {
                        if (map[row][column] == '-')
                            if ((x > column * 32 - 32) &&
                                (x < column * 32 + 32) &&
                                (y - pacSpeed > row * 32 - 32) &&
                                (y - pacSpeed < row * 32 + 32)
                                )
                            {
                                canMove = false;
                            }
                    }
                }
                if (canMove)
                    y -= pacSpeed;
            }
 
            if (SdlHardware.KeyPressed(SdlHardware.KEY_ESC))
                gameFinished = true;
 
            // Move enemies and environment
            for (int i = 0; i < amountOfEnemies; i++)
            {
                xEnemy[i] += incrXEnemy[i];
                if ((xEnemy[i] < 1) || (xEnemy[i] > 760))
                    incrXEnemy[i] = -incrXEnemy[i];
            }
 
            // Collisions, lose energy or lives, etc
            for (int i = 0; i < amountOfDots; i++)
                if (visible[i] &&
                    (x > xDot[i] - 32) &&
                    (x < xDot[i] + 32) &&
                    (y > yDot[i] - 32) &&
                    (y < yDot[i] + 32)
                    )
                {
                    score += 10;
                    visible[i] = false;
                }
 
            // Pause till next fotogram
            SdlHardware.Pause(40);
        }
    }
}