Форум программистов, компьютерный форум CyberForum.ru

Ping Pong 2D, ncurses - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
[WRG]
 Аватар для [WRG]
50 / 50 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
01.10.2013, 14:51     Ping Pong 2D, ncurses #1
Написал наколенную реализацию игры в пинг понг в консоли Linux (поэтому там есть сторонний kbhit())
Прошу сильно не пинать за кучку костылей
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#include <stdio.>
#include <ncurses.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <sys/ioctl.h>;
 
struct moveobj                      //двигающаяся точка
{
public:
    float x, y;                     //координаты
 
    void setCoord(int m, int n)
    {
        x = m;
        y = n;
    }
};
 
struct straight                     //линия, по которой движется точка
{
    float x, y;                     //точка на пряиой
    float m, n;                     //напрявляющий вектор
 
    void setCoord(int m, int n)
    {
        x = m;
        y = n;
    }
 
    void setVector(int m0, int n0)
    {
        m = m0;
        n = n0;
    }
};
 
struct terminal             //размер окна терминала
{
    int xMax, yMax;
};
 
struct platform             //платформа
{
    int x, y;               //координаты левого края
    int xMax, yMax;         //крайние положения в терминале
    int length;             //длина в символах
 
    void setxy(int m, int n)
    {
        x = m;
        y = n;
    }
 
    void setxymax(int m, int n)
    {
        xMax = m;
        yMax = n;
    }
 
    char *show()
    {
        static char pForm[40];
        char *ptr = pForm;
 
        for (int i = 0; i < length; i++)
            *ptr++ = '=';
 
        *ptr++ = '\0';
 
        return pForm;
    }
};
 
 
 
int _kbhit();       //kbhit function
 
 
 
int main(int argc, char **argv)
{
    initscr();              //ncurses begin
    keypad(stdscr, true);c
    //halfdelay(1);
    cbreak();
    curs_set(0);
 
    float x0 = 1, y0 = 1; //начальные координаты
 
    moveobj point;
    point.setCoord(x0, y0);
 
    terminal term;
    getmaxyx(stdscr, term.xMax, term.yMax);
 
 
    straight line;
    line.setCoord(0, 0);
    line.setVector(1, 2);
 
    platform bottomPlatform;
    bottomPlatform.length = 10;
    bottomPlatform.setxymax(term.xMax-1, term.yMax - bottomPlatform.length - 1);
    bottomPlatform.setxy(bottomPlatform.xMax, 40);
 
    mvprintw(point.x, point.y, "*");
    refresh();
 
 
    while(1)
    {
        getmaxyx(stdscr, term.xMax, term.yMax);
        bottomPlatform.setxymax(term.xMax-1, term.yMax - bottomPlatform.length - 1);
        //keypad(stdscr, true);
 
        cbreak();
 
        mvprintw(point.x, point.y, " ");
        mvprintw(bottomPlatform.x, bottomPlatform.y, "%s", "                 ");
        refresh();
 
        point.x = point.x + line.m * 0.3;
        point.y = point.y + line.n * 0.3;
 
        if (_kbhit())
        {
            int c = getch();
            switch (c)
            {
            case KEY_LEFT:
                bottomPlatform.y -= 5;
                break;
            case KEY_RIGHT:
                bottomPlatform.y += 5;
                break;
            }
        }
 
        //bottomPlatform.y = point.y - bottomPlatform.length / 2;
 
        if (bottomPlatform.y < 0)
            bottomPlatform.y = 0;
 
        if (bottomPlatform.y + bottomPlatform.length > term.yMax)
            bottomPlatform.y = term.yMax - bottomPlatform.length;
 
        mvprintw(point.x, point.y, "0");
        mvprintw(bottomPlatform.x, bottomPlatform.y, "%s", bottomPlatform.show());
        refresh();
        usleep(10 * 1000);
 
 
        if ((point.x >= term.xMax) || (point.x <= 0))
            line.m = -line.m;
 
        if ((point.y >= term.yMax) || (point.y <= 0))
            line.n = -line.n;
    }
 
 
 
    getch();
    endwin();   // ncurses end;
    return 0;
}
 
