Урок 8 - Игровая камера
В этом уроке я опишу, как сделать игровую камеру, т. е. камера, управляемая при помощи мышки и клавиатуры.
Можно будет смотреть во все стороны и передвигаться.
Разбираем код программы:
В раздел Var заносим переменные:
MouseMove1: boolean; TempX1,TempY1,SingX,SingY,TempX2,TempY2 : integer; Point: Tpoint; Camera: TCamera;В процедуре FormPaint:
try if MouseMove1=false then begin GetCursorPos(Point); TempX1:=point.X; TempY1:=point.Y; MouseMove1:=true; end; finally SetCursorPos(screen.Width div 2,screen.Height div 2); //Центруем курсор GetCursorPos(Point) ; //получаем координаты и записываем их в переменную Point if MouseMove1=true then begin TempX2:=point.X; TempY2:=point.Y; SingX:=TempX1-TempX2; SingY:=TempY1-TempY2; if (Camera.phiY<=90) and (Camera.phiY>=-90) then begin Camera.phiY:=Camera.phiY+(-SingY/8); end else begin if Camera.phiY>=90 then //Ограничения Camera.phiY:=90; //На if Camera.phiY<=-90 then //Угол обзора Camera.phiY:=-90; //По вертикали end; Camera.phiX:=Camera.phiX+(-SingX/4); TempX1:=0; TempY1:=0; TempX2:=0; TempY2:=0; SingX:=0; SingY:=0; MouseMove1:=false; end; end;Конструкция try finally здесь обязательна т.к. сначала надо получить координаты курсора и только после этого позволить ему сместится и опять засечь его координаты.
Переменные TempX1 и TempY1 – координаты до смещения.
Переменные TempX2 и TempY2 – координаты после смещения.
Переменные SingX и SingY – разница между предыдущими и новыми координатами.
Для работы кода необходимо создать 2 составных типа переменных:
type TVector = record //Вектор X,Y,Z:GLfloat; end; TCamera = record Pos: Tvector; //Позиция камеры PhiY: single; //вертикальный улол поворота камеры PhiX: single; //горизонтальный Speed: glFloat; //Скорость камеры end;Коэффициенты смещения по горизонтали и вертикали делятся на 4 и 8 – это чувствительность мыши.
Мы будем поворачивать и двигать не камеру а МИР вокруг камеры. Самыми простыми функциями glRotatef и glTranslatef
ВАЖНО: Эти функции нужно вызывать в особом порядке!!!
Сначала повернем мир по вертикале, а потом по горизонтали и совершим перемещение.
glRotatef(-Camera.PhiY-90,1,0,0); //поворот по вертикали glRotatef(-Camera.PhiX,0,0,1); //поворот по горизонтали glTranslatef(-Camera.Pos.X,-Camera.Pos.Y,-Camera.Pos.Z); //смешение мираЭто нужно делать до отрисовки сцены, позиции источников света тоже надо задавать после. Теперь надо сделать обработку клавиатуры.
В раздел Const:
VK_W = $57; VK_S = $53; VK_D = $44; VK_A = $41; VK_SHIFT = $10; VK_SPACE = $20;В процедуре FormPaint после обработки мыши:
if (GetAsyncKeyState(VK_W)<>0) or (GetAsyncKeyState(VK_S)<>0) or (GetAsyncKeyState(VK_D)<>0) or (GetAsyncKeyState(VK_A)<>0) then begin Camera.Speed:=0.005; if (GetAsyncKeyState(VK_W)<>0) then begin Camera.Pos.X:=Camera.Pos.X+Camera.Speed*cos((Camera.phiX+90)*Pi/180); Camera.Pos.Y:=Camera.Pos.Y+Camera.Speed*sin((Camera.phiX+90)*Pi/180); end; //Назад if (GetAsyncKeyState(VK_S)<>0) then begin Camera.Pos.X:=Camera.Pos.X+Camera.Speed*cos((Camera.phiX-90)*Pi/180); Camera.Pos.Y:=Camera.Pos.Y+Camera.Speed*sin((Camera.phiX-90)*Pi/180); end; //Вправо if (GetAsyncKeyState(VK_D)<>0) then begin Camera.Pos.X:=Camera.Pos.X+Camera.Speed*cos((Camera.phiX)*Pi/180); Camera.Pos.Y:=Camera.Pos.Y+Camera.Speed*sin((Camera.phiX)*Pi/180); end; //Влево if (GetAsyncKeyState(VK_A)<>0) then begin Camera.Pos.X:=Camera.Pos.X+Camera.Speed*cos((Camera.phiX+180)*Pi/180); Camera.Pos.Y:=Camera.Pos.Y+Camera.Speed*sin((Camera.phiX+180)*Pi/180); end; end; //Вниз if (GetAsyncKeyState(VK_SHIFT)<>0) then Camera.Pos.Z:=Camera.Pos.Z-0.005; //Вверх if (GetAsyncKeyState(VK_SPACE)<>0) then Camera.Pos.Z:=Camera.Pos.Z+0.005;Функция GetAsyncKeyState(индекс) отслеживает нажатия клавиш в системе независимо статуса активности приложения.
Управление:
W – Вперёд
S – Назад
A – Влево
D – Вправо
Shift – Вниз
Space – Вверх
И нарисуем сцену:
glBindTexture(GL_TEXTURE_2D,Glass); RenderBox; //куб glBindTexture(GL_TEXTURE_2D,Eart); glBegin(GL_QUADS); glNormal(0.5,0.5,1); glTexCoord(0,1); glVertex3f(-10,10,-1.1); glTexCoord(1,1); glVertex3f(10,10,-1.1); glTexCoord(1,0); glVertex3f(10,-10,-1.1); glTexCoord(0,0); glVertex3f(-10,-10,-1.1); glEnd;В этом примере появилась новая функция задания перспективы:
gluPerspective(Угол обзора, ClientWidth/ClientHeight,ближайшая точка, дальняя точка);
Осталось только сделать в ObjectIspector параметр Form1.BorderStyle = none и WindowState = maximize. Всё простенькая игра готова.
Добавил(а): oktavius | Дата: 2012-11-21 | |
А как загрузить карту с 3dMax?
|
Добавил(а): Klesh | Дата: 2012-11-21 | |
Окей, в ближайшее время будет опубликован урок по экспорту модели в формате 3DS из 3ds max.
|
Добавил(а): oktavius | Дата: 2012-11-22 | |
Отлично буду очень рад)
|
Добавил(а): juzhnij | Дата: 2013-05-20 | |
У меня возникла проблема с которой я никак не могу справиться - когда я разворачиваюсь в виртуальном пространстве все текстуры начинают просвечиваться насквозь, мне набо накладывать на те же координаты текстуры в обратную сторону или есть проще решение?
|
Добавил(а): juzhnij | Дата: 2013-05-20 | |
Ну и плюс к этому в движении иногда текстура на текстуру в какой то части накладывается, как будто они по многу раз за кадр прорисовываются.
|
Добавил(а): juzhnij | Дата: 2013-05-22 | |
Спасибо за неучастие, проблему решил самостоятельно.
|
Добавил(а): evgen8195 | Дата: 2014-05-12 | |
Вопрос: как сделать так чтобы отображался и двигался(!) курсор мыши?
|
No results found.