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

== Изучаем 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, ни капли не реалистичный, зато очень точный. Есть маленький совет: атакуйте издалека.
Ну а теперь Д/З: 
# Осуществите более реалистичный разворот к игроку 
# Реализуйте ошибки Ai (т.е. неточное попадание и т.д.) 
# Чтобы AI не стрелял постоянно в одну и туже точку после гибели игрока 
# И вообще, придумайте что-то своё
На это Д/З я не буду писать решение в следующей части. Реализуйте это, и отправьте мне на e-mail, и если всё будет хорошо, ты получишь предложение, от которого нельзя отказаться. Жду!!
Всё, что мы на кодили, здесь: part5.rar.
Author: Влад Энгельгардт
Source: https://gamedev.ru
ID: 03933
Category:Графика
Category:DirectX
Category:Учебники