Меню Сайта
Главная
Чат
__________________
Naruto TV-1
Naruto TV-2 Shipudenn
Naruto MOVIE-3
Naruto MOVIE-4
Naruto Приколы-Online
____________________
Windows XP
Linux
Vista
_______________
Games
3D_Модели
Програмы нужные Для Создания ИГР
ГАЛЕРЕЯ СКРИНШОТОВ из УРОКОВ
_______________________
--Blitz3D для начинающих---
Первая комната Blitz3d---
--Основы Cоздания Cетевых Игр---
Создание чата---
--Спрайты и Tекстуры---
Моделирование---
--Создание Серьезных Уровней---
Создание Kосмической Aркады---
--Звук, музыка и Интерфейс---
Создание основ Pолевой Игры---
--Простейший First-Person Шутер---
--Пиктограмма exe-файла---
___________________
Обои для Рабочего Стола
_________________
Раздел Банеров
Друзья-Сайта
Аниация и кправление камерой---
Redact
 

ToP Sites http://mo3del.ru/ http://mir3d.3dn.ru/ http://sw-in.narod.ru/

Создание Kосмической Aркады---

Урок 7. Создание космической аркады

7.1.  Игровая сцена и объекты.

     Если вы не видели одну из первых игр Джона Кармака (
John Carmack) оздателя легендарных игр - Wolfenstein 3D, Doom и многих других)  Slordax The Unknown Enemy то самое время с ней ознакомиться, так как мы постараемся создать нечто подобное. Суть игры Slordax в следующем: мы управляем маленьким космическим корабликом, который несется сквозь пространство и своей огневой мощью вселяет страх в пытающиеся ему противостоять вражеские летающие объекты Создавая такую игру мы закрепим пройденный материал, так как:
1. Создадим модели кораблей
2. Вспомним управление объектами при помощи клавиатуры
3. Повторим тему коллизий (столкновений спрайтов и объектов типа
mesh)
4. Затронем создание спрайтовых эффектов
5. Научимся вести список лучших результатов игры и т.д.

    Что же из себя будет представлять наша игровая сцена ? Игровое поле будет состоять из двух объектов типа
plane которые будут двигаться в одном направлении, но с разными скоростями, имитируя ближние и удаленные звезды. Текстуру для этих целей можно создать в стандартном редакторе Paint в течении 30 секунд. Если у вас не возникло такого желания, то можете воспользоваться этой:



     Что касается объектов, то нас их будет 4 вида: наш корабль, уверенно рассекающий космические просторы, вражеские корабли (по сути один и тот же корабль, только в большом количестве), объект - выстрел нашего корабля (их тоже может быть несколько на экране) и объект - взрыв (нашего и вражеского корабля).
     Логика нашей игры совершенно бесхитростна: если во вражеский корабль  попадает одна из выпущенных нами ракет, то он взрывается и распадается на мелкие части. Реально мы, конечно, не будем дробить модель вражеского корабля на частицы - мы просто уберем его с экрана, а в месте его пребывания создадим эффект взрыва. Если же враждебный нам корабль зацепит наш своим корпусом, то погибают оба. У нас в запасе будет 3 жизни, посему гибель одного - двух наших кораблей будет не критична, главное сохранить хотя бы один, уничтожив при этом всех врагов!
     Итак опишем типы, отвечающие за информацию об объектах нашей стрелялки:
 

; Тип вражеского корабля
Type EnemyShip
 
Field Ship
 
Field ShipX#
 
Field ShipZ#
 
Field ShipSpeed#
End Type

; Тип взрыва после столкновения или попадания
Type Frag
 
Field alpha#,entity
End Type

; Тип ракеты (выстрел нашего корабля)
Type Bullet
 
Field rot#,sprite,time_out
End Type

Тип вражеского корабля состоит из поля в котором содержится ссылка на модель, две координаты по осям X и Z (расположение в текущий момент времени) и скорость.
Тип взрыва характеризуется двумя полями: ссылкой на спрайт, визуализирующий одну из частиц взрыва и величиной прозрачности этой частицы, которая меняется со временем.
Тип ракеты определяется углом поворота спрайта, ссылкой на спрайт, и временем жизни ракеты в игре.

7.2.  Создадим модели кораблей.

     К этому уроку у Вас уже должен был накопиться порядочный опыт общения с редактором моделей
Milkshape3D. Наверняка после нашего ознакомительного занятия с его возможностями не раз пробовали создать какой-нибудь свой анимированный объект или скачивали с Интернета готовые модели и редактировали их в этой программе.
    Поэтому процесс создания примитивных модели кораблей не должно вызвать у Вас затруднений.
Давайте для начала создадим вражеский корабль. Откройте редактор
Milkshape3D и используя инструменты: сфера, цилиндр и коробка (box) смоделируйте нечто подобное рисунку приведенному ниже:


 
Из рисунка видно, что центральной частью нашего простенького кораблика является сфера, из которой в разные стороны торчат пять цилиндров внешние концы которых соединены планками (объект
box). Не забудьте внедрить один объект типа Joint (на рисунке - синим цветом) и привязать его ко всем точкам нашей модели, для того чтоб Milkshape3D правильно экспортировал его в формат .md2. На Ваше усмотрение вы можете экспортировать модель в .Х, .3ds или .b3d формат так как модель все равно не будет содержать никакой анимации. Мы же все таки остановимся на .md2., для чего в папку, где будет содержаться итоговая модель запишем файл типа .qc, с описанием только одной последовательности:
$sequence stop 1 1
Таким образом, модель лишена какой-либо анимации и будет двигаться только повинуясь алгоритму нашей программы. Вы можете скачать модель и файл
ms3d - для вражеского корабля. Если у Вас есть огромное желание, то для разминки создайте текстуру для этой модели и обтяните ею корабль.

Столь же просто создадим и модель нашего корабля, для чего понадобятся  три объекта типа цилиндр и четыре объекта
ящик (box). Цилиндры можно чуть сузить (операция масштабирования на выделенном фрагменте объекта) для большего правдоподобия. Должно получиться примерно следующее:



Не забудьте, как и в предыдущем  случае внедрить один объект типа Joint (на рисунке - синим цветом) и привязать его ко всем точкам (вертексам) нашей модели, для того чтоб Milkshape3D правильно экспортировал его в формат .md2. Создание текстуры для корабля остается за Вами.
Вы можете скачать модель и файл
ms3d - для нашего корабля.

7.3.  Перемещение кораблей и контроль столкновений.

 Перемещение нашего корабля строго линейное, а именно вдоль осей Х и
Z. Нам остается только контролировать, чтоб корабль не мог покинуть пределы игрового пространства.

If KeyDown(200) ; Up
 
If EntityZ(ship) < 14
   
MoveEntity ship, 0, 0, 0.2
  EndIf
EndIf
If KeyDown(208) ; Down
  If EntityZ(ship) > -1
   
MoveEntity ship, 0, 0, -0.2
 
EndIf
EndIf

If KeyDown(203) ; Left
 
If EntityX(ship) > -8
    MoveEntity ship, -0.2, 0, 0
  EndIf
EndIf
If KeyDown(205) ; Right
  If EntityX(ship) < 8
   
MoveEntity ship, 0.2, 0, 0
  EndIf
EndIf

    Как Вы видите из приведенного кода, корабль жестко замкнут в диапазоне координат
-1, 14 по оси
Z и -8, 8 по оси Х. Дискретность перемещений выбираем 0.2, однако Вы можете поварьировать этот параметр в зависимости с Вашими предпочтениями.
    По замыслу игры, корабли противника должны появляться с некоторым интервалом в игровой зоне нашей стрелялки. Само собой напрашивается решение применить функцию времени
Millisecs() для контроля появления кораблей противника. Давайте зададим число вражеских кораблей константой, зарезервируем специальный массив, в котором будет хранится время появления в игровой зоне всех кораблей врага и напишем функцию, которая случайным образом генерирует это время.

Const NUM_ENEMY_ROCKETS = 20
Dim aEnemies( NUM_ENEMY_ROCKETS )

;---------------------------------------------------------

Function CreateRNDRockets()
  aEnemies(0) =
MilliSecs()+1000
  SeedRnd MilliSecs()
  For i=1 To NUM_ENEMY_ROCKETS
     aEnemies(i) = aEnemies(i-1)+
Rnd(1000,3000)
  Next
  iEnemy = 1
End Function

Как видно из вышеприведенного фрагмента кода - 20 вражеских кораблей будут появляться в игре с интервалом в 1000 - 3000 миллисекунд одна за другой. После вызова нашей функции CreateRNDRockets() массив aEnemies будет содержать время появления врагов на игровом поле.
Теперь давайте займемся созданием и перемещением кораблей противника
. В главном цикле программы создадим условие, которое будет сравнивать текущее время со временем уже занесенным ранее в массив
aEnemies и при истинности этого условия создавать новую вражескую ракету в игровой зоне.

