Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/16: Рейтинг темы: голосов - 16, средняя оценка - 5.00
2 / 1 / 1
Регистрация: 02.07.2018
Сообщений: 49

Проблема с механизмом рисования

12.11.2018, 22:56. Показов 3828. Ответов 32

Студворк — интернет-сервис помощи студентам
Недавно я написал программу "Змейка" в которой используется следующий графический механизм
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
                HWND hwnd = GetConsoleWindow();
        HDC dc = GetDC(hwnd);
        RECT window = {};
        HBRUSH brush;
        brush = CreateSolidBrush(RGB(0, 0, 255));
        SelectObject(dc, brush);
        RECT WinCoord = {};
        GetWindowRect(hwnd, &WinCoord);
        Rectangle(dc, 90, 80, 490, 100);
        DeleteObject(brush);
        Rectangle(dc, 90, 100, 110, 480);
        DeleteObject(brush);
        Rectangle(dc, 90, 460, 490, 480);
        DeleteObject(brush);
        Rectangle(dc, 470, 100, 490, 460);
        DeleteObject(brush);
Так вот, при тестировании этой программы я столкнулся с тем, что при многократной перерисовке этот механизм рано или поздно зависает и перестает работать, сталкивался ли кто из вас с этой проблемой и если да, то как её решить?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.11.2018, 22:56
Ответы с готовыми решениями:

Проблема рисования толстой пунктирной линии
Всем привет! столкнулся с такой проблемой что не получается нарисовать толстую пунктирную линию. Когда устанавливаю толщину линии...

Работа С Механизмом Удалениеобъекта
Возможно кто знает как работать с механизмом УдалениеОбъекта ???? Если ЗначениеЗаполнено(Ссылка) Тогда Удаление = Новый...

Как пользоваться механизмом флагов в С++
объясните пожалуйста,как работает флаг в С++,его механика,максимально простым языком,если с примером,то вообще отлично!:)

32
2 / 1 / 1
Регистрация: 02.07.2018
Сообщений: 49
18.11.2018, 11:38  [ТС]
Студворк — интернет-сервис помощи студентам
Да, не верю и прошу пруфы.
0
2736 / 891 / 331
Регистрация: 10.02.2018
Сообщений: 2,128
18.11.2018, 12:02
Alexberkut98, помимо удаления кисти нужно ещё освобождать HDC (GetDC ==> ReleaseDC).
У меня 12 студия, в ней нет поддержки 11 стандарта. Что бы скомпилировать пришлось в структуре Sharic убрать инициализацию переменных и добавить обнуляющий их конструктор. Далее программа крашилась при завершении игры в Raiting_Record, так как переменная Head1 содержала мусор. Пришлось добавить в конструктор Zmeia обнуление Head1 и Tail1. Далее змейка не управлялась нажатием клавиш, так как цикл опроса клавиатуры совмещённый с ожиданием времени (начало Napravlenie_hoda) всегда обнулял переменную <c>, решил проблему выносом обнуления из цикла в место объявления переменной <c> и парой строк if (c == 0) c = pred;. Napravlenie_hoda - вызывается рекурсивно, что не очень хорошо, теоретически, можно получить переполнение стека.
0
2 / 1 / 1
Регистрация: 02.07.2018
Сообщений: 49
18.11.2018, 12:23  [ТС]
Цитата Сообщение от Ygg Посмотреть сообщение
У меня 12 студия, в ней нет поддержки 11 стандарта. Что бы скомпилировать пришлось в структуре Sharic убрать инициализацию переменных и добавить обнуляющий их конструктор.
Прошу отдельно пояснить насчет 11 стандарта и причин, по которым он прощает моему коду то, что не прощает вам.
Цитата Сообщение от Ygg Посмотреть сообщение
программа крашилась при завершении игры в Raiting_Record, так как переменная Head1 содержала мусор.
А как же условие
C++
1
if (Head1 != NULL)
которое я специально добавил, чтоб функция работала тогда и только тогда, когда у неё есть с чем работать?
Цитата Сообщение от Ygg Посмотреть сообщение
змейка не управлялась нажатием клавиш, так как цикл опроса клавиатуры совмещённый с ожиданием времени (начало Napravlenie_hoda) всегда обнулял переменную <c>
Не совсем понимаю, в чем тут проблема? У меня вроде такой ошибки не происходит.
Цитата Сообщение от Ygg Посмотреть сообщение
Napravlenie_hoda - вызывается рекурсивно, что не очень хорошо, теоретически, можно получить переполнение стека.
Рекурсивность используется лишь в случае заполнения змейкой выбранного сектора.


