dasPoda

now with 12% more Poda

Performance Links

No comments

I found these pretty nifty:

replacing TextField and improving performance
http://lab.polygonal.de/2009/04/26/goodbye-textfield/

Round up of ActionScript 3.0 and Flex optimization techniques and practices
http://www.insideria.com/2009/04/51-actionscript-30-and-flex-op.html

Tips on how to write efficient AS3
part 1
part 2

a faster way of tweening (faster than tween max, but who's measuring)
Tweensy

Written by dasPoda

Friday 22 May 2009 at 9:58 pm

Posted in flash

Navigating within a loop

No comments

My loop class

I have come up against this a few times, where I needed to create a series of numbers, usually integers, that are in loop. The first time I came across
This was for the salted herring portfolio website. I needed to create these fish/cursors that displayed some basic flocking behaviour. Along with the standard boid setup, they had to face either left or right. They would only point up or down when they were moving that direction. The change in direction also needed to be smooth, which leads us to our problem of averaging angles. If you do the average of 0 and 60 degrees, you can do some simple arithmetic and you get the average of 30. However if you average 350 and 10, trigonometry would give us 0 where as basic arithmetic would give us 180. The reason is that our equation doesn’t know how that 10 is closer to 350 if you go the other direction.

This is how I dealt with that…
I converted both the angles to their x and y components, and averaged those. Then I did an aTan on the averaged x and y values, giving me the average of the two angles.

This is the simplified formula in a function that would get the average of angles a and b (in radians).

private function averageNums($a:Number, $b:Number):Number {
    var avg:Number = (Math.atan2( Math.sin($a) + Math.sin($b) , Math.cos($a) + Math.cos($b) ));
    return avg;
}

This worked for the fish, but there is a problem with this equation. If you average 0 and 180 degrees you will not get the right average.

I noticed this when I worked on another project that was looping images and I thought I could use this simple system, where instead of using 360 degrees total, I could use the set number of frames I had and round to the closest int. After spending a bit of time with the trig way of doing this, I found a much more versatile way of doing this by simply looking for the value that’s closer and finding the distance. In addition to getting a bit more reliability here, I’m now able to interpolate between the two values.

Here is the code:

/**
 * LoopNavigator - stack size has to be assigned
 * functions:
 * getDistance
 * travel
 * interpolate
 */
package loopNavigator {
    
    /**
     * @author Daniel Poda / 2009
     */
    public class LoopNavigator {
        
        private var _stackSize:int;
        
        public function LoopNavigator($stackSize:int) {_stackSize = $stackSize;}
        
        /**
         * Get distance from $a to $b
         * @param    $a
         * @param    $b
         * @return
         */
        public function getDistance($a:int, $b:int):int {
            // get all distances and find the smallest
            var norm$B:int = $b - $a;    // normalize
            var dist:int;
            var dist2:int;
            
            dist = norm$B;
            dist2 = _stackSize-((_stackSize - norm$B)%_stackSize);
            if (dist == dist2) {
                dist2 = (norm$B - _stackSize) % _stackSize;
            }
            if (abs(dist) > abs(dist2)) { dist = dist2 }
            
            return dist;
        }
        
        /**
         * Travel $distance from $start
         * @param    $start - staring int
         * @param    $dist  - direction(+/-) and distance to travel
         * @return  distance and direction of travel
         */
        public function travel($start:int, $dist:int):int {
            var b:int = ($start + $dist)%_stackSize;
            if (b < 0) { b = _stackSize + b };
            return b;
        }
        
        /**
         * Interpolate the value between $a and $b
         * @param    $a 
         * @param    $b 
         * @param    $i interpolate value defaults to 0.5 - halfway
         * @return  interpolated value
         */
        public function interpolate($a:int, $b:int, $i:Number=0.5):int {
            // get distance
            var dist:int = Math.round(getDistance($a, $b) * $i);
            return travel($a, dist);
        }
        
        // for a small speed boost
        private function abs($num:Number):Number {
            if ($num < 0) { return -$num }; return $num; 
        };
    }
}

Written by dasPoda

Tuesday 31 March 2009 at 9:41 pm

Posted in flash

Used tags: , ,

Calling Javascript from Flash

No comments

This just in
I was used to sending calls to java from within the flash file using the navigateToURL function. If you look around the Google, you will find a lot of people are doing the same still. In AS3, there is a more reliable alternative - ExternalInterfaceCall

I'm saying more reliable, since I found out that IE6 does not necessarily like calling java from an swf using navigateToURL. (I believe sp1 wasn't liking it but sp2 was OK)

Aside from being more reliable, it is also a bit shorter.

var myData:String = "my data string";

// using navigateToURL
var js:URLRequest = new URLRequest();
js.url = "javascript:sendToJavaScript('" + myData + "')";
navigateToURL(js, '_self');

// using External interface call
ExternalInterface.call("sendToJavaScript", myData);

Written by dasPoda

Monday 30 March 2009 at 9:39 pm

Posted in flash

Un-checking Radio Buttons in AS3

No comments

Radio Buttons and Un-checking in AS3

There is no direct way of un-checking a radio burron. However here's a work-around: create an invisible radio button and don't include it as a child but do add it to the radio button group.

Example:

// Let’s say you have a radio button group (RBGroup) and three radio Buttons (RB1, RB2 and RB3)
// First thing you need to do is add the RB’s to the group and add them as chilren
RB1.group = RBGroup ;
RB2.group = RBGroup ;
RB3.group = RBGroup ;

addChild(RB1) ;
addChild(RB2) ;
addChild(RB3) ;

//To change the selection you would…
RBGroup.selection = RB1 ;

//And to to check the selection you can do this
trace(RB1.selected);
 
// However, 'RB1.selected' This is a read-only parameter, so you couldn’t set all to false to un-check them
// Create another radio button and add it to the group
RBnone.group = RBGroup;

// Then you can change the selection to RBnone
RBGroup.selection = RBnone;

And as long as this radio button is NOT ADDED as child (invisible) it will appear to be unselecting all.

Written by dasPoda

Tuesday 24 February 2009 at 7:07 pm

Posted in flash

Used tags: , , ,

crossing lines in AS3

Trying to see if two lines connect or not?

No comments

Here's a little class (just barely) I wrote to aid with a little personal project

the idea is that you treat both lines as functions and equate them to one another.
Pa + fa * (Pb - Pa) = Pc + fb * (Pd - Pc);

Each point is made of x and y, so you separate the equation by substituting each point by x and then y; You can then solve for fa and fb;

It is important to solve for both fa and fb because the in both cases you are treating the intersecting line as infinite. (of course, this could be useful in some applications)

If the resulting numbers fall within 0 and 1, they intersect. if the number is infinity, they are parallel. In my code, I'm excluding when this number is 0 or 1. These are the end points, and I don't consider that as crossing.

package 
{
  import flash.geom.Point;
  
  /**
  * ...
  * @author Daniel Poda / 2008
  */
 package  
{
	import flash.geom.Point;
	
	/**
	* ...
	* @author Daniel Poda / 2008
	*/
	public class pointUtils
	{
		
		public function getIntersectingPointF($A:Point, $B:Point, $C:Point, $D:Point):Number {
			var A:Point = $A.clone();
			var B:Point = $B.clone();
			var C:Point = $C.clone();
			var D:Point = $D.clone();
			var f_ab:Number = (D.x - C.x) * (A.y - C.y) - (D.y - C.y) * (A.x - C.x);
			
			// are lines parallel
			if (f_ab == 0) { return Infinity };
			
			var f_cd:Number = (B.x - A.x) * (A.y - C.y) - (B.y - A.y) * (A.x - C.x);
			var f_d:Number = (D.y - C.y) * (B.x - A.x) - (D.x - C.x) * (B.y - A.y);
			var f1:Number = f_ab/f_d
			var f2:Number = f_cd / f_d
			if (f1 == Infinity || f1 <= 0 || f1 >= 1) { return Infinity };
			if (f2 == Infinity || f2 <= 0 || f2 >= 1) { return Infinity };
			return f1;
		}
		
		public function getIntersectingPoint($A:Point, $B:Point, $C:Point, $D:Point):Point
		{
			var f:Number = getIntersectingPointF($A, $B, $C, $D);
			if (f == Infinity || f <= 0 || f >= 1) { return null };
			
			var retPoint:Point = Point.interpolate($A, $B, 1 - f);
			return retPoint.clone();
		}
		
	}
	
}

Written by dasPoda

Friday 07 November 2008 at 1:18 pm

Posted in flash

Used tags: , ,