воскресенье, 21 февраля 2010 г.

Управление Камерой



С того времени, когда я начал рассматривать Blender не как мощный инструмент 3D моделирования, а как среду программирования, меня интересовал вопрос управления в виртуальном мире.

В предыдущих постах я показывал, как решать совершенно не стандартные для Blender задачи.

Итак, хоть я скрытый злодей, помышляющий о том, как завоевать вселенную, она мне не нужна, как и власть и деньги, хотя без денег на «железо» и интернет не обойтись, мной больше двигают исследовательские цели. Ну, скажите, какой смысл от мира, если его нельзя пощупать и поизучать? На мой взгляд – никакого. Поэтому, создав виртуальный мир, мне стало интересно, а как же все-таки в него пустить меня, исследователя?

Решение простое и одно – надо писать скрипт и запустить его в Blendr. Скрипт управления камерой. Возиться самому мне в ту пору, естественно, не хотелось. Я только представил все эти аффинные преобразования да еще в трех мерном мире, мне сразу плохо стало. Другой математической модели управления камерой тогда я не видел. И перспектива возиться с матрицами меня, прямо скажу, очень сильно, тогда еще студента, угнетала. Но ведь к тому времени на Blender уже писались игры, а, значит, управление камерой было реализовано. Значит, задача сводится к нахождению удовлетворительного и, по возможности, универсального скрипта управления камерой. Несколько вариантов с преобразованиями матриц я отмел, как меня не устраивающие, и стал искать дальше.

Все же странно устроен человек, не представляя, как это можно сделать иначе, отметает варианты и ищет, уж поистине то, не знаю что. Но, самое интересное, в людском мире то, что это «не знаю что» находится. Удовлетворивший меня скрипт находится на www.tutorialforblender3D.com, но так же файл с этим же скриптом я выкладываю здесь. В тексте ничего не меняю, считаю, что не имею на это право. А вот здесь объясню механизм его работы.

Считается одной из самых сложных задач по обучению программирования – перевод текста программы на человеческий язык, то есть словами объяснить алгоритм работы Вашей программы. Лично я не люблю взять готовый скрипт и использовать его, не разобравшись в механизмах его работы, если, что-то не понял, то изучаю этот скрипт до дыр. Но для того, чтобы понять работу скрипта управления логикой, нужно понимать логику управления логическими блоками (считайте это каламбуром, а не тавтологией). Про работу логических блоков я объяснять не стану (в обозримом будущем выйдет моя статья по созданию игр в Blender, а повторяться, я не люблю – если возникнет необходимость что-то уточнить, можно задать вопрос и посмотреть на демонстративный файл).


На рисунке продемонстрированы все необходимые настройки логических блоков:

Сенсер одни – Mouse, он настроен на событие Movement, контроллер тоже одни, в нем находится наш скрипт, управления камерой. А вот актуаторов – 2: одни, LookLeftRight, отвечает за движения камеры по горизонтали, второй, LookUpDown, - по вертикали.

Условно я делю скрипт на две части: get и set части. В первой части мы объясняем скрипку откуда он берет исходные данные и что с ними делает, во второй части присваиваем полученные результаты – все как всегда просто:

# импортируем библиотекуt Rasterizer

import Rasterizer

# для удобства чтения скрипта вводим переменную, которой присваиваем текущий

# контроллер

controller = GameLogic.getCurrentController()

# назначаем переменную, к которой этот скрипт присоединяем

player = controller.getOwner()

# присваиваем переменной сенсор с именем Mouse

#здесь имеется ввиду то имя, которым Вы назвали сенсор в логических блоках

mouse = controller.getSensor("Mouse")

# вводим переменные, которым присваиваем наши актуаторы

lookLeftRight = controller.getActuator("LookLeftRight")

lookUpDown = controller.getActuator("LookUpDown")

В этом мы связали входящие данные и выходящие, на мой взгляд, именно эта связь является самой трудной для понимания: тут происходит основная связь скрипта с логикой самого файла – если скрипт универсальный, то файл надо подстраивать под этот скрипт, вот для это на и назначаются все переменные, но идем дальше.

# назначаем переменным ширину и высоту экрана, это надо для перемещения

width = Rasterizer.getWindowWidth()

height = Rasterizer.getWindowHeight()

# определяем mouse movement функцию

def mouseMove():

# определяем расстояние, пройденное от центра экрана

x = width/2 - mouse.getXPosition()

y = height/2 - mouse.getYPosition()

# инициализируем mouse если еще не сделали этого

if hasattr(player, 'mouseInit') == False:

x = 0

y = 0

# тут баг

# и вместо True. надоиспользовать 1

player.mouseInit = 1

# возвращаем передвижение мыши

return (x, y)

# присваиваем mouse значения, полученные функцией, их два X,Y

move = mouseMove()

# задаем чувствительность

sensitivity = 0.001

# Суммируем направление и чувствительность

#на самом деле умножаем, но оставил термин из комментария к скрипту

# move[0] – это перемещение мыши по X

# move[1] – это перемещение мыши по Y

leftRight = move[0] * sensitivity

upDown = move[1] * sensitivity

# устанавливаем, полученные значения в актуаторы

lookLeftRight.setDRot( 0.0, 0.0, leftRight, False)

lookUpDown.setDRot( upDown, 0.0, 0.0, True)

# используем, уже полученные актуаторы в нашем файле

GameLogic.addActiveActuator(lookLeftRight, True)

GameLogic.addActiveActuator(lookUpDown, True)

# размещаем mouse в центре экрана

Rasterizer.setMousePosition(width/2, height/2)


Вот и все – скрипт работает, можете проверять.

Это один из лучших скриптов для управления камерой при создании игр, у меня он лежит в качестве боевого скрипта.

Желаю Вам успехов.

Комментариев нет:

Отправить комментарий