В этом уроке мы создадим управляемую ракету монстра, а также определим метод, с помощью которого монстр сможет определить местонахождение игрока.
rem
Создаем снаряд монстра
Make
Object Sphere 102,2
texture
object 102,2
Hide
Object 102
Эта часть кода, создающая сферу для ракеты монстра, помещается в программе до основного цикла. Заметьте, что в качестве текстуры объекта мы используем текстуру под номером 2. Эта та же самая текстура, которую мы применяли для ракеты игрока и других эффектов. Повторное применение текстур сокращает объем памяти, используемой вашей программой.
rem
Создаем эффект взрыва для монстра
Make
Object Sphere 130,20
texture
object 130,2
ghost
object on 130
Hide
Object 130
Make
Object Sphere 131,20
texture
object 131,2
ghost
object on 131
Hide
Object 131
Этот код также вставляется в программу до основного цикла. Он создает объекты взрыва для ракеты монстра.
rem
Загружаем шлейф ракеты монстра
Load
Image "fire.bmp",2
For
x =100 to 110
Make
object plain x+10,5,5
Texture
object x+10,2
Set
object x+10,1,0,0
Ghost
object on x+10
Hide
object x+10
Next
x
MPn=110
Как вы заметили, эта часть кода взята из эффекта шлейфа снаряда игрока. Сам код остался прежним, изменились только номера объектов. Счетчик частиц шлейфа ракеты монстра "MPn" установлен в значение 110, что соответствует номеру первого объекта в совокупности частиц этого шлейфа.
Load
3Dsound "fireball2.wav",102
Load
3Dsound "Explode.wav",103
Этот код загружает звуковые эффекты для ракеты монстра. Заметьте, что мы не задействовали повторно звуковые эффекты, использованные ранее для снаряда игрока. Мы загрузили новые звуки, потому что звуковые эффекты для снарядов игрока и монстра могут воспроизводиться одновременно.
If
MonsterBulletLife > 0 then Gosub MonsterShootBullet
If
MonsterExplode > 0
Gosub MonsterExplodeRocket
else
Gosub MonsterAI
endif
Этот код помещается в нашем основном цикле. Здесь производится проверка времени "жизни" ракеты монстра, продолжительности ее взрыва и выполняются соответствующие подпрограммы, как и в отношении снаряда игрока. Добавилась лишь подпрограмма "MonsterAI". Мы ведь не хотим, чтобы монстр пытался стрелять в то время, когда взрывается предыдущий снаряд. Чтобы убедиться, что этого не происходит, мы используем сравнение "If Then Else".
Rem
Простой AI для управляемой ракеты монстра
MonsterAI:
Point object 3,X#,Y#,Z#
PDist=Sqrt((mX# - X#)^2 + (mY#+25 - Y#)^2 + (mZ# - Z#)^2)
if PDist<1500
if MonsterBulletLife=0 or MonsterBulletLife < 500-PDist/10
Point object 3,X#,Y#-25,Z#
Position object 102,mX#,mY#+25,mZ#
Set object to object orientation 102,3
MonsterBulletLife =500
show object 102
Loop sound 102
Endif
endif
Return
Когда вызывается подпрограмма"MonsterAI", объект "монстр" направлен прямо на игрока. Рассчитывается расстояние между игроком и монстром. Если оно меньше 1500, то продолжается выполнение кода. Если игрок находится вне зоны видимости, ничего не происходит и подпрограмма далее не выполняется, а продолжает выполняться код из основного цикла. Если игрок находится в пределах досягаемости, программа проверяет, не закончилось ли время "жизни" ракеты и не попала ли она в игрока. Способ, с помощью которого мы проверяем, попала ли ракета в цель, заключается в вычислении значения "500-PDist/10". Ракета монстра пролетает 12 единиц координат в единицу своей "жизни". Время ее жизни составляет 500, таким образом, она может преодолеть расстояние в 6000 единиц. Если мы разделим расстояние, или величину переменной "PDist", на 12, то получим число единиц "жизни", которое ракета монстра затратила на подлет к игроку. Если расстояние между монстром и игроком составляет 1200 единиц, то необходимое на подлет к игроку число единиц "жизни" ракеты будет равно 100. Если мы вычтем эту величину из общего числа единиц "жизни" ракеты, то получим 400. Если это значение больше, чем значение переменной "MonsterBulletLife", тогда мы знаем, что ракета не попала в игрока. Мы делим расстояние на 12, а не на 10, что позволяет снаряду пролететь немного дальше, прежде чем можно будет выстрелить еще раз. Это делает игру более реалистичной, позволяя ракете пролететь мимо игрока. Если значение переменной "MonsterBulletLife" позволяет выстрелить еще раз, ракета монстра нацеливается прямо на координаты игрока. Ракете монстра задаются начальные и конечные координаты, устанавливается время ее "жизни" равное 500, объект "ракета" становится видимым и начинает воспроизводиться ее звук.
Rem
Выстрел ракеты монстра
MonsterShootBullet:
Dec MonsterBulletLife
Move object 102,12
MbX#=Object position X(102)
MbY#=Object position Y(102)
MbZ#=Object position Z(102)
inc MPn
if MPn=121 then MPn=110
Scale object MPn,100,100,100
Position object MPn,MbX#,MbY#,MbZ#
Position sound 102,MbX#,MbY#,MbZ#
point object MPn,X#,Y#,Z#
Zrotate object MPn,rnd(180)
Show object MPn
for x = 1 to 10
scale object int((Wrapvalue((MPn-9+x)*36))/36)+110,100+x*25,100+x*25,100+x*25
next x
if MbY# < Get Ground height(1,MbX#,MbZ#) then MonsterBulletLife=0
Pdist=Sqrt((X# - MbX#)^2 + (Y#+25 - MbY#)^2 + (Z# - MbZ#)^2)
if Pdist<50
GoSub PlacePlayer
MonsterBulletLife = 0
endif
Rem Управляемая ракета
if Pdist <500 and Pdist>250 then Point object 102,X#,Y#,Z#
if Pdist < 100 then point object 102,X#,Y#,Z#
if MonsterBulletLife = 0
Hide object 102
stop sound 102
for x=110 to 120
hide object x
next x
MonsterExplode = 20
endif
Return
Подпрограмма "MonsterShootBullet" очень похожа на подпрограмму "ShootBullet", однако мы добавили несколько строк для того, чтобы сделать ракету монстра управляемой. Это создает игровое напряжение и бросает вызов игроку, пытающемуся уклониться от ракеты монстра.
Rem Управляемая ракета самонаведения
if Pdist <500 and Pdist>250 then Point object 102,X#,Y#,Z#
if Pdist < 100 then point object 102,X#,Y#,Z#
Это код для управляемой ракеты самонаведения. Если ракета находится на расстоянии от 500 до 250 единиц от игрока, она самонаводится по текущим координатам игрока. Находясь на расстоянии 100 единиц от игрока, ракета снова получает текущие координаты цели. Это дает игроку немного времени на попытку уклониться от ракеты.
Rem
Взрыв ракеты монстра
MonsterExplodeRocket:
Position
object 130,MbX#,MbY#,MbZ#
Show
object 130
Position
object 131,MbX#,MbY#,MbZ#
Show
object 131
EScale=20*(30-MonsterExplode)
Scale
object 130,EScale,EScale,EScale
Yrotate
object 130,WrapValue(MonsterExplode*37)
Scale
object 131,EScale/1.5,EScale/1.5,EScale/1.5
Yrotate
object 131,WrapValue(359-MonsterExplode*37)
Dec
MonsterExplode
If
MonsterExplode = 0 then hide object 130: Hide object 131
If
MonsterExplode=18
position sound 103,X#,Y#,Z#
play sound 103
endif
If
MonsterExplode < 15 then position sound 103,X#,Y#,Z#
Return
Код подпрограммы "MonsterExplodeRocket" такой же, как и в подпрограмме "ExplodeRocket". Единственное, что отличает эти две подпрограммы - это переменные координат ракеты монстра и номера объектов и звуков.