Итак, мы уже достаточно вооружены, чтобы сделать простенькую игру, так что хватит абстрактных примеров, а начнём уже делать игры, а то, что мы ещё не изучили, узнаем в самом процессе, по мере надобности…

Что это будет за игра? Сделаем такой вариант игры, которую делали в основах по BlitzBasic`у, только трёхмерный. Там у нас будет шарик, который будет ездить по плоскости, собирать, допустим, жёлтые кубики, и умирать от столкновения с красными… короче, сюжет стандартный…

Начнём с того, что создадим шарик игрока и его управление… (ну и камеру со светом):

SeedRnd MilliSecs() 

Graphics3D 640,480,16,1

SetBuffer BackBuffer()

Global Player=CreateSphere()

cam=CreateCamera()

PositionEntity cam,0,60,0

TurnEntity cam,90,0,0

lit=CreateLight()

TurnEntity lit,70,70,0

Repeat

	If KeyDown(200) MoveEntity Player,0,0,.2
	
	If KeyDown(208) MoveEntity Player,0,0,-.2
	
	If KeyDown(203) TurnEntity Player,0,3,0
	
	If KeyDown(205) TurnEntity Player,0,-3,0
	
	UpdateWorld
	
	RenderWorld
	
	Flip

Until KeyHit(1)

End

Итак, всё просто – есть шарик, который ездит где-то внизу и поворачивается… вот только одно меня здесь смущает – не понятно, куда этот шарик повёрнут – он везде круглый, не видно, где перед, где … гм… это… зад. У меня вот такое решение этого вопроса – что если сделать у него такой мини хвост – как у капли или метеора? Т.е. здесь просто бы подошёл конус. Можно, конечно, сделать ещё один объект – как раз конус и просто сделать привязку к шару, но привязки полезны, когда нам нужно обязательно 2 различных объекта, а не один, или, например, если привязка через некоторое время должна пропасть… здесь же нам желателен объект, представляющий из себя цельный меш. Можно сделать модельку в 3ДМаксе, конечно, а потом её сюда загрузить, вот только зачем забивать лишнее дисковое пространство на модельки… которые мы сами можем сделать в самом Блитце! Как? Очень просто – присоединив к мешу шара меш конуса!

Вот как мы поступим (после создания шара):

Plac=CreateCone(8)

RotateMesh Plac,-90,0,0 

ScaleMesh Plac,1,1,1.2

PositionMesh Plac,0,0,-1.5

Здесь мы создаём конус по имени Plac, вертим его там и по всякому подгоняем. Так как после создания шар будет стоять в точке 0,0,0 – конус будет ровно подогнан к нему – можете запустить и посмотреть… Вот только если вы будете этот шар двигать, конус останется на месте (естественно ). Итак, как я уже говорил, можно этот конус привязать (особой разницы не будет), но всё таки основываясь на программерскую этику, сделаем из них один объект (у нас есть возможность, да и зачем нам 2 объекта вместо одного).

добавляем:

AddMesh Plac,Player

Эта команда добавляет один меш к другому… то есть в данном случае мы добавляем меш конуса к мешу шара. НО! При этом сам объект конуса не исчезает (то есть мы этот конус как бы добавляем копированием). Короче, теперь у нас 2 меша – шар присоединённый к конусу, и сам конус, который нам сейчас не нужен. Поэтому (опять новая команда) мы его уберём:

FreeEntity Plac

Эта команда убирает заданный объект (в данном случае конус) и (самое главное) очищает от него память. Когда будете делать большие игры, где будет много уровней, при выходе из одного из них, не забывайте очищать ненужные объекты, иначе они будут копиться и занимать память, которая (L) не резиновая, в результате всё будет тормозить после определённого времени «играния»…

Дальше… не будет же этот шарик просто так ездить по полю! Надо создать ему определенные препятствия. Создадим-ка мы кубики, и разбросаем их по нашему будущему полю:

Dim Walls(29)

For i=0 To 29
	
	Walls(i)=CreateCube()
	
	PositionEntity Walls(i),Rnd(-50,50),0,Rnd(-50,50)

Next

Здесь мы, как вы видите, создаём массив на 30 элементов, и затем расставляем в них кубики. А сами кубики раскидываем в случайном порядке по полю.

Так… кубики есть… столкновения нету… вывод: надо вставить сюда наш коллизион детекшн, который мы так старательно изучали в прошлой главе!

Поехали:

Сначала мы должны определить 2 константы для наших объектов – для шарика и для кубиков:

Const TypePlayer=1,TypeWalls=2

Вставьте эту строчку после инициализации графики – т.е. в начало… так типы есть, осталось только указать что шар и кубики к ним принадлежат:

EntityType Player, TypePlayer

Эту строчку поставьте после создания самого объекта шарика- т.е. после присоединения к нему конуса…

EntityType Walls(i), TypeWalls

А эту вставьте в конец цикла создания кубиков (После команды PositionEntity Walls(i)…)

Так, типы задали, конечно, но сталкиваться они всё равно не будут – пока мы прямо не укажем, что они, мол, сталкиваться должны.

Collisions TypePlayer,TypeWalls,2,2

Здесь мы задали, что TypePlayer – который у нас является шаром должен сталкиваться с TypeWalls – т.е. с кубиками, соприкасаясь методом сфера к полигону, полностью скользя по нему. Можно последнюю цифру заменить на 1 – тогда шарик будет как бы «прилипать» к кубикам. Эту строчку поставьте после создания всех кубиков…

Хочу сразу заметить: (из своего опыта) команды Collisions нужно ставить одной из последних – т.е. сначала нужно инициализировать все предметы, затем их все расставить по местам, и только ПОТОМ обозначать коллизии между ними… можно, конечно сразу задать константы, и все столкновения между этими константами, но потом, когда вы будете создавать объекты, помните, что создаются-то они все в одной точке – 0,0,0 и получается, что находятся друг в друге, и затем, когда мы будем их расставлять, могут появиться баги – т.е. мы скажем объекту, типа, «Поставься в точку 0,10,100», а он окажется в точке 0,8,70 (или типа того), и можно долго ругаться, вспоминая его материнские отношения … либо в таком случае нужно делать так: создавать объекты, и тут же их переставлять в новые места… но, по-моему то как я предложил – лучше!!! (Scaven никогда не обманывает!)

Так, теперь можно со спокойной душой всё это дело запустить… да нет, не в производство - рановато пока…

Но уже что-то вырисовывается!

По традиции – полный код всего этого безобразия:

SeedRnd MilliSecs() 

Graphics3D 640,480,16,1

SetBuffer BackBuffer()

Const TypePlayer=1,TypeWalls=2

Global 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


FreeEntity Plac

Dim Walls(29)


For i=0 To 29

	Walls(i)=CreateCube()
	
	PositionEntity Walls(i),Rnd(-40,40),0,Rnd(-40,40)
	
	EntityType Walls(i), TypeWalls

Next


cam=CreateCamera()

PositionEntity cam,0,60,0

TurnEntity cam,90,0,0

 

lit=CreateLight()

TurnEntity lit,70,70,0

Collisions TypePlayer,TypeWalls,2,2

Repeat

	If KeyDown(200) MoveEntity Player,0,0,.2
	
	If KeyDown(208) MoveEntity Player,0,0,-.2
	
	If KeyDown(203) TurnEntity Player,0,3,0
	
	If KeyDown(205) TurnEntity Player,0,-3,0
	
	UpdateWorld
	
	RenderWorld
	
	
	Flip


Until KeyHit(1)

End