Friday, September 18th, 2009 | Author: Dave

Recently I did a kids game in Flash that was deployed as a kiosk and which toured a handful of the nations zoos. One of the requirements for the game was that at the end, it would ’sneeze’ on the player - emitting a brief blast of distilled water. After a fair amount of research I found what I needed in SWFKit, one of the leading ‘wrapper’ tools for Flash. By using SWFKit you have all sorts of access to various Windows components like the registry, dialogs, file system and a lot more. I find it invaluable for kiosk work.

The essential component however was an ActiveX component, created by the same SWFKit team. It is called CPortX ActiveX Component and is what allows SWFKit and Flash to communicate with one of your com ports.

So first, you need SWFKit and you can get that at: http://www.swfkit.com

Once you have it installed, you need to get the CPortX ActiveX component, which you get from the same site at: http://www.swfkit.com/swfkit/download.html#tools

Once you have the component installed you’ll be able to send messages to a com port directly from Flash.

The second phase in my research was then how to get the com port to now turn a pump on and off. After much searching I found what I needed in an RS-232 controlled relay from relaycontrollers.com

For this project I used their R15RS - a fairly low cost, single relay controller with a 5 amp rating. I also picked up a power supply for it, and a cable to go between it and the computer’s com port. All together the three pieces were just under $100.

With this simple setup: the ActiveX component and the relay, you can control all sorts of devices from Flash. I however, needed to control a ’sneezer’. What I did for this was to use a windshield washer pump, available at any auto parts store, with the output going to a nozzle, that could be set to spray anything from a stream to an atomized vapor. Think kitchen cleaner nozzle and you’ll get the picture.

Here’s an image of the relay controller that was used:
relay

The labels, NO, COM and NC mean Normally Open, Common, and Normally Closed. When the relay is off, ie the coil is not energized, the Common arm connects to the Normally Closed connection. When the relay is energized, the Common swings over the the Normally Open connection. With that in mind, the pump and its power supply would be connected like so:

relay_schem

When the relay is turned on the Common swings over to Normally Open and provides power to the pump. Simple as that.

The next step is to write a bit of code to send the proper signals to the com port. For this, the code is written within SWFKit and then called from Flash using ExternalInterface.

Within SWFKit choose to make a new file. This will add an Initialize script to the script list, which is called automatically. Within initialize you need to create an instance of the CPortX ActiveX component:

var commx = new ActiveXObject("CPortX.ComPortX");
 
if (commx == null)
{
	Dialogs.msgBox("Please install the CPortX ActiveX control!");
	return false;
}
 
commx.syncMethod = 2;
 
getMainWnd().onClose = function ()
{
	commx.close;
}

First, we try and create an instance of the component. If it’s null, then it hasn’t been installed and a dialog is presented. The syncMethod is then set to 2, which sets the baud rate and such. Finally, the onClose method is created that closes down the component when the projector is closed.

Next, we need two more scripts - one to turn the relay on, and one to turn it off. You do this by right clicking the Script panel and selecting New Script. First - the relayON script:

if (commx.connected) commx.close;
commx.port = "COM4";
commx.open;
commx.writeStr("\xFE\x01");
commx.close;

Using the commx instance created within the initialize script, the port is set to com4, opened and then written to before being closed. By sending the hexadecimal FE and then 01 the relay is instructed to turn on. The FE instructs the relay (or modem) to ‘listen’ and then you send the command. In this case a 1 turns the pump on. Makes sense.

Turning it off is just as simple, sort of. Here’s the relayOFF script:

if (commx.connected) commx.close;
commx.port = "COM4";
commx.open;
 
var ss = new StringStream;
ss.put('\xFE');
ss.put(0);
 
commx.write(ss);
commx.close;

The difference here is that I could not use commx.writestr(”\xFE\x00″); - it simply would not work to send a 0 this way. The great folks at SWFKit provided the fix, telling me to use the StringStream object to send it instead. But the same thing happens - we send the FE telling the relay to listen, and then 0 to turn it off.

Lastly, we just need to call these two scripts from within Flash using ExternalInterface. First I have a turnOn() method which calls the SWFKit relayON script:

function turnOn():void
{			
	ExternalInterface.call("ffish_run", "relayON");			
}

This is called from a sneeze method, which calls turnOn(), and also starts a timer to call turnOff():

