15. Первая 3Д игра. Часть 5 – оптимизация кода
Но
это ещё не всё… Дальше мы возьмём готовые куски кода, и создадим из них
функции… (вот где всё самое клёвое-то начинается J!!!)
Для
начала предлагаю сделать функцию, создающую кубики. Назовём её, например, CreateWalls(tn), в скобки которой будем указывать, сколько кубиков нам
надо создать! (Вот для чего нам нужны были списки J)…
Функции
(как вы помните) нужно вставлять в конце кода, после команды End. Как мы её сделаем? Да просто вырежем весь кусок кода,
в котором мы создаём кубики и стены, и засунем в функцию (поменяв заодно
цифру 29 на tn – переменную, в которой будет
содержаться число, введённое в функцию):
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
|
Ну а
вместо этого куска кода вставим вызов этой функции – т.е. так:
If
EntityCollided (Player,TypeTarget)
PositionTarget()
UpdateWorld
Score=Score+1
Speed=Speed+.01
EndIf
|
Заодно,
заменим строчку в самом начале, когда мы создаём цилиндр:
PositionEntity
Target,Rnd(-40,40),0,Rnd(-40,40)
|
…на:
(а
то я забыл в самом начале указать проверку на пересечение с кубиками, и
получалось так, что в самом начале цилиндр мог находиться наполовину в кубе J)
Так
продолжим нашу вырезательную деятельность…
Теперь
засунем в функцию команды создания игрока
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
|
А
наверху у нас останется:
Global Player
CreatePlayer()
|
Также
сделаем функцию для создания цилиндра
Function CreateTarget()
Target=CreateCylinder()
PositionTarget()
EntityColor Target,255,215,0
EntityType Target,TypeTarget
End
Function
|
Ну,
а наверху, мы напишем…
Global
Target
CreateTarget()
|
Не
забудьте обозначить переменную Target как Global – иначе
функция не «увидит» её…
И
функцию для создания камеры и света
Function CreateEnv()
cam=CreateCamera()
PositionEntity cam,0,40,0
TurnEntity cam,90,0,0
lit=CreateLight()
TurnEntity lit,70,70,0
End
Function
|
Ну,
и наверху, не забыв обозначить переменные cam и lit как Global, напишем
Global
cam
Global
lit
CreateEnv()
|
Теперь,
возьмём все команды в главном цикле (кроме команды Flip), и сделаем из них… правильно Функцию! А как вы
догадались? J…
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)
End
UpdateWorld
RenderWorld
Color 255,215,0
Text 320,10,"Score
: "+Score,True,True
End Function
|
И
весь главный цикл у нас будет представлять:
Repeat
UpdateGame()
Flip
Until
KeyHit(1)
|
А команды
инициализации после некоторой оптимизации и расставления по местам будут
выглядеть так:
SeedRnd
MilliSecs()
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()
CreatePlayer()
CreateWalls(29)
CreateTarget()
CreateEnv()
Collisions TypePlayer,TypeWalls,2,2
Collisions TypePlayer,TypeTarget,2,2
|
И последнюю
функцию мы создадим сами. Она будет очистит из памяти все объекты которые мы
тут создавали…
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
|
Обратите
внимание на то, как удаляются списки. Сначала удаляются все объекты,
занимающие память, а потом указатель на элемент списка… ну, понятно, короче J…
И заодно
вызовем эту функцию как раз перед командой End. (ну это надеюсь сами сделаете)
Вот
так выглядит наш код после оптимизации, (или офункциации J):
SeedRnd
MilliSecs()
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()
CreatePlayer()
CreateWalls(29)
CreateTarget()
CreateEnv()
Collisions TypePlayer,TypeWalls,2,2
Collisions TypePlayer,TypeTarget,2,2
;*******************
;Main Cycle
;*******************
Repeat
UpdateGame()
Flip
Until
KeyHit(1)
FreeGame()
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)
End
UpdateWorld
RenderWorld
Color 255,215,0
Text 320,10,"Score
: "+Score,True,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. Выведение
|