Author Topic: FlxTimer, multiple callbacks + arguments (no DispatchEvents)  (Read 13308 times)

Wing Eraser

  • Guest
I've created a timer for flixel which called FlxTimer. Hmmm where have I seen that name before? If you have seen this thread: http://flixel.org/forums/index.php?topic=2540.0 you'll notice two different FlxTimer's.

On Flash Game Dojo you'll find Kronoshifter's FlxTimer with similar, actually based on this FlxTimer :P, functionality. He approached things on other ways than I did. Decide which one you like the most (ease, cpu and memory usage).

It doesn't use any Event class from ActionScript. It simply uses the in build timer of flixel. It includes delay and callback for on start and on complete. You can create as many callbacks and arguments to one timer.
The timer will be paused when FlxG.pause is set to true.

Use for flixel 2.55
FlxGame and FlxG need to be modified
wingeraser/FlxTimerPlus.as must be in plugin folder of flixel.



Example (PlayState)
Code: [Select]
override public function create():void
{
...


/**
 * Example 1
 * Very simple how to create callbacks and adding arguments.
 */
var t:FlxTimerPlus = new FlxTimerPlus(2); // duration of 2 seconds.
t.onStart(say, ["Example 1 - Callbacks and Arguments"]); // When the timer starts, call the callback.
t.onStart(begin, [1,2,3]); // When the timer starts, call the callback.
t.onComplete(helloFlixel); // no arugments
t.onComplete(say, ["Hello Wing Eraser"]); // 1 argument, String
t.onComplete(whoAreYou, ["Wing Eraser", 24]); // 2 arguments, String and int
t.start(); // Start the timer.


/**
 * Example 2
 * Show delay.
 */
var t2:FlxTimerPlus = new FlxTimerPlus(1, 3); // duration of 1 second, delay of 3 seconds.
t2.onStart(say, ["Example 2 - Delay"]); // after 3 seconds this will show up.
t2.onComplete(helloFlixel); // after 4 seconds this will show up.
t2.start();


/**
 * Example 3
 * Repeat
 */
var t3:FlxTimerPlus = new FlxTimerPlus(1, 5, 1); // 7 sec, Repeat once (-1 infinitely).
t3.onStart(say, ["Example 3 - Repeat"]); // starts at 5 and ends at 6.
t3.onRepeat(say, ["-Repeat"]);
t3.onRepeat(getCurrentTotalTime, [t3]); // it should be 6.
t3.onComplete(say, ["Example 3 - Repeat finished"]);
t3.start();


/**
 * Example 4
 * Destroy timers
 */
var t4:FlxTimerPlus = new FlxTimerPlus(1, 5, -1); // inifinite loop.
t4.onStart(say, ["Example 4 - Destroy timers"]); // starts at 5
t4.onRepeat(say, ["-Repeat ex.4"]); // starts at 6
t4.onComplete(t4.destroy); // it will be destroyed when it's finished, but it will never finished.
t4.start();


/**
 * Example 5
 * Remove callback
 */
var t5:FlxTimerPlus = new FlxTimerPlus(1, 6);
t5.onStart(say, ["Example 5 - Remove callback"]);
t5.onComplete(say, ["This callback doesn't live"]); // you won't see this.
t5.onComplete(say, ["This callback lives"]); // you'll see this.
t5.killAt(1); // the t5[1] callback is killed.
t5.start();


/**
 * Example 6
 * Get the current time and progress
 */
var t6:FlxTimerPlus = new FlxTimerPlus(1, 7, 1); // 9 seconds total (100%).
t6.onStart(say, ["Example 6 - Get the current progress and time"]);
t6.onStart(getTotalProgress, [t6]); // 7 sec, it should be 0.778 (7/9) (77.8% rounded).
t6.onComplete(getCurrentTotalTime, [t6]); // it should be 9 seconds.
t6.onComplete(getTotalProgress, [t6]); // it should be 1 (100% rounded).
t6.start();

Complete code of FlxTimerPlus
Code: [Select]
package org.flixel.plugin.wingeraser
{
import org.flixel.FlxG;

/**
* @author Ka Wing Chin a.k.a. Wing Eraser
*
* This timer class is made for flixel.
* It doesn't use any Event class from ActionScript. It simply uses
* the in build timer of flixel.
* It includes delay, repeatDelay and callback for onStart, onRepeat and onComplete.
* You can create as many callbacks and arguments to one timer.
* The timer will be paused when <code>FlxG.pause = true</code>;
*/
public class FlxTimerPlus
{
// Number of seconds that the timer should run.
private var _seconds:Number;
// Number of seconds that should elapse before the time begins.
private var _delay:Number;
// Number of sconds that should elapse before the repeat begins.
private var _repeatDelay:Number;
// Number of times that the time should repeat. To repeat indefinitely use -1.
private var _repeat:int;
// Counts how many repeats are left.
private var _repeatLeft:int;
// Counts how many onRepeats are left.
private var _repeatCallbackCounter:int;
// An array of functions that should be called when the time has completed or started.
private var _callbacks:Array;
// The current time in seconds that has elapsed.
private var _currentSeconds:Number;

// A helper for seconds.
private var _internalTime:Number;
// A helper for repeat.
private var _cachedRepeat:int;
// A helper for onStart.
private var _isStart:Boolean;
// A helper for delay.
private var _isDelay:Boolean;
// A helper for onRepeat.
private var _isRepeat:Boolean;
// A helper for force complete by kill.
private var _completion:Boolean;
// A helper for force complete by destroy.
private var _destroy:Boolean;

// @private Whether the timer is startded.
public var started:Boolean;
// @private Whether the timer is finished.
public var finished:Boolean;
// Duration of the timer in seconds including any repeats or repeatDelays.
private var _totalDuration:Number;
// @get The current total time in seconds that has elapsed including repeats and repeatDelays.
public var currentTotalTime:Number;


/**
* Constructor
* @param seconds Number of seconds that the timer should run.
* @param delay Number of seconds that should elapsed before the time begins.
* @param repeat Number of times that the timer should repeat. To repeat indefinitely, use -1.
* @param repeatDelay Amount of time in seconds between repeats.
*/
public function FlxTimerPlus(seconds:Number, delay:Number = 0, repeat:int = 0, repeatDelay:Number = 0)
{
_seconds = seconds;
_delay = delay;
_repeat = _cachedRepeat = repeat;
if(repeatDelay <= 0)
_repeatDelay = 0;
else
_repeatDelay = repeatDelay;

started = false;
finished = true;
_isStart = false;
FlxG.addTimer(this);
}


/**
* A function that should be called when the timer begins.
* @param fn The function that carries out the callback.
* @param args Arguments for the callback.
*/
public function onStart(fn:Function, args:Array = null):void
{
if(!_callbacks)
_callbacks = [];
_callbacks[_callbacks.length] = [fn, args, 0];
}


/**
* A function that should be called when the timer has finished.
* @param fn The function that carries out the callback.
* @param args Arugments for the callback.
*/
public function onComplete(fn:Function, args:Array = null):void
{
if(!_callbacks)
_callbacks = [];
_callbacks[_callbacks.length] = [fn, args, 1];
}


/**
* A function that should be called every time the timer repeats.
* @param fn The function that carries out the callback.
* @param args Arguments for the callback.
*/
public function onRepeat(fn:Function, args:Array = null):void
{
if(!_callbacks)
_callbacks = [];
_callbacks[_callbacks.length] = [fn, args, 2];
++_repeatCallbackCounter;
}


/**
* Starts the timer.
*/
public function start():void
{
if(started)
return;

_currentSeconds = currentTotalTime = _totalDuration = 0;
_isDelay = true;
if(_delay > 0)
_internalTime = _delay;
else
_internalTime = 0;

_repeatLeft = _repeat = _cachedRepeat;
_isStart = finished = false;
started = true;
}


/**
* Pauses the timer during play. This is not the same as the internal pause.
*/
public function togglePause():void
{
started = !started;
}


/**
* Stops the timer.
*/
public function stop():void
{
finished = true;
started = _isDelay = _isRepeat = false;
}


/**
* Stops and starts the timer.
*/
public function reset():void
{
stop();
start();
}


/**
* Kills all callbacks.
* @param complete Optionally forcing to completion first. onRepeats
* won't be called.
*/
public function killAll(complete:Boolean):void
{
if(!complete)
{
if(_callbacks)
_callbacks = [];
}
else
{
_repeat = 0;
_completion = true;
}
}


/**
* Kills a callback at a current position.
* @param at The position of the callback in the array.
* @param complete Optionally forcing to completion first.
* onRepeats won't be called.
* @return True if any callbacks were successfully found and
* removed. False otherwise.
*/
public function killAt(at:int, complete:Boolean = false):Boolean
{
if(at >= 0 && at < _callbacks.length)
{
if(!complete)
_callbacks.splice(at, 1);
else
{
// If it's a onRepeat, check how many there are left.
if(_callbacks[at][2] == 2)
{
_callbacks.splice(at, 1);
_repeatCallbackCounter--;
if(_repeatCallbackCounter == 0)
_repeat = 0;
}
else
(_callbacks[at] as Array).push(true);
}
return true;
}
else
return false;
}


/**
* Kills a callback by Function.
* @param fn The Function that needs to be removed.
* @param complete Optionally forcing to completion first.
* Includes onRepeats.
* @return True if any callbacks were successfully found and
* removed. False otherwise.
* // TODO: fix this!
*/
public function killCallback(fn:Function, complete:Boolean = false):Boolean
{
for each (var a:Array in _callbacks)
{
if(a.indexOf(fn) > -1)
return killAt((_callbacks[a.indexOf(fn)] as Array).indexOf(fn), complete);
}
return false;
}


/**
* Allows particular properties of the callback to be killed.
* @param fn The callback
* @return True if any callbacks were successfully found and the
* properties of it were removed. False otherwise.
*/
public function killVarsAt(at:int):Boolean
{
if(at >= 0 && at < _callbacks.length)
{
_callbacks[at][1] = null;
return true;
}
else
return false;
}

/**
* Allows particular properties of the callback to be killed.
* @param fn The callback
* @return True if any callbacks were successfully found and the
* properties of it were removed. False otherwise.
* // TODO: fix this.
*/
public function killVars(fn:Function):Boolean
{
for each (var a:Array in _callbacks)
{
trace(a.indexOf(fn));
if(a.indexOf(fn) > -1)
return killVarsAt(_callbacks[a.indexOf(fn)]);
}
return false;
}


/**
* Removes the timer from game.
* @param complete onRepeats won't be called.
* @return True if any callbacks were successfully found and
* removed from game. False otherwise.
*/
public function destroy(complete:Boolean = false):Boolean
{
if(complete)
{
_repeat = 0;
_destroy = true;
if(finished)
{
_callbacks = null;
return FlxG.killTimer(this);
}
return true;
}
else
{
_callbacks = null;
return FlxG.killTimer(this);
}
return false;
}


/**
* Value between 0 and 1 indicating the progress of the time according
* to its duration where 0 is at the beginning, 0.5 is halfway finished,
* and 1 is finished. This includes repeats and repeatDelays.
*/
public function currentTotalProgress():Number
{
return currentTotalTime / totalDuration;
}



/**
* This is the main loop for the timer.
*/
public function update():void
{
if(!started)
return;

if (_internalTime <= _currentSeconds)
{
if(_isDelay)
{
_isDelay = false;
_currentSeconds = 0;

// Callbacks onStart
if (!_isStart)
{
_isStart = true;
_internalTime = _seconds;
callback(0);
}
// Callbacks onRepeat
else if(!_isRepeat)
{
_isRepeat = true;
_internalTime = _seconds;
callback(2);
}
return;
}
else if(_repeatLeft > 0 || _repeat == -1)
{
if(_repeatLeft > 0)
_repeatLeft--;
_isRepeat = false;
_internalTime = _repeatDelay;
_isDelay = true;
_currentSeconds = 0;
return;
}
else
{
// Callbacks onComplete
callback(1);
stop();
if(_destroy)
destroy();
return;
}
}
_currentSeconds += FlxG.elapsed;
currentTotalTime += FlxG.elapsed;
}


/**
* Calls all callbacks.
* @param type onStart=0, onComplete=1, onRepeat=2.
*/
private function callback(type:int):void
{
for each(var callback:Array in _callbacks)
{
if(callback[2] == type)
{
(callback[0] as Function).apply(null, callback[1]);
if(_completion)
callback.splice(0);
else if(callback[3])
callback.splice(0);
}
}
}


/**
* Gets the duration of the timer in seconds including any repeats or
* repeatDelays.
* @return The total duration in seconds. If the return is -1, it means
* the timer uses a inifinte repeat.
*/
public function get totalDuration():Number
{
_totalDuration = _seconds + _delay + (_repeat * _repeatDelay) + (_repeat * _seconds);
if(_totalDuration == 0)
return -1;
else
return _totalDuration;
}


/**
* Sets the number of times that the timer should repeat.
* @param repeat To repeat indefinitely, use -1.
*/
public function set repeat(repeat:int):void
{
_repeat = _cachedRepeat = repeat;
}


/**
* Sets the amount of time in seconds between repeats.
* @param repeatDelay Time in seconds. If repeat is 0, then
* repeatDelay will also be 0
*/
public function set repeatDelay(repeatDelay:Number):void
{
if(_repeat == 0 && repeatDelay > 0)
_repeatDelay = 0;
}

public function get callbacks():Array
{
return _callbacks;
}
}
}


FlxGame
Code: [Select]
Add this to FlxGame

protected function update():void
{
var mark:uint = getTimer();

FlxG.elapsed = FlxG.timeScale*(_step/1000);
FlxG.updateSounds();
FlxG.updatePlugins();
_state.update();
FlxG.updateCameras();
if(!FlxG.paused) // Add this line
FlxG.updateTimers(); // Add this line

if(_debuggerUp)
_debugger.perf.flixelUpdate(getTimer()-mark);
}



protected function switchState():void
{
//Basic reset stuff
FlxG.resetCameras();
FlxG.resetInput();
FlxG.destroySounds();
FlxG.clearBitmapCache();
FlxG.killAllTimers(); // Add this line

//Clear the debugger overlay's Watch window
if(_debugger != null)
_debugger.watch.removeAll();

//Clear any timers left in the timer manager
var timerManager:TimerManager = FlxTimer.manager;
if(timerManager != null)
timerManager.clear();

//Destroy the old state (if there is an old state)
if(_state != null)
_state.destroy();

//Finally assign and create the new state
_state = _requestedState;
_state.create();
}


FlxG
Code: [Select]
Add this to FlxG

/**
 * A Vector that holds FlxTimer objects.
 */
static protected var timers:Vector.<FlxTimerPlus>;


/**
* Calls update on the FlxTimerPlus objects.
*/
static internal function updateTimers():void
{
if(!timers)
return;
for each(var t:FlxTimerPlus in timers)
{
if(t && !t.finished)
t.update();
}
}

/**
* Adds a FlxTimerPlus object.
* @param timer The timer that you want to add.
*/
static public function addTimer(timer:FlxTimerPlus): FlxTimerPlus
{
if(!timers)
timers = new Vector.<FlxTimerPlus>();
timers[timers.length] = timer;
return timer;
}

/**
* Removes a FlxTimerPlus object.
* @param timer The timer that you want to remove.
* @param complete Optionally forcing to completion first.
* onRepeats won't be called.
* @return True if the timer were removed. False otherwise.
*/
static public function killTimer(timer:FlxTimerPlus, complete:Boolean = false):Boolean
{
if(!timers)
return false;
if(complete)
return timer.destroy(true);
else
{
timers.splice(timers.indexOf(timer), 1);
return true;
}
}



/**
* Kills all timers.
* @param complete Optionally forcing to completion first.
* onRepeats won't be called.
* @return True if all timers were successfully removed.
* False otherwise.
* // TODO: fix completion = true.
*/
static public function killAllTimers(complete:Boolean = false):Boolean
{
if(!timers)
return false;

for each(var t:FlxTimerPlus in timers)
{
if(complete)
t.destroy(true);
else
{
t.stop();
t=null;
}
}

if(!complete)
timers = new Vector.<FlxTimerPlus>();
return true;
}


/**
* Resumes all paused FlxTimerPlus.
*/
static public function resumeAllTimers():void
{
for each(var t:FlxTimerPlus in timers)
{
if(!t.started)
t.togglePause();
}
}


/**
* Pauses all FlxTimerPlus.
*/
static public function pauseAllTimers():void
{
for each(var t:FlxTimerPlus in timers)
{
if(t.started)
t.togglePause();
}
}


/**
* Play all timers. FlxTimerPlus that are stopped will be started again.
* It won't play if timers are paused. Use resumeAllTimers.
*/
static public function playAllTimers():void
{
for each(var t:FlxTimerPlus in timers)
{
if(t && !t.started && t.finished)
t.start();
}
}


/**
* Stop all FlxTimerPlus.
*/
static public function stopAllTimers():void
{
for each(var t:FlxTimerPlus in timers)
{
t.stop();
}
}


Example, FlxGame mod and FlxG mod are included in the zip.
Download: here
It's up to you which one you like it most.


If you want to bitch about timers, do it here and keep the topic "Compilation of Flixel 3rd party Classes" clean.
« Last Edit: Sun, Jan 22, 2012 by Wing Eraser »

Kronoshifter

  • Member
  • **
  • Posts: 34
  • Karma: +0/-0
    • View Profile
I would like to point out that the Signal class is not part of the Flash API. Last time I checked, AS3 Signals uses callback just like everything else here. Also, don't bash the performance unless you've checked it. I would also like to point out a glaring hole in your version: There is no way to remove callbacks. Surely you don't want EVERY callback registered to fire every time?

On the upside, that onStart is genius. I wish I'd thought of that. I was also never sure how to implement repeating. Good job on that.
« Last Edit: Tue, Mar 8, 2011 by Kronoshifter »

Wing Eraser

  • Guest
I would like to point out that the Signal class is not part of the Flash API. Last time I checked, AS3 Signals uses callback just like everything else here. Also, don't bash the performance unless you've checked it. I would also like to point out a glaring hole in your version: There is no way to remove callbacks. Surely you don't want EVERY callback registered to fire every time?
Signal class is indeed not a part of Flash API, read it wrong on the internet.
If I look carefully at the Signal classes, it use Event and EventDispatcher. As far I know, from reading books and Jack Doyle (GreenSock), Events are always slower than callbacks.
The next version will support, FlxG.removeAllTimers, FlxG.pauseAllTimers, FlxG.resumeAllTimers, FlxTimer.killAll, FlxTimer.killAt, FlxTimer.complete (force complete). Maybe also Vector.<Function>.


Quote
On the upside, that onStart is genius. I wish I'd thought of that. I was also never sure how to implement repeating. Good job on that.
Thanks.

I see that you've updated your FlxTimer at Flash Game Dojo.
If you feel that I've bashed your creation, I'm sorry. My FlxTimer is not a replacement, but an alternative.


Offtopic: Performance Array vs Dictionary
Array
+ Fast!
- But slow at searching a specific object.
- Use more memory (3 times more than Dictionary)


Dictionary
+ Less memory usage (3 times less than Array)
+ Very fast at searching a specific object.
- Slow at reading

Wing Eraser

  • Guest
The following things have been updated or changed:
- It uses one array to store callbacks for onStart and onComplete.
-  No need to add timer to FlxG.
- Some places the for-loop has been replaced by while or for each (due performance and synchronize by removing a timer).


New
- Remove callback
- currentTime, returns the current duration of the timer.
- currentProgress, returns the progress of the timer.
- FlxG.resumeAllTimers
- FlxG.pauseAllTimers
- FlxG.playAllTimers
- FlxG.stopAllTimers
- FlxG.killAllTimers

- The example app itself has now buttons to activate resume, pause, play, stop and kill all.

Btw this FlxTimer has been inspired by GreenSock. If you already use GreenSock, FlxTimer is not needed, because GreenSock use a timer. Search the forum how to use GreenSock in flixel.

Check the first post for code and download

« Last Edit: Fri, Mar 11, 2011 by Wing Eraser »

Kronoshifter

  • Member
  • **
  • Posts: 34
  • Karma: +0/-0
    • View Profile
Quote
I see that you've updated your FlxTimer at Flash Game Dojo.
If you feel that I've bashed your creation, I'm sorry.
Don't feel bad. I needed to get it changed back anyways. I realized that I only used Signals because I was being lazy. Plus, I wanted my arguments in my callbacks back. :)

Plus, seeing your version actually creates some competition for me. I better kick it into gear.

Titch

  • Contributor
  • ****
  • Posts: 270
  • Karma: +0/-0
  • Thing with the guy in the place.
    • View Profile
Any chance of posting just the modified code for FlxG and FlxGame?

I'm running a version with some other small hacks in and I don't want to scroll through the whole code making everything match again.
Free cake whippings every day at #flixel on irc.freenode.net.

Wing Eraser

  • Guest
FlxG and FlxGame are added in the first post.

Wing Eraser

  • Guest
A very tiny update and oh yeah I forgot to put FlxG.killAllTimers() in the switchState of FlxGame.

Why is there a update? That's because I like tiny perfomance boost and less memory usage ;D.

Is there a feature you want in the timer, just post here or PM me.

javariajee

  • New Member
  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
    • acne and treatment
 ;D As any dermatologist can tell you, acne sebum is caused by excess production of oil by the sebaceous glands, (acne sebum!)which clogs skin pores and leads to the accumulation of dirt and bacteria. The accumulate oil, dirt and bacteria then inflame the skin and cause an infection that bursts through to the surface of the skin, forming blackheads, whiteheads and pimples. acne sebum can attack various parts of the body, but the face, back and chest are some of the most common places for acne outbreaks. Acne comes in mild and severe cases, and the severe cases may cause permanent scarring. Self-esteem and confidence may also be affected by acne's impact on your appearance.

Titch

  • Contributor
  • ****
  • Posts: 270
  • Karma: +0/-0
  • Thing with the guy in the place.
    • View Profile
Thanks for that Wing :)
Free cake whippings every day at #flixel on irc.freenode.net.

Kronoshifter

  • Member
  • **
  • Posts: 34
  • Karma: +0/-0
    • View Profile
Quote
On Flash Game Dojo you'll find Kronoshifter's FlxTimer with similar, actually based on this FlxTimer , functionality.

I would like to point out that I originally did mine the way I have it now, albeit without the onStart. Honestly don't know why I switched to AS3 Signals.
« Last Edit: Wed, Mar 23, 2011 by Kronoshifter »

seandime

  • Member
  • **
  • Posts: 40
  • Karma: +0/-0
    • View Profile
nice work :)

Im just wondering what the advantage of using this is over the standard flash.util Timer class?

Kronoshifter

  • Member
  • **
  • Posts: 34
  • Karma: +0/-0
    • View Profile
Quote
Im just wondering what the advantage of using this is over the standard flash.util Timer class?
Performance, I think. Callbacks are much faster than Flash's Event system, not to mention that both FlxTimers running around have much more functionality than Flash's Timer. You can't keep track of how much time the timer has left until it's done with Flash's Timer.

Titch

  • Contributor
  • ****
  • Posts: 270
  • Karma: +0/-0
  • Thing with the guy in the place.
    • View Profile
Just a note. If you make a FlxTimer with no callbacks it causes a crash when the timer tries to update due to a null objects reference (there is no _callbacks for it to get length from. I used this as my solution:

LINE 165:
Code: [Select]
var l:int;
if (_callbacks) l = _callbacks.length;
REPLACING
Code: [Select]
var l:int = _callbacks.length;
Free cake whippings every day at #flixel on irc.freenode.net.

Wing Eraser

  • Guest
Thanks Titch.
However is not needed anymore in the next update, because it didn't make any sense that I didn't declared _callbacks in the constructor. FlxTimer is used for calling methods when the time is started or completed, otherwise it's useless creating a timer that doesn't do anything.

New features are underway and also bug fixes..

Titch

  • Contributor
  • ****
  • Posts: 270
  • Karma: +0/-0
  • Thing with the guy in the place.
    • View Profile
Quote
FlxTimer is used for calling methods when the time is started or completed, otherwise it's useless creating a timer that doesn't do anything.

On the contrary, I've had a least one instance where I didn't need to add callbacks for the timer to be usefull.

In my instance, I wanted something to happen in the update loop as long as a timer was still running (checking player input for a melee attack against a delay timer). So all I needed to do was check timer.finished in the attack function. No need for using any of the callbacks. Thus my suprise when it caused a crash :)

I -could- have switched a bool on and off using callbacks, but that seemed silly since there was one on the timer already.

FlxTimer has been a god send for me, I've got a ton of stuff running timers or activating at a certain time based tick.
Free cake whippings every day at #flixel on irc.freenode.net.

Wing Eraser

  • Guest
Quote
On the contrary, I've had a least one instance where I didn't need to add callbacks for the timer to be usefull.

In my instance, I wanted something to happen in the update loop as long as a timer was still running (checking player input for a melee attack against a delay timer). So all I needed to do was check timer.finished in the attack function. No need for using any of the callbacks. Thus my suprise when it caused a crash Smiley

Ah! That makes sense. I'll revert it back to the old one. This weekend there will be an update. The update() has been rewritten and there are new features added.

Wing Eraser

  • Guest
In the first version there was something I didn't like: the repeat that keeps calling onStart and onComplete. The timer already started, so why calling onStart when it's already started and why calling onComplete when the timer is not even completed. So, I created onRepeat with repeatDelay.

Also, I've rewritten the update to a cleaner code and added some new  features.
- onRepeat
- repeatDelay
- force to complete. When you kill a timer, you can make it to force to complete. After the timer is completed it will kill itself.
- killVarsAt


Changes
- killCallbackAt (before killAt)


Bugs and not working
- killCallback, use killCallbackAt
- killVars, use killVarsAt
- FlxG.killAllTimers when completion = true


There is no track of the current time and progress between onStart and when it onStart finishes, between onStart/onRepeat and onComplete, and between onRepeat and when the onRepeat finishes.

It can be created by adding some extra variables. I don't know if this is needed.

In the PlayState example 7-11 are commented. Just uncomment them if you want to use them.

I hope you like the new FlxTimer.
« Last Edit: Sun, Apr 3, 2011 by Wing Eraser »