Управление камерой
|
|
ninth | Дата: Среда, 04.02.2009, 14:59 | Сообщение # 1 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Написал небольшой скелет для управления камерой в нефпсных играх. По правой кнопке осуществляется вращение камеры. Колёсиком приближение и отдаление
|
|
| |
ninth | Дата: Среда, 04.02.2009, 15:11 | Сообщение # 2 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Вот пример использования, переделанный из Hellow World Code # -*- coding: utf_8 -*- import direct.directbase.DirectStart from pandac.PandaModules import * from direct.task import Task from direct.actor import Actor from direct.interval.IntervalGlobal import * from CameraHandler import CameraHandler
#загрузка модели окружения environ = loader.loadModel("models/environment") environ.reparentTo(render) environ.setScale(0.25,0.25,0.25) environ.setPos(-8,42,0)
#загрузка моддели и проигрывание анимации pandaActor = Actor.Actor("models/panda-model",{"walk":"models/panda-walk4"}) pandaActor.setScale(0.005,0.005,0.005) pandaActor.reparentTo(render) pandaActor.loop("walk")
#создаём четыре интервала pandaPosInterval1= pandaActor.posInterval(13,Point3(0,-10,0), startPos=Point3(0,10,0)) pandaPosInterval2= pandaActor.posInterval(13,Point3(0,10,0), startPos=Point3(0,-10,0)) pandaHprInterval1= pandaActor.hprInterval(3,Point3(180,0,0), startHpr=Point3(0,0,0)) pandaHprInterval2= pandaActor.hprInterval(3,Point3(0,0,0), startHpr=Point3(180,0,0))
#создаём из интервалов последовательность и проигрываем её pandaPace = Sequence(pandaPosInterval1, pandaHprInterval1, pandaPosInterval2, pandaHprInterval2, name = "pandaPace") pandaPace.loop()
CameraHandler() run()
|
|
| |
ninth | Дата: Среда, 04.02.2009, 20:46 | Сообщение # 3 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Доработал код. Теперь при подведении к краю экрана камера перемещается - а-ля камера в стратегиях
|
|
| |
3dmax | Дата: Четверг, 05.02.2009, 00:41 | Сообщение # 4 |
Генерал-майор
Группа: Проверенные
Сообщений: 334
Награды: 0
Репутация: 1
Статус: Offline
| ну вправо, влево перемещаеться, а вот вверх вниз, получаеться зум типа вперед- назад. А я вот хочу сделать камеру от 3-лица, но пока оч слаб в питоне
|
|
| |
ninth | Дата: Четверг, 05.02.2009, 07:23 | Сообщение # 5 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Это кажется, что зум - подними камеру повыше - по умолчанию она почти над землёй, поэтому получается, что она движется вперёд-назад. Правой кнопкой хватаешь и крутишь камеру, как повыше поднимешь, попробуй. Если будет время - набросаю скелет для перемещения кубика с камерой от третьего лица
|
|
| |
ninth | Дата: Четверг, 05.02.2009, 10:26 | Сообщение # 6 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Запостил тему с примером управления TPS
|
|
| |
3dmax | Дата: Понедельник, 09.02.2009, 02:39 | Сообщение # 7 |
Генерал-майор
Группа: Проверенные
Сообщений: 334
Награды: 0
Репутация: 1
Статус: Offline
| Хочу сделать чтобы камера всегда вращалась от 3-го лица а не при нажатии кнопки. на скок я понял вот это объявление метода (или как оно правильно называется) : self.accept("mouse3",self.startDrag) вызываеться вот этим созданием экземпляра (или как оно правильно называется) def startDrag(self): self.dragging=True но как заставить self.dragging=True работать постоянно не пойму. Извиняюсь за ламерские вопросы ,я ток учусь.
|
|
| |
ninth | Дата: Понедельник, 09.02.2009, 11:17 | Сообщение # 8 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Это, если тебе нужно именно управление камерой. Здесь мы в конце задачи помещаем курсор в центр экрана, и смещение для вращения камеры, соответственно считаем от центра, а не от той точки, где нажали клавишу. Регистацию нажатия можно закомментировать или удалить. Code def dragTask(self,task): if base.mouseWatcherNode.hasMouse(): self.dragging=True mpos = base.mouseWatcherNode.getMouse() if self.dragging: self.turnCameraAroundPoint((-mpos.getX())*100,(-mpos.getY())*100,self.target,self.camDist) else: moveY=False moveX=False if self.my>0.8: angleradiansX = base.camera.getH() * (math.pi / 180.0) aspect=(1-self.my-0.2)*5 moveY=True if self.my<-0.8: angleradiansX = base.camera.getH() * (math.pi / 180.0)+math.pi aspect=(1+self.my-0.2)*5 moveY=True if self.mx>0.8: angleradiansX2 = base.camera.getH() * (math.pi / 180.0)+math.pi*0.5 aspect2=(1-self.mx-0.2)*5 moveX=True if self.mx<-0.8: angleradiansX2 = base.camera.getH() * (math.pi / 180.0)-math.pi*0.5 aspect2=(1+self.mx-0.2)*5 moveX=True if moveY: self.target.setX(self.target.getX()+math.sin(angleradiansX)*aspect) self.target.setY(self.target.getY()-math.cos(angleradiansX)*aspect) self.turnCameraAroundPoint(0,0,self.target,self.camDist) if moveX: self.target.setX(self.target.getX()-math.sin(angleradiansX2)*aspect2) self.target.setY(self.target.getY()+math.cos(angleradiansX2)*aspect2) self.turnCameraAroundPoint(0,0,self.target,self.camDist) base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2) return task.cont Если ты хочешь что б поворотом мыши вращался актёр, то тут нужно по-другому - это работать с тем примером, который в соседней теме. Однако принцип тот же - считаем смещене от центра экрана, который в панде принят за 0:0, поворачиваем актёра и возвращаем курсор в центр
|
|
| |
3dmax | Дата: Понедельник, 09.02.2009, 12:13 | Сообщение # 9 |
Генерал-майор
Группа: Проверенные
Сообщений: 334
Награды: 0
Репутация: 1
Статус: Offline
| Ну для начала я хочу сделать хотя бы чтобы камера просто вращалась, так сказать все по порядку .
|
|
| |
ninth | Дата: Понедельник, 09.02.2009, 12:54 | Сообщение # 10 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Ну тогда замени dragTask тем, что я привёл выше. Но вообще у этих примеров разный принцип - здесь рассчитывается позиция на основе углов поворота, положения центральной точки и заданного расстояния до этой точки, а в соседнем примере - камера просто цепляется чайлдом актёра, поэтому её положение и перемещение зависит от положения актёра без каких-либо дополнительных рассчётов
|
|
| |
3dmax | Дата: Понедельник, 09.02.2009, 21:52 | Сообщение # 11 |
Генерал-майор
Группа: Проверенные
Сообщений: 334
Награды: 0
Репутация: 1
Статус: Offline
| Да все работает норм. А вот такую формулу сам придумал ? base.camera.setPos( dist*math.sin(angleradiansX)*math.cos(angleradiansY)+p.getX(), -dist*math.cos(angleradiansX)*math.cos(angleradiansY)+p.getY(), -dist*math.sin(angleradiansY)+p.getZ() )Добавлено (09.02.2009, 21:52) --------------------------------------------- А какой функцией скрывать курсор ? и еще вопрос как сделать чтобы камера продолжала вращаться когда курсор доходит до конца, чтобы он перепрыгивал на противоположную сторону. Я так понимаю нужно ему присваивать противоположные координаты ?
|
|
| |
ninth | Дата: Понедельник, 09.02.2009, 23:54 | Сообщение # 12 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Да, как вариант, умножать на (-1) - т.к. координаты экрана для панды от -1:-1 до 1:1 Для скрытия мыши попробуй так: Code props = WindowProperties() props.setCursorHidden(True) base.win.requestProperties(props)
|
|
| |
ninth | Дата: Вторник, 10.02.2009, 00:01 | Сообщение # 13 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Однако есть подводный камень - твой код может воспринять перемещение мыши на другую сторону не так как хотелось бы, т.е. он повернёт камеру в соотвтствии с этим
|
|
| |
3dmax | Дата: Вторник, 10.02.2009, 10:40 | Сообщение # 14 |
Генерал-майор
Группа: Проверенные
Сообщений: 334
Награды: 0
Репутация: 1
Статус: Offline
| вот попробовал такое if camHpr.getX() <85 : camHpr.setX(270) ниче не дало, цыфры меняються а курсор нет. Нужно непосредственно как то координату курсора менять
|
|
| |
ninth | Дата: Вторник, 10.02.2009, 11:50 | Сообщение # 15 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| ммм так я не понял чего ты хочешь? camHpr - это углы поворота камеры курсор мыши устанавливается base.win.movePointer(0, X, Y)
|
|
| |