XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Барахолка
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
NCrashed

offline
Опыт: 13,553
Активность:
Механика Ньютона
Эта наработка позволит вам создавать юниты, котырые подчиняются всем законам физики. Они будут скатываться с горы или в яму, отскакивать от земли и других тел не хуже чем в любых "knockback systems". Вы сможете создать реалистичные модели звездных систем и приделать к каждой планете несколько спутников. Все движение происходит в пространстве, так что можно легко сделать юнитов перепрыгивающих клиффы как в грядущем Starcraft II. Система полностью сделана без использования кеша, что позволяет ей работать на любой версии вара.
Достоинства системы:
  • Может являтся основой для других более сложных систем
  • Все движение происходит в пространстве
  • Отсутствие кеша и return-bug функций
  • В коде имеет описание к любой функции, и сами они отсортированы.
  • Множество параметров для своей тонкой настройки
  • Тела активно взаимодействуют с ландшафтом

Импорт:

  1. Установить JassNewGenPack (далее JNGP), который можно найти на сайте "http://XGM.ru" в разделе "утилиты". Проверьте чтобы в путях к карте и к редактору не было русских букв и, когда открываете первый раз карту или создаете ее, сохраняйте ее по 2 раза. Проверте, чтобы во вкалдках меню "Grimorie" стояла галка "Disable we syntax cheker" и в "JassHelper" стояла галка "Enable JassHelper".
  2. Скопировать папку "Библиотеки" к себе на карту.
  3. Для версии 5.5 есть GUI интерфейс. (В редакторе триггеров появится новая категория "Fisics Dinamik Library", там есть большинство функций +несколько функций к условиям, вроде GetLastCreatedBody,"Получить скорость" и.п.)
  4. Начиная с версии 6.5 система работает на cJass'е. Установите версию не ниже 1.4.
» Инструкция по установки GUI интерфейса
  1. Если у вас не установлено для редактора триггеров никаких своих надстроек, то качайте из аттача архив "ui", разархивируйте его в папку Warcraft'а III. Перезапустите JNGP.
  1. Если у вас установлены свои тригги:
    • В папке Warcraft'а ищите папку UI, открывайте файл "triggerdata.txt", теперь откройте тот же файл из архива в аттаче. Ищите в моем экземпляре:

TC_FDL="Fisics Dynamik Library",ReplaceableTextures\WorldEditUI\ObjectEditor-CustomDoodad
вставьте в свой файл туда же где нашли в моем, дальше ищите
// FDL Types
Body=0,1,1,"Body",integer
Вставьте туда же в свой файл, дальше ищите:

// /------------------------------------------\
// |          #begin FDL Functions         |
// \------------------------------------------/
Все функции от открывающей шапки до закрывающей скопируйте к себе, они должны быть перед строкой [TriggerCalls].
Дальше после этой строки ищите снова шапку (она рядом), копируйте к себе (после строки [TriggerCalls]), сохраняйтесь.
  • Открывайте файл "triggerstrings.txt", ищите первую шапку, копируйте к себе функции, до строки [TriggerCallStrings], ищите вторую шапку, снова копируйте к себе функции (не забыли что после строки [TriggerCallStrings]?), сохраняйте, перезагружайте JNGP.
  • Если при загрузке карты возникли ошибки с gui надстройкой, пишите в приват, прикладывайте эти 2 файла и я вам исправлю их.

Использование:

  1. Первый важный момент. Система добавляет новый объект "Body". Чтобы создать этот объект нужно
воспользоваться функцией:
call CreateBody(objecttype.create(),x,y,z, Юнит, масса тела), где objecttype интерфейс вашего объекта, о них ниже (можно взять стандартный тип icerock) 
или
call CreateBodySimple(objecttype.create(),Юнит) 
тогда тело создатся в месте где стоит юнит. Вот пример триггера, который создает тело при входе
юнита в регион:
function Trig_BodyUnitEnterRect_Actions takes nothing returns nothing
    globals
        Body b // объявление глобальной переменной
    endglobals
    set b = CreateBodySimple(GetEnteringUnit(), 100) // теперь в переменной b лежит "тело" юнита вошедшего в регион
