Simply game/2

Материал из ALT Linux Wiki
< Simply game
Версия от 16:28, 3 января 2013; Tora-bora (обсуждение | вклад) (initial page)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Журнал ALT-review

Как написать простейшую стрелялку используя двумерные массивы
ALT-review logo.png
В этой статье мы попробуем описать алгоритм для простейшей стрелялки

Автор: Kostyalamer   Раздел: игры   Тег: программирование


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

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

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

Игровое поле вписывается в один экран и соответствует двумерному массиву (допустим 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)