Назад

   В этом уроке мы добавим монстру искусственный интеллект (ИИ), позволяющий ему вести охоту на игрока, лучше стрелять и определять, не прячется ли игрок за преградой или рельефом местности.
 

 Rem Загружаем мишень
Load object "idle.x",3
Append Object "Walk.x",3,21

Эти строки кода вводятся до начала основного цикла. Команда "Append Object" загружает данные анимации из другого файла и добавляет их к существующему объекту, не загружая новый. Объекты в каждом из файлов, которые вы собираетесь "склеить", должны быть идентичными, в противном случае команда будет выполнена неправильно. Команда использует три параметра. Первый параметр - имя присоединяемого файла. Второй параметр - номер объекта, к которому вы хотите присоединить данные анимации. Третий параметр - номер кадра, в который требуется добавить анимацию. Если номер кадра больше, чем общее число кадров в первой последовательности анимации, команда будет выполнена неправильно.
 
 

  if DecoCollide(MbX#,MbY#,MbZ#) = 1
   MonsterBulletLife = 0
   BulletAvoidDeco = BulletAvoidDeco + 2
  Endif
 

  if MbY# < Get Ground height(1,MbX#,MbZ#)
   MonsterBulletLife=0
   ShootUp=3
  endif

Переменные "ShootUp" и "BulletAvoidDeco" добавлены в подпрограмму "MonsterShootBullet". Переменной "ShootUp" присваивается значение 3, если ракета монстра попала в "землю". Эта переменная будет использоваться для изменения угла, под которым стреляет монстр, чтобы ракета огибала рельеф местности. Переменная "BulletAvoidDeco" увеличивается каждый раз на 2, когда ракета попадает в одну из колонн. Эта переменная изменяет угол стрельбы монстра, чтобы ракета огибала преграды. Хотя монстр в этом случае стреляет не прямо в игрока, ракета имеет возможность самонаведения после того, как она была выпущена.
 

  Rem Простой ИИ для самонаводящейся ракеты монстра
MonsterAI:
   Point object 3,X#,Y#,Z#
   If AvoidDeco >0
    mA# = Object Angle Y(3)
    Dec AvoidDeco
    Yrotate object 3,WrapValue(mA#+AvoidDeco*60)
   endif

   Rem Перемещаем монстра в новое место
   Position Object 3,mX#,mY#,mZ#

   Rem Проверяем расстояние до игрока
   PDist=Sqrt((mX# - X#)^2 + (mY#+25 - Y#)^2 + (mZ# - Z#)^2)

   Rem Если игрок в зоне видимости, выпускаем ракету
   if PDist<1500
    if MonsterBulletLife=0 or MonsterBulletLife < 500-Pdist/10
     Point object 3,X#,Y#-25,Z#
     If BulletAvoidDeco > 0
      CornerAim = Rnd(1)
      mA# = object angle Y(3)
      if CornerAim = 0 then Yrotate Object 3,WrapValue(mA#+BulletAvoidDeco*10)
      if CornerAim = 1 then Yrotate Object 3,WrapValue(mA#+BulletAvoidDeco*-16)
      Dec BulletAvoidDeco
     Endif

     If ShootUp > 0
      mA# = object angle X(3)
      XRotate Object 3,WrapValue(mA#+ShootUp*-8)
      Dec ShootUp
     Endif

     Position object 102,mX#,mY#+25,mZ#
     Set object to object orientation 102,3
     MonsterBulletLife =500
     show object 102
     Loop sound 102

     Rem Воспроизводим цикл анимации объекта
     Loop Object 3,0,20
    Endif
   Endif

   if PDist>1000
    Rem Сохраняем старое положение
    OldmX# = mX#
    OldmZ# = mZ#
    OldmY# = mY#

    Rem Воспроизводим анимацию ходьбы
    Loop Object 3,21,46

    Rem Переместить монстра
    Move Object 3,7

    Rem Получаем новую позицию
     mX# = Object Position X(3)
     mZ# = Object Position Z(3)
    mY# = Get Ground Height(1,mX#,mZ#)

    Rem Проверка столкновения с колоннами
    If DecoCollide(mX#,mY#,mZ#) = 1 and AvoidDeco = 0
     mX# = OldmX#
     mZ# = OldmZ#
     mY# = OldmY#
     AvoidDeco = 3
    Endif
   Endif
Return

В подпрограмме "MonsterAI" мы добавили код, необходимый для того, чтобы монстр обходил преграды, а также код, меняющий угол стрельбы монстра, в случае, если две переменные, описанные выше, имеют значение отличное от 0.

   If AvoidDeco >0
    mA# = Object Angle Y(3)
    Dec AvoidDeco
    Yrotate object 3,WrapValue(mA#+AvoidDeco*60)
   endif

Если значение переменной "AvoidDeco" больше 0, ее значение уменьшается на 1, а также изменяются углы поворота монстра путем добавления величины "AvoidDeco", умноженной на 60, к текущим углам поворота монстра. Когда монстр натыкается на колонну, переменная "AvoidDeco" принимает значение 3. При каждом проходе цикла монстр перемещается сначала на 180, затем на 120, а потом на 60 градусов. Это заставляет монстра полукругом отойти назад от того места, где он "уткнулся" в преграду. Эта часть кода показывает, как монстр перемещается между преградами.

     If BulletAvoidDeco > 0
      CornerAim = Rnd(1)
      mA# = object angle Y(3)
      if CornerAim = 0 then Yrotate Object 3,WrapValue(mA#+BulletAvoidDeco*10)
      if CornerAim = 1 then Yrotate Object 3,WrapValue(mA#+BulletAvoidDeco*-10)
      Dec BulletAvoidDeco
     Endif

Логика проверки переменной "BulletAvoidDeco" аналогична той, что описана выше, только величина изменения углов полета ракеты не такая большая. Когда ракета первый раз попадает в колонну, переменная "BulletAvoidDeco" принимает значение 2. Если ракета снова попадает в колонну, к этому значению прибавляется 2. Это делается до тех пор, пока ракета не сможет обогнуть преграду. Ракета выстреливается вправо или влево случайным образом, что увеличивает шансы того, что она пролетит мимо преграды.
 

   if PDist>1000
    Rem Сохраняем старое положение
    OldmX# = mX#
    OldmZ# = mZ#
    OldmY# = mY#

    Rem Воспроизводим анимацию движения
    Loop Object 3,21,46

    Rem Перемещаем монстра
    Move Object 3,7

    Rem Получаем новое положение
     mX# = Object Position X(3)
     mZ# = Object Position Z(3)
    mY# = Get Ground Height(1,mX#,mZ#)

    Rem Проверка столкновения с преградой
    If DecoCollide(mX#,mY#,mZ#) = 1 and AvoidDeco = 0
     mX# = OldmX#
     mZ# = OldmZ#
     mY# = OldmY#
     AvoidDeco = 3
    Endif
   Endif

Эта часть кода управляет перемещением монстра. Сначала мы сохраняем предыдущие координаты монстра, прежде чем начать перемещать его. Затем воспроизводим цикл анимации ходьбы при помощи команды "Loop Object". В данном случае у этой команды на два параметра больше, чем в предыдущем. Два параметра после номера объекта - это диапазон воспроизводимых кадров. Это те кадры, которые мы добавили к объекту ранее. Анимация воспроизводится в цикле, пока мы перемещаем объект. Потом мы сохраняем новые координаты монстра и проверяем, не сталкивается ли он с препятствиями. Если столкновение происходит, мы не меняем значение координат монстра и устанавливаем значение "AvoidDeco" равным 3, заставляя монстра полукругом обойти объект.

   If ShootUp > 0
      mA# = object angle X(3)
      XRotate Object 3,WrapValue(mA#+ShootUp*-8)
      Dec ShootUp
     Endif

Выражение сравнения для переменной "ShootUp" также добавлено к подпрограмме "MonsterAI". Если ракета монстра попадает в "землю", то переменная "ShootUp" принимает значение 3, а угол выстрела ракеты монстра увеличивается на 24 градуса. При каждом проходе цикла угол уменьшается на 8 градусов. Это дает возможность ракете монстра лететь по наилучшей траектории в направлении игрока.

Как видите, мы не проверяем, вышел ли монстр за пределы матрицы. В этом нет необходимости, так как монстр всегда движется навстречу игроку, а игрок не может выйти за пределы матрицы. Эти несколько строк кода должны сделать игру более интересной и наделить монстра определенным характером в процессе его охоты на игрока.

 

Hosted by uCoz