[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 3
  • 1
  • 2
  • 3
  • »
Форум Panda3D - по русски » Общий форум » Проекты » Демо игра "Танки" (типа физ движок)
Демо игра "Танки"
LunarДата: Понедельник, 26.07.2010, 10:56 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 18
Награды: 0
Репутация: 0
Статус: Offline
Всем привет.
Чисто ради изучения движка, пытаюсь сделать игру типа "Танки онлайн" http://tankionline.com/ru/ (пока без онлайна :)).
После прочтения описания ODE на форуме, решил что для онлайн игры физику надо в минимуме писать самому, для одинакового расчета на разных машинах.
То что у меня получилось во вложении.
Вот собственно и вопрос:
Как сделать так, что-бы танк на наклонной поверхности разворачивал корпус параллельно этой плоскости но естественно учитывал угол H (направление движения).
Попытка начала решения есть но, танк по разному наклоняется в зависимости от его вектора движения. По одной поверхности танк нормально подымается, на другую носом роет... smile
Прикрепления: exit.zip (225.4 Kb)
 
ninthДата: Понедельник, 26.07.2010, 12:27 | Сообщение # 2
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Для начала, лучше перейди от работы с углами к работе с векторами, раз уж связался с самописной физикой ) Похоже, что проблемы в том, как в панде считаются углы (-180;180) а не (0;360)
А так, чуть позже более подробно гляну.
 
ninthДата: Понедельник, 26.07.2010, 12:41 | Сообщение # 3
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Собственно суть в том, что тебе надо расположить корпус танка в некоторой плоскости так чтобы он был максимально параллельно поверхности, но дело в том, что в одной плоскости гарантированно будут лежать только три точки (а не четыре как у тебя), так что основная задача найти эти три точки, после этого строится перпендикуляр к найденной плоскости и в соответствии с этим располагается твой танк.
 
LunarДата: Понедельник, 26.07.2010, 17:03 | Сообщение # 4
Рядовой
Группа: Пользователи
Сообщений: 18
Награды: 0
Репутация: 0
Статус: Offline
ninth,
Ну физика это я громко сказал, легкая имитация...
Маленькое уточнение. Четыре сферы отвечают только за коллизию с препятствиями. По Z я двигаю танк только с помощью луча CollisionRay, через него вычисляю Z и через него же вычисляю нормаль, которая выдается в радианах, перевожу в градусы и поворачиваю танк по углам P и R (строки 316-329). Но тут видимо можно как-то повернуть и по H но с учетом поворота танка... Я сделал еще один луч позади танка... Получается что надо сделать три луча?


Сообщение отредактировал Lunar - Понедельник, 26.07.2010, 18:41
 
ninthДата: Вторник, 27.07.2010, 08:50 | Сообщение # 5
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Мда... посмотрел более внимательно ) Пока всё не зашло слишком далеко, советую пересмотреть подход к структуризации кода - вынеси танк в отдельный класс хотя бы )

Первое, что следует сделать - это работать не с моделью танка, а с пустым узлом, на который навешивать уже модель и всё остальное т.к. при смене масштаба или ориентации модели вероятно придётся корректировать ещё пачку переменных, а если ты будешь работать (вращать, перемещать и т.д.) с пустым узлом единичного масштаба, то на то как сделана модель будет глубоко фиолетово.
Второе, если на танке не планируется анимации (имеется ввиду скелетная или вершинная), то использовать Actor не нужно - грузи как обычную модель
Третье - теги не предназначены для хранения постоянно обновляемых переменных. Одно преобразование из строк в значения с плавающей запятой и обратно чего стоят, обычно такие переменные хранят как свойства класса.
Четвёртое - не стоит использовать try except до финального варианта - это глушит другие ошибки, я так понимаю, ты сделал это для обхода проблемы с пустым списком entries? Тогда сделай if entries: т.к. пустой список == False

К вопросу ориентации - попробуй так:
n = entries[0].getInto().getNormal()
q = Quat()
q.setFromAxisAngle(self.a,n)
self.tank.setQuat(q)
здесь self.a - это переменная - угол поворота танка. Естественно, в другом месте он тогда уже не должен поворачиваться, т.е. setH() у тебя не должно быть задействовано.

 
LunarДата: Вторник, 27.07.2010, 11:10 | Сообщение # 6
Рядовой
Группа: Пользователи
Сообщений: 18
Награды: 0
Репутация: 0
Статус: Offline
ninth,
Спасибо! Про класс пока не думал, решил только набросать, потом раскидывать по классам... такой подход к разработке у меня когда ничего изначально не известно про приложение, а запустить побыстрее хочется :). С пустым узлом это дело хорошее, переделаю. Про Actor отдельное спасибо, а то все время ругался что танк не чарактер. Теги использовал как самый быстрый вариант разработки в данном случае (опять же для теста), try except дело такое как-то сразу появился потом не стал изменять, но предложение твое возьму на вооружение :). И самое главное - ориентация то что я и хотел... щас засяду буду пробовать...
 
LunarДата: Вторник, 27.07.2010, 12:57 | Сообщение # 7
Рядовой
Группа: Пользователи
Сообщений: 18
Награды: 0
Репутация: 0
Статус: Offline
Ну в общем я сделал поворот как ты рекомендовал остальное не правил...
Правда добавил некоторые дебаг сообщения в окне, сферы азимутов и ограничил диапазон угла по H до 360 градусов.
Танк стал пытаться повторять поверхность но что-то не очень правдиво у него выходит :). Посмотришь на досуге?

Добавлено (27.07.2010, 12:52)
---------------------------------------------
Опытным путем выяснил, что если от текущего угла P танка отнимать 15 градусов то на наклонной плоскости танк поворачивается с корректным повторением наклона... но по прямой поверхности естественно заваливается вперед на теже 15 градусов.. откуда эта погрешность вылазит не могу понять...

Code

n = entries[0].getInto().getNormal()
q = Quat()
q.setFromAxisAngle(self.a,n)
self.tank.setQuat(q)
self.tank.setP(self.tank, -15)

Добавлено (27.07.2010, 12:57)
---------------------------------------------
нашел... надо делать так

Code

n = entries[0].getInto().getNormal()
q = Quat()
q.setFromAxisAngle(self.a,n)
self.tank.setQuat(q)
self.tank.setP(self.tank, -angleP)

где -angleP это угол наклона плоскости P по которой ездим... уфф вроде заработало... теперь надо все привести в порядок. Спасибо ninth за алгоритм, очень признателен

Выяснил один интересный факт кому может пригодится, такой код тормозит очень сильно (выполняется в обработчике taskMgr)

Code

ang=(self.hprTank.getHpr()-self.hprPole.getHpr())
ttt=u"Полигон: H=%.2f, P=%.2f, R=%.2f\nТанк: H=%.2f, P=%.2f, R=%.2f\nРазница: %s\nq=%s"%(angleH,angleP,angleR,self.tank.getH(),self.tank.getP(),self.tank.getR(),ang,q)
self.textObject.setText(ttt)
Прикрепления: exit_001.zip (244.3 Kb)


Сообщение отредактировал Lunar - Вторник, 27.07.2010, 13:14
 
ninthДата: Вторник, 27.07.2010, 14:13 | Сообщение # 8
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Насчёт onscreentext - это официально в мануале сказано, что он тяжёлый т.к. каждый раз текст рендерится... можно попробовать перегнать текст в родной формат, но не уверен, что сильно поможет.

Ещё можно устанавливать tank.lookAt(tank.getPos()+normal), только тогда ориентацию осей надо менять - поворот по R, а движение по У

 
LunarДата: Вторник, 27.07.2010, 14:59 | Сообщение # 9
Рядовой
Группа: Пользователи
Сообщений: 18
Награды: 0
Репутация: 0
Статус: Offline
Спасибо за советы.
Но пока меня так устраивает как ты посоветовал в начале, надо только плавности добавить и сойдет :).
Перепишу это все более культурно и выложу

Добавлено (27.07.2010, 14:59)
---------------------------------------------
Кстати а посоветуй как сделать так что-бы над моделью (танком) текст располагать, ну типа ник водителя танка.

 
ninthДата: Вторник, 27.07.2010, 15:39 | Сообщение # 10
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
если хочешь просто как спрайт - можешь посмотреть в сторону billboard
если на экране, то нужно делать проекцию танка в экранные координаты
 
LunarДата: Среда, 28.07.2010, 11:27 | Сообщение # 11
Рядовой
Группа: Пользователи
Сообщений: 18
Награды: 0
Репутация: 0
Статус: Offline
Вот что на данный момент получилось
Разбил предварительно на классы, добавил класс бота пустой без физики и логики но с шарами ля коллизий и лучом.
Вопрос по поводу
Quote (ninth)
Первое, что следует сделать - это работать не с моделью танка, а с пустым узлом, на который навешивать уже модель и всё остальное т.к. при смене масштаба или ориентации модели вероятно придётся корректировать ещё пачку переменных, а если ты будешь работать (вращать, перемещать и т.д.) с пустым узлом единичного масштаба, то на то как сделана модель будет глубоко фиолетово.

А собственно коллизии привязывать к пустому узлу или все таки к танку. Можно по подробнее, кстати что-то приаттачить один узел к другому у меня не получается, тупо снимаю координаты и позиционирую.
Можешь подробнее рассказать или отправить к примеру? Вроде-бы тут был пример с пандой... но там только движение было. Не сочти за труд.
Прикрепления: exit_002.zip (260.7 Kb)
 
ninthДата: Среда, 28.07.2010, 12:46 | Сообщение # 12
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Коллизии лучше привязывать тоже к узлу. Суть в том, что чайлды повторяют масштаб, позицию и ориентацию родителей и только после этого применяют свою. К примеру, тебе моделер сделал мега танк, но развернул его задом наперёд или вообще боком, так что тебе приходится программно менять поворот танка... и код, отвечающий за движение т.к. теперь у тебя перед не по оси +Х а по оси -Х или вообще по У. А если ты не в том масштабе сделал, то ещё и скорость перемещения придётся корректировать. Пустой же узел всегда имеет один и тот же масштаб и поворот, а прилепленный к нему танк ты можешь вертеть как угодно - хоть на башню поставить и всё равно он будет двигаться за этим "узлом".

привязка осуществляется с помощью my_node_path.reparentTo(my_other_nodepath), да-да render тоже является всего лишь узлом сцены.

Code

mdl1 = loader.loadModel("smiley")
mdl2 = loader.loadModel("smiley")
mdl2.reparentTo(mdl1)
mdl1.reparentTo(render)
mdl2.setX(10)
mdl1.setZ(20)
 
LunarДата: Среда, 28.07.2010, 14:56 | Сообщение # 13
Рядовой
Группа: Пользователи
Сообщений: 18
Награды: 0
Репутация: 0
Статус: Offline
Ну вот раскидал все на классы, привязал танки к пустым нодам.
Что скажеш. На твоих советах уже нормальная тема получается.
А теперь о непонятном - как сделать коллизии между танками, маякни куда копать если не трудно.
Прикрепления: exit_003.zip (253.8 Kb)
 
ninthДата: Среда, 28.07.2010, 15:41 | Сообщение # 14
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
код позже гляну, коллизии между объектами это setIntoBitMask и setFromBitMask. into - в объект можно врезаться, from - объект сам может врезаться
http://panda3d.org.ru/publ/1-1-0-29
 
LunarДата: Среда, 28.07.2010, 19:09 | Сообщение # 15
Рядовой
Группа: Пользователи
Сообщений: 18
Награды: 0
Репутация: 0
Статус: Offline
В общем вот что за сегодня получилось. Танки как тараканы бегают по карте. своим танком их можно толкать, но они сами не толкаются между собой.
Если кто-то объяснит до конца как это сделать буду счастлив, а то уже мозг сломал не могу допереть какую им маску ставить.
И еще из-за просчета колизий, сильно падает FPS смотрел через pstats.exe, тоже нужна помощь а то на нетбуке падает с 150 fps до 16-24.
Но вообще я доволен smile
Прикрепления: exit_004.zip (254.7 Kb)
 
Форум Panda3D - по русски » Общий форум » Проекты » Демо игра "Танки" (типа физ движок)
  • Страница 1 из 3
  • 1
  • 2
  • 3
  • »
Поиск: