Функция main()
В функции main()
мы сначала вызываем функцию инициализации init()
, а затем заходим в цикл while()
. Цикл主要 состоит из трех частей:
- Проверяем ввод пользователя: Если нажата клавиша "w" или пробел, птица поднимется на две строки. Если нажата клавиша "q", игра завершится. Если нажата клавиша "z", игра будет приостановлена.
- Перемещаем птицу и перерисовываем ее.
- Проверяем, столкнулась ли птица с трубами.
Посмотрим на код:
int main()
{
char ch;
init();
while(1)
{
ch = getch(); // Получаем ввод с клавиатуры
if(ch == ' ' || ch == 'w' || ch == 'W') // Если нажата пробел или клавиша "w"
{
// Перемещаем птицу и перерисовываем ее
move(bird_y, bird_x);
addch(CHAR_BLANK);
refresh();
bird_y--;
move(bird_y, bird_x);
addch(CHAR_BIRD);
refresh();
// Если птица столкнулась с трубами, завершаем игру
if((char)inch() == CHAR_STONE)
{
set_ticker(0);
sleep(1);
endwin();
exit(0);
}
}
else if(ch == 'z' || ch == 'Z') // Приостановка
{
set_ticker(0);
do
{
ch = getch();
} while(ch!= 'z' && ch!= 'Z');
set_ticker(ticker);
}
else if(ch == 'q' || ch == 'Q') // Завершение
{
sleep(1);
endwin();
exit(0);
}
}
return 0;
}
В функции main()
мы сначала инициализируем экран, а затем в цикле получаем ввод с клавиатуры. Если нажата клавиша "w" или пробел, птица поднимется на две строки. Если нажата клавиша "q", игра завершится. Если нажата клавиша "z", игра будет приостановлена.
Теперь посмотрим на функцию init()
:
void init()
{
initscr();
cbreak();
noecho();
curs_set(0);
srand(time(0));
signal(SIGALRM, drop);
init_bird();
init_head();
init_wall();
init_draw();
sleep(1);
ticker = 500;
set_ticker(ticker);
}
Функция init()
сначала инициализирует экран с использованием функций, предоставляемых ncurses
. Затем она вызывает несколько вспомогательных функций для выполнения конкретной инициализации. Обратите внимание, что мы устанавливаем функцию обработчика сигнала drop()
и настраиваем интервал таймера.
Посмотрим на каждую вспомогательную функцию инициализации.
Функция init_bird()
инициализирует позицию птицы:
void init_bird()
{
bird_x = 5;
bird_y = 15;
move(bird_y, bird_x);
addch(CHAR_BIRD);
refresh();
sleep(1);
}
Функции init_head()
и init_wall()
инициализируют связанный список для хранения труб:
void init_head()
{
Node tmp;
tmp = (node *)malloc(sizeof(node));
tmp->next = NULL;
head = tmp;
tail = head;
}
void init_wall()
{
int i;
Node tmp, p;
p = head;
for(i = 0; i < 5; i++)
{
tmp = (node *)malloc(sizeof(node));
tmp->x = (i + 1) * 19;
tmp->y = rand() % 11 + 5;
p->next = tmp;
tmp->next = NULL;
p = tmp;
}
tail = p;
}
Функция init_draw()
инициализирует экран:
void init_draw()
{
Node p;
int i, j;
// Пробегаемся по связанному списку
for(p = head->next; p->next!= NULL; p = p->next)
{
// Рисуем трубы
for(i = p->x; i > p->x-10; i--)
{
for(j = 0; j < p->y; j++)
{
move(j, i);
addch(CHAR_STONE);
}
for(j = p->y+5; j <= 23; j++)
{
move(j, i);
addch(CHAR_STONE);
}
}
refresh();
sleep(1);
}
}
Таким образом, наша игра Flappy Bird завершена.