Благодарен за детальный анализ кода. Однако хотелось бы взглянуть на его исправленную версию, с комментариями в переделанных участках. И опять пояснениями, почему у меня таких ошибок не всплывало.
0
2736 / 891 / 331
Регистрация: 10.02.2018
Сообщений: 2,128
18.11.2018, 12:37
C++
1
2
3
4
5
6
7
8
9
10
struct Sharic
{
    int x1=0; int y1=0; int x2=0; int y2=0;// требует поддержки C++ 11 (появилась начиная с 15 студии)
};
 
struct Sharic
{
    Sharic() : x1(0), y1(0), x2(0), y2(0) {} // альтернатива
    int x1; int y1; int x2; int y2;
};
В случае отсутствия явной инициализации Head1 может принимать случайные значения отличные от 0
C++
1
2
    Zmeia() : Head(NULL), Tail(NULL) {}; //Инициализируем адреса как пустые
    Zmeia() : Head(NULL), Tail(NULL), Head1(0), Tail1(0) {}; //Инициализируем адреса как пустые
С вводом я может не допонял логику и как-то попортил её, но в оригинале по выходу из данных циклов у меня <c> всегда был равен <pred>. После исправления я хоть смог порулить змейкой.
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
void Zmeia::Napravlenie_hoda(int a, char pred)//В каком направлении должна идти змейка
{
    setlocale(LC_ALL, "Russian");
    //char c;// было
    char c = 0;//стало
    int l = 0;
    do
    {
        SYSTEMTIME st;
        GetLocalTime(&st);
        int u = st.wSecond;
        int r = 0;
        do {
            do {
                //c = 0; //было
                if (_kbhit())
                {
                    c = _getch();
                    if (c == 'e')
                    {
                        cout << "Пауза. Чтобы продолжить нажмите q ";
                        while (c != 'q')
                        {
                            c = _getch();
                        }
                        c = pred;
                        system("cls");
                        HWND hwnd = GetConsoleWindow();
                        HDC dc = GetDC(hwnd);
                        RECT window = {};
                        HBRUSH brush;
                        brush = CreateSolidBrush(RGB(0, 0, 255));
                        SelectObject(dc, brush);
                        RECT WinCoord = {};
                        GetWindowRect(hwnd, &WinCoord);
                        Rectangle(dc, 90, 80, 490, 100);
                        DeleteObject(brush);
                        Rectangle(dc, 90, 100, 110, 480);
                        DeleteObject(brush);
                        Rectangle(dc, 90, 460, 490, 480);
                        DeleteObject(brush);
                        Rectangle(dc, 470, 100, 490, 460);
                        DeleteObject(brush);
                        ReleaseDC(hwnd, dc);
                    }
                }
                else
                {
                    SYSTEMTIME st;
                    GetLocalTime(&st);
                    r = st.wSecond;
                }
            } while (r<(u + 1) && !_kbhit());//Работаю над тем, что бы змейка научилась двигалаться самостоятельно
            //if (!_kbhit()) // было
            if (c == 0) // стало
                c = pred;
        } while (c == 'w'&&pred == 's' || c == 's'&&pred == 'w' || c == 'a'&&pred == 'd' || c == 'd'&&pred == 'a' || c == 'd'&&a == 1 && c == 'x');//Здесь мы не даем змейке идти задом на перёд
...
0
2 / 1 / 1
Регистрация: 02.07.2018
Сообщений: 49
18.11.2018, 12:59  [ТС]
Большое спасибо за ваши предложения. Теперь я бы все же хотел перейти к графическому механизму, что с ним не так?
0
2736 / 891 / 331
Регистрация: 10.02.2018
Сообщений: 2,128
18.11.2018, 13:17
Я уже озвучил своё мнение: помимо удаления кисти нужно ещё освобождать HDC (GetDC ==> ReleaseDC)
После добавления ReleaseDC и DeleteObject в три регулярно вызываемых функции рисования (Stiranie, Obhod и Risuem_Sharik) GDI-хендлы перестают расти в процессе движения змейки. Но нужно сделать подобное для всех функций рисования.
C++
1
2
3
4
5
6
7
8
    HWND hwnd = GetConsoleWindow();
    HDC dc = GetDC(hwnd);
    HBRUSH brush = CreateSolidBrush(RGB(0, 0, 0));
    HBRUSH oldBrush = (HBRUSH)SelectObject(dc, brush);
    // рисуем
    SelectObject(dc, oldBrush);
    DeleteObject(brush);
    ReleaseDC(hwnd, dc);
0
2 / 1 / 1
Регистрация: 02.07.2018
Сообщений: 49
18.11.2018, 13:50  [ТС]
Нужен твой совет. Ситуация улучшилась, но появилась другая проблема и для того чтоб полностью ее оценить, нужно послать тебе видео, чей размер превышает максимально допустимые 20 мб. Что мне делать?
0
2736 / 891 / 331
Регистрация: 10.02.2018
Сообщений: 2,128
18.11.2018, 13:59
Возможно будет достаточно пары показательных скриншотов и немного текстового описания.
0
18.11.2018, 14:01

Не по теме:

Цитата Сообщение от Alexberkut98 Посмотреть сообщение
Ситуация улучшилась
как так? всё же прекрасно было! Лишь завистливые я и nonedark2008, чего-то наговаривали...

0
2 / 1 / 1
Регистрация: 02.07.2018
Сообщений: 49
18.11.2018, 14:11  [ТС]
Вплоть до 17-го яблока игра шла хорошо (до этого только где то до 10-го) а потом случилось это. Причем управление слушалось, но эти белые ячейки все появлялись и не исчезали.
Миниатюры
Проблема с механизмом рисования  
0
2736 / 891 / 331
Регистрация: 10.02.2018
Сообщений: 2,128
18.11.2018, 15:06
Лучший ответ Сообщение было отмечено Alexberkut98 как решение

Решение

Не знаю, у меня не появляются
Но, похоже, что глючит генерация нового яблока, когда змейка длинная и яблоко выпадает в хвост змеи происходит какое-то зацикливание. Вот с таким кодом играл (слишком большой, что бы влезть без сжатия).
Вложения
Тип файла: zip main.zip (5.7 Кб, 1 просмотров)
1
2 / 1 / 1
Регистрация: 02.07.2018
Сообщений: 49
18.11.2018, 15:50  [ТС]
1. Зачем вы закомментировали условия типа
C++
1
if (temp->y1 < 120 && o == 0)
если только на нем и держится защита от выхода за пределы поля.
2. Зачем вы закомментировали
C++
1
Head->x1 != 1000
если это по сути условие продолжения игры?
3. Не могли бы вы скинуть мне в личные сообщения вашу почту на gmail, Что бы я там попробовал скинуть вам полное видео игры?
0
2736 / 891 / 331
Регистрация: 10.02.2018
Сообщений: 2,128
18.11.2018, 16:12
Я заблокировал выход за границы, потому что сильно увеличил скорость игры. Мне было лень долго ползать от яблока к яблоку, а что бы игра не прекращалась при ударе о стенку на таких скоростях я временно убрал часть ограничений. Head->x1 != 1000 это, наверное, можно было и не комментировать, я его принял за что-то другое пока искал нужные строки.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.11.2018, 16:12

Reject связанный с механизмом логина
Всем привет! Получил вчера письмо счастья о том, что мое приложение отклонено. Ругаются на логин, который происходит у меня следующим...

Управление исполнительным механизмом, привод
В общем, раз прошлую тему закрыли, а я обещал уведомить Grey по окончании патентования, то создаю новую тему. В ходе составления заявки...

Каким механизмом расположить виджеты на форме?
Доброго этого самого ув. Алл!! Подскажите пожалуйста, имеем задумку сделать такое вот безобразие как на картинке. Т.е. QMainWindow, в нем...

Подключение БД к клиентскому приложению с механизмом ADO
Господа,какую нужно сделать базу данных для делфи? Смотрел видео и там нужно было подключить базу данных к делфи,я так понял это база...

Что не так со стандартным механизмом событий?
Сам пользуюсь стандартными event`ами. Объявил, подписался, создал обработчик, вызвал и радуюсь. Всё просто и понятно. Но в ряде вроде...


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

Или воспользуйтесь поиском по форуму:
33
Ответ Создать тему
Новые блоги и статьи
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Оказывается, Unreal Engine позволяет качество на порядки выше, чем было в Lineedge
Etyuhibosecyu 05.07.2026
Жаль, конечно, что я не узнал об этом, пока Lineedge существовала, а то бы Noname2331 написал, что волки превращаются в пиксельную кашу, а я бы его попросил скачать какую-нибудь бриллиантовую или Pro. . .
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru