TimeOut class

Update: No need to use this with Flash 8 since we now (finally) have the setTimeout() function.

Some time ago I created a TimeOut class which used flash’s setInterval command, I’ve become less and less pleased with the way setInterval works, specifically in tracking interval ID’s and so on.

Since they are difficult to track I’ve decided to use a different method using a temporary MovieClip instance instead, this isn’t ideal either, but keeping tabs on a MovieClip is a lot simpler and more reliable.

I’d be interested to hear how other people have dealt with the problem, in most cases I keep things in a sequence or use an event dispatcher so that timeout’s aren’t required, but sometimes I just need to use one, usually when I’m being lazy.

Anyway, here’s the code…

/*
Class: TimeOut

Description:
A TimeOut class which uses a temporary MovieClip to perform timing,
as opposed to setInterval which is messy.

Usage:

:myTimer = new TimeOut(_root:MovieClip, 10:Number, this:Object, myFunction:Function, arguments:Array);

Version:
24-08-2005

Author:
Jason Milkins | jason@mentalaxis.com | <http ://www.mentalaxis.com>
*/
class TimeOut
{
 /*
 Property: exFunction

 Description:
 Callback function

 Datatype:
 Function

 Access:
 [Private]

 */
 private var exFunction : Function;
 /*
 Property: exObj

 Description:
 Callback object

 Datatype:
 Object

 Access:
 [Private]

 */
 private var exObj : Object;
 /*
 Property: exArgs

 Description:
 Arguments to be sent to the callback function

 Datatype:
 Array

 Access:
 [Private]

 */
 private var exArgs : Array;
 /*
 Property: inTime

 Description:
 Calculated running time of the TimeOut instance

 Datatype:
 Number

 Access:
 [Private]

 */
 private var inTime : Number;
 /*
 Property: timerEngine

 Description:
 Temporary movieclip created to run the timer

 Datatype:
 MovieClip

 Access:
 [Private]

 */
 private var timerEngine : MovieClip;
 /*
 Property: startTime

 Description:
 Calculated start time of the class instance

 Datatype:
 Number

 Access:
 [Private]

 */
 private var startTime : Number;
 /*
 Property: endTime

 Description:
 Calculated end time of the class instance

 Datatype:
 Number

 Access:
 [Private]

 */
 private var endTime : Number;
 /*
 Function: onTimeOut

 Description:
 The onTimeOut function runs the function supplied to the TimeOut instance, and then cleans up the timerEngine.

 Access:
 [Private]

 */
 private function onTimeOut ()
 {
  exFunction.apply (exObj, exArgs);
  timerEngine.onEnterFrame = null;
  timerEngine.removeMovieClip ();
  timerEngine = null;
 }
 /*
 Function: TimeOut

 Description:
 Setup the timer and provide the callback object, function and arguments.

 Access:
 [Public]

 Parameters:
 inClip - [MovieClip] Timeline clip to attach the timer engine.
 inSeconds - [Number] Number of seconds to wait before timeout
 inObj - [Object] callback object
 inFunction - [Function] callback function on object
 args - [Array] arguments to pass to the callback function

 */
 public function TimeOut (inClip : MovieClip, inSeconds : Number, inObj : Object, inFunction : Function, args : Array)
 {
  exObj = inObj;
  exFunction = inFunction;
  exArgs = args;
  inTime = inSeconds * 1000;
  startTime = getTimer ();
  endTime = startTime + inTime;
  //
  var _instance = this;
  //
  timerEngine = inClip.createEmptyMovieClip ("timerEngine" + getTimer () , 1600);
  //
  timerEngine.onEnterFrame = function ()
  {
   if (getTimer () >= _instance.endTime)
   {
    _instance.onTimeOut ();
   }
  }
 }
}
</http>

Add comment August 24th, 2005

Superformula

The Superformula developed by Johan Gielis is a simple formula that can generate a vast diversity of natural shapes. It produces everything from simple triangles and pentagons, to stars, spirals and petals. More information on the Superformula: Paul Bourke.
Based on the first Flash implementations of Flashforum members, Especially based on e2e4 and i++ contributions.

