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

 

Итак, движок разработан, что ещё делать программисту? Улучшать внешний вид! Всё таки игрок будет смотреть и оценивать игру «извне» - т.е. по тому, как она выглядит, и играется, а не по тому, каким образом там реализована проверка на столкновения J… Поэтому нельзя недооценивать некоторые мелочи, которые могут приукрасить вашу игру… что можно сделать сначала? Ну, во первых, я предлагаю всё разукрасить! (а то чёрно-белое всё как-то примитивно смотрится…) Делать-то для этого много не надо, а всё равно смотреться будет круче!

 

Так, сначала разукрасим игрока зелёным (поставьте эту строчку после создания игрока):

 

EntityColor Player,0,255,0

 

…затем кубики красным (эту строчку нужно вставить в цикл создания кубиков):

 

EntityColor Walls(i),255,0,0

 

…и, наконец, закрасим цилиндр жёлтым…

 

EntityColor Target,255,215,0

 

Во, теперь куда красочнее всё смотрится! Красный, жёлтый, зелёный… CGA, блин… А? Что такое CGA спрашиваете?.. да – так, молодость вспомнил… нет, это не светофор J

 

Если хотите, конечно, можете подставить свои цвета. Как выбрать себе цвет? Самый лёгкий способ – зайдите в PaintBrush, затем в меню Палитра->Изменить Палитру, и нажмите на кнопочку «Определить цвет», там такой спектр вылезет, и снизу цифры. Те что слева – как раз те, которые нужны J!

 

Во-вторых. Есть такие мелочи, которые очень сильно улучшают внешний вид игры… это какой-нибудь вид, дополнительный выбор или ещё что-нибудь, что не очень сложно реализовать, но при этом сильно изменяет игру в лучшую сторону… Например, в моём проекте про Катапульту это была способность «следить» за снарядом…

 

Так вот, сейчас предлагаю внести 2 изменения, во-первых камеру при её создании поставить чуть пониже, строчку

 

PositionEntity cam,0,60,0

 

заменить на

 

PositionEntity cam,0,40,0

 

И вставить такую ма-а-аленькую строчку кода в главный цикл игры, которая правда, покажет, что игра всё-таки трёхмерная:

 

PointEntity cam,Player

 

Догадались, что она будет делать? Она будет следить за нашим шариком, находясь в одной точке над серединой! Это немного ухудшит вид, зато смотреться сама игра будет в 2 раза круче J… вот так какая-то строчка может сильно повлиять на целую игру!

 

Вот, вроде как и оформили чуть-чуть.. ладно я тут ещё хотел кое-что добавить – стены, которые будут ограничивать область самой игры (а то раньше забыл добавить, а сейчас как бы и место как раз есть J).

 

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

 

Но, для этого нам надо добавить ещё 4 элемента массива, поэтому:

 

Dim Walls(29)

 

заменим на:

 

Dim Walls(33)

 

Дальше создадим 4 кубика, которые у нас скоро станут стенами:

 

For i=30 To 33

 Walls(i)=CreateCube()

 EntityColor Walls(i),100,20,0

 EntityType Walls(i),TypeWalls

Next

 

Здесь мы создаём ещё 4 кубика, меняем цвет и задаём тип столкновения… ну, понятно, короче J

 

Теперь расставим их по местам, где они будут стоять:

 

PositionEntity Walls(30),-50,0,0

PositionEntity Walls(31),50,0,0

PositionEntity Walls(32),0,0,-50

PositionEntity Walls(33),0,0,50

 

Но, кубики-то так кубиками и останутся, поэтому мы должны их расширить! Можно использовать команду ScaleEntity, но здесь я предлагаю использовать новую команду – FitMesh!

 

Синтакс: FitMesh объект, x, y, z, ширина, высота, длина – эта команда так трансформирует объект, и перемещает его вертексы, что он занимает ровно отведённый куб, задаваемый этими параметрами… очень полезная команда! Позволяет вам задать именно такой размер для модели, какой вы хотите, независимо от того, какой размер модели был до этого… J!

Так, вот для примера, возьмём Walls(30) – который находится слева от нашего игрока (в начале, во всяком случае J), что нам надо с ним сделать? Пусть в ширине будет 2, в высоту он будет от –1 до 2 (т.е. выше всех остальных наших объектов), и в длину – на всё поле + ещё немножко (т.к. кубики у нас расставляются от –40 до 40 – т.е. на дистанции 80, сделаем размер поля равным 100…) – т.е. от –50 до 50.

 

Значит мы пишем: FitMesh –1,-1,-50,2,3,100 – не забудьте, что последние 3 цифры – не координаты, а размеры!

А для Walls(33) – который находится спереди, нам надо сделать ширину от –50 до 50, длину от –1 до 2, а длину  от –1 до 1!

И для неё мы пишем: FitMesh –50,-1,-1,100,3,2

 

Так по аналогии все команды:

 

FitMesh Walls(30),-1,-1,-50,2,3,100

FitMesh Walls(31),-1,-1,-50,2,3,100

FitMesh Walls(32),-50,-1,-1,100,3,2

FitMesh Walls(33),-50,-1,-1,100,3,2

 

Вот, вроде внешний вид и приведён в норму… на выставку она может не попрёт, но для первой игры очень даже неплохо! Зато я знаю что ваша вторая (ну не вторая, так третья!) – точно будет намного красочнее и интереснее! (Главное не забудьте мне прислать мне демку или ссылку на скриншоты J!)

 

Весь код:

 

SeedRnd MilliSecs()

 

Graphics3D 640,480,16,1

SetBuffer BackBuffer()

 

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

Global Speed#=.1,Score=0

 

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

EntityColor Player,0,255,0

 

FreeEntity Plac

 

 

Dim Walls(33)

 

For i=0 To 29

 Walls(i)=CreateCube()

 Repeat 

  PositionEntity Walls(i),Rnd(-40,40),0,Rnd(-40,40)

 Until Abs(EntityX(Walls(i)))>10 Or Abs(EntityZ(Walls(i)))>10

 EntityType Walls(i), TypeWalls

 EntityColor Walls(i),255,0,0

Next

 

For i=30 To 33

 Walls(i)=CreateCube()

 EntityColor Walls(i),100,20,0

 EntityType Walls(i),TypeWalls

Next

PositionEntity Walls(30),-50,0,0

 FitMesh Walls(30),-1,-1,-50,2,3,100

PositionEntity Walls(31),50,0,0

 FitMesh Walls(31),-1,-1,-50,2,3,100

PositionEntity Walls(32),0,0,-50

 FitMesh Walls(32),-50,-1,-1,100,3,2

PositionEntity Walls(33),0,0,50

 FitMesh Walls(33),-50,-1,-1,100,3,2

 

 

Target=CreateCylinder()

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

EntityColor Target,255,215,0

 

EntityType Target,TypeTarget

 

cam=CreateCamera()

PositionEntity cam,0,40,0

TurnEntity cam,90,0,0

 

lit=CreateLight()

TurnEntity lit,70,70,0

 

Collisions TypePlayer,TypeWalls,2,2

Collisions TypePlayer,TypeTarget,2,2

 

Repeat

 

 

 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)

  Repeat

   inter=False

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

   For i=0 To 29

    If MeshesIntersect(Target, Walls(i)) inter=True

   Next

  Until inter=False

  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

 

 Flip

 

Until KeyHit(1)

 

End

 

 

 Оглавление:

 

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