function sneeze():void
{		
	turnOn(); //relay			
 
	myTimer = new Timer(400, 1);
        myTimer.addEventListener(TimerEvent.TIMER, turnOff);
        myTimer.start();
}
 
 
function turnOff(e:TimerEvent):void
{	
	myTimer.removeEventListener(TimerEvent.TIMER, turnOff);
	ExternalInterface.call("ffish_run", "relayOFF");			
}

When sneeze() is called, it calls turnON() which turns the relay on, and in turn the pump. A timer is then started which calls turnOff() after 400 ms. The turnOff() method removes the timer listener and calls the relayOFF script within SWFKit. As you might have guessed the 400 ms timing was decided on by simple testing… it gave the pump just enough time to send out a nice little burst of water, aimed right at the player’s face. Believe it or not, it was a big hit.

With this kind of setup - SWFKit and a controllable relay there is a lot of possibility to do things from within Flash that might have otherwise been impossible. The relay company also makes multi-channel relays, which you could use to enable switching of various devices all from the same application. Lots of potential here.

Category: Flash  | 2 Comments
Saturday, September 05th, 2009 | Author: Dave

Here’s a nice little tip for smoothing bitmaps when you’re loading them from an external source. Let’s say you use something like so to load a client logo:

var logoLoader = new Loader();
addChild(logoLoader);
logoLoader.load(new URLRequest("myUrl/myFile.jpg"));
logoLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, logoComplete);

When the jpg has loaded, logoComplete will be called - you can smooth the image using:

function logoComplete(e:Event):void 
{	
	//smooth loaded image	
	var bit:Bitmap = e.target.content;
	if(bit != null){
		bit.smoothing = true;
	}
 
	//resize to fit grid squares
	bit.width = bit.height = SQUARE_SIZE;
 
	//fade in
	TweenLite.from(bit, 1, { alpha:0 } );
}

This can be especially handy if you’re resizing the image by setting its width and height, as shown here.
girl_sample
Here’s a sample of loading an identical 150×150 jpeg image and then resizing to 300×300 with the above code. The one on the left has the bit.smoothing = true; line commented out.

Category: as3  | Leave a Comment
Wednesday, July 01st, 2009 | Author: Dave

Recently, I did a kids game that featured bugs dropping from the sky on parachutes. I handled the vertical motion using script, but thought I’d do the back and forth swinging on the chute using the timeline. Minus the vertical motion I got something like this:

It works, but as you can see Flash doesn’t rotate bitmaps very well, and the client was less than thrilled with it. So, I did a bit of looking and found that if I used pure code I could make a bitmap object from my library items and use the smoothing option. Instead of what I had, I got this:

Much nicer. Here’s the AS3 code I used:

var bug = new Bitmap(new BugA(50,56), "auto", true);
var par = new Bitmap(new Parachute(60,60), "auto", true);
 
var rot = 1.8;
var c = new Sprite();
 
c.addChild(par);
par.x = -30;
par.y = -20;
 
c.addChild(bug);
bug.x = -20;
bug.y = 22;
 
addChild(c);
 
c.x = 100;
c.y = 70;
 
addEventListener(Event.ENTER_FRAME, loop);
 
function loop(e:Event)
{
	c.rotation += rot;
	if(rot > 0){
		if(c.rotation > 25){rot *= -1;}
	}else{
		if(c.rotation < -25){ rot *=-1;}
	}
}

The first two lines are what make the magic happen. A bug and parachute bitmap object is created from simple .png graphics in the library. They have their linkage properties set to export for ActionScript like so:
linkage
Their base class is of type BitmapData because they are images. The final parameter of the Bitmap constructor is the smoothing parameter. By default it is false. Setting it to true, gives us the smooth rotation we’re after.
The remainder of the code creates a Sprite object, places the two Bitmap objects into it, and then places the Sprite so it can be see - with addChild. An Enter Frame listener is added so that the loop function is called. All it does it rotate the object back and forth. All in all, pretty simple and the client was much happier with the result.

Category: as3  | Leave a Comment
Tuesday, June 16th, 2009 | Author: Dave

I’ve been using the uint type in AS3 quite a lot, just because it makes sense for what I’m doing. But yesterday I ran into a gotcha with it. I was using it for a bonus score in a game, that was being decremented every so often by a timer. Since I wanted it to stop when it reached 0, I did the typical:

function updateBonus(e:TimerEvent){
  bonus -= 3;
  if(bonus < 0){
    bonus = 0;
    bonusTimer.removeEventListener(TimerEvent.TIMER, updateBonus);
  }
  bonusText.text = String(bonus);
}