endfunction

//===========================================================================
function InitTrig_BodyUnitEnterRect takes nothing returns nothing
    set gg_trg_BodyUnitEnterRect = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_BodyUnitEnterRect,  GetWorldBounds() )
    call TriggerAddAction( gg_trg_BodyUnitEnterRect, function Trig_BodyUnitEnterRect_Actions )
endfunction
  1. Теперь скажу о остальных функциях:
call b.Speed( vx , vy , vz) // ставит телу скорость по проекциям на оси
call b.AddSpeed( vx, vy, vz) // добавляет скорость телу

call b.AddG() // включает притяжение тела к земле
call b.AddCustomF(9.8) // тоже самое, но позволяет вам ставить свое "ускорение свободного падения" 

call b.Radius( r ) // теперь тело является шаром с радиусом  r, теперь оно будет сталкиваться с другими телами у которых тоже установлен радиус

call b.AddFriction( 0.4 ) // добавляет сухое трение с землей, берет коэффициент трения мю
call b.AddVFriction( 0.2 ) // добавляет вязкое трение с окружающей средой.

call b.AddAttractionForce( a ) // добавляет притяжение тела b к телу a
call b.StartCircleSimple( a, 0) // помогает запускать на орбиту спутники, где тело a - центр вокрук которого вращается тело, второй параметр крен оси
call b.StartCircle(x,y, Speed, at) // тело будет двигаться вокруг точки (x y) со скоростью Speed. at - ускорение, позволяющее двигаться по спирали
call b.SCanRun(true) // Позволяет юниту сопротивлятся движению
  1. Теперь еще важный момент: после того как вы задали параметры движения надо написать
call b.Start() 
и тело начнет движение, чтобы остановить его
call b.Stop()
а чтобы удалить
call RemoveBody( u ), где u юнит-основа
или
call b.Remove(false) - при true юнит-основа удалится
вот расширенный предыдущиц пример:
function Trig_BodyUnitEnterRect_Actions takes nothing returns nothing
    globals
        Body b // объявление глобальной переменной
    endglobals
    set b = CreateBodySimple(GetEnteringUnit(), 100) // теперь в переменной b лежит "тело" юнита вошедшего в регион
    call b.AddG()
    call b.Radius(50)
    call b.AddFriction(0.2)
    call b.SCanRun(true)
    call b.Speed(200,200,300)
    call b.Start() // В итоге югит подпрыгнет, пролетит по параболе и  медленно остановится
endfunction

//===========================================================================
function InitTrig_BodyUnitEnterRect takes nothing returns nothing
    set gg_trg_BodyUnitEnterRect = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_BodyUnitEnterRect,  gg_rct_BodyJump )
    call TriggerAddAction( gg_trg_BodyUnitEnterRect, function Trig_BodyUnitEnterRect_Actions )
endfunction

Использование интерфейсов

1.Нужно создать прототип объекта и занести его в PDLTypes или в другое удобное место. Вот шаблон:
interface BodyData {
        real m = 0 // Масса
        // Ускорение свободного падения
        real gx = 0 
        real gy = 0
        real gz = -Gravitational_acceleration
        
        real mu = 0 // Коэффициент сухого трения
        real k = 0 // Коэффициент вязкого трения
        real r = 0 // Радиус тела, нужно для столкновений
        real q = 0 // Заряд
        real elastic = GetRandomReal(0.7,1) // Коеффициент упругости тела
        boolean AllowRest = true // Можно ли выключать тело, если оно не двигается
        
