23. Lives. End of game
We did not check collisions with our enemies so far. Doing it is very similar to checking collisions with dots, but don't need (yet) to verify if their are visible or not. Each time we hit a ghost, we should lose one live and move to our starting position; if we lose three lives, the game must end:
for (int i = 0; i < amountOfEnemies; i++) if ( (x > xEnemy[i] - 32) && (x < xEnemy[i] + 32) && (y > yEnemy[i] - 32) && (y < yEnemy[i] + 32) ) { x = startX; y = startY; lives--; if (lives == 0) gameFinished = true; }");
And those "startX and "startY" coodinates might be more centered on screen than our previous ones:
static int startX = 32 * 8; static int startY = 32 * 11;
So the resulting program should be almost as simple as it was:
/* First mini-graphics-game skeleton Version M: three lives */ using System; public class SdlMuncher { static int startX = 32 * 8; static int startY = 32 * 11; static int lives = 3; static int x, y; static int pacSpeed; static int amountOfEnemies; static float[] xEnemy = { 150, 400, 500, 600 }; static float[] yEnemy = { 100, 200, 300, 400 }; static float[] incrXEnemy = { 5f, 3f, 6f, 4.5f }; static int[] xDot; static int[] yDot; static bool[] visible; static int amountOfDots; static Image dotImage; static Image enemyImage; static Image pacImage; static Image wallImage; static string[] map = { "-----------------", "-.......-.......-", "-.--.--.-.--.--.-", "-...............-", "-.--.-.---.-.--.-", "-....-..-..-....-", "----.--...--.----", ".................", "----.-.-.-.-.----", "-....-.-.-.-....-", "-.--.-.---.-.--.-", "-...............-", "-.--.-.---.-.--.-", "-....-.....-....-", "-----------------" }; static int score; static Font sans18; public static void Init() { bool fullScreen = false; SdlHardware.Init(800, 600, 24, fullScreen); dotImage = new Image("data/dot.png"); enemyImage = new Image("data/ghostGreen.png"); pacImage = new Image("data/pac01r.png"); wallImage = new Image("data/wall.png"); x = startX; y = startY; pacSpeed = 4; amountOfEnemies = 4; // Data for the dots // First: count how many dots are there amountOfDots = 0; for (int row = 0; row < 15; row++) { for (int column = 0; column < 17; column++) { if (map[row][column] == '.') amountOfDots++; } } xDot = new int[amountOfDots]; yDot = new int[amountOfDots]; 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++; } } } score = 0; // Font sans18 = new Font("data/Joystix.ttf", 18); } public static void Intro() { Image pac = new Image("data/pac01r.png"); Image ghost = new Image("data/ghostGreen.png"); int x = -40; do { SdlHardware.ClearScreen(); SdlHardware.WriteHiddenText("Hit SPACE to start", 300, 500, 0xCC, 0xCC, 0xCC, sans18); 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 bool CanMoveTo(int x, int y, string[] map) { 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 > row * 32 - 32) && (y < row * 32 + 32) ) { canMove = false; } } } return canMove; } public static void Main() { Init(); Intro(); // Game Loop bool gameFinished = false; 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.WriteHiddenText("Score: "+score, 610, 100, 0x80, 0x80, 0xFF, sans18); SdlHardware.WriteHiddenText("Lives: " + lives, 610, 140, 0x80, 0x80, 0xFF, sans18); SdlHardware.ShowHiddenScreen(); // Read keys and calculate new position if (SdlHardware.KeyPressed(SdlHardware.KEY_RIGHT) && CanMoveTo(x + pacSpeed, y, map)) x += pacSpeed; if (SdlHardware.KeyPressed(SdlHardware.KEY_LEFT) && CanMoveTo(x - pacSpeed, y, map)) x -= pacSpeed; if (SdlHardware.KeyPressed(SdlHardware.KEY_DOWN) && CanMoveTo(x, y + pacSpeed, map)) y += pacSpeed; if (SdlHardware.KeyPressed(SdlHardware.KEY_UP) && CanMoveTo(x, y - pacSpeed, map)) 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; } for (int i = 0; i < amountOfEnemies; i++) if ( (x > xEnemy[i] - 32) && (x < xEnemy[i] + 32) && (y > yEnemy[i] - 32) && (y < yEnemy[i] + 32) ) { x = startX; y = startY; lives--; if (lives == 0) gameFinished = true; } // Pause till next fotogram SdlHardware.Pause(40); } } }