14 мая 2010 в 20:12
Blitz3d уроки 15. Оптимизация кода
Но это ещё не всё… Дальше мы возьмём готовые куски blitzbasicа, и создадим из них функции…
Для начала предлагаю сделать функцию, создающую кубики. Назовём её, например, CreateWalls(tn), в скобки которой будем указывать, сколько кубиков нам надо создать! (Вот для чего нам нужны были списки
Функции (как вы помните) нужно вставлять в конце blitzbasicа, после команды End. Как мы её сделаем? Да просто вырежем весь кусок blitzbasicа, в котором мы создаём кубики и стены, и засунем в функцию (поменяв заодно цифру 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
… а вместо него напишем:
CreateWalls(29)
Дальше предлагаю создать функцию для того, чтобы ставить цилиндр в случайное место и заодно проверять его – вырежем то, что у нас в главном цикле, где цилиндр устанавливается в случайное место, и проверяется его пересечение с кубиками:
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
Ну а вместо этого куска blitzbasicа вставим вызов этой функции – т.е. так:
If EntityCollided (Player,TypeTarget) PositionTarget() UpdateWorld Score=Score+1 Speed=Speed+.01 EndIf
Заодно, заменим строчку в самом начале, когда мы создаём цилиндр:
PositionEntity Target,Rnd(-40,40),0,Rnd(-40,40) …на: PositionTarget()
(а то я забыл в самом начале указать проверку на пересечение с кубиками, и получалось так, что в самом начале цилиндр мог находиться наполовину в кубе)
Так продолжим нашу вырезательную деятельность…
Теперь засунем в функцию команды создания игрока
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), и сделаем из них… правильно Функцию! А как вы догадались?
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
Обратите внимание на то, как удаляются списки. Сначала удаляются все объекты, занимающие память, а потом указатель на элемент списка… ну, понятно, короче
И заодно вызовем эту функцию как раз перед командой End. (ну это надеюсь сами сделаете)
Вот так выглядит наш blitzbasic после оптимизации, (или офункциации):
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
комментарии отсутствуют
авторизуйтесь