int _kbhit()
{
    static bool inited = false;
    int left;
 
    if (!inited) {
        termios t;
        tcgetattr(0, &t);
        t.c_lflag &= ~ICANON;
        tcsetattr(0, TCSANOW, &t);
        setbuf(stdin, NULL);
        inited = true;
    }
 
    ioctl(0, FIONREAD, &left);
 
    return left;
}

Столкнулся с такой проблемой - платформа внизу медленно реагирует на нажатия стрелок на клавиатуре. Понял, что это связано с тем, что цикл из за usleep() медленно проходит итерацию. Уменьшил задержку, соответственно пришлось уменьшить скорость шарика, а то летал как бешеный. Но Часть проблемы осталась всё равно - платформа реагирует на нажатие клавиши, перемещаясь на одну единицу, затем замирает на долю секунды, и потом уже двигается, пока не отпустить клавишу. Оказалось связано с системными настройками на картинке. Если поставить короткую задержку, то всё почти идеально, но пользователь же не будет менять задержку ради игры.
Вопрос: как работать с клавиатурой, чтобы не возникало задержек? Как делают это в реальных играх?
Миниатюры
Ping Pong 2D, ncurses   Ping Pong 2D, ncurses  
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.10.2013, 14:51     Ping Pong 2D, ncurses
Посмотрите здесь:

ping C++
Ping...неудается с функцию system поместить переменную C++
Исходники Ping'a C++
библиотека <ncursesw/ncurses.h> C++
Ping по списку адресов с применением system C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
aLarman
636 / 557 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
01.10.2013, 17:57     Ping Pong 2D, ncurses #2
в реальных играх используют готовые игровые движки
[WRG]
 Аватар для [WRG]
50 / 50 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
01.10.2013, 21:01  [ТС]     Ping Pong 2D, ncurses #3
но в движке это как-то реализовано! Вот я и спрашиваю, как такое можно реализовать при помощи ncurses, кроме как изменением настроек системы.
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
01.10.2013, 21:12     Ping Pong 2D, ncurses #4
скорость движения привязана в играх к фпс.
То есть оценивается, сколько времени прошло с момента предыдущей отрисовки, это время, грубо говоря, и умножается на скорость движения объекта, чтобы получить величину, на которую требуется изменить его координаты.

Добавлено через 58 секунд
В твоём случае, usleep стоит убрать, а клавиатуру обрабатывать лучше не в цикле отрисовки
[WRG]
 Аватар для [WRG]
50 / 50 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
01.10.2013, 21:27  [ТС]     Ping Pong 2D, ncurses #5
попробую. но без usleep() точка будет летать как бешенная, что в принципе можно регулировать коэффициентом. только вот проблемы это наверно не решит, ведь тут уж так задумано в системе - если вы зажмёте какую нибудь букву, печатая текст, она не начнет сразу же печататься в больших количествах, есть задержка, видимо, от ложных срабатываний.

Добавлено через 3 минуты
как и ожидалось, эффекта нет, зато всё мерцает, из-за слишком быстрого обновления консоли.
тут дело в использовании getch(). надо заменить её каким-то аналогом, который не будет считывать символы. хотелось бы узнать, есть ли такие?
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
01.10.2013, 21:50     Ping Pong 2D, ncurses #6
А функцию эту ты взял откуда-то?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int _kbhit()
{
    static bool inited = false;
    int left;
 
    if (!inited) {
        termios t;
        tcgetattr(0, &t);
        t.c_lflag &= ~ICANON;
        tcsetattr(0, TCSANOW, &t);
        setbuf(stdin, NULL);
        inited = true;
    }
 
    ioctl(0, FIONREAD, &left);
 
    return left;
}
Моё предложение - вместо
Цитата Сообщение от [WRG] Посмотреть сообщение
usleep(10 * 1000);
поставить
C++
1
2
3
4
for (i=0; i<10; i++){
  usleep(1000);
  if (_kbhit()) c = getch();
}
Так клавиатура будет опрашиваться даже в перерыве между кадрами!
С количеством шагов в цикле/длиной задержек надо экспериментировать
[WRG]
 Аватар для [WRG]
