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:

Appearance of Game01j

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.