I’ve put together a little example to draw SuperShapes, copy the code into frame 1 of a new flash movie.

function getSuperPoint (m:Number, n1:Number, n2:Number, n3:Number, phi:Number)
{
 var r:Number;
 var t1:Number;
 var t2:Number;
 var a:Number = 1;
 var b:Number = 1;
 var x:Number = 0;
 var y:Number = 0;
 t1 = (1 / a) * Math.cos ((m / 4) * phi);
 t1 = Math.abs (t1);
 t1 = Math.pow (t1, n2);
 t2 = (1 / b) * Math.sin ((m / 4) * phi);
 t2 = Math.abs (t2);
 t2 = Math.pow (t2, n3);
 r = Math.pow (t1 + t2, 1 / n1);
 if (r != 0)
 {

  r = 1 / r;
  x = r * Math.cos (phi);
  y = r * Math.sin (phi);
 }
 var p:Object = {x:x, y:y};
 return p;
}
function drawSuperShape (m, n1, n2, n3)
{
 var maxAngle:Number = 12 * Math.PI;
 var x = 300;
 var y = 200;
 _root.lineStyle (1, 0x0000AA);
 for (var i = 0; i < = maxAngle; i += 0.01)
 {
  var p:Object = getSuperPoint (m, n1, n2, n3, i);
  if (i == 0)
  {
   _root.moveTo (x + (p.x * 100), y + (p.y * 100));
  }
  else
  {
   _root.lineTo (x + (p.x * 100), y + (p.y * 100));
  }
 }
}

// Then create an animated runner...

var a = 70, b = 10;
var m:Number = a / b;
var n1:Number = .5;
var n2:Number = 3;
var n3:Number = .5;

_root.createEmptyMovieClip ("control", 100);
control.onEnterFrame = function ()
{
 b -= 3;
 a += 1.5;
 _root.m = a / b;
 _root.clear ();
 _root.beginFill (0x000000, 10);
 _root.drawSuperShape (_root.m, _root.n1, _root.n2, _root.n3);
 _root.endFill ();
};

Add comment March 3rd, 2005

Filled Arc’s anyone?

I’ve always loved arc’s, especially in images like this one.

I remember seeing Sci-fi imagery from the 60’s and 70’s with patterns similar to these and I always wondered where they first originated.

Anyway, after playing with Ric Ewing’s advanced drawing API methods for a while I decided I wanted a means of drawing these filled arc shapes, and the draw wedge method was tantalizingly close, so I had a little play with it this afternoon and here’s what I came up with.

The code is fully AS2.0 compliant so you can just drop it into a DrawingMethods class if you have one. There’s nothing wrong with just running it from the timeline either if you’re so inclined.

I’ve also put a little example code at the bottom which will draw images like the one above. I’m also working on a little animated demo which I’ll post up quite soon.

Enjoy.

 /*
 Function: drawFilledArc

 Description:
 Draws filled Arc shapes (with interior and exterior radius)

 Author: Jason Milkins jason@mentalaxis.com | <http ://www.mentalaxis.com>

 Version: 1.0

 Note:
 Based on code by Ric Ewing </http><http ://www.ricewing.com>

 Parameters:
 mc - MovieClip target to draw in
 x, y - center point of the wedge.
 startAngle - starting angle in degrees.
 arc - sweep of the wedge. Negative values draw clockwise.
 exteriorRadius - exterior radius of wedge.
 interiorRadius - interior radius of wedge.

 Note:
 Comments formatted for NaturalDocs
 */
 function drawFilledArc (mc, x, y, startAngle, arc, exteriorRadius, interiorRadius ) : Void
 {
  // if yRadius is undefined, yRadius = radius
  // Init vars
  var segAngle_a, segAngle_b, theta_a, theta_b, angle, angleMid, segs, ax, ay, bx, by, cx, cy, dx, dy;
  // limit sweep to reasonable numbers
  if (Math.abs (arc) > 360)
  {
   arc = 360;
  }
  // Flash uses 8 segments per circle, to match that, we draw in a maximum
  // of 45 degree segments. First we calculate how many segments are needed
  // for our arc.
  segs = Math.ceil (Math.abs (arc) / 45);
  // Now calculate the sweep of each segment.
  segAngle_a = arc / segs
  segAngle_b = -arc / segs;
  // The math requires radians rather than degrees. To convert from degrees
  // use the formula (degrees/180)*Math.PI to get radians.
  theta_a = - (segAngle_a / 180) * Math.PI;
  theta_b = - (segAngle_b / 180) * Math.PI;
  // convert angle startAngle to radians
  angle = - (startAngle / 180) * Math.PI;
  // draw the curve in segments no larger than 45 degrees.
  if (segs > 0)
  {
   // draw a line from the end of the interior curve to the start of the exterior curve
   ax = x + Math.cos (startAngle / 180 * Math.PI) * exteriorRadius;
   ay = y + Math.sin ( - startAngle / 180 * Math.PI) * exteriorRadius;
   mc.moveTo (ax, ay);
   // Loop for drawing exterior  curve segments
   for (var i = 0; i < segs; i ++)
   {
    angle += theta_a;
    angleMid = angle - (theta_a / 2);
    bx = x + Math.cos (angle) * exteriorRadius;
    by = y + Math.sin (angle) * exteriorRadius;
    cx = x + Math.cos (angleMid) * (exteriorRadius / Math.cos (theta_a / 2));
    cy = y + Math.sin (angleMid) * (exteriorRadius / Math.cos (theta_a / 2));
    mc.curveTo (cx, cy, bx, by);
   }
   // draw a line from the end of the exterior curve to the start of the interior curve

   startAngle += arc;
   angle = - (startAngle / 180) * Math.PI;
   // draw the interior (subtractive) wedge
   // draw a line from the center to the start of the interior curve
   dx = x + Math.cos (startAngle / 180 * Math.PI) * interiorRadius;
   dy = y + Math.sin ( - startAngle / 180 * Math.PI) * interiorRadius;
   mc.lineTo (dx, dy);
   // Loop for drawing interior curve segments
   for (var i = 0; i < segs; i ++)
   {
    angle += theta_b;
    angleMid = angle - (theta_b / 2);
    bx = x + Math.cos (angle) * interiorRadius;
    by = y + Math.sin (angle) * interiorRadius;
    cx = x + Math.cos (angleMid) * (interiorRadius / Math.cos (theta_b / 2));
    cy = y + Math.sin (angleMid) * (interiorRadius / Math.cos (theta_b / 2));
    mc.curveTo (cx, cy, bx, by);
   }
   mc.lineTo (ax, ay);
  }
 }

And here’s the demo code…

my_mc = _root.createEmptyMovieClip ("poop", 100);
my_mc.i = 0;
my_mc.inc = 20;
my_mc.cenX = 350;
my_mc.cenY = 350;
innerRad = 20 + (Math.random () * 150);

my_mc.onEnterFrame = function ()
{
 if (Math.random () * 100 < 10)
 {
  my_mc.clear ();
  for (n = 0; n < 10; n ++)
  {
   innerRad = 20 + (Math.random () * 150)
   my_mc.lineStyle(2, 0x000000, 10);
   my_mc.beginFill (0xAA0000, 20 + (Math.random () * 60));
   drawFilledArc (my_mc, my_mc.cenX, my_mc.cenY, Math.random () * 360 , - Math.random () * 360 , innerRad, innerRad + (Math.random () * 40) + 4);
   my_mc.endFill ();
  }
 }
}

Add comment February 28th, 2005

ActionScript - function randomRange()

A very basic function to provide a random number between two values… Not exactly innovative but anyway here it is…
/***************************************
* @description generate a random number
* from a range
*
* @params  from, start of range
* @params  to, end of range
* @params  integer, return an integer?
* @returns random num in range
*/

function randomRange
(
    from:Number, 
    to:Number, 
    integer:Boolean
) : Number
{
    var range:Number = to - from;
     if(integer)
    {
        var randomNumber:Number = Math.round
        (
             Math.random()*range
        );
    }
    else
    {
        var randomNumber:Number = Math.random()*range;
    }
    randomNumber += from;
    return randomNumber;
};

Add comment December 11th, 2004

Next Posts