Урок 3: Управление камерой В этом уроке мы сделаем управление камерой Шаг 1: WSAD Первое, что мы должны сделать - изменить наш главный цикл, что в файле init.lua. Он должен выглядеть так: scn = elf.LoadScene("level1.pak") while elf.Run() == true do end Для чего же нужна переменная scn, находящаяся перед elf.LoadScene? Мы не использовали ее в предыдущих уроках! Да, она не требовалась в предыдущих уроках. Функция elf.LoadScene возвратит в эту переменную дескриптор загруженного уровня, и мы сможет обращаться к нему по этой переменной. Теперь мы должны сделать таким же способом активную камеру: scn = elf.LoadScene("level1.pak") cam = elf.GetSceneActiveCamera(scn) while elf.Run() == true do end Как видите, мы можем передавать переменную scn в функцию elf.GetSceneActiveCamera для активации камеры именно на этой сцене. Теперь у нас есть камера, заключенная в переменную cam, что же дальше? а дальше мы должны прописать код для чтения с клавиатуры нажатых клавиш. давайте проделаем это для кнопки W, которую мы будем использовать для передвижения камеры вперед. scn = elf.LoadScene("level1.pak") cam = elf.GetSceneActiveCamera(scn) while elf.Run() == true do if elf.GetKeyState(elf.KEY_W) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, -12.0) end end elf.GetKeyState возвращает состояние клавиши. в нашем случае elf.KEY_W указывает на клавишу W. эта функция может возвращать следующие значения: elf.UP - кнопка не нажата elf.PRESSED - кнопка была нажата и отпущена elf.DOWN - кнопка нажата и не отпущена elf.RELEASED - кнопка была отпущена У нас появилась функция elf.MoveActorLocal, которая сдвигает камеру. эта функция так же может быть применена для любого игрового объекта. Слово Local в имени функции означает, что мы передвигаем объект в его координатных осях (локальных), а не в осях сцены (глобальных). Для смещения объекта в глобальнх осях используется функиця elf.MoveActor. Числа, являющиеся аргументами этой функции - координаты смещения объекта за единицу времени. Тогда почему в аргументе мы указали изменение координаты по оси Z, а камера двигается вперед? Потому что направление осей объектов отличается от направления осей уровня. по идее Z будет смещать объект вперед, Y вверх, а X вправо/влево. советую это запомнить, дабы не допустить ошибок в дальнейшем так же не стоит забывать, что для elf.MoveActor смещение уже будет по глобальным игровым осям. Попробуйте теперь протестировать игру. Если камера не движется, поищите ошибку в логе или консольном окне. Теперь давайте допишем нашу программу для управления кнопками A,S,D. Код будет аналогичным: elf.LoadScene("level1.pak") cam = elf.GetSceneActiveCamera(scn) while elf.Run() == true do if elf.GetKeyState(elf.KEY_W) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, -12.0) end if elf.GetKeyState(elf.KEY_S) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, 12.0) end if elf.GetKeyState(elf.KEY_A) == elf.DOWN then elf.MoveActorLocal(cam, -12.0, 0.0, 0.0) end if elf.GetKeyState(elf.KEY_D) == elf.DOWN then elf.MoveActorLocal(cam, 12.0, 0.0, 0.0) end end Опять же, вы можете протестировать игру. Шаг 2: Управление с помощью мышки Теперь давайте научим камеру реагировать на мышку. Курсор должен будет все время находиться в игровом окне, но его видно быть не должно. Скроем его функцией elf.HideMouse, аргументом которой будет TRUE. Но ведь теперь мы не можем закрыть игровое окно нажатием крестика! Значит, нужно добавить код выхода из игры нажатием клавиши Esc. Вы, конечно же, можете закрывать игру нажатием функциональной клавиши F10, но все же... итак, вот наш код: elf.HideMouse(true) scn = elf.LoadScene("level1.pak") cam = elf.GetSceneActiveCamera(scn) while elf.Run() == true do if elf.GetKeyState(elf.KEY_W) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, -12.0) end if elf.GetKeyState(elf.KEY_S) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, 12.0) end if elf.GetKeyState(elf.KEY_A) == elf.DOWN then elf.MoveActorLocal(cam, -12.0, 0.0, 0.0) end if elf.GetKeyState(elf.KEY_D) == elf.DOWN then elf.MoveActorLocal(cam, 12.0, 0.0, 0.0) end if elf.GetKeyState(elf.KEY_ESC) == elf.PRESSED then elf.Quit() end end Запустите и проверьте. Если при нажатии ESC игра не закрывается, то ее можно выключить комбинаций ALT+F4 или просто нажатием F10. Теперь давайте заставим камеру реагировать на повороты мышки. Для этого нам нужно знать разницу, между начальным углом поворота камеры и углом, после остановки мышки, когда вы ее переместите. В этом нам поможет функция elf.GetMouseForce. Присвоим ее значение переменной mf и допишем код поворота камеры при передвижении мышки: elf.HideMouse(true) elf.LoadScene("level1.pak") while elf.Run() == true do cam = elf.GetSceneActiveCamera(scn) if elf.GetKeyState(elf.KEY_W) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, -12.0) end if elf.GetKeyState(elf.KEY_S) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, 12.0) end if elf.GetKeyState(elf.KEY_A) == elf.DOWN then elf.MoveActorLocal(cam, -12.0, 0.0, 0.0) end if elf.GetKeyState(elf.KEY_D) == elf.DOWN then elf.MoveActorLocal(cam, 12.0, 0.0, 0.0) end mf = elf.GetMouseForce() elf.RotateActor(cam, 0.0, 0.0, -mf.x*10.0) elf.RotateActorLocal(cam, -mf.y*10.0, 0.0, 0.0) if elf.GetKeyState(elf.KEY_ESC) == elf.PRESSED then elf.Quit() end end У мышки и 3D пространства отличается система координат, поэтому в функицях поворота мы используем отрицательное значение mf. Функция elf.RotateActor(cam, 0.0, 0.0, -mf.x*10.0) здесь отвечает за поворот камеры по оси Y относительно самой камеры. Соответственно, elf.RotateActorLocal(cam, -mf.y*10.0, 0.0, 0.0) - за поворот по X, опять же, относительно камеры, это очень важно. Так же стоит заметить, что в движке BlendELF все операции с поворотами объектов используют градусы, а не радианы, что тоже очень важно. Наконец, можно запустить игру. Вы можете летать по уровню и оглядываться мышкой, очень неплохая основа для шутера от первого лица
Источник: КЛИК» |