23 февраля 2010 в 14:34
Blitz3d уроки 11. Первая 3Д игра– разработка движка
Я не спорю, ездить шариком по плоскости, лавируя между кубиков, в созданной вами программе конечно очень захватывающе… но боюсь другие люди (не вы… – да, да существуют ещё и другие!) скажут что это, конечно, круто, но Quake им нравится больше… правильно, они ничего не понимают в искусстве! Вот только таких людей подавляющее большинство, да и сами игры обычно создаются для других людей (за редким исключением), а этим варварам нужно что? Стимул, блин – ну не нравится им просто спокойно ездить по полю! Хорошо, мы им такое сейчас устроим!
Начнём со стимула! Помните, в змейке кажется для этого использовали такой квадратик, который надо было собирать… используем этот примитивный метод.
Для начала добавим для него отдельную константу – вот так:
Const TypePlayer=1,TypeWalls=2,TypeTarget=3
Дальше создадим сам объект… на этот раз у нас будет цилиндр, и укажем его тип:
Target=CreateCylinder() EntityType Target,TypeTarget
Ну, и добавим коллизион детекшн для кучи:
Collisions TypePlayer,TypeTarget,2,2
Ок, вроде основу инициализировали…
Дальше сделаем так, чтобы цилиндр перемещался в другое место при столкновении с шаром. Как это сделать? Естественно – условием внутри главного цикла (вы хоть помните такой?):
If EntityCollided (Player,TypeTarget) PositionEntity Target,Rnd(-40,40),0,Rnd(-40,40)
Новая команда? Точно! Вы наверное уже поняли что это? Да – это и есть проверка на соприкосновение: Пишется так EntityCollided (Объект, тип с которым он соприкасается) – итак, эта команда возвращает нам True, если заданный в скобках объект соприкасается с заданным типом. Т.е. в данном случае – шар соприкасается с типом цилиндра (TypeTarget). Перед использованием этой команды нужно обязательно указать этот тип коллизии командой Collisions, а иначе она работать не будет!
Так, теперь уже ездить можно не бесцельно, а гоняясь за цилиндром.
Но, опять же – слишком миролюбиво… нам нужен Гейм Овер!!! Как его реализовать? Очень просто – когда шар будет сталкиваться с кубиками – тогда и будет конец игры!
Следующее условие:
If EntityCollided (Player,TypeWalls) End
Здесь мы пишем, что когда шар сталкивается с типом кубиков, игра заканчивается… она просто выходит… грубо, конечно, но мы всё это потом исправим, я вам обещаю! …правда исправим!!! Да я вас вообще когда-нибудь обманывал?.. …Когда??!
Пойдём дальше… игрок начинает подумывать о том, что ему хочется выйти тогда, когда игра даёт ему шанс расслабиться – то есть проиграв или просто затормозив где-нибудь, у игрока начинает происходить процесс анализа происходящего. К чему это я? А, да – внимание игрока должно быть сосредоточено на игре – т.е. шарик должен всё время быть в движении, что бы у центрального процессора человека под названием «мозг» даже не появлялось мысли о кнопке Esc, НО и двигаться быстро он тоже не должен – если человек будет проигрывать сразу после нажатия кнопки Старт – тоже будет не очень хорошо…
Теперь нам нужна постоянная скорость, и, естественно, стрелки управления – вперёд-назад теперь нам будут не нужны (если игрок будет передвигаться с постоянной скоростью), поэтому строчки:
If KeyDown(200) MoveEntity Player,0,0,.2 If KeyDown(208) MoveEntity Player,0,0,-.2
…можно заменить на:
MoveEntity Player,0,0,.2
Так… уже что-то, во что можно ПОИГРАТЬ, во всяком случае уже интереснее… но поиграв какое-то время (минут 10) можно натренироваться так, что пальцы уже сами будут нажимать на стрелки, и обходить препятствия используя уже один спинной мозг , и опять же центральный процессор головного мозга будет посылать сигналы о том, что, типа, не пора бы выйти?.. поэтому требуется усложнять игру. Как это сделать? О, в голову приходят всякие извращённые мысли о том, что можно сделать с игроком, но, думаю, лучше всего просто так увеличивать скорость после каждого собранного цилиндра… заодно ещё и будем записывать очки игрока!
Для этого нам потребуется указать новые переменные (эту строчку нужно вставить где-нить в начале, допустим, после констант…):
Global Speed#=.1,Score=0
Здесь у нас Speed# (не забудьте, что когда вы собираетесь использовать дробные числа, вы должны использовать # после названия переменных, а то у вас ничего не получится) – скорость, и Score – очки
Теперь, скорость должна увеличиваться после столкновения с цилиндром, поэтому простое условие:
If EntityCollided (Player,TypeTarget) PositionEntity Target,Rnd(-40,40),0,Rnd(-40,40)
…заменим на:
If EntityCollided (Player,TypeTarget) PositionEntity Target,Rnd(-40,40),0,Rnd(-40,40) Score=Score+1 Speed=Speed+.01 EndIf
Т.е. здесь мы при условии, что шар сталкивается с Типом цилиндра, выполняются три действия – цилиндр перемещается в новое место, переменная Score увеличивается на 1, и переменная Speed увеличивается на 0.1… вот только скорость-то от этого не меняется, поэтому строчку перемещения самого игрока в цикле:
MoveEntity Player,0,0,.2
…заменим на:
MoveEntity Player,0,0,Speed#
Что-то изменилось? Видите – теперь игрок передвигается не просто со скоростью 0.2, а со значением переменной Speed#, которое изменяется…
Ну, вот так намного интереснее – теперь это уже может, хоть и с натягом, но называться игрой…! В это даже самому можно поиграть, чем я сейчас и займусь… после того, как покажу, как писать на экране количество очков игрока…
Итак новая команда:
Text 320,10,"Score : "+Score,True,True
Синтакс: Text x, y, текст, центрирование по х, центрирование по у – эта команда схожа с командой Print, только предназначена для графического режима…
Эта команда 2-х мерная, т.е. рисуется поверх экрана… запомните, 2-х мерные команды типа рисования линий, картинок, текста нужно ставить между командами RenderWorld и Flip, иначе вы их не увидите!!!
Ну всё кажется самая глючная из ваших игр готова… да… глючная, а всё же игра!!! Но все глюки мы постараемся убрать в следующей части.
Весь код:
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 Target=CreateCylinder() PositionEntity Target,Rnd(-40,40),0,Rnd(-40,40) EntityType Target,TypeTarget cam=CreateCamera() PositionEntity cam,0,60,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 If EntityCollided (Player,TypeTarget) PositionEntity Target,Rnd(-40,40),0,Rnd(-40,40) Score=Score+1 Speed=Speed+.01 EndIf If EntityCollided (Player,TypeWalls) End UpdateWorld RenderWorld Text 320,10,"Score : "+Score,True,True Flip Until KeyHit(1) End
комментарии отсутствуют
авторизуйтесь