8. Independent movements
Our enemy is able to move... but it only does when our character does. It happens because the "Readkey" command is a "blocking command": the execution of the whole program stops until a key is pressed.
But there is a workaround: we can check if any key has been pressed using "KeyAvailable", and get information about that key (using "ReadKey") only if there is any keypress to check:
if (Console.KeyAvailable) { userKey = Console.ReadKey(false); if(userKey.Key == ConsoleKey.RightArrow) x++; if(userKey.Key == ConsoleKey.LeftArrow) x--; if(userKey.Key == ConsoleKey.DownArrow) y++; if(userKey.Key == ConsoleKey.UpArrow) y--; }
So the whole program would be:
/* First mini-console-game skeleton Version J: enemy moves on its own, even if player does not */ using System; public class Game01j { public static void Main() { int x=40, y=12; int xDot1=10, yDot1=5; bool visibleDot1 = true; int xDot2=20, yDot2=15; bool visibleDot2 = true; int xDot3=60, yDot3=11; bool visibleDot3 = true; int xEnemy=15, yEnemy=17; int incrXEnemy=1; int score = 0; ConsoleKeyInfo userKey; // Game Loop while( 1 == 1 ) { // Draw Console.Clear(); Console.Write("Score: {0}",score); if (visibleDot1) { Console.SetCursorPosition(xDot1, yDot1); Console.Write("."); } if (visibleDot2) { Console.SetCursorPosition(xDot2, yDot2); Console.Write("."); } if (visibleDot3) { Console.SetCursorPosition(xDot3, yDot3); Console.Write("."); } Console.SetCursorPosition(x, y); Console.Write("C"); Console.SetCursorPosition(xEnemy, yEnemy); Console.Write("A"); // Read keys and calculate new position if (Console.KeyAvailable) { userKey = Console.ReadKey(false); if(userKey.Key == ConsoleKey.RightArrow) x++; if(userKey.Key == ConsoleKey.LeftArrow) x--; if(userKey.Key == ConsoleKey.DownArrow) y++; if(userKey.Key == ConsoleKey.UpArrow) y--; } // Move enemies and environment xEnemy += incrXEnemy; if ((xEnemy == 0) || (xEnemy == 79)) incrXEnemy = -incrXEnemy; // Collisions, lose energy or lives, etc if ((x == xDot1) && (y == yDot1) && visibleDot1) { score += 10; visibleDot1 = false; } if ((x == xDot2) && (y == yDot2) && visibleDot2) { score += 10; visibleDot2 = false; } if ((x == xDot3) && (y == yDot3) && visibleDot3) { score += 10; visibleDot3 = false; } // Pause till next fotogram // TO DO } } }
Which would look like this:

Still not perfect: this will move way too fast. We'll correct it in the next section.
Suggested exercise: Search information on how to use "Thread.Sleep", so that it does not move so fast.