Inscrit le: 21 Avr 2008 Messages: 1607 Sujets: 81 Spécialité en worldedit: Utiliser le travail des autres Médailles: 3 (En savoir plus...)
Posté le: 16/05/12 15:34 Sujet du message: Problème de lag à cause des effets spéciaux
Salut, j'essaye de créer un sort qui invoque un cercle constitué de plusieurs effets spéciaux. Ces effets subissent également une rotation pour fermer le cercle et d'autres forment une spirale vers l'intérieur du cercle.
J'ai 2 types d'effets différents, une boule et une traînée (feu du phénix). Ces 2 effets sont superposés.
Mon problème vient lorsque le nombre d'effet est supérieur à 1 (1 boule + 1 traînée). Warcraft freeze et je dois fermer.
Le problème est le même si je ne met pas le feu du phoenix.
Donc est-ce que vous auriez des conseils pour m'aider à améliorer le code et gagner en performance? Je pense que le problème vient d'une boucle dans une fonction qui se répète (timer).
Merci
private constant function GetSpeed takes integer lvl returns real
return 2.
endfunction
private constant function GetSpiral takes integer lvl returns real
return 10.
endfunction
private constant function GetAoE takes integer lvl returns real
return 200. + 25. * lvl
endfunction
private function DamageOptions takes xedamage spellDamage returns nothing
set spellDamage.dtype = DAMAGE_TYPE_UNIVERSAL
set spellDamage.atype = ATTACK_TYPE_NORMAL
set spellDamage.exception = UNIT_TYPE_STRUCTURE
set spellDamage.visibleOnly = true
set spellDamage.damageSelf = true
set spellDamage.damageAllies = true
set spellDamage.allyfactor = -1.0
endfunction
private function IsValidTarget takes unit u returns boolean
return not IsUnitType(u, UNIT_TYPE_DEAD) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(u, UNIT_TYPE_FLYING) and not IsUnitType(u, UNIT_TYPE_MECHANICAL)and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitAlly(u,GetOwningPlayer(GetTriggerUnit()))==true
endfunction
//===============================================================================================
//===============================================================================================
//===============================================================================================
globals
private xedamage xed
endglobals
private struct Data
timer t
unit c
real sx
real sy
xefx array fx_bolt[N_BOLT]
xefx array fx_ray[N_BOLT]
xefx array fx_ray_2[N_BOLT]
xefx array fx_bolt_2[N_BOLT]
real ex
real ey
integer lvl
real duration = 0.00
private static thistype temp
//Creation du cercle
static method Create takes unit caster, real x, real y returns thistype
local thistype this = thistype.allocate()
local integer i = 1
local real a = (GetUnitFacing(caster) + 360 / N_BOLT + 90) * bj_DEGTORAD
set .c = caster
set .sx = x
set .sy = y
set .t = NewTimer()
set .lvl = GetUnitAbilityLevel(.c, SPELL_ID)
call BJDebugMsg(R2S(.sx))
call BJDebugMsg(R2S(x))
loop
set .ex = .sx + GetAoE(.lvl) * Cos(a)
set .ey = .sy + GetAoE(.lvl) * Sin(a)
set .fx_bolt[i] = xefx.create(.ex, .ey, a + bj_PI / 2 )
set .fx_bolt[i].fxpath = FX_BOLT
set .fx_bolt[i].scale = FX_SCALE_BOLT_INIT
set .fx_bolt[i].z = 60.
call .fx_bolt[i].recolor(RED, GREEN, BLUE, ALPHA)
// set .fx_bolt_2[i] = xefx.create(.ex, .ey, a + bj_PI / 2 )
// set .fx_bolt_2[i].fxpath = FX_BOLT
// set .fx_bolt_2[i].scale = FX_SCALE_BOLT_INIT
// set .fx_bolt_2[i].z = 60.
// call .fx_bolt_2[i].recolor(RED, GREEN, BLUE, ALPHA)
set .fx_ray[i] = xefx.create(.ex, .ey, a + bj_PI / 2 )
set .fx_ray[i].fxpath = FX_RAY
set .fx_ray[i].scale = FX_SCALE_RAY
set .fx_ray[i].z = 60.
call .fx_ray[i].recolor(RED, GREEN, BLUE, ALPHA)
// set .fx_ray_2[i] = xefx.create(.ex, .ey, a + bj_PI / 2 )
// set .fx_ray_2[i].fxpath = FX_RAY
// set .fx_ray_2[i].scale = FX_SCALE_RAY
// set .fx_ray_2[i].z = 60.
// call .fx_ray_2[i].recolor(RED, GREEN, BLUE, ALPHA)
set a = a + (2 * bj_PI / N_BOLT)
set i = i + 1
exitwhen i >= N_BOLT
endloop
call SetTimerData(.t, this)
call TimerStart(.t, XE_ANIMATION_PERIOD, true, function thistype.onMove)
return this
endmethod
//Rotation des FX
static method onMove takes nothing returns nothing
local thistype this = thistype(GetTimerData(GetExpiredTimer()))
local integer i = 1
local unit u = null
local real x
local real y
local real distance
set temp = this
loop
set x = .sx - .fx_bolt_2[i].x
set y = .sy - .fx_bolt_2[i].y
set distance = SquareRoot(x*x + y*y)
set .fx_bolt[i].xyangle = .fx_bolt[i].xyangle + GetSpeed(.lvl)
set .fx_bolt[i].x = .sx + GetAoE(.lvl) * Cos(.fx_bolt[i].xyangle - bj_PI / 2)
set .fx_bolt[i].y = .sy + GetAoE(.lvl) * Sin(.fx_bolt[i].xyangle - bj_PI / 2)
set .fx_ray[i].xyangle = .fx_ray[i].xyangle + GetSpeed(.lvl)
set .fx_ray[i].x = .sx + GetAoE(.lvl) * Cos(.fx_ray[i].xyangle - bj_PI / 2)
set .fx_ray[i].y = .sy + GetAoE(.lvl) * Sin(.fx_ray[i].xyangle - bj_PI / 2)
exitwhen i >= N_BOLT
endloop
set .duration = .duration + XE_ANIMATION_PERIOD
if .duration >= 3.*2 or (GetUnitCurrentOrder(.c) != String2OrderIdBJ(ORDER_ID)) or GetWidgetLife(.c) <= 0.405 then
call .destroy()
call ReleaseTimer(GetExpiredTimer())
endif
endmethod
private method onDestroy takes nothing returns nothing
local integer i = 1
loop
call .fx_bolt[i].destroy()
call .fx_bolt_2[i].destroy()
call .fx_ray[i].destroy()
call .fx_ray_2[i].destroy()
set i = i + 1
exitwhen i >= N_BOLT
endloop
endmethod
static method Conditions takes nothing returns boolean
local thistype this
call BJDebugMsg40;I2S40;SPELL_ID))
if GetSpellAbilityId40;) == SPELL_ID then
set this = thistype.Create40;GetTriggerUnit40;), GetSpellTargetX40;), GetSpellTargetY40;))
call BJDebugMsg40;R2S40;GetSpellTargetX40;)))
endif
return false
endmethod
Inscrit le: 23 Aoû 2007 Messages: 7146 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 16/05/12 17:10 Sujet du message:
Tu ne changes jamais la valeur de i dans cette loop :
Jass:
loop
set x = .sx - .fx_bolt_2[i].x
set y = .sy - .fx_bolt_2[i].y
set distance = SquareRoot(x*x + y*y)
set .fx_bolt[i].xyangle = .fx_bolt[i].xyangle + GetSpeed(.lvl)
set .fx_bolt[i].x = .sx + GetAoE(.lvl) * Cos(.fx_bolt[i].xyangle - bj_PI / 2)
set .fx_bolt[i].y = .sy + GetAoE(.lvl) * Sin(.fx_bolt[i].xyangle - bj_PI / 2)
set .fx_ray[i].xyangle = .fx_ray[i].xyangle + GetSpeed(.lvl)
set .fx_ray[i].x = .sx + GetAoE(.lvl) * Cos(.fx_ray[i].xyangle - bj_PI / 2)
set .fx_ray[i].y = .sy + GetAoE(.lvl) * Sin(.fx_ray[i].xyangle - bj_PI / 2)
exitwhen i >= N_BOLT
endloop
Ce qui provoque donc une seule itération de loop si N_BOLT <= 1 et un nombre "infini" (jusqu'à la limite d'opérations admises : limit op) si N_BOLT > 1.
Ceci explique cela.
A moins que tu utilises des struct qui extend d'autres struct, il vaut mieux simplement utiliser la method "destroy", en n'oubliant pas "deallocate" à l'intérieur de celle ci.
De même, utilise plutôt "create" avec "allocate", que "Create", car si tu ne le fais pas, la méthode create sera quand même crée, et donc augmentation de la taille du script de la map pour rien. _________________
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum