Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 08.07.2013
Сообщений: 4

Залипание клавиши в консоли

10.09.2013, 09:36. Показов 3972. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, изучаю Шарп, уверено решил написать консольную змейку, но так уж сложилось, что задачу в написании змейки усложняю постепенно.
На данный момент написал программу которая двигает по полю игры ячейку в заданном мной направлении с клавиатуры через определенный промежуток времени. Все вроде даже получилось, но покоя не даёт один нюанс - если несколько секунд держать клавишу зажатой в одном направлении - ячейка упорно продолжает движения в указанную мной сторону, несмотря на мои судоржные попытки ёё развернуть, а реагировать начинает только через несколько десятков секунд. В общем управление с опозданием. Чтобы нормально играть, нужно строго на каждый такт счетчика тыцать клавишу 1 раз. Провёл в попытках это исправить не 1 час, но никак не получилось, подскажите как реализовать фикс данной проблемы.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Threading; 
 
class _Main
{
    static void Main()
    {
        //ConsoleKeyInfo cki=new ConsoleKeyInfo();
        bool exit = false;
        ConsoleKeyInfo cki;
        const int H = 20;//Высота
        const int W = 20;//Ширина
        char[,] field = new char[H, W];
        int pointH=0;
        int pointW=0;
        int count = 0;
 
        while (!exit)
        {
            if (Console.KeyAvailable)
            {
                cki = Console.ReadKey(true);
                switch (cki.Key)
                {
                    case ConsoleKey.UpArrow:
                        pointH--;
                        break;
 
                    case ConsoleKey.DownArrow:
                        pointH++;
                        break;
 
                    case ConsoleKey.LeftArrow:
                        pointW--;
                        break;
 
                    case ConsoleKey.RightArrow:
                        pointW++;
                        break;
                    case ConsoleKey.Escape:
                        exit = true;
                        break;
                    default:
 
                        break;
                }
            }
           
            count++;
            //Проверка на выход из границ
            if (pointH > H-1)
                pointH = 0;
            if (pointH < 0)
                pointH = H-1;
            if (pointW > W-1)
                pointW = 0;
            if (pointW < 0)
                pointW = W-1;
            //Заполняем поле игры
            for (int i = 0; i < H; i++)//Высота
            {
 
                for (int j = 0; j < W; j++)//Ширина
                {
                    if (i == pointH && j == pointW)
                        field[i, j] = '*';
                    else
                        field[i, j] = '-';
                }
            }
 
            //Выводим на экран поле игры
            for (int i = 0; i < H; i++)//Высота
            {
                for (int j = 0; j < W; j++)//Ширина
                {
                    Console.Write(field[i, j]);
                }
                Console.WriteLine();
            }
            Console.WriteLine(count);
            Thread.Sleep(400);
            Console.Clear(); //Чистим консоль
        }
    }
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.09.2013, 09:36
Ответы с готовыми решениями:

Эмуляция нажатия клавиши в консоли
В общем... вообще, у меня есть вот такая вот фиговина: ConsoleKeyInfo key = Console.ReadKey(); switch (key.Key) { ... } ...

Отловить нажатие клавиши в консоли
Здравствуйте! Необходимо отловить нажатие клавиши пробел или Enter, когда я не нахожусь в консоли, то есть она свернута. Подскажите,...

Выход из консоли по нажатию клавиши
Кто-нибудь знает как можно выходить из консоли при нажатии на определённую клавишу или введя определённое число. Например, мне нужно, чтобы...

11
 Аватар для mbean
46 / 42 / 14
Регистрация: 18.02.2012
Сообщений: 82
10.09.2013, 11:34
Проблема в том, что Вы сразу начинаете двигать объект при нажатии клавиши. Правильнее было сделать так, чтобы при нажатии клавиши менялся вектор движения, а не координаты объекта.
0
39 / 37 / 8
Регистрация: 01.08.2013
Сообщений: 106
10.09.2013, 11:44
Согласен, с предыдущим форумчанином)
немного переделал, вышло как то так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
bool exit = false;
            ConsoleKeyInfo cki;
            const int H = 20;//Высота
            const int W = 20;//Ширина
            char[,] field = new char[H, W];
            int pointH = 0;
            int pointW = 0;
            int count = 0;
            int lastTp = 0;
 
            DateTime nt = DateTime.Now;
            int tic = 400;
 
            while (!exit)
            {
                if (Console.KeyAvailable)
                {
                    cki = Console.ReadKey(true);
                    switch (cki.Key)
                    {
                        case ConsoleKey.UpArrow:
                            lastTp = 0;
                            break;
 
                        case ConsoleKey.DownArrow:
                            lastTp = 1;
                            break;
 
                        case ConsoleKey.LeftArrow:
                            lastTp = 2;
                            break;
 
                        case ConsoleKey.RightArrow:
                            lastTp = 3;
                            break;
                        case ConsoleKey.Escape:
                            exit = true;
                            break;
                    }
                }
 
                if ((DateTime.Now - nt).TotalMilliseconds > tic)
                {
                    switch (lastTp)
                    {
                        case 0:
                            pointH--;
                            break;
 
                        case 1:
                            pointH++;
                            break;
 
                        case 2:
                            pointW--;
                            break;
 
                        case 3:
                            pointW++;
                            break;
                    }
 
                    Console.Clear(); 
                    count++;
                    //Проверка на выход из границ
                    if (pointH > H - 1)
                        pointH = 0;
                    if (pointH < 0)
                        pointH = H - 1;
                    if (pointW > W - 1)
                        pointW = 0;
                    if (pointW < 0)
                        pointW = W - 1;
                    //Заполняем поле игры
                    for (int i = 0; i < H; i++)//Высота
                    {
 
                        for (int j = 0; j < W; j++)//Ширина
                        {
                            if (i == pointH && j == pointW)
                                field[i, j] = '*';
                            else
                                field[i, j] = '-';
                        }
                    }
 
                    //Выводим на экран поле игры
                    for (int i = 0; i < H; i++)//Высота
                    {
                        for (int j = 0; j < W; j++)//Ширина
                        {
                            Console.Write(field[i, j]);
                        }
                        Console.WriteLine();
                    }
                    Console.WriteLine(count);
                    //Thread.Sleep(400);
                    //Чистим консоль
 
                    nt = DateTime.Now;
                }
            }