        // Создание тела
        method onCreate takes Body b returns void defaults void
        // Касание земли, срабатывает все время пребывания на земле
        method onGround takes Body b returns void defaults void
        // Столкновение
        method onCollusion takes Body b, Body b2 returns void defaults void
        // Сильное столкновение, скорость сильного столкновения в параметрах
        method onForcedColl takes Body b, Body b2 returns void defaults void
        // Столкновение с декорацией, срабатывает все время пересечения тела и дестра
        method onDestrColl takes Body b, destructable destr returns void defaults void
        // Столкновение с юнитом, срабатывает все время пересечения тела и юнита
        method onUnitColl takes Body b, unit u returns void defaults void
        // Столкновение с краем карты
        method onWorldBound takes Body b returns void defaults void 
        // Тело раскололось, передает структуру с осколками
        method onCrack takes Body b, CrackedBody cb returns void defaults void
        // Тело ударилось о клифф
        method onTerrainCliff takes Body b returns void defaults void
        // Тело отправлено в стек спокойных тел
        method onRest takes Body b returns void defaults void
        // Тело выбрано
        method onSelect takes Body b returns void defaults void
        // Тело больше не выбрано
        method onDeselect takes Body b returns void defaults void
        // Смерть тела
        method onDeath takes Body b returns void defaults void
        // Выход и цикла обработки
        method onExit takes Body b returns void defaults void
        // Приказ точка
        method onPointOrder takes Body b, real TargetX, real TargetY returns void defaults void
        // Приказ цель
        method onTargetOrder takes Body b, widget target returns void defaults void
        // Приказ без цели
        method onOrder takes Body b returns void defaults void
        // Помещение в цикл обработки
        method onStart takes Body b returns void defaults void
  
            // Тело привязали пружиной к телу b, если b = null, тогда тело привязано к точке
            method onSpringBinded takes Body a, Body b, Spring sp returns void defaults void
            // Тело освобождено
            method onSpringUnBinded takes Body a returns void defaults void
}


Задание всех свойств и событий необязательно, если их не объявить, то значения будут браться по стандарту.

Объект пружина

В версии 0.9 были добавлены пружины, вот список функций для работы с ними:
Методы создания пружины:
    static Spring Ini(Body a, Body b, real k, real l, real kb) - Метод создает пружину, связывающую два тела.
K - жесткость пружины, l - длина недеформированной пружины, kb - коэффициент затухания
    
    static Spring IniBindedToPoint(Body a, real x, real y, real z,real k, real l, real kb) - Метод создает пружину привязывающую тело к точке (x,y,z).
    
Методы:
void SetK(real k) - Метод установки жесткости

void SetL(real l) - Метод установки длины недеформированной пружины

void SetKB(real kb) - Метод установки коэффициента затухания

void BindToPoint(rBody a,eal x,real y,real z) - Метод привязки пружины к точке

void BindToBody(Body a, Body b) - Метод привязки пружины к двум телам

bool IsBTP() - Метод проверки на привязку к точке

bool IsV() - Метод проверяет включена ли визуализация

void SetVisible(bool flag, string estr, real step) - Метод установки визуализации
    
void Render(bool ReDrawAll) - Служебный метод прорисовки

void Destroy() - Метод уничтожения пружины
 
Функции:

void DestroySpring(unit u1,unit u2) - Функция уничтожения пружины между двумя телами

Spring FindSpring(unit u1,unit u2) - Поиск пружины по двум телам

Spring FindAnySpring(unit u) - Поиск пружины по одному телу. Возвращает первую пружину, которую найдет.

int FindSpringInStack(unit u1,unit u2) - Поиск в стеке цикла обработки

int FindAnySpringInStack(unit u) - Поиск любой пружины в стеке, прикрепленной к телу
Пример смотрите в четвертом тесте "Пружины". Советую не использовать визуализацию эффектами со звуками, появляются утечки, которые пока не удалось устранить.

Скриншоты:

Изменения:

