Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование с нуля - это совсем просто! 124) Программирование спрайтовых игр: Делаем арканоид


Школа программирования

124) Программирование спрайтовых игр: Делаем арканоид

Последний выпуск по программированию спрайтовых игр был - 115.

Практический пример

Рассмотрим изученные возможности BlitzBasic на примере создания простейшего арканоида. Для этого нам потребуются: основная игровая панель, спрайты шарика, биты и кирпичиков. В демонстрационной версии воспользуемся готовыми рисунками из примера арканоида, входящего в поставку BlitzBasic, однако весь код напишем сами с нуля.

Изображения хранятся в каталоге BlitzBasic Samples/2D Samples/blitzanoid/gfx/. Панель - файл field.bmp, шарик - ball.bmp, бита - bat.bmp, кирпичики - все в одном файле blocks.bmp.

Создадим заготовку программы с главным циклом отображения. В таком виде она только будет отображать на экране число кадров в секунду:

  Graphics 640,480,16
  SetBuffer BackBuffer()

  fps = 1
  fpsc = 0
  tim = MilliSecs()
  while not KeyHit(1)
  Cls

  Text 100,100,fps
  Flip

  fpsc = fpsc+1
  if MilliSecs()-tim > 1000 then
  tim = MilliSecs()
  fps = fpsc
  fpsc = 0
  end if

  Wend
  end

Следующий шаг - отображение на экране игровой панели. Можно делать это сразу командой DrawImage, однако не исключено, что в будущем отображение панели потребует дополнительно вывод набранных очков, бонусов и других сведений. Поэтому выделим для этой цели отдельную функцию DrawBoard, пока пустую:

  function DrawBoard()

  end function

  а вызывать ее будем в главном цикле:

  while not KeyHit(1)
    Cls

    DrawBoard()

    Text 100,100,fps
    Flip
  ...

В начало программы добавим команду загрузки спрайта игрового поля:

  Graphics 640,480,16
  SetBuffer BackBuffer()

  Global sprBoard = LoadImage("field.bmp")
  ...

а в функцию его отображения - команду вывода спрайта:

  ;
  function DrawBoard()
  DrawImage sprBoard,0,0
  end function

Проверьте, как работает программа, и переметите вывод значения FPS в более подходящее место.

Кирпичи, шарик и бита

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

В нашем же случае все игровые объекты характеризуются, в сущности, схожими параметрами - для их обработки требуется фактически лишь знание местоположения на экране, скорость и идентификатор спрайта. Поэтому будем для простоты использовать один общий тип данных TBrick, который сейчас опишем, а вот внутри него уже выделим отдельное поле для различия между шаром, битой, кирпичом и т. д.

  type TBrick
  Field Id
  Field n
  Field obj
  Field x#, y#
  Field sx#,sy#
  end type

Id - это наш, внутренний номер, обозначающий класс объекта. Пусть значение 1 будет соответствовать кирпичику, значение 2 - мячу, значение 3 - бите (ракетке).

n - некий уникальный номер объекта в игре.

obj - идентификатор спрайта.

x#,y# - координаты на экране.

xs#, sy# - скорость движения.

Пусть первоначально у нас в игре будет 25 кирпичей и по одному шарику и бите. Тогда их инициализация в начале программы может выглядеть так:

  for i = 1 to 25
     b.TBrick = New TBrick
     b\x# = i*20-3
     b\y# = 30
     b\Id = 1
     b\n = i
     b\obj = LoadAnimImage("blocks.bmp",32,16,0,14)
  Next

Обратите внимание, что хотя мы считаем каждый кирпич статичным спрайтом, загружаем мы не одну картинку, а серию, как в анимированный. Это позволит в дальнейшем менять, например, цвет кирпичика в зависимости от различных условий, просто указывая номер спрайта в группе.

Далее, нам требуется одна бита:

  b.TBrick = New TBrick
  b\x# = 20
  b\y# = 460
  b\Id = 3
  b\n = 200
  b\obj = LoadImage("bat.bmp")

Условимся, что ее уникальный номер - 200, а значение "внутреннего" типа - 3. И один шарик:

  b.TBrick = New TBrick
  b\x# = 20
  b\y# = 130
  b\sx# = 2
  b\sy# = -4
  b\Id = 2
  b\n = 100
  b\obj = LoadImage("ball.bmp")

Номер - 100, значение типа - 2.

Вывод объектов на экран

Дополним функцию DrawBoard() отображением всех кирпичиков. Для этого воспользуемся известным вариантом оператора цикла, перебирающим все значения некоторого пользовательского типа.

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

  ;
  function DrawBoard()

  DrawImage sprBoard,0,0

  ;
  for b.TBrick = Each TBrick
   DrawImage b\obj, b\x#, b\y#
  Next

  end function

Запустите программу - на экране появится уже достаточно красивое, но пока неподвижное изображение.

Оживляем биту

Внутри цикла перебора элементов нам теперь надо проверить, является ли текущий объект битой (значение его поля Id должно равняться 3).

  if b\Id = 3 then

  end if

В этом случае x-координату биты просто надо привязать к текущей x-координате мыши:

  for b.TBrick = Each TBrick

   DrawImage b\obj, b\x#, b\y#
   
   if b\Id = 3 then ; бита
     b\x# = MouseX()
   end if

  Next

Запустите программу и проверьте, как двигается бита.

Запускаем шарик

Следующий шаг - оживление шарика. Сделаем это уже знакомым нам способом - просто будем изменять его координату на значение скорости. Выполним это внутри соответствующей проверки на принадлежность текущего объекта типу "шарики":

  if b\Id = 2 then ; шарик!
    b\x# = b\x# + b\sx#
    b\y# = b\y# + b\sy#
   end if

При соприкосновении шарика со стенкой его скорость должна меняться на противоположную. Но надо учесть направление его движения, чтобы при отражении от вертикальной стены менялась лишь x-составляющая, и наоборот.

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

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


(c) 2004-2006 Сергей Бобровский bobrovsky as russianenterprisesolutions.com

Школа программирования с нуля
Все предыдущие выпуски базового курса всегда тут:
http://www.infiltration.ru/p/

Дизайн рассылки: Алексей Голубев - Web-дизайн и web-программирование


В избранное