Это, если нужно действительно змейку, т.е. постоянное движение объекта, но при этом реагирование на кнопки.

Добавлено через 52 секунды
P.S. tic - скорость, если сразу не видно.
1
0 / 0 / 0
Регистрация: 08.07.2013
Сообщений: 4
10.09.2013, 11:46  [ТС]
Вы правы, спасибо за ответ. Но всё-же, мне было бы интерестно узнать причину этого недоразумения. Код хоть и корявый но по сути, как я понимаю, должен работать правильно. Какова причина залипания?
0
39 / 37 / 8
Регистрация: 01.08.2013
Сообщений: 106
10.09.2013, 11:48
Цитата Сообщение от Alexhoua Посмотреть сообщение
Вы правы, спасибо за ответ. Но всё-же, мне было бы интерестно узнать причину этого недоразумения. Код хоть и корявый но по сути, как я понимаю, должен работать правильно. Какова причина залипания?
Буфер накапливает нажатия, и в то время, пока приложение висит на Thread.Sleep - забивается нажатиями.
1
0 / 0 / 0
Регистрация: 08.07.2013
Сообщений: 4
10.09.2013, 12:22  [ТС]
А с этого возникает вопрос - можно ли как-то буфер очистить?
Чисто для себя интересуюсь.
0
 Аватар для mbean
46 / 42 / 14
Регистрация: 18.02.2012
Сообщений: 82
11.09.2013, 00:00
Цитата Сообщение от Alexhoua Посмотреть сообщение
А с этого возникает вопрос - можно ли как-то буфер очистить?
Чисто для себя интересуюсь.
Ваша программа этим и занимается.
C#
1
2
    while (Console.KeyAvailable)
        Console.ReadKey(true);
0
0 / 0 / 0
Регистрация: 08.07.2013
Сообщений: 4
11.09.2013, 01:32  [ТС]
Цитата Сообщение от mbean Посмотреть сообщение
Ваша программа этим и занимается.
C#
1
2
    while (Console.KeyAvailable)
        Console.ReadKey(true);
Как я понимаю, в данной строчке она занимается не очисткой буфера, а его заполнением новыми значениями.
0
39 / 37 / 8
Регистрация: 01.08.2013
Сообщений: 106
11.09.2013, 07:37
Таки да, она просто вытаскивает всё, что есть в буфере. В с++ была команда fflush, а вот в c#, если честно, что то не слышал про аналогичную чистку.
1
 Аватар для mbean
46 / 42 / 14
Регистрация: 18.02.2012
Сообщений: 82
11.09.2013, 18:54
Цитата Сообщение от Alexhoua Посмотреть сообщение
Как я понимаю, в данной строчке она занимается не очисткой буфера, а его заполнением новыми значениями.
Неверно, буфер заполняется значениями при нажатии клавиш на клавиатуре. Функция Readkey считывает значение из буфера, если он не пустой.

Цитата Сообщение от onicdr Посмотреть сообщение
Таки да, она просто вытаскивает всё, что есть в буфере. В с++ была команда fflush, а вот в c#, если честно, что то не слышал про аналогичную чистку.
Увы в плане работы с консолью класс Console очень ограничен по функциональности.
1
0 / 0 / 0
Регистрация: 14.02.2019
Сообщений: 4
18.10.2020, 20:11
как по мне проще так :


while (Console.KeyAvailable)
{
Console.ReadKey(true);
}
0
18.10.2020, 20:17

Не по теме:

На всякий случай: теме 7 лет.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.10.2020, 20:17
Помогаю со студенческими работами здесь

В переменную считать нажатие клавиши из консоли
Добрый вечер, форумчане. Как сделать так, чтобы в переменную считывалась нажатая клавиша из консоли, без нажатия энтера? Аналог getche()...

Ожидание нажатия клавиши для закрытия консоли
Если запускать программу не через среду программирования, то она выполняется и, не дав разглядеть результат, закрывается. В C++ на этот...

Считывание нажатой клавиши в консоли некорректна (Символы двоятся)
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace T1 { class Program ...

Как в консоли можно получить значение нажатой пользователем клавиши
Как в консоли C# можно получить значение нажатой пользователем клавиши, или узнать значение введенной строки? Помню как то 3 года назад...

Нажатие клавиши в консоли
Здравствуйте! Можно ли как-то узнавать: нажата ли клавиша в консоли. И если - нет, то как это правильно реализовать в Forms?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru