Fess | Дата: Среда, 13.11.2013, 23:40 | Сообщение # 1 |
Добрый админ
Сообщений: 2339
Статус:
| В чем разница?
Честно говоря, данную тему стоит начать с простого вопроса: в чем разница между хорошим программистом (а если вы пишете скрипты для редактора ARMA, то вы тоже, в какой-то степени, программист) и плохим программистом?
Не буду загадывать вам загадки и сразу выдам ответ: хороший программист сможет написать такой алгоритм, который будет работать в несколько... миллионов раз быстрее. Как так? А вот. Оптимизация.
Ладно, отбросим абстрактные размышления в сторону и давайте сразу подумаем, где нам может пригодится оптимизация в редакторе ArmA? Я более чем уверен, что большинство скриптов, которые вы пишите (я надеюсь, что вы пишите, вы ведь пишите, правда?), довольно простые, и компьютер с ними справляется на ура.
Очень плохие вещи в ваших скриптах
Например, я недавно писал скрипт, который превращает обычную гранату в очень мощную. Сейчас я напишу слабые места этого скрипта.
Во-первых, это EventHandler. Для тех кто не знает, объясняю на пальцах - это такой цикл, который проверяет, не совершил ли объект, на котором висит хэндлер, определенного действия.
[ Пофантазируем. Пусть процессору надо узнать, что вы чихнули. Чтобы это узнать, процессор будет задавать вам этот вопрос примерно 75 раз в секунду. "Вы чихнули? Нет? А сейчас? ... А сейчас?". Естественно, что в определенный момент вы все же чихнете, и процессор узнает об этом. Примерно так же работают хендлеры. ]
Я повесил хэндлер типа "FIRED", то есть "определенное действие" в данном случае - это выстрел или бросок гранаты. При обнаружении определенного действия хэндлер обращается к специальной процедуре execVM, которая в свою очередь вызывает .sqf скрипт. Это если разжевывать.
player addEventHandler ["Fired", {as = [_this] execVM "granata.sqf";}];
Как видим, действий выполняется достаточно много, да еще и в цикле. Запомните: циклы - это плохо. Но в этот раз я использовал цикл - и все хорошо, FPS не упал, игра работает плавно, граната взрывается, норм. То есть один цикл\эвентхандлер - это не смертельно.
А теперь приведу такой пример из практики.
Делал я как-то зомби-миссию с радиацией, торговлей, аптечками - все дела. При этом на каждом зомби у меня висело по хендлеру с условием "УБИТ" - ибо по задумке за каждого убитого зомби игроку начислялись деньги, которые он мог потратить на патроны\оружие т.д. Почему так делал - потому что хендлер типа "УБИТ" имеет возвращаемое значение "убийца", т.е. я проверял условие < if (убийца == игрок) > и если да, то тогда начислял деньги.
Все вроде круто. А теперь представьте - у меня 140 зомби на карте. Естественно вдруг РЕЗКО проседает FPS (со 120 до 18), а все потому, что огромное количество эвентхандлеров бомбят процессор бессмысленными запросами, в итоге проц не справляется, создаётся большая очередь команд, как следствие, падение FPS и заторможенная работа скриптов. Например, убиваешь зомби, а хендлер срабатывает только спустя 10 секунд. Представьте, какая очередь была, ведь проц. способен обрабатывать миллионы операций в секунду!
Какой из этого можно сделать вывод? Первый: эвентхандлеры - это плохо. Второй: такой способ никуда не годится, реализовывать подсчет нужно как-то по-другому. Но как?
Немного оптимизируем
Самый простой вариант: давайте не будем вешать хендлеры на каждого зомби, а будем реализовывать подсчет через массив allUnits, при этом будем обращаться не один раз за фрейм (то есть 75 раз в секунду, если у вас в игре 75 FPS), а один раз в СЕКУНДУ. Ведь, в сущности, нам не важно, чтобы деньги начислялись на счет именно в момент прохождения пули сквозь череп бедного зомби.
Код _price = 10; // пусть цена одного зомби будет $10 player_balance = 0; // это начальный баланс игрока, обратите внимание, написал без черточки _
while {true} do { _before = {alive _x && _x == "ЗОМБИ"} count allUnits; sleep 1; _after = {alive _x && _x == "ЗОМБИ"} count allUnits;
if(_before != _after) then { player_balance = player_balance + _price*abs(_before - _after); // иначе говоря прибавляем кол-во убитых умноженное на цену одного зомби }; };
Так как этот скрипт в ДЕСЯТКИ раз меньше загружает процессор (при 140 зомби у вас было бы не 140, а >10500 обращений в секунду), вы освободите ему приличное количество времени, чтобы он попинал балду. Кстати, на освобожденные ресурсы вы сможете заспавнить еще зомби.
Теперь проблемы. Этот скрипт сработает в случае смерти зомби, не обязательно от рук игрока. То есть если бедняга где-то на краю карты упадет со скалы вниз головой в море - денежки придут к игроку на счет. Фигня, а неприятно, правда? Ну да ладно, игра стоит свеч.
Хорошо, про это поговорили. Теперь реально полезный совет.
Зачем ставить статус: нет?
Когда вы ставили юнитов в редакторе, вы ведь видели там где-то строчку СТАТУС: В СТРОЮ ? И вероятно, даже знаете, за что она отвечает? Ну если не знаете, то статус "В ПОЛЕТЕ" ставить нужно вертолетам, если вы хотите, чтобы они появились сразу в воздухе; статус "В СТРОЮ" стоит ставить тогда, когда вам надо, чтобы юниты отряда появлялись не так, как вы их расставили, а согласно позициям в построении "КЛИН". Короче говоря при запуске миссии они сразу будут стоять клином, даже если вы их по-другому ставили. Чтобы этого не было - ставьте "СТАТУС: НЕТ", тогда они появятся на нужных местах, (но после этого все равно клином построятся).
Так вот. А вы видели, что у неодушевленных предметов эта строчка тоже имеется, причем по умолчанию там В СТРОЮ? Обычно люди так и оставляют, не обращая на нее внимания. А игра тем временем старательно просчитывает место, который данный чайник должен занять в своем собственном построении клином. На это у процессора уходят что? Правильно, силы и нервы, то есть операции в секунду.
А если у вас вся карта заполнена такими объектами? Например, вы решили построить стену, продублировав один большой мешок с песком <высота_стены * длинна_стены> раз? например стена 3*10 - это уже тридцать мешков. Тридцать пузатых ворюг сил вашего процессора.
То есть суть мысли в том, что у неодушевленных предметов ставьте "НЕТ" - так вы сэкономите ресурсы. А чем больше у проца ресурсов, тем лучше для вас - это сказывается еще как на скорости работы скриптов, так и на FPS.
|
|
| |
Fess | Дата: Среда, 13.11.2013, 23:54 | Сообщение # 2 |
Добрый админ
Сообщений: 2339
Статус:
| Со временем, может быть, допишу эту статью, а вот - выучите английский и прочитайте http://community.bistudio.com/wiki/Code_Optimisation .
|
|
| |