Изучаем DelphiX (Часть 2)

Previous  Top  Next

    
 

Изучаем DelphiX. Часть 2: Усложняем нашу игру.

Автор: Влад Энгельгардт

Хех! загружу:"

Прежде чем начать, объясню решение Д/З:

1. Сделайте так, чтобы при уходе патрона из зоны видимости он уничтожался:

Это очень легко сделать достаточно в процедуру DoMove патрона вставить:

Code:

if y<= 0 then Dead;

if y>= 600 then Dead;

 

Нужно это для того, чтобы повысилось качество игры.

2. Сделайте, чтобы патроны стреляли очередями, а не кучами как у меня:

Вот эта задача была посложнее первой. Во-первых, как я сделал в первой части этого туториала, делать нельзя из-за причины небольшой "кривости" DelphiX, он может держать только определённое количество спрайтов, а если их больше он или выходит или подвисает. Так что, делаем вот так:

В класс с плеером добавляем две переменные, он теперь выглядит так (я добавил комментарии к тем строчкам которые изменились):

Code:

TPlayerSprite = class(TImageSprite)

  Private

   lngpolet:integer;    //расстояние которое пролетела пуля

   oldlngpolet:integer; //расстояние которое пролетела предыдущая пуля

protected

   procedure DoMove(MoveCount: Integer); override;

end;

 

Процедура DoMove класса PlayerSprite изменяется следующим образом:

 

Code:

Procedure TPlayerSprite.DoMove(MoveCount: Integer);

Begin

inherited DoMove(MoveCount);

if isLeft in Form1.DXInput1.States then x:=x-5;

if isRight in Form1.DXInput1.States then X:=x+5;

if isup in Form1.DXInput1.States then

begin

   if lngpolet-oldlngpolet>=250 then // Если расстояние между пулями меньше 250,

                                     // то пуля не создаётся

   begin

     Inc(lngpolet);

     with TPlayerFa.Create(Engine) do

     begin

       PixelCheck := True;

       Image := form1.dxImageList1.Items.Find('Pula');

       X := Self.X+Self.Width  -40;

       Y := Self.Y+Self.Height -80;

       Width := Image.Width;

       Height := Image.Height;

     end;

     oldlngpolet := lngpolet; //после создания пули - последняя становится первой

   end;

end;

if y >= form1.DXDraw1.SurfaceHeight-image.Height then

   y := form1.DXDraw1.SurfaceHeight-image.Height;

if x >= form1.DXDraw1.SurfaceWidth -image.Width  then

   x := form1.DXDraw1.SurfaceWidth -image.Width;

if y <= 0 then

   y := 1;

if x <= 0 then

   x:=1;

lngpolet := lngpolet + MoveCount;  // расстояние увеличиваем, когда пуля движется

end;

 

Вот и всё, что требовалось сделать.

В этой части вы узнаете:
1. Создание анимации.
2. Создание примитивного AI.
3. Создадим простенькие взрывы.

Создание анимации.

Анимация в DelphiX строится следующим образом:

clip0108

Это пример покадровой анимации. У каждого кадра должен быть одинаковый размер.

В данной ситуации:
Ширина: 40
Высота: 38

Давайте теперь, применим ее к нашей игре.
Идём в DXImageList, находим наш спрайт Pula и загружаем картинку с анимацией. Далее устанавливаем свойства спрайта следующим образом:

clip0109

и в процедуре DoMove класса PlayerSprite изменяем код следующим образом:

Code:

Procedure TPlayerSprite.DoMove(MoveCount: Integer);

begin

inherited DoMove(MoveCount);

if isLeft in Form1.DXInput1.States then x:=x-5;

if isRight in Form1.DXInput1.States then X:=x+5;

if isup in Form1.DXInput1.States then

begin

   if lngpolet-oldlngpolet>=250 then

   begin

     Inc(lngpolet);

     with TPlayerFa.Create(Engine) do

     begin

       PixelCheck := True;

       Image := form1.dxImageList1.Items.Find('Pula');

       X := Self.X+Self.Width  -40;

       Y := Self.Y+Self.Height -80;

       Width := Image.Width;

       Height := Image.Height;

       AnimCount := Image.PatternCount; //число кадров

       AnimLooped := True;              //повторять ли анимацию

       AnimSpeed := 10 / 1000;          //скорость анимации

     end;

     oldlngpolet := lngpolet;

   end;

end;

if y >= form1.DXDraw1.SurfaceHeight-image.Height then

   y := form1.DXDraw1.SurfaceHeight-image.Height;

if x >= form1.DXDraw1.SurfaceWidth -image.Width  then

   x := form1.DXDraw1.SurfaceWidth -image.Width;

if y <= 0 then

   y := 1;

if x <= 0 then

   x:=1;

lngpolet := lngpolet + MoveCount;

end;

 

Можно проделать тоже самое с другими классами для придания реалистичности игры.

Cоздание примитивного AI.

Для начала маленько улучшим наш класс плеера, добавим в него столкновение, и он теперь выглядит следующим образом:

Code:

TPlayerSprite = class(TImageSprite)

  private

   lngpolet:integer;

   oldlngpolet:integer;

protected

   procedure DoMove(MoveCount: Integer); override;

   //добавляем

   procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;

end;

 

Далее создаём процедуру DoCollision и вставляем в неё следующее:

Code:

procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);

begin

if Sprite is TPlayerFa then Dead;

Collision;

end;

 

Дальше пред implementation добавляем 1 переменную:

Code:

plx:double;            //X плеера

 

Далее обновим класс TPlayerFa и он станет таким:

Code:

TPlayerFa = class(TImageSprite)

private

   stril:Integer; // Как вы заметили, добавилась переменная

protected

   procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;

   procedure DoMove(MoveCount: Integer); override;

  public

   constructor Create(AParent: TSprite); override;

   destructor Destroy; override;

end;

 

А в TPlayerFa добавляем строчку:

Code:

Procedure TPlayerFa.DoMove(MoveCount: Integer);

begin

  y:=y-stril; // когда стреляет игрок, с этой скоростью будет двигаться пуля

  y:=y+stri; // когда стреляет AI, с этой скоростью будет двигаться пуля

  if y<= 0 then Dead;

  if y>= 600 then Dead;

end;

 

А процедура TBoSS.DoMove становиться такой:

Code:

Procedure TBoSS.DoMove(MoveCount: Integer);

begin

  inherited DoMove(MoveCount);

  if x>= 600 then I:= false;

  if x<= 0 then I:= true;

  if i= true then X := X+5;

  if i= false then X := X-5;

  if plx=x then //если равна х плеера стреляем

  begin

    with TPlayerFa.Create(Engine) do

     begin

     PixelCheck := True;

     Image := form1.dxImageList1.Items.Find('Pula');

     X := Self.X+Self.Width-70;

     Y := Self.Y+Self.Height+10;

     Width := Image.Width;

     Height := Image.Height;

     stril:=5;        //скорость патрона

     end;

  end;

   Collision;

end;

 

И естественно полнеет и TPlayerSprite:

Code:

Procedure TPlayerSprite.DoMove(MoveCount: Integer);

begin

inherited DoMove(MoveCount);

plx:=x;            //чтобы наш комп видел нашего плеера

if isLeft in Form1.DXInput1.States then

begin

   x:=x-5;

   plx:=x;

end;

if isRight in Form1.DXInput1.States then

begin

   X:=x+5;

   plx:=x;

end;

if isup in Form1.DXInput1.States then

begin

   if lngpolet-oldlngpolet>=250 then

   begin

     Inc(lngpolet);

     with TPlayerFa.Create(Engine) do

     begin

       PixelCheck := True;

       Image := form1.dxImageList1.Items.Find('Pula');

       X := Self.X+Self.Width  -40;                   

       Y := Self.Y+Self.Height -80 ;                  

       Width := Image.Width;

       Height := Image.Height;

       stril:=-4;

     end;

     oldlngpolet := lngpolet;

   end;

end;

if y >= form1.DXDraw1.SurfaceHeight-image.Height then

   y := form1.DXDraw1.SurfaceHeight-image.Height;              

if x >= form1.DXDraw1.SurfaceWidth -image.Width  then

   x := form1.DXDraw1.SurfaceWidth -image.Width;                

if y <= 0 then

   y := 1;

if x <= 0 then

   x:=1;

lngpolet := lngpolet + MoveCount;

Collision;

end;

 

И поменялся конструктор PlayerFa:

Code:

constructor TPlayerFa.Create(AParent: TSprite);

begin

inherited Create(AParent);

Image := form1.DXImageList1.Items.Find('Pula');

Width := Image.Width;

Height := Image.Height;

AnimCount := Image.PatternCount;    //число кадров

AnimLooped := True;                 //повторять ли анимацию

AnimSpeed:= 10 / 1000;

Collision;

end;

 

Создадим простенькие взрывы.

Для начала загрузим спрайт взрыва в DXImageList вот он: clip0110

Назовём его "ex" и установим размер кадра на 32Х48 (PatternHeight - PatternWidth)

Дальше, в класс TPlayerSprite в private добавляем procedure Hit; и создаём обработчик:

Code:

procedure TplayerSprite.Hit;

begin

Collisioned := False;

   Image := Form1.dxImageList1.Items.Find('Ex');

   Width := Image.Width;

   Height := Image.Height;

   AnimCount := Image.PatternCount;

   AnimLooped := False;

   AnimSpeed := 15/1000;

   AnimPos := 0;

end;

 

и в процедуре TPlayerSprite.DoCollision вставляем следущий код:

Code:

procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);

begin

if sprite is Tplayerfa then

begin

   TPlayerSprite(Sprite).Hit;

   dead;

end;

Done := False;

end;

 

Этот код надо разместить и в Tboss. DoCollision.

И под конец маленький бонус:
Можно создать бэкграунд, без создания нового класса достаточно в FormCreate написать:

Code:

with TBackgroundSprite.Create(DXSpriteEngine1.Engine) do

begin

   SetMapSize(1,1);

   Image := dxImageList1.Items.Find('bgr');

   Z:= -2;

   Tile := True;

end;

 

Где bgr спрайт-бэкграунд.
Вот мой БГ:

clip0111

Нравиться? Здесь можно скачать исподники всей этой части.
part2.rar(77,5 kB)

Автор: Влад Энгельгардт

©Drkb::03930