Озираемся и бегаем
Так-с-с : на поверхность посмотрели – пора двигаться дальше. Будем учить игрока двигаться:
;обновление игрока
Function update_user()
End Function
Так получается, что к глазам игрока (камере) и его ногам (сфере) будут обращаться вне функции создания игрока. А значит надо сделать хендлы камеры и сферы глобальными. Для этого подготовим для их хранения глобальные переменные:
Global user
Global camera
Теперь это уже не локальные переменные функции create_user, а глобальные всей программы.
Игрока мы будем обновлять на каждой итерации главного цикла, поэтому сразу допишем вызов соответствующей функции:
;инициализация графики
Graphics3D 800,600,32
SetBuffer BackBuffer()
Global user
Global camera
;создание игрока
Function create_user(x#=0,y#=1,z#=0)
user=CreateSphere()
camera=CreateCamera(user)
PositionEntity camera,0,1,-0.5
PositionEntity user,x#,y#,z#
End Function
;обновление игрока
Function update_user()
End Function
;создание игрового мира
Function create_world()
terrain=CreatePlane()
tertex=LoadTexture("terrain1.jpg")
EntityTexture terrain,tertex
FreeTexture tertex
create_user()
End Function
;функции закончились :)
;--------------------------------
create_world()
;MAIN LOOP
While Not KeyHit(1)=1
update_user()
RenderWorld()
Flip
Wend
;----------------------------
End
Так… перейдём к программированию движений: для удобства объявим в нашей функции переменную, отвечающую за смещения по осям (никто не мешает вам сделать разную скорость для движения вперёд, назад и шагов влево-вправо)
и кодируем движения нашей сферки (напомню: на ней укреплена камера)
If KeyDown(203)=1 *Then MoveEntity user,-V#,0,0
If KeyDown(205)=1 *Then MoveEntity user,V#,0,0
If KeyDown(200)=1 *Then MoveEntity user,0,0,+V#
If KeyDown(208)=1 *Then MoveEntity user,0,0,-V#
Запустим… результат, конечно зависит от производительности вашей машины, но, думаю, он не будет сильно разнится: при движении земля жутко мельтишит под ногами, так что невозможно даже оценить – в какую сторону мы сейчас двигаемся. Для устранения этого надо или понизить коэффициент скорости, или (что мы и сделаем ) растянуть текстурку:
tertex=LoadTexture("terrain1.jpg")
ScaleTexture tertex,10,10;вот тута новое
EntityTexture terrain,tertex
мир по-прежнему имеет весьма сомнительный вид, но уже лучше, чем было :grins
Теперь займёмся обзорами местности.
Будем вращать камеру вверх-вниз в зависимости от смещения мыши по Y-оси и влево-вправо от смещения по X-оси.
Угу: как же ну смотрю я вправо… ещё вправо… опа: курсор упёрся в правый край экрана и всё :sungl . Значит после оценки изменений мы должны вернуть мышь на исходную – самое логичное, в центр экрана. Получить текущий размер экрана в пикселях по X и по Y можно функциями
GraphicsWidth()
GraphicsHeight()
соответственно. Т.е. задвинуть мышь в центр экрана:
MoveMouse GraphicsWidth()*0.5,GraphicsHeight()*0.5
А снять перемещение мыши – измерив её скорость по осям:
MouseYSpeed()
MouseXSpeed()
Но вот ещё загвоздка: если мы будем крутить только камеру, то получается: мы развернули камеру влево и нажали кнопку ВПЕРЁД, но наша опора то как стояла, так и стоит неразвёрнутой – в результате смотрим вбок и прём вперёд, а надо бы идти, туда куда смотрим. С другой стороны вращать только основу мы не можем по схожей причине: Уставились мы в небо и нажали ВПЕРЁД и наша основа полетела тоже в небо (даже если мы включим гравитацию, эффект останется – модуль скорости будет равен проекции вектора скорости на поверхность т.е. если мы задерём голову вверх – cos(90)=0 и мы не сможем двигаться).
TurnEntity camera,MouseYSpeed(),0,0
TurnEntity user,0,-MouseXSpeed(),0
т.е. после доработок:
Function update_user()
V#=0.5
TurnEntity camera,MouseYSpeed(),0,0
TurnEntity user,0,-MouseXSpeed(),0
If KeyDown(203)=1 *Then MoveEntity user,-V#,0,0
If KeyDown(205)=1 *Then MoveEntity user,V#,0,0
If KeyDown(200)=1 *Then MoveEntity user,0,0,+V#
If KeyDown(208)=1 *Then MoveEntity user,0,0,-V#
MoveMouse GraphicsWidth()*0.5,GraphicsHeight()*0.5
End Function
Ндя… :o неприятный осадок всё же остался: как это можно так задрать голову, что увидеть происходящее за спиной и ниже и сделать 360 градусный проворт головы?!
Модифим – теперь камера не будет превышать указанный нами угол вверх и вниз:
Function update_user()
V#=0.5
u#=70;предельный угол
TurnEntity camera,MouseYSpeed(),0,0
TurnEntity user,0,-MouseXSpeed(),0
If KeyDown(203)=1 *Then MoveEntity user,-V#,0,0
If KeyDown(205)=1 *Then MoveEntity user,V#,0,0
If KeyDown(200)=1 *Then MoveEntity user,0,0,+V#
If KeyDown(208)=1 *Then MoveEntity user,0,0,-V#
MoveMouse GraphicsWidth()*0.5,GraphicsHeight()*0.5
If Abs(EntityPitch#(camera))>u# RotateEntity camera,u#*Sgn(EntityPitch#(camera)),0,0
End Function
ABS-модуль
EntityPitch# ( entity[,global] ) – угол вращения в плоскости Y0Z, т.е. вокруг оси X
SGN – функция-знак
Если что не понятно - ставим курсор на функцию и кликаем 2 раза F1.
;инициализация графики
Graphics3D 800,600,32
SetBuffer BackBuffer()
Global user
Global camera
;создание игрока
Function create_user(x#=0,y#=1,z#=0)
user=CreateSphere()
camera=CreateCamera(user)
PositionEntity camera,0,1,-0.5
PositionEntity user,x#,y#,z#
End Function
;обновление игрока
Function update_user()
V#=0.5
u#=70;предельный угол
TurnEntity camera,MouseYSpeed(),0,0
TurnEntity user,0,-MouseXSpeed(),0
If KeyDown(203)=1 *Then MoveEntity user,-V#,0,0
If KeyDown(205)=1 *Then MoveEntity user,V#,0,0
If KeyDown(200)=1 *Then MoveEntity user,0,0,+V#
If KeyDown(208)=1 *Then MoveEntity user,0,0,-V#
MoveMouse GraphicsWidth()*0.5,GraphicsHeight()*0.5
If Abs(EntityPitch#(camera))>u# RotateEntity camera,u#*Sgn(EntityPitch#(camera)),0,0
End Function
;создание игрового мира
Function create_world()
terrain=CreatePlane()
tertex=LoadTexture("terrain1.jpg")
ScaleTexture tertex,10,10
EntityTexture terrain,tertex
FreeTexture tertex
create_user()
End Function
;функции закончились :)
;--------------------------------
create_world()
;MAIN LOOP
While Not KeyHit(1)=1
update_user()
RenderWorld()
Flip
Wend
;----------------------------
End