while(key != 27)
{
while(!kbhit()) //ждет пока нажмем
{
. . .
switch (Move(g))//движение
{
case KONEC:
case STENA:
. . .
break;
case PLUS:
. . .
if (count == level)
{
cout << "Vy vyigrali! Pozdravlyayu!";
return(0);
}
break;
case MOVE:
break;
}//switch
//интересно, что без этой функции задержки змея сразу
//врезается в стену и конец игры
Sleep(g.pause); //
}//while(!kbhit()) //ждет пока нажмем
}//while(key != 27)
}
Пока змея бежит сама по себе, то программа все время крутится внутри цикла while(!kbhit()).
Функция Move(g) - движение змеи - с каждым вызовом передвигает змею на одну позицию
и возвращает MOVE, а затем сразу break и снова на начало цикла while(!kbhit()).
Интересно, что без функции задержки Sleep(g.pause) змея сразу врезается в стену
и конец игры. Величина задержки g.pause а следовательно и скорости движения змеи
задается в функции InitGame(g) и равна 100.
Функция InitGame(g) задает инициализацию переменных для начала игры - начальную длину змеи,
скорость змеи (величину задержки), садит яблоко. Но само изображение и движение змеи
по экрану происходит только после вызова функции Move().
Далее, как только мы пытаемся управлять змеей при помощи стрелок, и нажимаем одну из
стрелок, условие !kbhit() нарушено и программа выходит из цикла while(!kbhit()) и
попадает внутрь внешнего цикла while(key != 27).
Здесь программа прежде всего проверяет какую нажали клавишу:
key = getch();
Здесь происходит ряд проверок на тему: какая именно из стрелок была нажата
и изменяет соответствующим образом переменные, ответственные за направление
движения змеи. Ни на какие другие нажатия клавиш кроме стрелок этот код не реагирует.
Итак проверяем какая стрелка была нажата:
if(key==0||key==224){//это условие оябзательно выполнится
{
Суть этого кода в том, что определяется какая из стрелок нажата. Переменным g.nap,
if(key == 72 && g.nap != DOWN)//стрелка вверх
{
g.dx = 0;
g.dy = -1;
else if(key == 80 && g.nap != UP)//стрелка вниз
{
g.dx = 0;
g.dy = 1;
else if(key == 75 && g.nap != RIGHT)//стрелка влево
{
g.dx = -1;
g.dy = 0;
else if(key == 77 && g.nap != LEFT)//стрелка вправо
{
g.dx = 1;
g.dy = 0;
g.dx и g.dy передается соответствующее значение, но только в том случае, если ранее
направление движения не было противоположным.
В этом фрагменте кода интересно то, что дважды вызывается функция key = getch().
Если мы в эксперименте заремируем второй вызов функции key = getch(), то змея перестает
реагировать на нажатия стрелок и врезается в стену. Если мы наоборот заремируем первый вызов
функции, а второй вызов останется, то змея при движении один раз отреагирует на нажатие
стрелки, при втором нажатии любой стрелки змея остановится и застынет не реагируя ни на
какое нажатие. Так что оба вызова функции key = getch() здесь нужны.
Программа при таком коде работает хорошо. Змея бегает, поедает яблоки соответственно
растет. При этом функция Move() возвращает либо PLUS (съела яблоко) если еще не все яблоки
съедены, либо MOVE, если просто бежит, затем break и повторение цикла. Но после того, как
врезалась в стену или в себя, то программа останавливается и никак не может выйти на какие
бы клавиши мы не жали. Зависает.
Таким образом надо предусмотреть выход.
Еще интересно, что когда я во фрагменте кода:
case STENA:
// getch();
break;
Заремировал getch(), то змея перестала умирать. После того, как врезалась в стену, она
снова по нажатию клавиши продолжает двигаться и собирать яблоки и расти. Такой неумирающей
змеей можно собрать любое количество яблок.
Если в нижеприведенном коде я ремирую условие if, то после столкновения со стеной
while(!kbhit())
{
программа перестает реагировать на нажатие клавиш.
if(Pause==true)
{
continue;
Программа устроена так, что с каждым съеденным яблоком змея начинает двигаться быстрее.
Для введения количества яблок, за которым будет идти охота, а заодно и защиты от
неправильного ввода напишем простую функцию:
//За каким количеством яблок охота?
void Level(Game &g) {
int num = 1;
g.num = 3;
bool bul = true;
while(bul){
GotoXY(10,14);cout <<"Vvedite chislo yablok ot 1 do 50 and type Enter"<< endl;
cin >> num;
if(num <0 || num > 50){
num = 3;
break;
}
bul = false;
}
g.num = num;
system("cls");
}
И поместим эту функцию в main() сразу после объявления объекта g класса Game.
Назад |
Начало урока |
Вверх |
Вперед
Содержание