v1.0: В карте показан пример использования: система из двух звезд и планеты.
v2.0: Нажатие на оленя демонстрирует новые возможности (тяготение к земле, сила сухого трения, силы упругости для гравитационных взаимодействий)
v3.0: Теперь можно выбрать один из 6 тестов, раскрывающих суть системы
v3.1: Исправлены баг с трением и отменой приказа.
v4.0: Переделан вся система столкновений.(спасибо [b]Toadcop[/b] за подсказку) Теперь тела корректно реагируют на ямки,возвышения, на весь ланд. Теперь тела отскакивают от ланда под естественным углом. Убраны все баги с трением (иногда тела начинали самопроизвольно ползать=), Jittering по-научному.)
v5.0: Система опробована на практике, доведена до ума, финальная версия.
v5.2: Оптимизированная предыдущая версия, прирост производительности в 2 раза.
v5.5: Оптимизация теперь позволила иметь на карте более 100 объектов и практически без лагов (если только в яму не кидать бесчисленное кол-во тел ). Добавлен тест "Производительность". К каждому телу добавился параметр "эластичность". Создан GUI интерфейс.
v5.7: Устранены замеченные баги, спасибо участникам XGM, тест "Черная дыра" заменен на более внушительный и корректный. Переделана система движения юнита (не тела, а именно юнита), теперь тело-юнит отвечает на приказы и его попытки к движению учитываются =). Это, конечно, если включен мод. b.SCanRun(true).
v5.8: Добавлена функция "раскол" тела на две части, изменен тест сухого трения на тест раскола тела, исправлены мелкие баги.
v5.9: Версия для FDL CarLib.
v6.0: Устранены недостатки, указанные Van_Damm .
v6.5: Переход на cjass (работает начиная с версии 1.4). Переделана функция калибрации тел перед столкновением. Переписан модуль сухого трения, с учетом наклона плоскости. Добавлена условная трансляция блоков, ненужные блоки можно исключить при компиляции.
v7.0: Добавлены интерфейсы, которые позволяют создавать свои прототипы объектов со своими обработчиками событий. Доведена до ума система обнаружения столкновения (теперь через квадратное уравнение). Добавлены силы Кулона, продемонстрированные в тесте "Модель атома".
v.8.0:
  1. Custom вектор тяготения
  2. Функция упрощенного создания черной дыры
  3. Теперь не надо объявлять все события для нового типа тел.
  4. Добавлены события столкновения с клиффом, декором, обычными юнитами, границей мира, раскол тела, сильное столкновение, скорость которого определяется в параметрах.
v.9.0:
  1. Добавлен объект "пружина" и функции для работы с ним.
  2. События привязки пружиной и развязки
  3. Добавлен метод AddRandomSpeed и SetRandomSpeed для Body

Скачать
Наработка v6.0 добавлена на сайт
+300 опыта
Прикрепленные файлы
Тип файла: rar ui.rar (83.2 Кбайт, 240 просмотров )
Тип файла: w3x Fiziks0.65.w3x (49.1 Кбайт, 113 просмотров )
Тип файла: w3x Fiziks0.7.w3x (63.9 Кбайт, 60 просмотров )
Тип файла: w3x Fiziks0.8.w3x (65.4 Кбайт, 60 просмотров )
Тип файла: w3x Fiziks0.9.w3x (72.0 Кбайт, 396 просмотров )

Отредактировано NCrashed, 23.12.2009 в 15:41.
Старый 05.06.2009, 12:53
SRes
1110101000
offline
Опыт: 9,997
Активность:
Имхо - в варе это не нужно...
Старый 05.06.2009, 13:36
NCrashed

offline
Опыт: 13,553
Активность:
Например карты, действие которых происходит в космосе.

NCrashed добавил:
+ любые Cinemantic карты
Старый 05.06.2009, 13:55
Hellfim
Новичок
offline
Опыт: 79,637
Активность:
Хорошая вещь, но ты забыд как минимум 1 из важнейших частей, импульс.
Старый 05.06.2009, 14:40
Van Damm
wait... what?
offline
Опыт: 22,268
Активность:
А где реакция опоры и трение?

Цитата:
StartDvizenie
какой ужас =)
Старый 05.06.2009, 14:56
NCrashed