But the field never stopped updating, in fact it would get really big values in it after a while. Like 4294967295

Try this:

var a:uint = 0;
trace(a - 10);
// -10

Odd because I was expecting to see the large values I mention above, not -10. Because I’m not assigning the decrement to a.

var a:uint = 0;
a -= 10;
trace(a);
// 4294967286

There it is. Since a is unsigned, it rolls over to the maximum integer when less than 0. So the test I had (if a < 0) would never be true, and the bonus would eventually get huge. Good for the player, bad for the folks handing out prizes based on score.

So, simply changing the bonus’ type from uint to int fixed the issue. Such a simple thing to be tripped up by.

Category: as3  | Leave a Comment
Saturday, February 28th, 2009 | Author: Dave

I contend that for a nation to try to tax itself into prosperity is like a man standing in a bucket and trying to lift himself up by the handle.
– Winston Churchill

Monday, January 26th, 2009 | Author: Dave

For a long time I’ve been working to expand my OOD skills, and have read many articles, blogs and a few books. Head First Design Patterns is great, by the way. Anyway, one concept that you will come across repeatedly is that of encapsulating what varies.

Have a look at the following getUsers() method - this is a method from an AMFPHP service class that simply returns the data, for a given user, from a MySQL users table to Flash:

function getUser($id)
{	
        $sql = "SELECT * FROM users WHERE id=$id";
 
	$result = mysql_query($sql, $connector);
	if(mysql_num_rows($result) != 0){
		return mysql_fetch_array($result);
	}else{
		return -1;
	}
}

Simple enough. However, in a typical system you will have dozens of services and most of those services will have multiple methods - eg. to save, update and delete data as well. So, what happens when your shiny new system is installed on a server running PostgreSQL? Answer: You spend days changing API calls if your code looks like the above. And then you have two versions of your services. The problem is that you’ve programmed your services to work only with the MySQL API methods.

So how do you fix it? You encapsulate what varies - the database API calls. If you stick the database access stuff into its own class, and then access everything through your new database class, you remove the tight coupling you have to MySQL. If you need to change the database API calls, you only have to change one class, not the potentially hundreds that may use it. Let’s take a look at a modified version of the above method:

var $myDB;
$this->myDB = new DBAccess(); //create an instance of the DBAccess class
 
function getUser($id)
{	
	$sql = "SELECT * FROM users WHERE id=$id";
 
	$result = $this->myDB->query($sql);
	if($this->myDB->num_rows($result) != 0){
		return $this->myDB->fetch_array($result);
	}else{
		return -1;
	}
}

And over in your DBAccess class you’d define the query(), num_rows() and fetch_array() methods, along with any other database related functionality:

<?PHP
 
	class DBAccess
	{					
		function DBAccess(){}		
 
		function query($sql)
		{
			return mysql_query($sql, $this->getConnection());
		}
 
		function num_rows($result)
		{
			return mysql_num_rows($result);
		}
 
		function fetch_array($result)
		{
			return mysql_fetch_array($result);
		}		
 
		function getConnection(){			
			$con = mysql_connect("localhost", "DBUSER", "USERPASSWORD");
			mysql_select_db("DATABASENAME", $con);					
			return $con;
		}
	}
?>

If you change over to PostgreSQL you need only to modify DBAccess.php. And taking it a step further, you could put in switch statements enabling the class to use various databases.

Category: OOP  | Leave a Comment
Monday, January 12th, 2009 | Author: Dave

Some updated pics as recent as two days ago… he’s getting big already!
Click here

Wednesday, January 07th, 2009 | Author: Dave

In this tutorial we’ll develop classes to allow enemy ships, in a potential game, to move with various motions, using ActionScript 3’s event system.

Overview:
Motion class - this class will use an algorithm to move a single point around it’s own internal coordinate system. By that I mean the class is not tied to any particular object, it just does it’s thing and programmatically moves a point - it’s up to other objects that subscribe to motion update events to use the class’s x,y values.
Motion Event class - we’ll dispatch a custom event object from the motion class to allow the x,y values to be sent to any registered listeners.
Controller - just a bit of code on frame 1 of an .fla that will create instances of a library clip (the enemy) and set up the motion class to allow the enemies to move.

Getting Started:
To begin start a new .fla file using ActionScript 3. Make a small enemy movie clip (about 30×30) and delete it from the stage. Right-click it in the library and select Linkage. Check export for ActionScript and give it a class name of Invader. Giving the clip a class name will allow you to create instances of it programatically. For ease of use, you should create a new folder for this project and save your file there now. The classes you create will be saved into this same folder.

The Motion Class:
As stated previously, this class will simply move a point around. As it does it will dispatch events so that any objects that are listening (the enemies) can respond appropriately. Select File > New and choose ActionScript file from the dialog. Enter the class code:

package
{
	import flash.events.EventDispatcher;
	import flash.events.Event;
	import flash.utils.Timer;
        import flash.events.TimerEvent;
	import InvaderMoveEvent;
 
	public class MoveRoutine_circle extends EventDispatcher
	{
		private var curX:Number;
		private var curY:Number;
		private var ang:Number;
		private var myTimer:Timer;		
 
		function MoveRoutine_circle()
		{
			ang = 0;
			curX = 0;
			curY = 0;
			myTimer = new Timer(10);
			myTimer.addEventListener(TimerEvent.TIMER, evtMove);
		}
 
		public function move():void
		{
			myTimer.start();
		}
 
		public function pause():void
		{
			myTimer.reset();
		}
 
		private function evtMove(e:TimerEvent):void
		{
			ang += .05;
			if (ang >= 6.28) { ang = 0; }
 
			curX = Math.sin(ang);
			curY = Math.cos(ang);			
 
			dispatchEvent(new InvaderMoveEvent(curX, curY));
		}
	}
}

Save this class as MoveRoutine_circle.as in the same folder as your .fla file. Let’s have a look at the code. First, the class extends EventDispatcher in order to have event capabilities - other objects may add event listeners to this class, and the class can dispatch events as necessary. Within the constructor method, default values are applied to the class variables and a timer object is instantiated. The timer is told to call the evtMove() method every 10 ms. The move() and pause() methods simply start the timer running, and reset it respectively. Note that these are public methods allowing external control of the enemies. Finally, the evtMove() method - it is private because it is only called from within the class - by the timer. It accepts a single parameter, of type EventType, as all event listeners do.
So, within the evtMove() method is the code that does the actual moving of the point. As you may be able to tell, all this code does is to move the point in a circle. The ang variable starts at 0, as set in the constructor, and counts to 6.28 (2 * PI) by .05, before resetting back to 0. In radians this is one complete revolution. As ang is incremented, the sine and cosine are computed and placed in curX and curY. Next, the custom event is dispatched - and curX and curY are sent along to anyone interested.

Note: by playing with the algorithm you can create all sorts of interesting sub-motions. More on that later.

The InvaderMoveEvent class:
As the motion class runs it dispatches new InvaderMoveEvent objects to any registered listeners. Using a custom event here makes sense because it allows you to send the current x,y values directly to listeners. If you were to not use a custom event, the listeners would, after receiving the event, have to poll the motion object to retrieve the x,y values - making for more communication than necessary, and potentially slowing things down.
As before, select File > New and choose ActionScript file from the dialog. Enter the class code:

package 
{
	import flash.events.Event;
 
	public class InvaderMoveEvent extends Event 
	{
		private var _x:Number;
		private var _y:Number;
 
		public static const MOVE:String = "invader_move";
 
		function InvaderMoveEvent(nx:Number = 0, ny:Number = 0)
		{				
			_x = nx;
			_y = ny;			
			super(MOVE);
		}
 
		public function get x():Number
		{
			return _x;
		}		
 
		public function get y():Number
		{
			return _y;
		}
	}	
}

Save this class as InvaderMoveEvent.as in the same folder as your .fla file. As all custom events must do, it extends Flash’s built-in Event class and makes a call to super(eventType) in the constructor - invoking the Event class’s constructor with the data from the custom one. Because I’m using the event to simply carry the x,y data to listeners, and nothing else, I opted out of sending in any of the normal parameters (type, bubbles, etc) and just use the MOVE constant directly in the call to super(). I’ve also not done the override on clone or toString. Two getter methods provide the x,y values to the objects receiving the event.

Let’s quickly see this in action. Add this code to frame 1 of your Flash movie:

var moveCirc = new MoveRoutine_circle();
moveCirc.move();

As you might guess this bit of code creates an instance of the circle motion class and stores it in the variable moveCirc. Next a call to the object’s move() method starts the class’s internal timer which in turns starts making calls to the evtMove() method and begins dispatching the custom event. Underneath the current code add this:

moveCirc.addEventListener(InvaderMoveEvent.MOVE, see);
function see(e:InvaderMoveEvent){
	trace(e.x);
}

