Disabling User Input in a Console Application

2019-01-20 06:52发布

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)?

2条回答
该账号已被封号
2楼-- · 2019-01-20 07:11

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

查看更多
萌系小妹纸
3楼-- · 2019-01-20 07:26

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

查看更多
登录 后发表回答