offline
Опыт: 13,553
Активность:
Импулс - 2ой закон Ньютона в другой форме) его введу когда столкновения будут, Van Damm в следующей версии
Старый 05.06.2009, 15:09
Линкольн
Barg Ent.
offline
Опыт: 4,812
Активность:
NCrashed. Надеюсь следующая версия не будет весить полтора мегабайта.
Старый 05.06.2009, 15:15
NCrashed

offline
Опыт: 13,553
Активность:
Это из-за моделей), следующая будет на стандартных
Старый 05.06.2009, 15:16
DragonSpirit
у - уходи
offline
Опыт: 22,625
Активность:
NCrashed если отдать приказ движения "планете",то она продолжает двигать,но дёргается сильно...
Старый 05.06.2009, 15:19
NCrashed

offline
Опыт: 13,553
Активность:
Да, замечено - нужно отменять приказ или ставить тела за нетралов. То есть когда тела движутся этой системой, они не могут передвигаться обычным способом.
Старый 05.06.2009, 15:23
DragonSpirit
у - уходи
offline
Опыт: 22,625
Активность:
NCrashed тогда блокируй/удаляй приказ движения,а то не тру
Старый 05.06.2009, 15:24
Линкольн
Barg Ent.
offline
Опыт: 4,812
Активность:
Не понравилось то, что я умудрился запартачить твою систему за 18 секунд, и геометрия рук тут не причем. Я только изменил одно значение и сохранил.
Старый 05.06.2009, 15:36
MIW Inc

offline
Опыт: 1,500
Активность:
Так круто!!!! Но много слишком весит
Старый 05.06.2009, 15:42
PlayerDark
Coraline
offline
Опыт: 10,569
Активность:
Ох, мне не очень нравится подход к реализации физики. Хотя векторы это правильно.
Старый 05.06.2009, 15:51
NCrashed

offline
Опыт: 13,553
Активность:
PlayerDark - обоснуй мнение.
Линкольн Смотря, что ты изменил) если массы планет и звезд, то тут реально надо вычислять
DragonSpirit Все, теперь приказ блокируется
Старый 05.06.2009, 15:56
Линкольн
Barg Ent.
offline
Опыт: 4,812
Активность:
Изменил гравитационную постоянную Gi = 6.673 на Gi = 6.674.
А если я скажем сделаю Землю, поставлю возле нее Луну и задам соответствующие параметры.
Старый 05.06.2009, 16:07
NCrashed

offline
Опыт: 13,553
Активность:
Если рассчитаешь начальные скорости, то все норм)

NCrashed добавил:
Выложил облегченную версию - 19 кб с испарвленным багом движения

NCrashed добавил:
Линкольн, попробовал изменить гравитационную постоянную - ничего не изменилось. Наверно виноват WEU, который добавляет свои функции в gui, сча разберусь.

NCrashed добавил:
По моим наблюдениям, очень тяжело придумать нестандартную стабильную систему из 4 и более тел, в конце концов несколько тел разгоняются в гравитационных полях друг друга до 2 космической и улетают за пределы карты, тем самым вызывая крах варика.

NCrashed добавил:
Выложил облегченную версию с фиксированными багами (при отдаче приказа тело дергалось + ограничил пространство, где могут летать тела. Теперь фатала не будет)
Старый 05.06.2009, 17:13
SageOne
x
offline
Опыт: 46,054
Активность:
NCrashed сделай модели невыбираемыми, а если ландшафт заменить на пустоту, будет как в космосе - для пущей убедительности
Старый 05.06.2009, 18:22
NCrashed

offline
Опыт: 13,553
Активность:
Пиначет, мне нужно чтобы они выбирались, я определяю относительные координаты x y по кружкам). То есть текстуру земли заменить? Я думаю пока не надо, так как я делаю силы трения и Гука, а для них земля нужна.
Старый 05.06.2009, 18:44
DragonSpirit
у - уходи
offline
Опыт: 22,625
Активность:
Цитата:
То есть текстуру земли заменить? Я думаю пока не надо

+1,карта только потолстеет...
NCrashedкогда вторая версия? )
Старый 05.06.2009, 19:13
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 13:30.