У верен много начинающих джасеров не могут до конца оптимизировать свой код.Вот и я один из таких. Решил создать тему в которой опытные джасеры будут оптимизировать, или помогать,учить оптимизировать. Прощу составлять ваши вопросы\ответы в следующей форме.
Вопрос
Код спела который нужно оптимизировать Или
Ответ
Код спела который оптимизирован Начну пожалуй первый по тому что проблема оч интересует
Вопрос Как это оптимизировать, верней я знаю как тока не знаю что там есть r
pein, твой триггер локальный? и часто создается? зачем такого рода оптимизация вообще?
Code
function TriggerRegisterEnterRectSimple takes trigger trig, rect r returns event local region rectRegion = CreateRegion() call RegionAddRect(rectRegion, r) return TriggerRegisterEnterRegion(trig, rectRegion, null) endfunction
так выглядит бж функция, если ты хочешь оптимизировать ее то выглядеть в твоем случае она должна так
local region rectRegion = CreateRegion() call RegionAddRect(rectRegion, gg_rct_M_6 ) сall TriggerRegisterEnterRegion( gg_trg_M_6, rectRegion, null) set rectRegion = null
pein, return это оператор который возвращает значение функции может быть использован только в функциях которые что либо возвращают
а у тебя это событие находится в функции инициализации триггера которая ничего не берет и ничего не возвращает, поэтому и ошибка получается так как ты пытаешься заставить функцию возвращать значение типа event, чего она соответственно не может сделать поэтому тут и выдается ошибка, вместо оператора return тебе нужно просто использовать оператор call
ищё вопрос а если я все бж уберу ищё что то оптимизировать надо
ну это уже либо талант к программированию либо нет, в общем плане просто старайся писать чистый код, старайся искать более короткие пути решения с минимумом вызова функций, не стоит так же объявлять большое количество переменных , несомненно лучше работать с координатами чем с точками и т.д + каждое действие должно быть функционально и логичски выражено, старайся грамотно строить условия, ведь порой можно очень многое выразить в короткой записи.
я использую всегда эту функцию native CreateUnit takes player id, integer unitid, real x, real y, real face returns unit
если нужно будет создать несколько юнитов то просто используй цикл, да и в цикле будет удобно с массивом работать=) это максимально оптимальный вариант
Добавлено (22-11-2010, 19:32) --------------------------------------------- и вообще стронись функций с Loc в имени=)))) это точки, а точки всегда утечны=(((( + они медленнее кооррдинат в разы так как каждый раз создается новый объект типа точка
их надо заносить в переменые если без них не куда=) а потом онулять
их нужно заносить в переменные, потом удалять и обулять переменные, но это все равно может быть утечно
Quote (pein)
это координаты а как написать чтоб в области создавались скажем в udg_A_Region[0]
native CreateUnitAtLoc takes player id, integer unitid, location whichLocation, real face returns unit тоже самое но через точку центральную точку можно получить функцией
function GetRectCenter takes rect whichRect returns location return Location(GetRectCenterX(whichRect), GetRectCenterY(whichRect)) endfunction
отсюда видно что точки в любом случае создаются через координаты, и работая с точками ты создаешь ненужные действия и нагрузку
получить координаты центра через функции
native GetRectCenterX takes rect whichRect returns real native GetRectCenterY takes rect whichRect returns real
в итоге получаем оптимальный вариант как например
call CreateUnit( player, unit id, GetRectCenterX( udg_A_Region[0]), GetRectCenterY(udg_A_Region[0]), face)
если ты создаешь несколько юнитов через цикл, можно его оптимизировать вот так
local real x = GetRectCenterX( udg_A_Region[0]) local real y = GetRectCenterY( udg_A_Region[0]) local integer i = 1 local unit array u loop exitwhen i > 10 set u[i] = CreateUnit( player, unit id, x, y, face) set i = i + 1 endloop
то есть лучше объявить иногда лишнюю локалку чем в каждом новом действии цикла каждый раз заного определять координаты центра
их надо заносить в переменые если без них не куда=) а потом онулять
хочу сделать заявление =) можно обойтись без точек в 100% случаев, точки необходимы для работы на GUI, если вы переходите на Jass необходимо все делать через координаты, что бы создать полярное смещение в декартовых координатах нужно использовань основы тригонометрии, а именно
координаты точки с полярным смещение находятся так
x = x0 + r*Cos(a) y = y0 + r*Sin(a)
r - расстояние смешения x0,y0 - координаты точки относительно которой происходит смещение a - угол в радианах a = a0 * bj_DEGTORAD а0 - угол в градусах bj_DEGTORAD - константа перехода ( в коде ее следует писать именно так)
получить часто требуемы координаты можно найти по следующим функциям
координаты позиции юнита GetUnitX( unit ) GetUnitY( unit )
координаты центра области GetRectCenterX( rect ) GetRectCenterY( rect )
координаты указанной точки приказа способности GetSpellTargetX() GetSpellTargetY()
координаты точки приказа GetOrderPointX() GetOrderPointY()
проще использовать небольшую библиотечку для работы с математическими значениями, просто удобнее. Написать функции работающие с координатами. Грубо говоря GetAngle(x1,y1,x2,y2), GetDist(x1,y1,x2,y2), PolarX(x, dist,angle), PolarY(y, dist,angle) . значительно упростит читебельность кода. Отличие от стандартных AngleBetween \ DistanceBetween - во первых, работа на прямую с координатами, во вторых, что куда как не маловажно - легкость написания.
проще использовать небольшую библиотечку для работы с математическими значениями
не всегда это нужно, может будет и красивее смотреться но как никак это будет дополнительный вызов функции? все равно что в код напихать бж например смотрится куда компактнее и оптимальнее
CreateUnit( player, unitid, x0 + ( r * Cos(a)), y0 + ( r * Sin(a)), face)
через библиотеку это будет так
function PolarX takes real x, real dist, real angle returns real return x + dist * Cos(angle * bj_DEGTORAD) endfunction
function PolarY takes real y, real dist, real angle returns real return y + dist * Sin(angle * bj_DEGTORAD) endfunction
зачем этот вызов функции=) это тема по оптимизации а не по красоте написания кода
к тому же Atan2 находит угол в радианах, почему бы не использовать его сразу без переходов что удаляет две операции умножения=) такая библиотека не оправдывает себя порой
P.S ты бы хоть пример привел=))) я то понял о чем ты, а другие?=)
DarkVader, дело в том что да, оптимальнее писать сразу код, однако вызов функции облегчает написание и продуктивность работы кодера а не самого кода. Ну и к тому же по сути это практически одно и то же - математическое уравнение вынесенное в отдельную функцию.
Не забывай к тому же что читаемость кода - куда как важный параметр в кодинге.
и CreateUnit( player, unitid, x0 + r * Cos(a), y0 + r * Sin(a), face) захламляет строку в отличии от аккуратной CreateUnit( player, unitid, PolarX( x0, r, a), PolarY( y0, r, a), face)
Понятное дело что сути самого действия это не меняет но оптимизировать надо не только работу самого кода но и работу кодера. И если уж доводить до максимума оптимизацию то твоя функция должна выглядить так:
CreateUnit(player,unitid,x0+r*Cos(a),y0+r*Sin(a),face) без пробелов. И скобки в уравнении не нужны. Умножение и деление - первые действия в уравнении.
Добавлено (23-11-2010, 17:25) --------------------------------------------- именно по этому лучше сразу вынести в переменные все подобные запросы и писать в последствии CreateUnit(p,u,x,y,a) где до этого объявляются local player p = GetOwningPlayer(GetTriggerUnit()) local integer u = 'идюнита' local real x = GetUnitX(GetTriggerUnit()) local real y = GetUnitY(GetTriggerUnit()) local real a = GetAngle(x,y,GetLocationX(GetSpellTargetLoc()),GetLocationY(GetSpellTargetLoc()))
set x = PolarX(x, 10, a) set y = PolarY(y, 10, a)
call CreateUnit(p,u,x,y,a)
//actions
set p = null
конечно, когда речь идет о всего лишь создании юнита в оффсете - не стоит так делать, но когда речь идет о функции на движение юнита с эффектами и прочим - лучше повысить читабильность кода слегка занизив продуктивность, чем повышать продуктивность методами прямого умножения. К тому же я сомневаюсь что уравнение при вызове функции продуктивнее чем предварительное умножение и последующее использование при вызове.
Нормальный рост в течении игры ~+300 за минуту (в момент геймплея а не простого простоя) Терпимый рост в течении игры ~+700 за минуту (в момент геймплея а не простоя) Критический рост в течении игры ~+1000 за минуту (в момент геймплея а не простоя)
Если число растет когда ничего не происходит - карта требует оптимизации.
Code
function Trig_check_Actions takes nothing returns nothing local timer Timer = CreateTimer() call DisplayTextToForce(GetForceOfPlayer(Player(0)), I2S(GetHandleId(Timer))) call DestroyTimer(Timer) set Timer = null endfunction
function InitTrig_check takes nothing returns nothing local trigger trig = CreateTrigger() call TriggerRegisterTimerEventPeriodic(trig, 0.5) call TriggerAddAction(trig, function Trig_check_Actions) set trig = null endfunction
Немного меньше Есть некоторые функции(их довольно мало) которые возвращают точки и не имеют аналогов на координатах. Пример: constant native GetSpellTargetLoc takes nothing returns location
Немного меньше Есть некоторые функции(их довольно мало) которые возвращают точки и не имеют аналогов на координатах. Пример: constant native GetSpellTargetLoc takes nothing returns location