Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Программа на c#

Тимофей Я Знаток (333), открыт 3 недели назад
Почему даже когда я отпускаю пробел, игрок продолжает двигаться?

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();
}
5 ответов
Вадим Кулиш Профи (677) 3 недели назад
void MovePlayer()
{
while (true)
{
if (Console.KeyAvailable)
{
ConsoleKeyInfo keyInfo = Console.ReadKey(intercept: true);
if (keyInfo.Key == ConsoleKey.Spacebar)
{
PlayerY -= 1;
}
}
Thread.Sleep(100);
}
}
измени код на этот
Тимофей ЯЗнаток (333) 3 недели назад
все также, только игрок движется очень быстро
Sergio 2.1 Оракул (67261) 3 недели назад
 bool isJumping = false; 

void MovePlayer()
{
while (true)
{
if (Console.KeyAvailable)
{
ConsoleKeyInfo keyInfo = Console.ReadKey(intercept: true);
if (keyInfo.Key == ConsoleKey.Spacebar && !isJumping)
{
isJumping = true;
PlayerY -= 1;
Thread.Sleep(500); // Уменьшенная задержка
PlayerY += 1; // Возврат игрока вниз
isJumping = false;
}
}
Thread.Sleep(100);
}
}
Jurijus Zaksas Искусственный Интеллект (445688) 3 недели назад
Посмотри на это с другой стороны: почему он ДОЛЖЕН ПЕРЕСТАТЬ? Что в твоей программе происходит, когда ты отпускаешь пробел? (спойлер: ничего).
Сергей Гений (59758) 3 недели назад
Механика работы. ReadKey считывает не клавиатуру, а поток (очередь) ввода. Нажмите быстро 10 раз пробел - 10 пробелов попадут в поток и ваш игрок сделает ровно 10 шагов независимо от того нажимаете ли вы пробел в данный момент или нет.
Чтобы этого избежать можно например добавить перед PlayerY -=1; строку
  while (Console.KeyAvailable) Console.ReadKey(true); 
Тогда по крайней мере только один символ будет оставаться в потоке. А для более продвинутогого управления следует отказаться от потока ввода и обрабатывать нажатия клавиатуры.
Похожие вопросы