Разработка игры Fly (часть 5)

Опубликовал – 22.06.2010

Здравствуйте, коллеги. Вот и долгожданное продолжение цикла статей по разработке игры Fly. Времени становится все меньше, а тем для статей все больше. Мы уже подходим к заключительным урокам, и совсем скоро мы сможем поиграть в наше детище. Пожалуй, начнем урок.

Для начала, добавим возможность анимации объектов. Изменим немного процедуру отрисовки объектов. Откроем модуль uGraphics, ищем класс TRender меняем:

procedure Draw(pos: TPoint; size: TPoint; anim: TPoint; pic: TBitmap);

на

procedure Draw(pos: TPoint; vec: Integer; size: TPoint; anim: TPoint; animcount: TPoint; pic: TBitmap);

и, собственно, меняем формулу в самой процедуре:

наш кадр = размер * (текущий кадр анимации + ((кол-во кадров \ 2)  *  направление)):

procedure TRender.Draw(pos: TPoint; vec: Integer; size: TPoint; anim: TPoint; animcount: TPoint; pic: TBitmap);
begin
  BitBlt(Screen[SCR_MASK].Canvas.Handle, pos.x, pos.y, size.x, size.y, pic.Canvas.Handle, size.x * (anim.X + ((animcount.X shr 1) * vec)), size.y, SRCAND);
  BitBlt(Screen[SCR_NORM].Canvas.Handle, pos.x, pos.y, size.x, size.y, pic.Canvas.Handle, size.x * (anim.X + ((animcount.X shr 1) * vec)), 0, SRCPAINT);
  BitBlt(Screen[SCR_MAIN].Canvas.Handle, pos.x, pos.y, size.x, size.y, Screen[SCR_MASK].Canvas.Handle, pos.x, pos.y, SRCAND);
  BitBlt(Screen[SCR_MAIN].Canvas.Handle, pos.x, pos.y, size.x, size.y, Screen[SCR_NORM].Canvas.Handle, pos.x, pos.y, SRCPAINT);
end;

Теперь добавим в наш виртуальный метод MakeStep() в классе TGameObject прокрутку анимации:

if (anim.x < pred(animcount.x shr 1)) then
  inc(anim.x)
else
  anim.x := 0;

Теперь мы можем добавлять в нашу игру анимационные объекты, например, такой вертолет:

Если не видно – у него крутится пропеллер. Количество кадров можно сделать любое, но надо придерживаться правила. Количество кадров анимации в одну сторону должно совпадать с количеством кадров в другую. Кадры обязательно слева направо.

Давайте добавим такой вертолет в игру. Создадим класс THelicopter в модуле uModels:

THelicopter = class(TGameObject)
private
public
  procedure MakeStep(); override;
  constructor Create();
end;

и опишем его:

constructor THelicopter.Create();
begin
  inherited Create('helicopter'); //создаем объект helicopter
  PreparePic(6, 2); //говорим что кадров будет 6х2
  pos.x := FieldWidth + size.x; //позиция за экраном
  pos.y := random(50); //по высоте, низко не летаем
  speed := random(3)+1; //скорость от 1 до 3
  life  := 1; //одна жизнь
  id    := ID_HELI; //класс
  anim.X := 0; //кадр по умолчанию
  firetime := random(5000) + 2500; //время выстрела
end;

// AI
procedure THelicopter.MakeStep();
begin
  inherited ;
  if (remove) then exit;
  //AI совершенно простой
  //летаем от края экрана к краю
  //скидываем снаряд время от времени
  if (GetTickCount() - lasttime > 10) then begin
    if (vec = VEC_RIGHT) then
      if (pos.x + size.x >= FieldWidth) then
        vec := VEC_LEFT
      else
        inc(pos.x, Speed)
    else
      if (pos.x <= 0) then
        vec := VEC_RIGHT
      else
         dec(pos.x, Speed);
    lasttime := GetTickCount();
  end;
  if (GetTickCount() - lastfire > firetime) then begin
    state := ST_BOMB;
    firetime := random(5000) + 2500;
    lastfire := GetTickCount();
  end;
end;

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

if (gameobjectlist.GetCount(ID_HELI) < MAX_HELI) then
  gameobjectlist.Add(THelicopter.Create());

Предварительно указав константу MAX_HELI в модуле uConstants. Удобно, неправда ли? Ровно так же вы можете добавлять любые объекты. Давайте добавим самолетики. В модуль uModels помещаем класс TPlane:

TPlane = class(TGameObject)
private
public
  procedure MakeStep(); override;
  constructor Create();
end;

И опишем его:

constructor TPlane.Create();
begin
  inherited Create('plane'); //создаем plane
  PreparePic(2, 2); //2x2
  vec     := random(2); //направление и позиция
  if (vec = VEC_RIGHT) then pos.x := -30 else pos.X := FieldWidth + 30;
  pos.y   := random(105); //высота до уровня моря
  life    := 1; //одна жизнь
  id      := ID_PLANE; //класс
  speed   := random(5) + 1; //скорость от 1 до 5
  firetime:= random(5000) + 2500; //время выстрела
end;

procedure TPlane.MakeStep();
begin
  inherited ;
  if (remove) then exit;
  //AI самолета пролетать мимо
  //иногда скидывать снаряд
  if (GetTickCount() - lasttime > 10) then begin
    if (vec = VEC_RIGHT) then
      if (pos.x > FieldWidth + size.x) then remove := true else inc(pos.x, Speed)
    else
      if (pos.x < -size.x) then remove := true else dec(pos.x, Speed);
    lasttime := GetTickCount();
  end;
  if (GetTickCount() - lastfire > firetime) then begin
    state := ST_SHOT;
    firetime := random(5000) + 2500;
    lastfire := GetTickCount();
  end;
end;

Точно так же добавим в MainLoop() проверку на количество самолетиков в игре, чтобы они никогда не кончались:

if (gameobjectlist.GetCount(ID_PLANE) < MAX_PLANE) then
  gameobjectlist.Add(TPlane.Create());

Не забываем определить константу MAX_PLANE, равной двум самолетам на экране, в модуле uConstants.
Давайте же посмотрим на то, что у нас получилось:

Естественно, сейчас они беззаботно летают. В следующей, заключительной главе, я расскажу, как рассчитывать столкновения и как взрывать наши корабли и самолеты. Они так же научатся стрелять. На сегодня у меня все.

Исходные коды к данной статье fly (part 5).

Рассказать друзьям:
  • Добавить ВКонтакте заметку об этой странице
  • Мой Мир
  • Facebook
  • Twitter
  • Яндекс.Закладки
  • В Живую Ленту Google
  • Сто закладок
Комментарии (6) - Разработка игры Fly (часть 5)

Ответ

  1. Анонимно:

    жду продолжения! спасибо

    Thumb up Thumb down 0

  2. Анонимно:

    У меня все объекты прерывисто двигаются.

    Thumb up Thumb down 0

Ответить

Comments

Перед отправкой формы: