Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
#1

Ping Pong 2D, ncurses - C++

01.10.2013, 14:51. Просмотров 1236. Ответов 14
Метки нет (Все метки)

Написал наколенную реализацию игры в пинг понг в консоли 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() медленно проходит итерацию. Уменьшил задержку, соответственно пришлось уменьшить скорость шарика, а то летал как бешеный. Но Часть проблемы осталась всё равно - платформа реагирует на нажатие клавиши, перемещаясь на одну единицу, затем замирает на долю секунды, и потом уже двигается, пока не отпустить клавишу. Оказалось связано с системными настройками на картинке. Если поставить короткую задержку, то всё почти идеально, но пользователь же не будет менять задержку ради игры.
Вопрос: как работать с клавиатурой, чтобы не возникало задержек? Как делают это в реальных играх?
1
Миниатюры
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 (C++):

Задачка с ncurses.h - C++
Привет всем форумчанам! Не могу реализовать передвижение курсора в ncurses, хотя получалось делать на conio.h. Подскажите, пожалуйста,...

Библиотека <ncursesw/ncurses.h> - C++
где и что я могу скачать , что моя программа, в которой присутсвует данная библиотека #include &lt;ncursesw/ncurses.h&gt; скомпилировалась?...

Ошибка сборки библиотеки ncurses.h - C++
Доброе время суток ондофорумчани и однофорумчанки! Суть такая давно искал фрем для работы с псевдографикой и счастье нашел, но почему...

Как нарисовать в терминале линию? с++ ncurses - C++
Мне нужно нарисовать 10 линий . Из одной точки по одной линии в 10 других точек. Использую библиотеку ncurses желательно было бы найти...

Аналог библиотеки NCurses для windows - C++
Подскажите, где можно достать аналог библиотеки NCurses для Windows? P. S. Пробовал собрать PDCurses но Mingw отказывается собирать...

Как реализовать движение символа по экрану? ncurses.h - C++
Здравствуйте, друзья! Нужна помощь с ncurses. Подскажите пожалуйста, как реализовать движение символа по экрану? Т.е. как в...

14
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
Завершенные тесты: 1
01.10.2013, 17:57 #2
в реальных играх используют готовые игровые движки
1
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
01.10.2013, 21:01  [ТС] #3
но в движке это как-то реализовано! Вот я и спрашиваю, как такое можно реализовать при помощи ncurses, кроме как изменением настроек системы.
0
Kuzia domovenok
1960 / 1813 / 143
Регистрация: 25.03.2012
Сообщений: 6,288
Записей в блоге: 1
01.10.2013, 21:12 #4
скорость движения привязана в играх к фпс.
То есть оценивается, сколько времени прошло с момента предыдущей отрисовки, это время, грубо говоря, и умножается на скорость движения объекта, чтобы получить величину, на которую требуется изменить его координаты.

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

Добавлено через 3 минуты
как и ожидалось, эффекта нет, зато всё мерцает, из-за слишком быстрого обновления консоли.
тут дело в использовании getch(). надо заменить её каким-то аналогом, который не будет считывать символы. хотелось бы узнать, есть ли такие?
0
Kuzia domovenok
1960 / 1813 / 143
Регистрация: 25.03.2012
Сообщений: 6,288
Записей в блоге: 1
01.10.2013, 21:50 #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();
}
Так клавиатура будет опрашиваться даже в перерыве между кадрами!
С количеством шагов в цикле/длиной задержек надо экспериментировать
1
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
02.10.2013, 11:19  [ТС] #7
Нашел, видимо чья-то реализация для linux. Работает аналогично kbhit из conio.h

Добавлено через 6 минут
Попробовал ваш вариант. Ничего не изменилось, па крайней мере на глаз не заметно. Моё мнение, здесь задержка в цикле не причем, она мала. Виновата задержка печати символов повторно при зажатой клавише. Как и в любом текстовом редакторе: зажметё букву "ы" - сперва сразу появится одна буква "ы", потом через некоторый промежуток времени начнут появляться другие. Вот именно этот промежуток и мешает.
0
XRuZzz
Антикодер
687 / 593 / 29
Регистрация: 15.09.2012
Сообщений: 2,541
02.10.2013, 11:29 #8
вкусно, но это не C++
0
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
02.10.2013, 12:03  [ТС] #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++. Да и что это меняет. По сути ничего и не изменится, кроме структур. Вопрос не об этом.
0
XRuZzz
Антикодер
687 / 593 / 29
Регистрация: 15.09.2012
Сообщений: 2,541
02.10.2013, 14:53 #10
скажем это не по Страуструпу(создатель C++)
0
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
02.10.2013, 15:07  [ТС] #11
ну покажите мне тогда надо, как по Страуструпу!
0
XRuZzz
Антикодер
687 / 593 / 29
Регистрация: 15.09.2012
Сообщений: 2,541
02.10.2013, 15:25 #12
Цитата Сообщение от [WRG] Посмотреть сообщение
ну покажите мне тогда надо, как по Страуструпу!
зачем у него же всё в книгах изложено. вы сами можете открыть и посмотреть.
0
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
02.10.2013, 18:09  [ТС] #13
Что тут изменится, если сделать по Страуструпу, кроме замены структур на классы? В данном конкретном случае и структура-то от класса ничем не отличается, кроме того, что в ней по дефолту всё public.
0
Kuzia domovenok
1960 / 1813 / 143
Регистрация: 25.03.2012
Сообщений: 6,288
Записей в блоге: 1
02.10.2013, 18:12 #14
Цитата Сообщение от [WRG] Посмотреть сообщение
Что тут изменится, если сделать по Страуструпу, кроме замены структур на классы? В данном конкретном случае и структура-то от класса ничем не отличается, кроме того, что в ней по дефолту всё public.
при чём тут классы? Судя по использованию слова public, твоя программа и так для крестов, а не для сей.
0
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
02.10.2013, 18:16  [ТС] #15
Она скомпилится и как си программа, и как с++ программа, а изначально задумана как программа на С. Просто когда писал первую реализацию, под рукой не было компилятора С++.XRuZzz просто намекнул мне, что я написал не в С++ стиле.

Добавлено через 57 секунд
И мы опять отошли от темы. Видимо, на этот вопрос мне так просто ответа не получить.
0
02.10.2013, 18:16
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.10.2013, 18:16
Привет! Вот еще темы с ответами:

Ncurses | вывод на экран строки std::string - C++
Ребят, я чёт не могу разобраться. Собственно, надо в окно вывести строку, значение которой хранится в переменной типа std::string ...

ping - C++
Здраствуйте уважаемые програмисты.В коледже задали задание написать программу которая делает ping и сохраняет ip в txt.Вот мой код,но...

Исходники Ping'a - C++
Hi Kto pomojet najti source-i ping a ? ili objasnit kak mojno pisat spasibo

Написать функцию ping - C++
помогите осущиствить...долго копался в функции system что бы скопировть и переделать исходники-но ничего не получилось ксатти еще...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru