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

Изучаем DelphiX (Часть 2) Изучаем DelphiX. Часть 2: Усложняем нашу игру. Автор: Влад Энгельгардт Хех! загружу:" Прежде чем начать, объясню решение Д/З: 1. Сделайте так, чтобы при уходе патрона из зоны видимости он уничтожался: Это очень легко сделать достаточно в процедуру DoMove патрона вставить:

if y<= 0 then Dead;
if y>= 600 then Dead;
Нужно это для того, чтобы повысилось качество игры. 2. Сделайте, чтобы патроны стреляли очередями, а не кучами как у меня: Вот эта задача была посложнее первой. Во-первых, как я сделал в первой части этого туториала, делать нельзя из-за причины небольшой "кривости" DelphiX, он может держать только определённое количество спрайтов, а если их больше он или выходит или подвисает. Так что, делаем вот так: В класс с плеером добавляем две переменные, он теперь выглядит так (я добавил комментарии к тем строчкам которые изменились):
TPlayerSprite = class(TImageSprite)
  Private
  lngpolet:integer; //расстояние которое пролетела пуля
  oldlngpolet:integer; //расстояние которое пролетела предыдущая пуля
 protected
  procedure DoMove(MoveCount: Integer); override;
 end;
Процедура DoMove класса PlayerSprite изменяется следующим образом:
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 изменяем код следующим образом:
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. Для начала маленько улучшим наш класс плеера, добавим в него столкновение, и он теперь выглядит следующим образом:
TPlayerSprite = class(TImageSprite)
  private
  lngpolet:integer;
  oldlngpolet:integer;
 protected
  procedure DoMove(MoveCount: Integer); override;
  //добавляем
  procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
 end;
Далее создаём процедуру DoCollision и вставляем в неё следующее:
procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
 if Sprite is TPlayerFa then Dead;
 Collision;
end;
Дальше пред implementation добавляем 1 переменную:
plx:double; //X плеера
Далее обновим класс TPlayerFa и он станет таким:
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 добавляем строчку:
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 становиться такой:
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:
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:
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; и создаём обработчик:
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 вставляем следущий код:
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 написать:
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) Автор: Влад Энгельгардт

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...