Simply game/2

Материал из ALT Linux Wiki
ALT-review logo.png


Как написать простейшую стрелялку используя двумерные массивы

В этой статейке мы попробуем сляпать алгоритм для простейшей стрелялки. Понятно, что никакой ценности эта игрулька представлять не будет, но моя цель показать как программировать такие задачи, без привязки к какому-либо конкретному языку.

Логический уровень:

Игровое поле вписывается в один экран и соответствует двумерному массиву (допустим 50*50), по нему при помощи стрелок курсора двигается герой по пути собирая чего-нибудь (алмазики , монетки – что угодно). Периодически в разных точках игрового поля возникают враги, которые через определенный промежуток времени производят в вас выстрел если герой находится на одной горизонтали или вертикали с ними. Соответственно врага надо уничтожить до того как он пальнет в вас, иначе GameOver.

Пуляем естественно тоже по горизонтали/вертикали при помощи клавиши Space. Когда все алмазы собраны происходит переход на следующий уровень, где врагов становится больше или они быстрее стреляют. В общем смысл нашей учебной игрульки примерно понятен :-)

Математический уровень:

Все действие этой игры происходит в двумерном массиве байтов (50*50). Соответственно в пустых клеточках массива записаны 0, в клетке где стоит наш герой - 1, в клетках с алмазиками - 2, в клетках с врагами - 3 (как видим остается еще довольно много значений для врагов разного уровня, препятствий, аптечек и т.п.).

На будущее: По поводу аптечек - герой может быть убит не с первого попадания, а, например, с третьего (вводим в прогу переменную живучести героя, которая при каждом попадании уменьшается на единицу и при достижении 0 происходит Game Over). Тот же способ действует в отношении врагов, только там проще – при попадании во врага будем уменьшать значение в ячейке массива допустим с 5 до 3, при попадании во врага 3 в ячейку вписывается 0, соответственно вместо него возникает пустая клетка. Но эти украшательства я описывать не буду, поняв общие принципы вы легко сможете на базе этого скелета сделать довольно играбельную поделку (кстати можно еще и препятствия добавить, тогда игрушка начнет очень отдаленно напоминать спектрумовскую How to be a Hero с замороженными неподвижными монстрами и одним игровым экраном http://zx-games.ru/how-to-be-a-hero/).

  1. Для начала нам нужна подпрограмма обнуляющая массив и по случайному принципу заполняющая его клетки несколькими алмазиками. Она же выставляет начальные координаты нашего героя и записывает в соответствующую ячейку 1. Далее надо написать основное тело программы и прибить его гвоздями к таймеру.
  2. После того как первая подпрограмма произвела инициализацию массива, включается таймер, который генерирует раз в несколько секунд (допустим в 10) нового врага в свободную ячейку массива выбираемую по случайному закону (понятно, что эта ячейка должна быть пустой, т.е. в ней записан 0). Раз в 5 секунд тот же таймер запрашивает координаты героя (допустим они будут X,Y) и проверяет горизонталь (все ячейки массива от [0,Y] до [49,Y]) и вертикаль (ячейки от [X,0] до[X,49]) если на них обнаруживается хоть один враг, он производит выстрел (надо написать красивую подпрограммку, которая при помощи спрайтов и звуков все это достойно оформит, но это уже привязанно к конкретному языку - например Python+PyGame отлично подходят для подобных задач). На самом деле это очень упрощенный алгоритм выстрела, пока я писал всю эту теорию придумал более правильный, но для учебной стрелялки он подходит плохо ввиду своей сложности.

Взаимодействия с пользователем

Все что касается нашего главного героя, его перемещений, стрельбы я вынес в этот уровень. На самом деле сюда цепляется изрядный кусок математического уровня, что вполне естественно, ведь любые деления условны и эта структура сделана для упрощения труда кодера [для представителей младшего поколения объясню, что кодер – это человек, который пишет код :-)]

Итак, при нажатии стрелочек наш герой поворачивается и идет в соответствующую сторону, при нажатии на пробел он в эту же сторону стреляет (спецэффекты на вашей совести, мое дело скелет программы).

Нам нужны следующие подпрограммы:

  1. Программа рисующая игровое поле на экране, отрисовывающая алмазики и текущее положение героя (при его изменении), эта же программа отрисовывает новых врагов при их генерации таймером математического уровня (то есть она приводит в соответствие изображение на экране к содержанию вашего массива).
  2. Обработчик событий отслеживающий ваши манипуляции с клавиатурой и после проверки граничных условий (а то ваш герой убежит за границы массива, лови его потом по монитору :-)) и свободного поля в направлении движения (в ячейке массива должен быть 0 или алмазик 2 за который увеличивается переменная «богатства» героя). При соблюдении этих условий герой перемещается на следующее поле (записывая по старым координатам 0, а в ячейку соответствующую новому положению 1). При нажатии пробела происходит выстрел в направлении движения, заключающийся в проверке содержания соответствующих клеток массива в этом направлении на наличие в них врага, идею можно подглядеть в пункте 2.2. Только проверка (выстрел) делается не по 4-ем направлениям как для врага, а только в направлении движения. Как только переменная «богатства» героя достигнет некоторой критической величины, происходит переход на следующий уровень, сопровождаемый разными звуковыми и цветовыми эффектами на ваше усмотрение. Ура, наши победили!

На будущее: Конечно в идеале обработчик на первое нажатие стрелки должен по идее поворачивать героя в соответствующем направлении и только на следующее нажатие делать шаг в эту сторону. Ведь это поле может быть занято, что не даст нашему герою развернуться на месте и пальнуть во врага, получается довольно паршивая коллизия, проблема в общем не большая, думаю вы ее решите если будете писать подобную программу. Что бы у вас не возникало мыслей, что я чистый теоретик вот вам простая пулялочка на очень хорошей связке Python+PyGame (рекомендую всем игрo-писателям) http://kostyalamer.narod.ru/pygame03/pygame03.html

Понятно, что на учебную прогу, алгоритм которой я сочинил для этой статьи она не похожа, но кое-какие общие элементы есть (например процедура bah хорошо вписывается в контекст этой статьи), к тому же в листинге я оставил немножко комментариев - в общем если уж дочитали до этого места, то наверное разберетесь при желании.
Будем считать тему написания простейших игрушек при помощи массивов законченной, остальное уже додумаете сами. Я же довольно давно закончил с игрушками (эти статьи дань Спектрумовской молодости) и занялся совершено другими аспектами программирования (программирование апплетов для WindowMaker на python-е, но это уже совсем другая история, вряд ли интересная нашим читателям).

Главное помните, что написание таких игрушек лучшее средство (на мой взгляд) обучения программированию для начинающих. Особенно это актуально для школьников - скорее всего программистами (хотя кто знает) они не станут, но удовольствие от того, что сами создали игрушку получат огромное. Да и привычку думать подобные упражнения развивают сильно, в общем, счастливого хака.

С уважением, Константин Коган (kostyalamer) __SHOWFACTBOX__