Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Знаю, что новички часто проверяют все объекты на коллизии. А ведь так не надо делать. У меня в игре (Arrow – master2 … ) были тоже проверки на все объекты. И когда на карте было большое количество объектов (типо пуль, врагов, главного героя и бонусов), игра начинала зверски тормозить. Вот и пришёл к тому, что у меня в последних миссиях невозможно было играть.
Затем написал функцию, которая бы определяла, находится ли в радиусе определённом объект, или нет. То есть, если рядом с главным героем находится один враг, то только на него считается коллизия (враг захавать хочет героя). А все остальные не считаются. Следовательно, примерно уже 30 коллизий убиваем. Идём далее. Пули.. пуль может быть много на карте. Особенно, если у тебя пулемёт. :) Считаем, для каждой пули едёт проверка коллизий на всех монстров. Неправильно, подставляем для каждой пули эту функцию и вуаля! если только рядом с пулей находится монстр, то считаем коллизии. Посчитайте, сколько коллизий убиваем лишних? 30 пуль – 30 монстров. 900 коллизий!!! Так и примерно увеличиваем производительность игры в несколько раз. Так же с бонусами (но тут уже меньше. Всего максимум две коллизии) Следовательно, ставить надо ограничения функцию просчёта расстояний. Ну, конечно, не в проектах ,где 5-6 коллизий, а где их тьма. Хотя, даже ограничение и на 5 коллизий будет неплохо. Свести коллизии до двух– это класс! [blitz] Function IsCollide (x1#, x2# , y1# , y2# , Weight# , Height# ) If X1 > X2 -Weight And X1 < X2 +Weight And Y1 > Y1 - Height And Y1 < Y2 + Height Then Return 1 Else Return 0 End Function [/blitz] Так. А терь о функции. Если объект с координатам x1 и y1 находится в зоне шириной weight и высотой height b и координатами центра x2 и y2 (то бишь центр - враг.. иль чё-нить другое), то возвращаем 1. Если нет - 0 [blitz] If IsCollide (5,5,7,7,25,25)=1 Then .... [/blitz] Так же можно и в блитз3д делать, для упрощения коллизий. Допустим ,если два объекта находятся близко друг к другу, то включается коллизия - иначе отключается (просто не видел, чтобы это где-нибудь было реализовано). Только в блитз3д есть функцию EntityDistance, а в блитзмаксе я не знаю (:@ ), по этому идёт проверка координат. Ну, как вам статья ? :-) :-) :-) Верю тупая, но у меня вначале было куча проблем с этим. Кстати, в функции моей возможны ошибки, хотя не знаю. Cкажите если есть. (В игре у меня это не функцией реализовано, а так просто). Хотя всю статью можно было бы сказать так : "делайте проверку на дистанцию , друзья!" и сё... но чёт растянул я... З.Ы. Arrow - master 2 :teach: (ссыль в подписи :-) ) З.Ы.Ы. :@ :sarcastic_hand: |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Молодец, аффтар! Доброе дело написал!
Это будет очень полезно новичкам. |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Функцию лучше поправить на IsCollide, так по смыслу будет правильней.
|
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Данил
лутче напиши дяде Диме статью по определению колизии между сферами используя KD дерево ... очень поможеж :) |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
статья гафно? омг... хотя она для новичков.... вроде.. хз, в общем...
|
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Почему у меня никогда коллизии не тормозят ?
Может вы стратегию коллизий неправильно определяете ? правило 1 Избегайте коллизии сфера-полигон правило 2 Если вы используете сфера-полигон, то оптимизируйте ее: полигональная модель должна содержать вменяемое число полигонов, если не позволяет графика, используйте так называемую "коллижн-модель" специально сделаную низкополигональную сетку, совпадающую с вашим объектом, с установленной альфой в ноль, и назначайте коллизию на нее. правило 3 всегда удаляйте ненужные больше вам объекты: как пули, осколки. и тд. правило 4 не вызывайте многократно функцию EntityCollided, а делайте конструкции типа: entity=EntityCollided(en,x) If entity .... Endif правило 5 Экономте код, вызывайте функции ТОЛЬКО когда это необходимо. Например, ваш враг уже умер, зачем проверять его на попадание пули ? Используйте типы для сущностей, и флаги состояния, который распределяют ЧТО в данный момент делать с тем или иным элементом. |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Ы... (:
Игры нужно писать так, чтобы все коллизии были либо "сфера-сфера", либо "квадрат-квадрат" - и тогда всё будет шустрее некуда. (: P.S. Извините, я несколько пьян. Но строго после ремнота. ^__^ |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Поздравляю, Данил! Ты изобрел еще один велосипед. Этой функции лет эдак... короче больше чем тебе.
|
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
хехе.. не спорю... но почему-то в 80% примеров или исходников игр этого нет.. хехе
|
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Цитата:
ИМХО далеко не все об этом знают! Мне в свое время тоже пришлось "изобрести" дельтатайминг просто потому что никто не смог объяснить его толком. |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
В моей наработке физики основанной на окружностях и линиях, это было релизовано, и производительность вырастала в 4-20 раз. Т.к. перебор 200 линий и 20 окружностей занимал 4400 (между линия-окружность и окружность-окружность) и просчёт коллизии это занимало по 500мс :) Поэтому я тоже сделал подобное, и это не были уже мс с 3 цифрами на такие просчёты. В прочем, тут зависит от скорости перемещения объекта тоже, и ещё от много чего.
На заметку: все современные физ двиги, такие как PhysX, Bullet, Havok, Newton и другие используют эту систему. Так что мы не изобретаем новое, мы только оптимизируем работу кода и алгоритмов, добиваясь большей производительности. :) В общем Данил, ты больно писимистичничаешь, т.к. если ктото не отписался "Спасибо!", это не значит что он не прочёл твою статью, и что она не будет полезна ему ;) Так что Спасибо что написал, многим кто об этом не подрузумевал, будет полезно узнать об этом. |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
НЕт, с чего ты взял. Просто по некоторым камментам почему-то кажется, что говорят типа "нах я написал это, это и так все знают".. сорри
|
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Данил
Да нет, всё правильно. В разделе ФАК - это очень полезная информация. Мне кажется "правильный новичёк" сказал бы тебе большое спасибо. |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Цитата:
я думаю каждый кому поможет это статья скажет спасибо !! |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
IGR
Это означает новичка, который умеет учится на чужих советах и вместо изобретения велосипеда сначала тщательно данные советы собирает, а лишь затем начинает осторожно применять. |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
elmortem, это неправильный новичёк, правильный, это тот кто отрубиться от интернета возмёт RTMF и будет учиться. Вот только таких нету почти, но таким респект и они становяться в итоге лучшими...
|
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
MoKa, где ж ты видел таких новичков, которые сами будут "постигать тонкую науку мирового бытия", ведь проще задать вопрос на форуме, пусть чужие мозги парятся.Вижу как форум молодеет, приходят парни лет по 13-15 и задают глупые впросы, вот не знаю хорошо ли это?
|
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
dimanche13, вот от сюда можно заключить. Интернет - зло. Я сидел без инета и зубрил, и на то время считался новичком, и щас в б3д много не знаю, но главное тут опыт иметь, знать мало. И знакомые есть кто так постигал кодинг.
|
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Цитата:
но то что задают глупые вопросы - плохо !! ведь можно было действительно это прочитать и мозги други не парить !! |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Но все таки без инета тоже как-то неинтерестно прогить.. согласитесь, сделали супер мега игру, а показать почти некому(... также если возник вопрос, а в книги нет овтета, что делать? Инет...
Правда, с появлением безлимитного инета я почти забросил кодить.. так, по чуть-чуть бывает кодю че-нить |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Цитата:
а форум тебе для того что бы спросить что то , что не получается у самого !! |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Данил, не думаю что сделаешь сам мега игру кодя годик, только единицы, редкость. И я не про книги говорил, а про справку, и голову на плечах, книги - учат, и это уже не тот эффект, хотя лучше чем когда человек учит.
В общем заканчиваем оффтоп! FAQ раздел как никак. |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
|
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Сорри, но присоединюсь к всеобщему флуду :-) изобретать велосипеды полезно каждому новичку (и мне в том числе, я тоже задаю на форуме тупые вопросы) очень хорошо сказываетьс9 на логике и дает прирост +10 к умению построения алгоритма. По мне, так лучше изобрести кривой велосипед и потом его доравтывать, чем скопипастить мотоцикл. извините, если что не так сказал.
|
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Данил, молодец.
дядя дима, две сферы соприкасаются если растояние между их центрами меньше чем сумма радиусов. еще пара советов: 1. не сравнивайте строки (долго), ессено если в этом нет крайней необходимости. 2. не сравнивайте float на равентсово, может смутить. 3. если есть вложенные условия, проверяйте сначала самые маловероятные, если они не выполнются , то вложенные даже небудут проверяться. 4. не используйте "магические числа". т.е. если у вас есть 10 врагов, то заведите константу на их кол-во, чтобы потом незабыть что к чему. 5. скрвайте невидимые еммитеры (ето даже в варкрафте сделано) |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
HolyDel
есть 2000 сфер из них надо узнать коллизии для 10 сфер (с какой колизится) как ето оптимизировать ? 20 тыс проходов тормозит однако :) я тут усилино думаю о разбиении пространства хотя бы просто сегментную сетку наложить но все ручки не доходят |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
простая сегментная разбивка (впрочем, ты наверное и сам знаеш).
разбиваеш ограниченное пространство на n^3 кубов. создаеш n^3 списков (aka list из <list>) игровой цикл: отчищаеш все спсики первым прогоном 2000 операций, заносиш сферу в список. к которому она принадлежит (по координатам), если к нескольким (большая сфера), то заносиш во все списки к которым она принадлежит. далее, прогоняеш все сферы 2000 проходов. далее проеверяеш на коллизии тока сферы из тогоде списка (или кщк соседних), если сфера большая. аналогичная система юзается в вартич (тога 2д , n^2), она помогла офигенно поднять производительность при большом кол-ве юнитов (хотя немного ее снизила при малом кол-ве). исходники либы утеряны, в связи с потерей винта, и на данный момент усильно пишутся заново. Могу потом скинуть, прада ето будет 2д сегментная сетка. |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
HolyDel
у меня тоже 2д :) для jAqua... в общем в типе мира есть список существ думаю там и можно его разбивать идинственая трабла что сейчас нету границы мира потому трудно представляю как наложить явную сетку хотя можно сетку генерировать динамически если юнит математически по координатам относится к квадрату сетки то просто создадим етот квадрат ето будет економно со стороны памяти я уже начал все сильно оптимайзить... а то памяти жрет много :) зделал даж динамическую выгрузку ресурсов ... ибо нефиг мне >100 картинок в памяти держать в общем осталось подождать пока ручки дойдут :) |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
хорошая идея.
сетка допустим из 20 на 20 ячеек. перввм проходом просто узнаеш максимальные и минимальные координаты по обои осям, и запихиваеш в эту область сетку. один угол (минимальные координаты в котором) береш за смещение. пример: сетка находится тут: (-20,-20)(180,180) смещение dx = -20 смещение dy = -20 размер сетки sx 180 - (-20) =200 ; asx=1/sx; размер сетки sy 180 - (-20) =200 ; asy=1/sy; потом смотриш на сферу, допустим у нее координаты 50, 120 смотриш i = sphere.x-dx * asx * gridsize (размер сетки ето (в нашем случае 20)) смотриш j = sphere.y-dy * asy * gridsize (размер сетки ето) кстати, как создать массив typedef std::list<TSphere*> mylist mylist* m = new mylist[20*20 (угадайте почему?)] как обратиться к элементу? m[i*21+j] вот и получаем: m[i*21+j].push_back(sphere); на коллизии (предположим сферы в списке sphs) for(sphstype (тут должно быть чо то сове)::const_iterator ci=sphs.begin();ci!=sphs.end();++ci) { i = sphere.x-dx * asx * gridsize; j = sphere.y-dy * asy * gridsize; for (mylist::const_iterator mi=m[i*21+j].begin();mi!=end();++mi) { а проврим ка мы их на коллизии тут! } } PS. Данный пост направлен не дяде Диме в первую очередь, он и сам допрет. а вот новичкам очень рекомендую принять на вооружение, способ сильно поднимет производительность, при огромном количстве объектов. Да! писалось все в браузере, так что на работспособность не рассчитывайте, идея вроде верная. И спасибо джимону, за идею с динамически меняющейся сеткой. а то так ее ячейки получаются слишком большими, и в них много юнитов помещаются, такчто пользы почти в ноль. |
Re: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
HolyDel
из-за взаимонепонимания мы друг другу новые идеи даем :lol: :lol: :) я имеел ввиду что размер стороны квадрата сетки будет статичным = A и потом опишем type NetCube .. field objects:TList .. end type и Net:TList но будем создавать квадрат только если обьект туда попадает тоесть пустых квадратов в сетке у нас не будет хотя идея с динамическим размером мне понравилась :) |
Ответ: Увеличиваем производительность игры или как убить лишние коллизии. Советы новичкам.
Вложений: 1
Цитата:
Ниже в аттаче полный урок |
Часовой пояс GMT +4, время: 14:50. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot