Механика работы. ReadKey считывает не клавиатуру, а поток (очередь) ввода. Нажмите быстро 10 раз пробел - 10 пробелов попадут в поток и ваш игрок сделает ровно 10 шагов независимо от того нажимаете ли вы пробел в данный момент или нет.
Чтобы этого избежать можно например добавить перед PlayerY -=1; строку
while (Console.KeyAvailable) Console.ReadKey(true);
Тогда по крайней мере только один символ будет оставаться в потоке. А для более продвинутогого управления следует отказаться от потока ввода и обрабатывать нажатия клавиатуры.
using System.Runtime.InteropServices;
int width_s = 21;
int height_s = 30;
int PlayerY = height_s - 2;
Random random = new Random();
ConsoleColor color = ConsoleColor.Green ;
Thread colorChangingThread = new Thread(ChangeColorEveryFiveSeconds);
Thread moveThread = new Thread(MovePlayer);
void SetupConsole()
{
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll", SetLastError = true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", SetLastError = true)]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
const int GWL_STYLE = -16;
const int WS_MAXIMIZEBOX = 0x10000;
const int WS_THICKFRAME = 0x00040000;
const int WS_SIZEBOX = WS_THICKFRAME;
Console.BackgroundColor = ConsoleColor.DarkGreen;
Console.SetWindowSize(width_s, height_s);
Console.SetBufferSize(width_s, height_s);
Console.CursorVisible = false;
// Запрет изменения размеров окна
IntPtr hWnd = GetConsoleWindow();
SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) & ~WS_MAXIMIZEBOX & ~WS_SIZEBOX);
}
void DrawTerrain()
{
Console.SetCursorPosition(0, 0);
Console.ForegroundColor = ConsoleColor.DarkYellow;
for (int y = 0; y <= height_s - 1; y++)
{
Console.SetCursorPosition(0, y);
Console.Write(" \u2588\u2588 \u2588\u2588 ");
}
Console.ForegroundColor = ConsoleColor.Black ;
Console.SetCursorPosition((int)((float)width_s / 2), PlayerY);
Console.Write("\u2588");
Console.SetCursorPosition(0, 0);
Console.ForegroundColor = color;
Console.SetCursorPosition((int)((float)width_s / 2) - 1, 1);
Console.Write("\u2588\u2588\u2588");
Thread.Sleep(1000 / 10);
//Console.Clear();
}
void ChangeColorEveryFiveSeconds()
{
while (true)
{
if (color == ConsoleColor.Green ) { color = ConsoleColor.Red ; }
else { color = ConsoleColor.Green ; }
Thread.Sleep( random.Next (2, 3 + 1) * 1000);
}
}
void MovePlayer()
{
while (true)
{
if (Console.KeyAvailable)
{
ConsoleKeyInfo keyInfo = Console.ReadKey(intercept: true);
if (keyInfo.Key == ConsoleKey.Spacebar)
{
PlayerY -= 1;
Thread.Sleep(2000); // Задержка в 2 секунды
}
}
Thread.Sleep(100);
}
}
SetupConsole();
colorChangingThread.Start();
moveThread.Start();
while (true)
{
DrawTerrain();
}