50 / 50 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
02.10.2013, 11:19  [ТС]     Ping Pong 2D, ncurses #7
Нашел, видимо чья-то реализация для linux. Работает аналогично kbhit из conio.h

Добавлено через 6 минут
Попробовал ваш вариант. Ничего не изменилось, па крайней мере на глаз не заметно. Моё мнение, здесь задержка в цикле не причем, она мала. Виновата задержка печати символов повторно при зажатой клавише. Как и в любом текстовом редакторе: зажметё букву "ы" - сперва сразу появится одна буква "ы", потом через некоторый промежуток времени начнут появляться другие. Вот именно этот промежуток и мешает.
XRuZzz
Антикодер
577 / 478 / 23
Регистрация: 15.09.2012
Сообщений: 2,429
02.10.2013, 11:29     Ping Pong 2D, ncurses #8
вкусно, но это не C++
[WRG]
 Аватар для [WRG]
50 / 50 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
02.10.2013, 12:03  [ТС]     Ping Pong 2D, ncurses #9
Bash
1
2
3
bernhardt@NP355V4C:~/Coding/WORKSPACE/2d_test $ g++ main.cpp -lncurses
main.cpp:8:23: warning: extra tokens at end of #include directive [enabled by default]
bernhardt@NP355V4C:~/Coding/WORKSPACE/2d_test $
скомпилировалось, значит C++

на самом деле, это лишь проба пера, структуры вместо классов потому, что там, где начал писать, не было компилятора C++. Да и что это меняет. По сути ничего и не изменится, кроме структур. Вопрос не об этом.
XRuZzz
Антикодер
577 / 478 / 23
Регистрация: 15.09.2012
Сообщений: 2,429
02.10.2013, 14:53     Ping Pong 2D, ncurses #10
скажем это не по Страуструпу(создатель C++)
[WRG]
 Аватар для [WRG]
50 / 50 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
02.10.2013, 15:07  [ТС]     Ping Pong 2D, ncurses #11
ну покажите мне тогда надо, как по Страуструпу!
XRuZzz
Антикодер
577 / 478 / 23
Регистрация: 15.09.2012
Сообщений: 2,429
02.10.2013, 15:25     Ping Pong 2D, ncurses #12
Цитата Сообщение от [WRG] Посмотреть сообщение
ну покажите мне тогда надо, как по Страуструпу!
зачем у него же всё в книгах изложено. вы сами можете открыть и посмотреть.
[WRG]
 Аватар для [WRG]
50 / 50 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
02.10.2013, 18:09  [ТС]     Ping Pong 2D, ncurses #13
Что тут изменится, если сделать по Страуструпу, кроме замены структур на классы? В данном конкретном случае и структура-то от класса ничем не отличается, кроме того, что в ней по дефолту всё public.
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
02.10.2013, 18:12     Ping Pong 2D, ncurses #14
Цитата Сообщение от [WRG] Посмотреть сообщение
Что тут изменится, если сделать по Страуструпу, кроме замены структур на классы? В данном конкретном случае и структура-то от класса ничем не отличается, кроме того, что в ней по дефолту всё public.
при чём тут классы? Судя по использованию слова public, твоя программа и так для крестов, а не для сей.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.10.2013, 18:16     Ping Pong 2D, ncurses
Еще ссылки по теме:

Что-то наподобие программы ping C++
C++ Аналог библиотеки NCurses для windows
C++ Как реализовать движение символа по экрану? ncurses.h

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

Или воспользуйтесь поиском по форуму:
[WRG]
 Аватар для [WRG]
50 / 50 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
02.10.2013, 18:16  [ТС]     Ping Pong 2D, ncurses #15
Она скомпилится и как си программа, и как с++ программа, а изначально задумана как программа на С. Просто когда писал первую реализацию, под рукой не было компилятора С++.XRuZzz просто намекнул мне, что я написал не в С++ стиле.

Добавлено через 57 секунд
И мы опять отошли от темы. Видимо, на этот вопрос мне так просто ответа не получить.
Yandex
Объявления
02.10.2013, 18:16     Ping Pong 2D, ncurses
Ответ Создать тему
Опции темы

Текущее время: 04:08. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru