16. Первая 3Д игра. Часть 6 – завершение

 

И вот теперь только мы готовы к тому, чтобы создать остальные части игры – это Стартовый экран и экран Гейм Овера (можно было бы и больше, конечно, но нам хватит J).

 

Для начала введём переменную, в которой будет находится информация о том, какой экран мы сейчас показываем. Ну, назовём её GameScr, а значения она будет принимать: 0 - стартовый экран, 6 - Экран Гейм Овера, и, например 9 – экран самой игры.

 

Global GameScr=0

 

Т.е. начинаться у нас будет со стартового экрана.

 

Теперь изменения пойдут в главном цикле. После которых он будет выглядеть вот так:

 

Repeat

 

 Select GameScr

 Case 0

 

 UpdateStartScreen()

 

 Case 9

 

 UpdateGame()

 

 End Select

 

 Flip

 

Until KeyHit(1)

 

Вы хотите узнать, что это за команды - Select и Case? Ну, это просто команды условия. Например, нам нужно что-то делать, в зависимости от того, какое значение принимает переменная variable. Можно написать так:

 

If variable=0 then

           

EndIf

If variable=1 then

           

EndIf

If variable=2 then

           

EndIf

If variable=3 then

           

EndIf

If variable=4 then

           

EndIf

 

А можно – так:

 

Select variable

Case 0

           

Case 1

           

Case 2

           

Case 3

           

Case 4

           

End Select

 

Достоинства последнего метода перечислять не буду J

 

Дальше, в зависимости от того, какое значение у переменной GameScr, выполняются определённые действия… т.е. если GameScr=9 (идёт сама игра), то мы вызываем функции UpdateGame(), в которую мы поместили все наши команды игры. А если GameScr=0, мы должны показывать стартовый экран. Мы вызываем функцию UpdateStartScreen(), которую сейчас напишем.

 

Так, стартовый экран у нас будет выглядеть таким образом: сверху большими буквами название – “First Game”, например, а снизу две опции – Start и Quit. Всё это будем делать текстом. Для этого нам нужно загрузить шрифт (два шрифта точнее):

 

Global fontB=LoadFont("Verdana",72)

Global FontM=LoadFont("Verdana",32)

 

Эти строчки поставьте после команд инициализации графики.

 

Синтакс: LoadFont (название,размер) – загружает шрифт. По-моему, всё ясно… J

 

Теперь создадим саму функцию UpdateStartScreen()

 

Function UpdateStartScreen()

 

 

 Cls

 SetFont FontB

 Color 255,100,40

 Text 320,150,"First Game",True,True

 SetFont FontM

 Text 320,240, "Start",True,True

 Text 320,280, "Quit",True,True

 

 

End Function

 

Так, экран сделали, теперь нам нужен курсор. Как сделать курсор? Так как наша игра никаких внешних ресурсов до сих пор не использовала, здесь тоже обойдёмся без картинок… Более того, я вообще предлагаю вместо курсора текст использовать, точнее символ «*»…

 

Вот как это сделать (вставить в функцию):

 

Color 250,200,0

Text MouseX(),MouseY(),"*",True,True

 

Получился жёлтый курсор. Однако кликание на текст ничего не даёт... Нам нужна проверка – не находится ли курсор над надписью Start или Quit.

 

Function UpdateStartScreen()

 

 

 Cls

 SetFont FontB

 Color 255,100,40

 Text 320,150,"First Game",True,True

 SetFont FontM

 Text 320,240, "Start",True,True

 Text 320,280, "Quit",True,True

 

 

End Function

 

Всё очень просто (хотя это и 2Д J)… Здесь мы используем команды RectsOverlap – она проверяет, не пересекаются ли заданные прямоугольники.

 

Синтакс: RectsOverlap (X коорд. прямоугольника 1, Y коорд. прямоугольника 1, Ширина прямоугольника 1, Высота прямоугольника 1, X коорд. прямоугольника 2, Y коорд. прямоугольника 2, Ширина прямоугольника 2, Высота прямоугольника 2)

 

X и Y координаты – левого верхнего угла прямоугольника.

 

tShift=0

If RectsOverlap(MouseX(),MouseY(),1,1,320-50,240-12,100,32) tShift=1

If RectsOverlap(MouseX(),MouseY(),1,1,320-50,280-12,100,32) tShift=2

 

Эти команды нужно вставить в начало функции.

 

Теперь мы у нас есть курсор и мы знаем, когда он находится над “Start” и ”Quit”. Теперь надо сделать так, чтобы цвет текста менялся, когда курсор будет наведён на него, так что немного перепишем строки:

 

If tShift=1 Color 0,255,0 Else Color 255,0,0

Text 320,240, "Start",True,True

If tShift=2 Color 0,255,0 Else Color 255,0,0

Text 320,280, "Quit",True,True

 

Так, интерактивность (хоть и примитивная, но хотя бы что-то J) присутствует, осталось только заставить это работать. Для этого нужно поставить в конец функции вот эти строчки:

 

If MouseHit(1)

  Select tShift

  Case 1

   CreatePlayer()

   CreateWalls(29)

   CreateTarget()

   CreateEnv()

  

   Collisions TypePlayer,TypeWalls,2,2

   Collisions TypePlayer,TypeTarget,2,2

 

   GameScr=9

  Case 2

   End

  End Select

 EndIf

 

Здесь у нас идёт проверка на нажатие левой кнопки. Затем, если курсор находится над Start`ом, происходит инициализация (мы её из начала кода вырезали), и меняется переменная GameScr, так, что со следующим кадром покажется уже не стартовый экран, а сама игра. Ну, а если курсор над кнопкой Quit, то программа просто выходит…

 

Дальше, теперь нам надо сделать так, чтобы при проигрыше или нажатии кнопки Esc, игра выходила на стартовый экран. Но перед этим, показывала экран ГеймОвера. Для этого внесём некоторые изменения в функцию UpdateGame():

Во первых сменим строчку, где игра заканчивается при столкновении с кубиком

 

If EntityCollided (Player,TypeWalls) End

 

 на эту:

 

If EntityCollided (Player,TypeWalls) Or KeyDown(1)

 GameScr= 6

 FreeGame()

EndIf

 

Теперь игра будет очищаться и выходить на экран геймовера. И теперь у нас будет только один способ (без нажатия Ctrl+Alt+Del J) выйти из игры – нажать Quit или Esc на стартовом экране. Поэтому немного поменяем условие в главном цикле:

 

Until KeyHit(1)

 

на :

 

Until Quit

 

Quit – будет нашей переменной, которая будет показывать, что на этом шаге игра выходит…

Сначала создадим её (в самом начале программы есь-сно, где мы задаём остальные глобальные переменные):

 

Global Quit=False

 

False будет обозначать, что, типа, игра не выходит ещё…

 

И сделаем некоторые изменения в функции UpdateStartScreen()

 

Case 2

 End

 

поменяем на:

 

Case 2

 Quit=True

 

И добавим ещё условие:

 

If KeyDown(1) Quit=True

 

Так, вот уже почти всё, осталось только сделать сам экран Геймовера, о котором мы тут столько говорим J

В главный цикл вставляем строчки Select`овского условия:

 

Case 6

 

 Cls

 Flip

 Cls

 SetFont fontB

 Color 255,0,0

 Text 320,240,"Game Over",True,True

 Flip

 Delay 1000

 FlushKeys

 GameScr = 0

 

Здесь у нас описан экран Геймовера: Что здесь и как – объясняю по порядку:

 

Сначала очищаем первую поверхность, флипим, очищаем вторую, устанавливаем шрифт, цвет и пишем Гейм Овер, опять флипим, ждём одну секунду (1000 миллисекунд) командой FlushKeys очищаем список всех нажатых клавиш (если была нажата Esc игра выйдет, дойдя до условия в функции UpdateStartScreen()), и меняем переменную GameScr на 0… вот экран Гейм Овера и готов… J.

 

На этом можно и закончить – мы сделали хоть и примитивную, но всё-таки полноценную игру!!! Практически можно поздравить вас, что вы всё-таки заставили себя дочитать это до конца, ну и себя самого, за то что этот кошмар под названием «писать туториал» позади J. Я постарался показать (хотя бы мельком) все аспекты программирования игры. Кстати, они не очень сильно отличаются от более «серьёзных» проектов, в которых просто больше элементов. Так что вы теперь готовы к писанию своих игрушек!!!

 

Вот весь код нашей получившейся в итоге игры:

 

SeedRnd MilliSecs()

 

Global GameScr=0

Global Quit=False

 

Type Walls

 Field model

End Type

 

Const TypePlayer=1,TypeWalls=2,TypeTarget=3

 

Global Speed#=.1,Score=0

 

Global Player

Global Target

Global cam

Global lit

 

Graphics3D 640,480,16,1

SetBuffer BackBuffer()

 

Global fontB=LoadFont("Verdana",72)

Global FontM=LoadFont("Verdana",32)

 

;*******************

;Main Cycle

;*******************

 

Repeat

 

 Select GameScr

 Case 0

 

 UpdateStartScreen()

 

 Case 6

 

 Cls

 Flip

 Cls

 SetFont fontB

 Color 255,0,0

 Text 320,240,"Game Over",True,True

 Flip

 Delay 1000

 FlushKeys

 GameScr = 0

 

 Case 9

 

 UpdateGame()

 

 End Select

 

 Flip

 

Until Quit

 

End

 

;*******************

;Functions

;*******************

 

Function CreateWalls(tn)

 

 For i=0 To tn

  w.Walls = New Walls

  w\model=CreateCube()

  Repeat 

   PositionEntity w\model,Rnd(-40,40),0,Rnd(-40,40)

  Until Abs(EntityX(w\model))>10 Or Abs(EntityZ(w\model))>10

  EntityType w\model, TypeWalls

  EntityColor w\model,255,0,0

 Next

 

 w.Walls = New Walls

  w\model=CreateCube()

  EntityColor w\model,100,20,0

  EntityType w\model,TypeWalls

 PositionEntity w\model,-50,0,0

  FitMesh w\model,-1,-1,-50,2,3,100

 

 w.Walls = New Walls

  w\model=CreateCube()

  EntityColor w\model,100,20,0

  EntityType w\model,TypeWalls

 PositionEntity w\model,50,0,0

  FitMesh w\model,-1,-1,-50,2,3,100

 

 w.Walls = New Walls

  w\model=CreateCube()

  EntityColor w\model,100,20,0

  EntityType w\model,TypeWalls

 PositionEntity w\model,0,0,-50

  FitMesh w\model,-50,-1,-1,100,3,2

 

 w.Walls = New Walls

  w\model=CreateCube()

  EntityColor w\model,100,20,0

  EntityType w\model,TypeWalls

 PositionEntity w\model,0,0,50

  FitMesh w\model,-50,-1,-1,100,3,2

 

End Function

 

Function PositionTarget()

 

 Repeat

  inter=False

  PositionEntity Target,Rnd(-40,40),0,Rnd(-40,40)

  For w.Walls = Each Walls

   If MeshesIntersect(Target, w\model) inter=True

  Next

 Until inter=False

 

End Function

 

Function CreatePlayer()

 

 Player=CreateSphere()

 

 Plac=CreateCone(8)

 RotateMesh Plac,-90,0,0

 ScaleMesh Plac,1,1,1.2

 PositionMesh Plac,0,0,-1.5

 AddMesh Plac,Player

 EntityType Player, TypePlayer

 EntityColor Player,0,255,0

 

 FreeEntity Plac

 

End Function

 

Function CreateTarget()

 

 Target=CreateCylinder()

 PositionTarget()

 EntityColor Target,255,215,0

 

 EntityType Target,TypeTarget

 

End Function

 

Function CreateEnv()

 

 cam=CreateCamera()

 PositionEntity cam,0,40,0

 TurnEntity cam,90,0,0

 

 lit=CreateLight()

 TurnEntity lit,70,70,0

 

End Function

 

Function UpdateGame()

 

 MoveEntity Player,0,0,Speed#

 If KeyDown(203) TurnEntity Player,0,3,0

 If KeyDown(205) TurnEntity Player,0,-3,0

 

 PointEntity cam,Player

 

 If EntityCollided (Player,TypeTarget)

  PositionTarget()

  UpdateWorld

  Score=Score+1

  Speed=Speed+.01

 EndIf

 

 If EntityCollided (Player,TypeWalls) Or KeyDown(1)

  GameScr=6

  FreeGame()

 EndIf

 

 

 UpdateWorld

 RenderWorld

 

 Color 255,215,0

 Text 320,10,"Score : "+Score,True,True

 

End Function

 

Function UpdateStartScreen()

 

 tShift=0

 If RectsOverlap(MouseX(),MouseY(),2,2,320-50,240-12,100,32) tShift=1

 If RectsOverlap(MouseX(),MouseY(),2,2,320-50,280-12,100,32) tShift=2

 

 Cls

 SetFont FontB

 Color 255,0,0

 Text 320,150,"First Game",True,True

 SetFont FontM

 If tShift=1 Color 0,255,0 Else Color 255,0,0

 Text 320,240, "Start",True,True

 If tShift=2 Color 0,255,0 Else Color 255,0,0

 Text 320,280, "Quit",True,True

 

 Color 250,200,0

 Text MouseX(),MouseY(),"*",True,True

 

 If MouseHit(1)

  Select tShift

  Case 1

   CreatePlayer()

   CreateWalls(29)

   CreateTarget()

   CreateEnv()

  

   Collisions TypePlayer,TypeWalls,2,2

   Collisions TypePlayer,TypeTarget,2,2

 

   GameScr=9

  Case 2

   Quit=True

  End Select

 EndIf

 If KeyHit(1) Quit=True

 

End Function

 

Function FreeGame()

 

ClearCollisions

 

 FreeEntity cam

 FreeEntity lit

 FreeEntity Player

 FreeEntity Target

 

 For w.Walls=Each Walls

  FreeEntity w\model

  Delete w

 Next

 

 Speed#=.1

 Score=0

 

End Function

 

 

 

 Оглавление:

 

0.  Введение

1.  В начале была Тьма

2.  Есть ли жизнь в DirectX

3.  Свобода и Власть 3Д (0)

4.  Свобода и Власть 3Д (1)

5.  2Д в 3Д

6.  Трёхмерный курсор

7.  Родительская зависимость или Привязки

8.  Фишки с привязками

9.  Коллизион Детекшн или как устроен мир…

10.     Первая 3Д игра. Часть 0 – основы движка

11.     Первая 3Д игра. Часть 1 – разработка движка

12.     Первая 3Д игра. Часть 2 – устранение багов

13.     Первая 3Д игра. Часть 3 – внешний вид

14.     Первая 3Д игра. Часть 4 – от массива к спискам

15.     Первая 3Д игра. Часть 5 – оптимизация кода

16.     Первая 3Д игра. Часть 6 – завершение

17.     Выведение

 

 

 

 

Используются технологии uCoz