If iEnemy <= NUM_ENEMY_ROCKETS
  
If (MilliSecs() >= aEnemies(iEnemy))
      CreateShip()
      iEnemy = iEnemy + 1
  
EndIf
EndIf

;---------------------------------------------------------
Function CreateShip.EnemyShip()
  es.EnemyShip=
New EnemyShip
  esShipSpeed=0.1
  esShip=CopyEntity( ship3 )
  EntityType esShip, TypeEnemy
  PositionEntity esShip, Rnd(-8,8), 1, 18
  SeedRnd MilliSecs()
  esShipX =
Rnd(-0.1,0.1)
  esShipZ =
Rnd(-0.4,0.4)
  Return es
End Function

     Что касается функции CreateShip , то она возвращает созданный элемент списка (очередную ракету противника). Позиция вновь созданного вражеского корабля задается чуть выше верхней границы игровой зоны, чтоб имитировать появление ракеты из-за пределов видимой области. К тому же координата Х ее задается случайным образом из диапазона (-8,8). Кроме того функция сразу задает скорости дальнейшего перемещения по осям Х и Z (в виде приращений), таким образом косвенно задавая угол под которым корабль будет двигаться после его появления.
     Перемещениями вражеских кораблей по экрану занимается созданная нами функция MoveShip. В ее обязанности будет входить определение столкновений нашего корабля с вражескими и осуществлять приращения к текущим координатам каждой из вражеских ракет.

Function MoveShip( es.EnemyShip )
    b_collision =
EntityCollided( esShip,TypePlayer )
   
; Enemy collided with player ship
   
If b_collision
      
DeleteEShip(esShip)
      
DestroyPlayerShip()
   
Else
      
MoveEntity esShip, esShipX, 0, esShipZ
      
If (EntityX(esShip) < -9.2) Or EntityX(esShip) > 9.2
         esShipX = -1*(esShipX )
      
EndIf
      
If (EntityZ(esShip) < -2.5) Or EntityZ(esShip) > 18.5
         esShipZ = -1*(esShipZ )
      
EndIf
   
EndIf
End Function

   Первая же строчка в функции MoveShip проверяет произошло ли столкновение вражеской ракеты с объектом типа TypePlayer то есть с нашим кораблем и если да, то вызывает функции удаления вражеской ракеты и нашего корабля (по крайней мере наш корабль теряет одну жизнь). Если же нет никаких столкновений, то происходит приращение координат и контроль за нахождением вражеской ракеты внутри игровой зоны. Таким образом вражеский корабль просто заперт в экране игры и отталкивается от стен меняя угол перемещений пока не будет убит выстрелом нашего корабля или после столкновения с ним.
   Функции уничтожения вражеских ракет и гибели одной из жизней нашего корабля приведены ниже:
 

Function DeleteEShip(b_collision)
 
For es.EnemyShip=Each EnemyShip
      If b_collision = esShip
         CreateExplosion(esShip,5)
         EmitSound expl, esShip
         FreeEntity esShip
         Delete es
         iKilled = iKilled + 1
      EndIf
  Next
End Function

Function DestroyPlayerShip()
  
HideEntity ship
   lModeImmortal = True
   lImmortalTime =
MilliSecs() + 3000
   lRefreshShip =
MilliSecs() + 100
   CreateExplosion(ship,10)
   PositionEntity ship, 0, 1, 0 ; Return Ship to start position
  
EmitSound playerexpl, ship
   If lModeImmortal
     
If iNumRockets > 0
        iNumRockets = iNumRockets - 1
      Else
        lGameLost =
True
       
HideEntity ship
        lModeImmortal =
False
     EndIf
   EndIf
End Function

Функция DeleteEShip вызывается после двух событий - столкновения с нашим кораблем и после попадания нашей ракеты во вражеский корабль. Ей передается аргумент - ссылка на вражеский корабль, который нужно удалить из игры. В результате выполнения этой функции по нашему замыслу должен прозвучать звук взрыва (EmitSound ) и его визуализация (CreateExplosion().

Функция
DestroyPlayerShip прячет наш корабль и переводит игру в режим lModeImmortal. Это такой режим, когда на 3 секунды (3000 мили секунд) наш корабль начинает мигать на экране и становится неуязвимым для вражеских кораблей. В этой функции также проверяется количество оставшихся жизней нашего корабля, за которые отвечает переменная iNumRockets .
Кроме того после гибели функция возвращает наш корабль на стартовую точку или вообще убирает с экрана, если потрачена последняя жизнь при этом инициализируется флаг lGameLost = True символизирующий о том, что игра проиграна.

7.4.  Стрельба по врагам.

   Для визуализации процесса стрельбы по вражеским ракетам, используем спрайт, которым мы уже пользовались ранее:


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

Global bull_sprite=LoadSprite( "spritesbluspark.bmp" )
ScaleSprite bull_sprite,0.5, 0.5
EntityRadius bull_sprite,0.01
EntityType bull_sprite, TypeBullet
HideEntity bull_sprite

Так как в программе проверяется столкновение ракеты с вражескими кораблями, то нужно описать тип коллизий:

Collisions TypeBullet, TypeEnemy, 1, 1

В главном цикле программы осуществим вызов функции, отвечающей за выстрел, причем клавишей для инициации выстрела, к примеру, выберем - Ctrl.

If KeyHit(29) And (Not lGameLost) ;Ctrl - fire
   CreateBullet( ship )
EndIf

После нажатия на эту злополучную для наших врагов клавишу, должен визуализироваться шарик, который начинает свое движение вдоль оси Z на встречу вражескому кораблю. Напишем функцию создания этого шарика с учетом того, что их может быть несколько в любой конкретный момент времени:

Function CreateBullet.Bullet( sh )
   b.Bullet=
New Bullet
   btime_out=150
   bsprite=
CopyEntity( bull_sprite, sh )
   EntityParent bsprite,0
   Return b
End Function

   Итак функция CreateBullet создает экземпляр выстрела нашего корабля и возвращает его значение. Одно из полей типа выстрела содержит тайм-аут, что по сути является временем жизни экземпляра этого объекта. В данном случае ему присвоено значение 100. Попробуйте уменьшить это число и вы увидите, что пущенный снаряд будет исчезать не долетев верхней границы экрана. Так как в качестве родительского объекта для копирования спрайта используется наш корабль, то снаряд вылетает из места текущего расположения нашего корабля.
   Теперь осталось создать функцию для обновления позиций всех выстрелов и проверки их столкновений с вражескими ракетами:

Function UpdateBullet( b.Bullet )
   btime_out=btime_out-1
   b_collision =
EntityCollided( bsprite,TypeEnemy )

   If (btime_out=0) Or b_collision
     iCollision = 2
     FreeEntity bsprite
     Delete b
    
DeleteEShip(b_collision)
     Return
   EndIf

   brot=brot+30
   RotateSprite bsprite,brot
   MoveEntity bsprite,0,0,0.2
End Function
 

Функция UpdateBullet должна располагаться в главном цикле программы. Для каждого из экземпляров выстрела функция уменьшает его время жизни btime_out и по достижении нуля уничтожает его. Уничтожение объекта спрайт, самого экземпляра объекта и вызов функции уничтожения вражеского корабля также возложено на хрупкие плечи этой функции. Нахождение коллизий с вражеским кораблем как всегда определяется функцией EntityCollided из набора Blitz3D. Если не происходит никаких столкновений, функция UpdateBullet  просто осуществляет вращения спрайта и его перемещение к верхней границе экрана.

7.5.  Эффект взрыва объектов

    Для создания более динамичного действия можно написать парочку функций красочного уничтожения объектов. Конечно мы могли просто удалять уничтоженные объекты с экрана, но это было бы очень скучно. Посему создадим эффект разлетающихся частиц в космическом пространстве. Для начала понадобятся несколько констант, которые мы определим в начале программы:

Const grav# = -.02, intensity = 3

Константа grav - будет отвечать за гравитацию частиц, а intensity за насыщенность частицами
нашего эффекта.
Само собой разумеется, что взрыв должен произойти в том месте, где располагался корабль в момент наступления события его уничтожения.
Создадим функцию
CreateExplosion, которая и будет создавать эффект взрыва

Function CreateExplosion(EnemyShip, num)
  
For i=1 To num
     
For t=1 To intensity
           f.Frag=
New Frag
           falpha=
Rnd(2,3)
           fentity=
CopyEntity( bull_sprite, EnemyShip )
           ScaleSprite fentity, 0.2, 0.2
           EntityColor fentity,Rnd(255),Rnd(255),Rnd(255)
           EntityParent fentity,0
           RotateEntity fentity,Rnd(360),Rnd(360),Rnd(360)
      Next
   Next
End Function

В качестве аргументов наша функция CreateExplosion получает объект вражеского корабля, который должен взорваться и число частиц взрыва, которое должно быть визуализировано на экране. Цвет частиц задается генератором случайных чисел (функция Rnd) Углы частиц также задаются случайным образом для того чтоб они разлетались в объемных координатах.

Теперь осталось создать функцию, которая будет обновлять эффект взрыва на экране. Назовем ее UpdateExplosion и приведем текст ниже:

Function UpdateExplosion()
  
For f.Frag=Each Frag
      falpha=falpha-dt*.02
      If falpha>0
         al#=falpha
 
       If al>1 Then al=1
         EntityAlpha fentity,al
         MoveEntity fentity,0,0,dt*.4
         ys#=fys+grav*dt
         dy#=fys*dt
         fys=ys
        
TranslateEntity fentity,0,dy,0
     Else
        
FreeEntity fentity
         Delete f
     EndIf
  Next
End Function

Как видно из функции - время жизни каждой из частиц составляющих взрыв зависит от интенсивности ее свечения (falpha). Если этот параметр достигает нуля - частица удаляется из игры. Скорость перемещения частиц взрыва задается в главном цикле программы следующими строками кода:

Repeat
elapsed=
MilliSecs()-time
Until elapsed>0
time=time+elapsed
dt=elapsed*60.0/3000.0

Попробуйте изменить число 3000 на меньшее и скорость частиц заметно повысится. Наоборот увеличение этого числа понижает скорость частиц.

7.6.  Итоги и полный текст программы

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

Graphics3D 640, 680
SetBuffer BackBuffer()

Const TypePlayer = 1, TypeBullet = 2, TypeEnemy = 3
Const NUM_ENEMY_ROCKETS = 20
Const grav#=-.02,intensity=3

Global iNumRockets% = 3
Global lModeImmortal = False
Global lImmortalTime, lRefreshShip
Global lShowShip = False
Global lGameLost = False
Global lGameWon = False

Global Font1, Font2
Font1 =
LoadFont("Arial Cyr",14, True)
Font2 =
LoadFont("Arial Cyr",40)

Dim aEnemies(NUM_ENEMY_ROCKETS)
Global iEnemy = 1
Global iKilled = 0

Global iCollision = 0

Global player=CreateSphere()
PositionEntity player,0, 10, 7
TurnEntity player,90,0,0

Global
cam=CreateCamera(player)
light=
CreateLight(1)
PositionEntity light, 2,3,4

; Sounds
Global expl=Load3DSound( "soundsshipexpl.wav" )
Global playerexpl=Load3DSound( "soundsrocketexpl.wav" )


; Our ship
Global ship=LoadMD2("MODELSship1.md2")
ScaleEntity ship, .1,.1,.1
PositionEntity ship, 0, 1, 0
EntityRadius ship,0.5
EntityType ship, TypePlayer

;Enemy Ship
Global ship3=
LoadMD2("MODELSship3.md2")
ScaleEntity ship3, .1,.1,.1
PositionEntity ship3, 0, 1, 10
EntityRadius ship3,1.0
EntityType ship3, TypeEnemy
Global ShipX# = -0.04
Global ShipZ# = -0.02
HideEntity ship3

Global Startex=LoadTexture("stars2.jpg")
Sky1=
CreatePlane()
PositionEntity Sky1,0,-1,0
EntityTexture Sky1, Startex
ScaleTexture Startex, 5, 5

Global Startex2=LoadTexture("stars2.jpg",4)
Sky2=
CreatePlane()
PositionEntity Sky2,0,-0.5,0
EntityTexture Sky2, Startex2
ScaleTexture Startex2, 10, 10

Global bull_sprite=LoadSprite( "spritesbluspark.bmp" )
ScaleSprite bull_sprite,0.5, 0.5
EntityRadius bull_sprite,0.01
EntityType bull_sprite,TypeBullet
HideEntity bull_sprite

; Тип вражеского корабля
Type EnemyShip
 
Field Ship
 
Field ShipX#
 
Field ShipZ#
 
Field ShipSpeed#
End Type

; Тип взрыва после столкновения или попадания
Type Frag
 
Field alpha#,entity
End Type

; Тип ракеты (выстрел нашего корабля)
Type Bullet
 
Field rot#,sprite,time_out
End Type


Collisions TypeBullet, TypeEnemy, 1, 1
Collisions TypePlayer, TypeEnemy, 1, 1
Collisions TypeEnemy, TypePlayer, 1, 1


CreateRNDRockets()
time=
MilliSecs()

Global dt#

listener=
CreateListener( player,.1,1,.2 )


While Not KeyDown( 1 )

Repeat
elapsed=
MilliSecs()-time
Until elapsed>0
time=time+elapsed
dt=elapsed*60.0/3000.0

If KeyDown(200) ; Up
 
If EntityZ(ship) < 14
   
MoveEntity ship, 0, 0, 0.2
  EndIf
EndIf
If KeyDown(208) ; Down
  If EntityZ(ship) > -1
   
MoveEntity ship, 0, 0, -0.2
 
EndIf
EndIf

If KeyDown(203) ; Left
 
If EntityX(ship) > -8
    MoveEntity ship, -0.2, 0, 0
  EndIf
EndIf
If
KeyDown(205) ; Right
  If EntityX(ship) < 8
   
MoveEntity ship, 0.2, 0, 0
  EndIf
EndIf


If KeyHit(29) And (Not lGameLost) ;Ctrl fire?
   CreateBullet( ship )
EndIf

For es.EnemyShip=Each EnemyShip
  
Text 10,10+iPos, esShip
   MoveShip( es )
   iPos = iPos + 10
Next

MoveEntity Sky1, 0, 0, -0.05
MoveEntity Sky2, 0, 0, -0.07

If iEnemy <= NUM_ENEMY_ROCKETS
  
If (MilliSecs() >= aEnemies(iEnemy))
     CreateShip()
     iEnemy = iEnemy + 1
  
EndIf
EndIf


; Если установлен режим бессмертия
If lModeImmortal
   If
MilliSecs() > lRefreshShip
     lRefreshShip =
MilliSecs() + 100
  
If lShowShip
     
ShowEntity ship
      lShowShip =
False
  
Else
     
HideEntity ship
      lShowShip =
True
   EndIf
   If
MilliSecs() > lImmortalTime
      lModeImmortal = False
     
ShowEntity ship
  
EndIf
  
EndIf
EndIf

For b.Bullet=Each Bullet
   UpdateBullet( b )
Next

UpdateExplosion()

UpdateWorld
RenderWorld

SetFont Font1
Text 10,50, "Rockets left: "+iNumRockets

If lGameLost
  
SetFont Font2
   Text 180,250, "You Have Lost!"
EndIf

If (iKilled >= NUM_ENEMY_ROCKETS) And (Not lGameLost)
  
SetFont Font2
   Text 150,250, "You Won The Game!"
EndIf

Flip

Wend

;-----------------------------------------------------------
; Create New Bullet
;-----------------------------------------------------------

Function CreateBullet.Bullet( sh )
  b.Bullet=
New Bullet
  btime_out=100
  bsprite=
CopyEntity( bull_sprite, sh )
  EntityParent bsprite,0
  Return b
End Function

;-----------------------------------------------------------
;     Update Bullet Position
;-----------------------------------------------------------

Function UpdateBullet( b.Bullet )
   btime_out=btime_out-1
   b_collision =
EntityCollided( bsprite,TypeEnemy )

  
If (btime_out=0) Or b_collision
     iCollision = 2
    
FreeEntity bsprite
    
Delete b
     DeleteEShip(b_collision)
    
Return
  
EndIf

   brot=brot+30
  
RotateSprite bsprite,brot
  
MoveEntity bsprite,0,0,0.2
End Function

;---------------------------------------
; Create New EnemyShip
;---------------------------------------

Function CreateShip.EnemyShip()
   es.EnemyShip=
New EnemyShip
   esShipSpeed=0.1
   esShip=
CopyEntity( ship3 )
   EntityType esShip, TypeEnemy
   PositionEntity esShip, Rnd(-8,8), 1, 18
   SeedRnd MilliSecs()
   esShipX =
Rnd(-0.1,0.1)
   esShipZ =
Rnd(-0.4,0.4)
   Return es
End Function

;---------------------------------------
; Update Ship Position
;---------------------------------------

Function MoveShip( es.EnemyShip )
   b_collision =
EntityCollided( esShip,TypePlayer )
   ; Enemy collided with player ship
   If b_collision
      DeleteEShip(esShip)
      DestroyPlayerShip()
   Else
      MoveEntity esShip, esShipX, 0, esShipZ
      If (EntityX(esShip) < -9.2) Or EntityX(esShip) > 9.2
        esShipX = -1*(esShipX )
      EndIf
  
   If (EntityZ(esShip) < -2.5) Or EntityZ(esShip) > 18.5
         esShipZ = -1*(esShipZ )
      EndIf
   EndIf
End Function

;---------------------------------------
; Destroy Player Ship
;---------------------------------------

Function DestroyPlayerShip()
   If Not lModeImmortal
     If iNumRockets > 0
        iNumRockets = iNumRockets - 1
     Else
       lGameLost =
True
       HideEntity ship
       lModeImmortal =
False
     EndIf
     PositionEntity ship, 0, 1, 0 ; Return Ship to start position
     EmitSound playerexpl, ship
     HideEntity ship
     lImmortalTime =
MilliSecs() + 3000
     lRefreshShip =
MilliSecs() + 100
     CreateExplosion(ship,10)
     lModeImmortal =
True
   EndIf
End Function

;---------------------------------------
; Update Ship Position
;---------------------------------------

Function CreateRNDRockets()
   aEnemies(0) =
MilliSecs()+1000
   SeedRnd MilliSecs()
   For i=1 To NUM_ENEMY_ROCKETS
      aEnemies(i) = aEnemies(i-1)+
Rnd(1000,3000)
   Next
   iEnemy = 1
End Function

;---------------------------------------
; Destroy EnemyShip
;---------------------------------------
Function DeleteEShip(b_collision)
  
For es.EnemyShip=Each EnemyShip
       If b_collision = esShip
          CreateExplosion(esShip,5)
          EmitSound expl, esShip
          FreeEntity esShip
          Delete es
          iKilled = iKilled + 1
       EndIf
   
Next
End Function

;-------------------------------------
; Create Explosion
;-------------------------------------

Function CreateExplosion(EnemyShip, num)
  
For i=1 To num
     
For t=1 To intensity
           f.Frag=
New Frag
           falpha=
Rnd(2,3)
           fentity=
CopyEntity( bull_sprite, EnemyShip )
           ScaleSprite fentity, 0.2, 0.2
           EntityColor fentity,Rnd(255),Rnd(255),Rnd(255)
           EntityParent fentity,0
           RotateEntity fentity,Rnd(360),Rnd(360),Rnd(360)
      Next
   Next
End Function

;-------------------------------------
; Update Particles of Explosion
;-------------------------------------

Function UpdateExplosion()
  
For f.Frag=Each Frag
      falpha=falpha-dt*.02
      If falpha>0
         al#=falpha
 
       If al>1 Then al=1
         EntityAlpha fentity,al
         MoveEntity fentity,0,0,dt*.4
        
TranslateEntity fentity,0,dy,0
     Else
        
FreeEntity fentity
         Delete f
     EndIf
  Next
End Function

End

Анализируя код программы космической аркады, вы также найдете функции загрузки шрифтов и звуков, с которыми мы ранее не сталкивались. Думается, что это не вызовет у вас никаких затруднений. Мы используем увеличение шрифта для вывода сообщений о поражении или победе в игре, а звуковые файл, который вы можете взять тут (shipexpl.wav и  rocketexpl.wav),  мы используем для озвучивания эффекта взрывов вражеских ракет и нашего корабля.
Заметим также, что все звуки должны располагаться в подкаталоге
Sounds каталога с программным модулем, спрайт  - в подкаталоге каталоге Sprites, а модели в подкаталог - Models. Вы можете расположить все модели звуки, спрайты в корневой каталог с игрой, если хотите, но тогда измените ссылки при загрузке этих ресурсов в теле программы.

Игровое окно программы выглядит примерно так:



После успешного уничтожения всех 20-и кораблей противника, вы получите радостное сообщение о своей победе. В противном случае программа сообщит о том что миссия провалена.


Что будет далее:

           Следующей урок затронет тему создания ландшафтов. Мы научимся делать горы и впадины, рассаживать деревья и создавать водные массивы, небо и многое другое.

 

 

уже 16010 посетителей!
 
Часы
 
Этот сайт был создан бесплатно с помощью homepage-konstruktor.ru. Хотите тоже свой сайт?
Зарегистрироваться бесплатно