2

I am making a C# console text-based game, and because I wanted it to look more old-school, I've added an effect so that any text (descriptions, tutorials, dialogues) looks like it's being typed, and it looks like this:

public static int pauseTime = 50;

class Writer
{
    public void WriteLine(string myText)
    {
        int pauseTime = MainClass.time;
        for (int i = 0; i < myText.Length; i++)
        {
                Console.Write(myText[i]);
                System.Threading.Thread.Sleep(pauseTime);
        }
        Console.WriteLine("");
    }
}

But then I thought that this might be annoying and I thought about adding an option to skip the effect and make all the text appear at once. So I chose the Enter key to be the "skip" key, and it makes the text appear at once, but pressing the enter key also creates a new text line, scrambling the text.

So I want to somehow disable user input, so that the user cannot write anything in the console. Is there a way to, for example, disable the command prompt (and by command prompt I don't mean cmd.exe, but the flashing "_" underscore sign)?

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
Piotr
  • 53
  • 1
  • 1
  • 9

2 Answers2

2

I think what you want is Console.ReadKey(true) which will intercept the pressed key and won't display it.

class Writer
{
    public void WriteLine(string myText)
    {
        for (int i = 0; i < myText.Length; i++)
        {
            if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Enter)
            {
                Console.Write(myText.Substring(i, myText.Length - i));
                break;
            }
            Console.Write(myText[i]);
            System.Threading.Thread.Sleep(pauseTime);
        }
        Console.WriteLine("");
    }
}

Source: MSDN Article

Tonkleton
  • 547
  • 3
  • 14
  • No problem! You've probably already got a solution, but as a bonus I've edited my post to contain an example which does not require another thread by using the Console.KeyAvailable property. Enjoy! – Tonkleton Sep 11 '15 at 22:17
  • HUGE THANKS for all the effort you put into that, it works even better than my solution. I am afraid thanking you is the only thing I can do for you,so once again THANK YOU! – Piotr Sep 11 '15 at 22:29
0

Instead of just sleeping between Writes, you could listen for key input using this class (as suggested here):

class Reader {
  private static Thread inputThread;
  private static AutoResetEvent getInput, gotInput;
  private static ConsoleKeyInfo input;

  static Reader() {
    getInput = new AutoResetEvent(false);
    gotInput = new AutoResetEvent(false);
    inputThread = new Thread(reader);
    inputThread.IsBackground = true;
    inputThread.Start();
  }

  private static void reader() {
    while (true) {
      getInput.WaitOne();
      input = Console.ReadKey();
      gotInput.Set();
    }
  }

  public static ConsoleKeyInfo ReadKey(int timeOutMillisecs) {
    getInput.Set();
    bool success = gotInput.WaitOne(timeOutMillisecs);
    if (success)
      return input;
    else
      return null;
  }
}

In your loop:

Console.Write(myText[i]);
if (pauseTime > 0)
{
    var key = Reader.ReadKey(pauseTime);
    if (key != null && key.Key == ConsoleKey.Enter)
    {
        pauseTime = 0;
    }
}

I have just handwritten this and not checked it, so if it doesn't work let me know

Community
  • 1
  • 1
Glen Thomas
  • 10,190
  • 5
  • 33
  • 65
  • I just checked it, unfortunately it doesn't work. When I press Enter when a line of text is being written, it erases the part that was allready written and then continues writing. Also, the first character on every line is skipped. But thank you for responding. – Piotr Sep 11 '15 at 22:01