Подход
Самое сложное при создании этой игры - сделать так, чтобы мяч правильно отскакивал от стен. Многие программисты не учитывают ни диаметр мяча, ни его скорость. В результате может случиться, что мяч будет отскакивать не от стены, а от точки, расположенной за ней.
Рассмотрим ситуацию, когда мяч оказывается за стеной. При этом надо выяснить, насколько далеко залетел мяч за пределы игрового поля. Так как мяч перемещается на несколько пикселов в одном кадре, он может легко проскочить за стену на несколько пикселов.
После того как вы узнаете, насколько далеко за стеной оказался мяч, вы можете изменить направление его движения, а затем поместить мяч на соответствующее расстояние с нужной стороны стены. На рис. 11.2 показана диаграмма работы данного алгоритма.
Рисунок 14.2. Диаграмма показывает, как изменяется положение мяча после столкновения со стеной
Столкновения с битой рассматриваются точно так же, как и столкновения со стеной. Единственное различие - вы должны изначально убедиться, что вертикальное положение биты допускает удар мяча об нее.
Если мяч проходит через горизонтальное положение биты, но ее там нет, нужно присвоить некой переменной значение, указывающее, что мяч был пропущен. Таким образом, у пользователя не будет другого шанса отбить мяч, пока тот летит до границы экрана.
Искусственный интеллект для этой игры можно создать разными способами. Один из них - сделать так, чтобы бита всегда следовала за мячом. Однако в этом случае у компьютера просто не будет возможности пропустить мяч.
Лучше, если бита компьютера будет медленно двигаться в направлении мяча. Если мяч будет лететь слишком быстро, компьютер может не успеть переместить биту в правильное положение. Кроме того, бита будет двигаться только тогда, когда мяч летит в искусственного противника.
Словосочетание "искусственный интеллект" звучит таинственно. Однако для игр не так важно, чтобы противник был умным. Компьютер должен только способствовать захватывающей игре. Конечно, в большинстве игр гораздо проще создать безупречного противника. Однако в таком случае игра для компьютера становится беспроигрышной, что не интересно для игрока. Трудность состоит в том, чтобы создать противника, обладающего некими навыками (это сделает игру непростой), но чтобы имеющихся навыков не хватало для беспроигрышной игры.
Для того чтобы счет игры был сохранен, нужны несколько переменных. Однако создать паузу в игре между подачами мяча довольно сложно, поэтому в игре будет два кадра: в первом программа ждет, когда игрок щелкнет по кнопке "serve", а во втором разворачивается само действие игры. Этот второй кадр начинается с установки произвольного начального положения мяча.
Код для определения, в каком месте биты или стены ударился мяч, похож на код предыдущих двух игр. Единственное отличие заключается в том, что теперь мяч может отскакивать не только от верхней биты, а и от любой ее точки. Таким образом, становится немного проще отбить мяч.
При столкновении мяча с блоком направление его движения по вертикали изменяется на противоположное. Блок же удаляется с экрана.
В предыдущих играх было достаточно определить, когда мяч ударяется о блок, для чего использовался метод hitTest. Теперь задача усложняется: надо рассмотреть все четыре стороны мяча по отношению ко всем четырем сторонам блока. Если мяч и блок полностью перекрываются, то считается, что произошло столкновение. С помощью метода hitTest можно было бы определить момент, когда мяч находится внутри прямоугольного блока. Но этого не достаточно для данной игры.
При столкновении мяча с битой рассчитывается расстояние между центром мяча и центром биты. Длина биты - 50 пикселов, так что это расстояние может быть чуть более 25 пикселов, либо со знаком "+", либо со знаком "-". Разделите данное число на 4 и получите значение между -7 и 7.
Новое значение будет присвоено переменной dx, которая определяет скорость движения мяча по горизонтали.
Это значит, что игрок может направлять мяч. Если, например, он отобьет мяч левым краем биты, мяч будет направлен резко влево. Если же отбить серединой биты, то мяч полетит прямо вверх.
Чтобы следить за положением мяча, необходима новая переменная. Можно использовать х для горизонтальной и у для вертикальной характеристики положения шара. Третья переменная, z, следит за глубиной -как глубоко внутри экрана находится шар.
Эти три переменные определяют положение мяча внутри воображаемого параллелепипеда, в котором происходит игра. Этот параллелепипед имеет горизонтальные и вертикальные размеры по 400 единиц и 140 единиц в глубину. Чтобы перевести это в координаты экрана, нужна некоторая ловкость. Если вы еще раз посмотрите на рис. 11.5, то заметите, что границы шахты видимы. Наружный квадрат (грань), ближний к игроку, находится на том же уровне, что и бита. Он имеет размер 400x400. Внутренняя грань, представляющая заднюю стену, имеет размер 120x120.
На рисунке 11.6 еще раз изображены обе грани, но на этот раз с обозначенными х, у и z координатами. Верхний левый угол обеих граней имеет значения х и у равные 0. Однако наружный угол имеет значение z равное 0, а внутренний - значение z, равное 140. Остальные углы обозначаются аналогично.
Если мяч находится на позиции (х, у) = (0,0) и движется от 0 к 140 вдоль оси Oz, то он движется вдоль ребра параллелепипеда (рис. 11.6). Если мяч в центре экрана, в положении (200,200), и движется от 0 до 140 вдоль Oz, ему вообще не нужно смешаться вправо или влево. Если мяч в какой-нибудь промежуточной позиции, например (50,65), и движется от 0 до 140 вдоль Oz, то он должен двигаться вдоль своей линии перспективы так, чтобы сохранить свое положение относительно передней и задней граней.
Иллюзия трехмерности достигается также за счет уменьшения значения масштаба мяча по мере его удаления.