What this does is register the timeline function see() to receive the MOVE event type from the class. Test the movie to see the results. You should see a continuous stream of numbers roll by (the points current x) in the output panel. When you’re done you should delete, or comment, those last three lines, as you don’t want the timeline to always listen for motion updates, the enemies will do that themselves.

Note: you could actually create n enemies, sticking references to them in an array. The timeline could receive the motion update and then iterate the array, passing in the values. However, that is essentially bypassing the event system, and inherently slower. Although in testing I got good results with this method, I opted to have individual enemies receive the event directly by registering their own update method.

The Enemy:
Previously, you created a small enemy graphic movieClip and set its class name to Invader. When you test the movie Flash automatically creates the Invader class, because one doesn’t exist in the folder. Click File > New and choose ActionScript file from the dialog. Enter the class code:

package 
{
	import flash.display.MovieClip;	
	import InvaderMoveEvent;
 
	public class Invader extends MovieClip
	{
		private var myX:Number;
		private var myY:Number;
 
		//s is a reference to the current motion class object
		public function Invader(s:*) {			
			s.addEventListener(InvaderMoveEvent.MOVE, doMove);
		}
 
		public function setPos(newX:Number, newY:Number):void
		{			
			myX = newX;
			myY = newY;
		}
 
		private function doMove(e:InvaderMoveEvent):void
		{			
			this.x = myX + e.x;
			this.y = myY + e.y;
		}
	}	
}

Save this class as Invader.as in the same folder as your .fla file. Now when you run the movie, this class will be attached to every enemy invader that is created. Let’s create a single enemy on stage to see how this works. Add these three lines to frame 1 and test the movie:

var p = new Invader(moveCirc);
p.setPos(0,0);
addChild(p);

You should see one enemy ship moving in a small circle. When you invoke the constructor:var p = new Invader(moveCirc); you pass in a reference to the current motion - moveCirc in this case. The Invader class then registers its doMove() method to receive motion updates. The setPos() method allows the code to set the invaders initial position, and updates the internal class variables accordingly. When an event is received, ie when doMove() is invoked the enemy position is updated - note that the enemy is always moved about it’s initial position, if you were to do something like: this.x = this.x + e.x; the objects would end up moving off screen.

Let’s see how more enemies do. Erase those last three lines that add the single enemy and replace them with the following:

for(var i=0; i < 8; i++){
	var v = new Invader(moveCirc);		
	v.setPos(50*i,0);
	addChild(v);	
}

Test the movie and you will see eight ships, all in a row and all moving in a small circle. The code on the frame is, essentially, your controller - it creates an instance of your motion class, and instances of an enemy ship class, and binds them together - by passing a reference to the motion class, to new enemy instances.

Things to try now include modifying the algorithm in the circle class to create differing motions. By creating new classes for your different motions you can create a plugin motion system quite easily. You can also quite easily create a compound motion, where the enemies march across and down the stage, as in the classic space invaders - and still keep their local motion as dictated by the motion class. You can do this by creating a new Sprite, adding the clips to the sprites display list, and then adding the sprite to the main display list. Like so:

var p = new Sprite();
for(var i=0; i < 8; i++){
	var v = new Invader(moveCirc);		
	v.setPos(50*i,0);
	p.addChild(v);	
}
addChild(p);

You can also make bigger circles simply by multiplying the curX and curY values by some number, inside the evtMove() method.

Here’s an interesting variation:

curX = Math.sin(ang) * 10;
curY = Math.tan(ang/2);
Category: Flash  | 4 Comments
Monday, December 29th, 2008 | Author: Dave

Yeah… so it’s been too long. But time flies when you have a baby… whew does it. But, here’s a link to some pictures Jackie has posted on the Kodak site… more to come.

http://www.kodakgallery.com/ShareLanding.action?c=o1r4veu.9ctvhrwe&x=0&h=1&y=-tx68zn&localeid=en_US

Category: Life  | One Comment
Wednesday, November 26th, 2008 | Author: Dave

Kaden was delievered at 11:48 am. He weighed 6 lbs 10 oz and was 19.5″ long. The pitocin did exactly what it was supposed to do - the nurses and doctor Leonhardt were all really great and it went as smooth as we could’ve ever hoped for. Jackie was awesome… she pushed so hard. She was beautiful. We took a bunch of pictures and I will get them posted sometime tomorrow evening if I can find some time.

Category: Life  | Leave a Comment