Fork me on GitHub
Not signed in (Sign In)

Welcome, Guest

Want to take part in these discussions? Sign in if you have an account, or apply for one below

    • CommentAuthorNickyD
    • CommentTimeAug 9th 2010
     
    I am working on a game project and one of the mechanics in this project entails that when a player touches a power up an effect is added to the stage using flint. To clean up the effect I am using a timer set to the duration of the last particles lifespan.
    This works fine assuming the player/user does not grab a second power up before the timer is up and the previous effect is cleaned. Is there an action or way to tell an emitter to clean itself up on its own when the last particle dies?

    //START SNIPPET**************************************************

    public var trail:Emitter2D;
    public var trailRenderer:BitmapRenderer;
    private var killTimer:Timer;

    //CLEANS UP THE HEART EFFECT FROM STAGE AND MEMORY********************************************************************
    //@xPos -the x position in which to draw the effect to
    //@yPos -the y position in which to draw the effect to
    public function GetHeart(xPos:Number, yPos:Number):void
    {
    var _xPos:Number = xPos + 2;
    var _yPos:Number = yPos + 10;

    trail = new Emitter2D();
    trail.counter = new TimePeriod(15, 0.4);
    trail.addInitializer(new SharedImage(new Dot(6)));
    trail.addInitializer(new ColorInit(0xFF9999, 0xFFCCFFCC));
    trail.addInitializer(new Position(new DiscZone(new Point(_xPos, _yPos), 15)));
    trail.addAction(new DeathZone(new DiscZone(new Point(_xPos, _yPos), 180), true));
    trail.addInitializer(new Lifetime(1.8,2.6));

    trail.addAction(new Age(Quadratic.easeInOut));
    trail.addAction(new Move());
    trail.addAction(new Fade(0, 1));
    trail.addAction(new Jet(12, -45, new RectangleZone(_xPos - 200, _yPos - 200, _xPos + 200, _yPos + 200),false));
    trail.addAction(new RandomDrift(150, 150));
    trail.addAction(new LinearDrag(0.3));
    trail.addAction(new ColorChange(0xFF0000, 0x00CCFFCC));
    trail.addAction(new ScaleAll(1, 0));

    trailRenderer = new BitmapRenderer(new Rectangle(_xPos - 200, _yPos - 200, _xPos + 200, _yPos + 200));
    trailRenderer.addFilter(new BlurFilter(8, 8, 2));
    trailRenderer.addFilter(new ColorMatrixFilter([1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0.95,0]));
    trailRenderer.addEmitter(trail);

    addChild(trailRenderer);
    trail.start();

    killTimer = new Timer(2600);
    killTimer.addEventListener(TimerEvent.TIMER, CleanGetHeart);
    killTimer.start();
    }

    //CLEANS UP THE HEART EFFECT FROM STAGE AND MEMORY********************************************************************
    public function CleanGetHeart(evt:TimerEvent):void
    {
    killTimer.stop();
    killTimer.removeEventListener(TimerEvent.TIMER, CleanGetHeart);
    killTimer = null;

    trail.stop();
    ParticleCreator2D(trail.particleFactory).clearAllParticles();
    trailRenderer.removeEmitter(trail);
    trail = null;
    removeChild(trailRenderer);
    trailRenderer = null;
    }

    //END SNIPPET ************************************************************

    Help is much appreciated. Thank you!
    • CommentAuthorNickyD
    • CommentTimeAug 9th 2010
     
    This seems to work better! The way I was calling it through the GameManager Class was incorrect. I initialized the EffectsObject once and then was trying to clean it up over itself again and again and in some cases the object was either not in existence or was already being used. I just ended up breaking the EffectsFactory Class down into smaller SingleEffects Classes and then just create them and add them manually through the Manager Class. I also changed the way I cleaned up the particles. This works for my current situation but I am sure there are much better ways to do this sort of thing. I am open to any and all suggestions:

    //ADDS THE OBTAIN HEART EFFECT TO THE STAGE AND MEMORY********************************************************************
    //@xPos -the x position in which to draw the effect to
    //@yPos -the y position in which to draw the effect to
    private function GetHeartEffect(xPos:Number, yPos:Number):void
    {
    var _xPos:Number = xPos + 2;
    var _yPos:Number = yPos + 10;

    trail = new Emitter2D();
    trail.counter = new TimePeriod(15, 0.4);
    trail.addInitializer(new SharedImage(new Dot(6)));
    trail.addInitializer(new ColorInit(0xFF9999, 0xFFCCFFCC));
    trail.addInitializer(new Position(new DiscZone(new Point(_xPos, _yPos), 15)));
    trail.addAction(new DeathZone(new DiscZone(new Point(_xPos, _yPos), 180), true));
    trail.addInitializer(new Lifetime(1.8,2.6));

    trail.addAction(new Age(Quadratic.easeInOut));
    trail.addAction(new Move());
    trail.addAction(new Fade(0, 1));
    trail.addAction(new Jet(12, -45, new RectangleZone(_xPos - 200, _yPos - 200, _xPos + 200, _yPos + 200),false));
    trail.addAction(new RandomDrift(150, 150));
    trail.addAction(new LinearDrag(0.3));
    trail.addAction(new ColorChange(0xFF0000, 0x00CCFFCC));
    trail.addAction(new ScaleAll(1, 0));

    trail.addEventListener(EmitterEvent.EMITTER_EMPTY, CleanEmitter);

    trailRenderer = new BitmapRenderer(new Rectangle(_xPos - 200, _yPos - 200, _xPos + 200, _yPos + 200));
    trailRenderer.addFilter(new BlurFilter(8, 8, 2));
    trailRenderer.addFilter(new ColorMatrixFilter([1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0.95,0]));
    trailRenderer.addEmitter(trail);

    addChild(trailRenderer);
    trail.start();
    }

    //CLEANS UP THE HEART EFFECT FROM STAGE AND MEMORY********************************************************************
    private function CleanEmitter(evt:EmitterEvent):void
    {
    trail.removeEventListener(EmitterEvent.EMITTER_EMPTY, cleanEmitter);
    trail.stop();
    ParticleCreator2D(trail.particleFactory).clearAllParticles();
    trailRenderer.removeEmitter(trail);
    trail = null;
    removeChild(trailRenderer);
    trailRenderer = null;
    }
    • CommentAuthorRichard
    • CommentTimeAug 10th 2010
     
    Hi Nicky

    I see no way to automate the clean-up within Flint since a key part of the clean-up is setting your references to the emitter and renderer to null.

    The call to clearAllParticles is unrelated to the rest of the code, and possibly not desired. The particleFactory retains dead particles so they can be reused in other effects later. This makes the initializing of those effects slightly quicker because the particles don't need to be created.

    Aside from that, your code is much like I would write.
    • CommentAuthorNickyD
    • CommentTimeAug 11th 2010
     
    Awesome thank you very much! I'll lose that line then.
    • CommentAuthorXor
    • CommentTimeSep 13th 2010
     
    > I see no way to automate the clean-up within Flint since a key part of the clean-up is setting your references to the emitter and renderer to null.

    You don't need to keep a reference and then it's possible to let the effect clean itself up. I use this in a simple effect framework that is instantiated, added to the display list and then removes itself from the list once some conditions are met. Since the display list will retain the object it will live until it removes itself. At that point there are no more references and the garbage collection can take care of it.

    Of course, if you want to still interact with the effect you'll need to keep a reference and null it when it's time to let it go.
    • CommentAuthorRichard
    • CommentTimeSep 16th 2010
     
    Absolutely. The display list keeps a reference to the renderer. The renderer keeps a reference to the emitter. The emitter keeps a reference to the actions. etc. Remove the renderer from the display list and everything is garbage collected. As you say, if you don't want to interact with your effect after creating it this makes clean-up very simple.
    • CommentAuthorkillerspaz
    • CommentTimeFeb 26th 2011 edited
     
    I have a similar question, however I am already doing everything as described in this thread (with the exception of the call to clearAllParticles()).

    I'm playing with a fun environment where the user can click on the renderer, and explosions occur. There could be as many explosions as the user desires at any given time.

    My approach is to create a new emitter per click, position it based on mouse coords, and start it up.
    My issue is that i have a BlurFilter applied to the renderer (BitmapRenderer), and upon an EMITTER_EMPTY, i still have artifacts from a blurred emitter on the renderer.

    I can't for the life of me figure out a good way to clean this up!

    I don't want to remove the filter or do anything drastic, as the user can start another emitter up around the time a pre-existing emitter is expiring. But if the emitter is stopped or removed, it seems the renderer stops executing filters.

    If i don't remove the emitter, clearly performance drops quickly as the pre-existing emitters are constantly dispatching that they're empty. I am going to move it to a pooled emitter system, but with just a single emitter active, this doesn't solve the issue.

    Any help?
    • CommentAuthorkillerspaz
    • CommentTimeFeb 27th 2011
     
    OK I managed to find a work around.

    Since my situation doesn't really have a lot of overhead, and isn't a game - I found it useful to have the renderer executing non stop.

    The way I did this was adding a bogus emitter:

    //Add a bogus emitter to force renderer to continue working.
    var bogusEmitter:Emitter = new Emitter();
    bogusEmitter.counter = new ZeroCounter();
    bogusEmitter.start();
    this._renderer.addEmitter(bogusEmitter);

    This way the renderer is still listening for Event.RENDER because it still has an emitter in it. This emitter just happens to do nothing. I suppose this is akin to say a game loop, I want the "game" engine to run forever.. In my case, it's just a BlurFilter on the renderer.

    Now while this satisfies my situation, I'm curious what the more appropriate approach would be for say someone doing a game where an explosion might occur, and blurring is utilized for effect. Would they just do something (which i was trying to avoid) cheezy and just say "ok after 5 seconds finally remove the emitter?" I wanted something a bit more accurate, but the ONLY thing I could think of was analyzing pixel data in the bitmap, which i would assume to be pretty slow in between each filter apply. And even still, that'd be more logic I'd have to write that I just don't care to do right now.
    • CommentAuthorRichard
    • CommentTimeFeb 27th 2011
     
    Your cheezy solution is possibly the most practical - that or the solution you have come up with. One other option that comes to mind is to use one emitter for all the explosions. Using a blast counter and a position initializer, one could reposition the position initializer and then restart the emitter to create another blast of particles on the one emitter.
    • CommentAuthorkillerspaz
    • CommentTimeFeb 27th 2011 edited
     
    Well if I have an emitter already running, and then update the position initializer, wouldn't I also be overriding the existing coutner object? I haven't looked into the source to see if it's a seeded object, or something that is referenced during the entire lifespan of the emitter - but i'd expect the latter. In which case, I'm not sure that'd work as I expect...