0

私は大学の仕事のために小さなゲームをやっていますが、ガベージコレクターが EventListeners でどのように機能するかをよく理解していません。「preCastTimer」EventListener が以下のコードで決して削除されないように感じます。問題は、完了したら削除する方法がわからないことです。

以下は、キーが押されたときに呪文を唱えるために使用するコードです

ここに、KeyboardEvents によって呼び出されるキャスト関数があり、fireball は MovieClip です。

preCast(fireball);

function preCast(spell)
{
    var tempSpell:Object = new spell;//create an object for the spell so castTime is accessible. 
    var preCastTimer:Timer = new Timer(tempSpell.castTime,1);
    var spellFunc:Function = cast(spell);
    preCastTimer.addEventListener(TimerEvent.TIMER_COMPLETE, spellFunc);

    preCastTimer.start();
}

function cast(spell):Function {
    return function(e:TimerEvent):void {
        parent.addChild(new spell);//For some reason if spell is not created here it never gets a parent
  };
}

火の玉 MovieClip のコードは次のとおりです。

package  {

    import flash.display.MovieClip;


    public class fireball extends MovieClip {
        public var castTime:uint = 1000;


        public function fireball() {
            // constructor code
        }
    }

}

以下のコードは、火の玉のタイムラインにあります。クラスを使ったほうがいいのはわかるが、コードがタイムラインのフレームではなくパッケージにある場合の親子関係はまだ理解できない

import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.geom.Point;

if (parent)//only run if a parent exists, when created as object no parent is defined
{
    x = parent.getChildByName("player").x;
    y = parent.getChildByName("player").y;

    var direction = new Point(parent.mouseX - x,parent.mouseY - y);
    rotation = Math.atan2(parent.mouseY - y,parent.mouseX - x) * 180 / Math.PI;
    direction.normalize(5);
    if (direction.x == 0 && direction.y == 0)
    {
        parent.removeChild(this);
        return;
    }

    var spellTimer:Timer = new Timer(500,1);


    spellTimer.addEventListener(TimerEvent.TIMER_COMPLETE, spellKiller);
    this.addEventListener(Event.ENTER_FRAME, motion);

    spellTimer.start();
}

function spellKiller(e:TimerEvent):void
{
    this.removeEventListener(Event.ENTER_FRAME, motion);
    spellTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, spellKiller);
    parent.removeChild(this);
}

function motion(e:Event)
{
    x +=  direction.x * 5;
    y +=  direction.y * 5;
}
4

2 に答える 2

0

引数 (5 番目の引数)があることに注意しaddEventListenerてください。useWeakReference

public function addEventListener(
    type:String,
    listener:Function,
    useCapture:Boolean = false,
    priority:int = 0,
    useWeakReference:Boolean = false
):void;

EventDispatcher ドキュメントから:

イベント リスナーが不要になった場合は、removeEventListener() を呼び出して削除してください。そうしないと、メモリの問題が発生する可能性があります。ガベージ コレクターは、ディスパッチ オブジェクトが存在する限りリスナーを削除しないため (useWeakReference パラメーターが true に設定されている場合を除く)、イベント リスナーはメモリから自動的に削除されません。

addEventListener解決策は、必要に応じて弱参照を使用するように呼び出しを単純に変換することです。

foo.addEventListener(type, listener, false, 0, true);

これがどのように役立つかわからない場合はお知らせください。

于 2013-11-08T16:20:10.030 に答える