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

Материал из DRKB


Изучаем DelphiX. Часть 5: AI.[править | править код]

"Все люди - всего на всего сложный AI"

Здравствуйте! Сегодня я реализую у вас на глазах, простенький Ai который будет стрелять по вам, и двигаться к вам. Бороться с ним будет "очень просто" (клавиатуру не поломайте), не смотря на его простенькое строение. В виде шаблона я возьму пример из части 4.

Начнём делать всё постепенно, нам ведь некуда тропится, правильно?

Для начала в Uses добавим модуль math. В этом модуле находятся процедуры с математикой.

Далее добавляем перед implementation в var:

var
  plres: Boolean; // plres - респаун: True - погиб 1 игрок, False - 2 игрок
  fa: Boolean;    // Выстрел нашего Ai True - стрелял, False - нет
  Player: TPlayerOne;
  PlayerAi: TPlayerTwo;


Процедура Domove изменяется у нашего Ai:

procedure TPlayerTwo.DoMove(MoveCount: Integer);
begin
  inherited DoMove(MoveCount);
  ang2 := Angle;
  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;
  begin
    if fa then
    begin
      if LngPolet - OldLngPolet >= 250 then
      begin
        Inc(LngPolet);
        with TPlayerFa.Create(Engine) do
        begin
          Image := Form1.DXImageList1.Items.Find('pul');
          X := Self.X + cos256(ang2) * 55;
          Y := Self.y + sin256(ang2) * 55;
          AngleFa := ang2;
          OldLngPolet := LngPolet;
        end;
        fa := False;
      end;
    end;
    LngPolet := LngPolet + MoveCount;
  end;
  Collision;
end;


Теперь идём в FormCreate и удаляем там всё кроме

procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
end;


Кликаем на DxDraw и в свойствах ищем: "OnInitialize" создаём событие, и вставляем:

  PlayerAi := TPlayerTwo.Create(DXSpriteEngine1.Engine);
  PlayerAi.Image := DXImageList1.Items.Find('krut');
  PlayerAi.X := 50;
  PlayerAi.Y := 250;
  PlayerAi.Width := PlayerAi.Image.Width;
  PlayerAi.Height := PlayerAi.Image.Height;

  Player := TPlayerOne.Create(DXSpriteEngine1.Engine);
  Player.Image := Form1.dxImageList1.Items.Find('krut');
  Player.x := 350;
  Player.y := 250;
  Player.Width := Player.Image.Width;
  Player.Height := Player.Image.Height;


Теперь кидаем на форму простой таймер (я назвал его Ai). Параметры такие:

Enabled = true
Interval = 1
Name = Ai


Создаём событие OnTime и пишем следующее:

  PlayerAi.Angle := Trunc(1 / sin256(Trunc((Player.y-PlayerAi.y) / (Player.x-PlayerAi.x))));
  if (Player.y-PlayerAi.y < 0) and (Player.x-PlayerAi.x > 0) then
    PlayerAi.Angle := PlayerAi.Angle + 192;
  If (Player.y-PlayerAi.y < 0) and (Player.x-PlayerAi.x < 0) then
    PlayerAi.Angle := PlayerAi.Angle + 128;
  If (Player.y-PlayerAi.y > 0) and (Player.x-PlayerAi.x < 0) then
    PlayerAi.Angle := PlayerAi.Angle + 64;
  if Player.x <= PlayerAi.x then
    PlayerAi.x := PlayerAi.x - 2.5;
  if Player.x > PlayerAi.x then
    PlayerAi.x := PlayerAi.x + 2.5;
  if Player.y <= PlayerAi.y then
    PlayerAi.y := PlayerAi.y - 2.5;
  if Player.y > PlayerAi.y then
    PlayerAi.y := PlayerAi.y + 2.5;
  if PlayerAi.x >= Player.x-140 then
  begin
    PlayerAi.x := PlayerAi.x - 2.5;
  end;

  if PlayerAi.y >= Player.y-140 then
  begin
    PlayerAi.y := PlayerAi.y - 2.5;
  end;

  if PlayerAi.y >= Player.y-150 then
  begin
    if PlayerAi.x >= Player.x-150 then
    begin
      fa := True;
    end;
  end;


Вот и всё, мы реализовали примитивный, и простенький Ai, ни капли не реалистичный, зато очень точный. Есть маленький совет: атакуйте издалека.

Ну а теперь Д/З:

  1. Осуществите более реалистичный разворот к игроку
  2. Реализуйте ошибки Ai (т.е. неточное попадание и т.д.)
  3. Чтобы AI не стрелял постоянно в одну и туже точку после гибели игрока
  4. И вообще, придумайте что-то своё

На это Д/З я не буду писать решение в следующей части. Реализуйте это, и отправьте мне на e-mail, и если всё будет хорошо, ты получишь предложение, от которого нельзя отказаться. Жду!!

Всё, что мы на кодили, здесь: part5.rar.


Author: Влад Энгельгардт
Source: https://gamedev.ru
ID: 03933