Posts Tagged ‘Actionscript’

Flash/Flex Integration: SWFLibrary v1.5

Tuesday, August 19th, 2008

Usually I like to post glamorous stuff, like 3D swirly things and experiments. Occasionally, however, I feel the need to release a little code in the interest of helping a few people out. This code is a review of sorts, since I already posted a similar utility back in June. However, since then I have been expanding my code library and I thought I’d share the latest and much improved version. It’s really a simple concept, but having this in my toolbox has lightened my workload as an ActionScripter considerably.

Advantages

This utility allows you to publish any symbol from Flash and access it at runtime from an ActionScript-only project, such as in Flex Builder. This has a few advantages:

  • Easy storage of many assets in one file
  • Ability to change graphics without recompiling the main application
  • Faster load times with only one HTTP request (as opposed to many separate images and sounds)
  • Ability to import vector graphics and animations at runtime
  • Smaller main SWF size

The one disadvantage that I can think of is that you’ll need to recompile your library SWF every time you make a change. However, I think the advantages above outweigh this.

Differences in v1.5

Here are the main differences from the last version:

  • The class is no longer static. This allows for more than one instance of SWFLibrary at a time.
  • The class can now return instances of Sprites, MovieClips, and Sounds from a library SWF.

Usage

1 - In Flash, select “Export for ActionScript” in the symbol’s Linkage settings in the Library (ex. ‘Character’).
2 - Publish the Flash file as a SWF.
3 - Load the SWF into an instance of SWFLibrary
4 - Access the symbol through SWFLibrary, using the class name chosen in Step 1.

A SWFLibrary can be used with four lines of code. Here’s what you’ll need:

// creates an instance of SWFLibrary, adds a listener, and loads a SWF
var gameAssets:SWFLibrary = new SWFLibrary
gameAssets.addEventListener( Event.COMPLETE, handleAssetsLoaded );
gameAssets.load( "myCustomGameAssets.swf" );
 
// accesses the asset (assumes there is a symbol exported as 'Character' in the loaded SWF, as seen in step 1 above)
// this code should run after the Event above has fired
var mySprite:Sprite = gameAssets.getSprite( "Character" );
addChild( mySprite );
 
// gets the asset as a MovieClip (assuming, of course, that it actually is a movieclip)
var myMC:MovieClip = gameAssets.getSprite( "Character" );
addChild( myMC );
 
// getting a sound
var mySound:Sound = gameAssets.getSound( "SoundLinkageNameHere" );
mySound.play();
// === ===

After a symbol has been retrieved from SWFLibrary, it may be treated like any other object.

Download

DOWNLOAD SOURCE

So have fun with this. Hopefully it saves you as much time as it saves me.

Son of Papervision! (VectorVision vs. FIVe3D)

Saturday, May 31st, 2008

ASIDE: So, the original theme of this article was a head to head between PV3D/VectorVision and FIVe3D, but then I realized that an offspring metaphor was really more apt, as explained below. Nonetheless, the following picture is too awesome not to use.

Papervision vs. FIVe3D

An awesome picture.

If you’ve been following this site for any amount of time, you’ve probably noticed that I’ve been spending quite a bit of time with Mathieu Badimon’s excellent FIVe3D engine. Probably too much time, in fact. I’ve talked about the features in other posts, so I won’t go into it here. If this is the first you’ve heard of it, go take a look at Mathieu’s examples, or click ‘FIVe3D’ in the tag cloud to the right to see what it is and some of the things it’s capable of.

It seems that the first thing people do when they see this engine is compare it with Papervision3D. I’ve resisted this for a long time; in my opinion, bitmap-based and vector-based 3D engines seem to be pretty close to the proverbial apples and oranges. However! As of sometime last week, Papervision and FIVe3D have been combined into some sort of (proverbial?) fruit punch, which means that inter-species comparisons make a lot more sense. It’s called VectorVision, and the men responsible for this unholy union are Barcinski & Jean-Jean, two mad scientists from Amsterdam.

Based on my earlier experiments, I’ve been kicking around the idea of a 3D tag cloud for this blog. FIVe3D, of course, seemed like the obvious man for the job due to its simplicity and the fact that Papervision hasn’t had anything in the way of quality text rendering. However, the experiments of the aforementioned Dutchmen made me wonder how Papervision would handle the task. So, I created a similar application using each library. You can see the results below; each image is a separate SWF- just click one to activate it.

FIVe3D Papervision3D
SWF size: 32k SWF size: 60k

Findings

As you can see, there are some differences; and of course, this is as basic as either engine gets. But in terms of pure capability, it looks like the offspring of PV3D and FIVe3D is indeed greater than either. Post your machine/browser and frame rates; I’d like to see what everyone else is getting.

FIVe3D Cheat Sheet: The Display Classes

Tuesday, May 27th, 2008

As should be obvious, I’ve been pretty fascinated with Mathieu Badimon’s elegant little 3D vector engine FIVe3D for some time now:

Experiments in the Third Dimension: FIVe3D
FIVe3D and TweenLite: Text Cloud
Best FIVe3D Experiment Yet
FIVe3D TextCloud: AS3 Tutorial and Source

And as I’ve mentioned, FIVe3D is in my opinion the easiest Flash 3D engine to pick up and play with. In my tutorial above (link #4), I am able to get a little demo running in just a few lines of ActionScript. However, my tutorial only covers the DynamicText3D class (and to a lesser extent, the Sprite3D class). Thus, as a companion work, I’ve put up a quick summary and comparison of the FIVe3D display classes below. Hopefully this will help tide a few people over until Mathieu releases the real documentation (which will certainly be much more exhaustive than my little effort).

Display Classes

Class Extends Description and Notes Dispatches MouseEvents?
Scene3D Sprite This is the base display class for the FIVe3D display list. It corresponds to the Stage in the normal Flash display list. Put simply, if it ain’t on here, it ain’t getting rendered. Yes
Graphics3D N/A This is the FIVe3D equivalent to the AS3 Graphics class. All FIVe3D display objects (with the exception of Scene3D and Sprite2D) have one, with the instance name of graphics3D. It has many of the same methods as the normal Graphics class, and you can also send an instance to the Drawing class if you want to draw additional shapes. Take a look at the example that comes with FIVe3D to see this in action. N/A
Shape3D Shape This is as basic (and as lightweight) as FIVe3D gets. Sprite3D and Shape3D share the same relationship as Sprite and Shape in AS3: both have a Graphics3D instance for drawing, but Shape3D is non-interactive and cannot have children. No
Sprite3D Sprite Just like a Sprite, but in three dimensions. Unlike Shape3D, this class can have children, each of which adopts its parents’ positions and rotations. It is also interactive. Yes
Sprite2D Sprite Sprite2Ds may be placed in three dimensions (that is, they have x, y, and z coordinates), but they can only rotate around the z axis. In other words, they’re just like normal Sprites with a “z” coordinate. Also, Sprite2Ds do not have a graphics3D object- just the plain old graphics. This means that you can’t use the methods in the Drawing class with this (unless you tweak the Drawing class). Yes
DynamicText3D Sprite3D This is a Sprite3D that displays font glyphs. Think of it as a 3D TextField. You can set the size, color, font (”typography”), and letter spacing. Fonts are kept in the typography package. Yes
Bitmap3D Shape This is analogous to a Shape3D that displays Bitmaps instead of vector graphics. Take a look at the Earth Cube source for an example of this in action.

No
Video3D Bitmap3D Video3D is a dynamic Bitmap3D, and a shell for a Video object. Just like a Video instance, you can use attachNetStream() or attachCamera() to set the video source. No

So let me know if this is useful to you- or if not, what would make it useful (more examples? benchmarks?). Hopefully it will at least give a little clarity to those who are curious about this engine.

FIVe3D TextCloud: AS3 Tutorial and Source

Friday, May 23rd, 2008

A few people have asked me to release the code to my FIVe3D Text Cloud example, so I’ve cleaned things up to the point where I wouldn’t be completely humiliated to release it into the wild. However, I thought I’d touch on a couple points and turn this post into something halfway between a tutorial and an exhibition.

If you just want the source code, you can download it at the bottom of the page. If you’d like the whole shebang, pray read on.

The (new and improved) example:

FIVe3D Basics

FIVe3D is ridiculously easy to set up. In this example, I used the following code to set up everything I needed:

// the Scene3D class is what contains and renders everything else
// think of it as a 3D Stage class
scene = new Scene3D();
scene.x = 375;
scene.y = 200;
addChild( scene );
 
// Sprite3D is, obviously, a 3D version of the standard Sprite class
// it is an actual DisplayObject, so you can use normal positioning, filters, etc. on it
container = new Sprite3D();
scene.addChild( container );

You’ll notice that the syntax is just like AS3 extended into the third dimension. You can nest Sprite3Ds just like Sprites. When you move or rotate the parent Sprite3D, the children will move and rotate with it. The reason I’ve created a container Sprite3D here is so I can rotate several children at the same time.

Now if I wanted to do this the easy way, I could just add my text in one big chunk with the DynamicText3D class that ships with FIVe3D. It works much like the AS3 TextField class, except that the fonts are actually ActionScript files (you’ll see what I mean when you crack open the FIVe3D source).

var txt:DynamicText3D = new DynamicText3D( HelveticaBold ); // HelveticaBold ships with FIVe3D
txt.size = 30;
txt.color = 0xD34328;
txt.text = "Pixelwelders LLC"
container.addChild( txt );

That’s it. The Scene3D class takes care of its own rendering, so you don’t have to trigger it yourself, Papervision-style. Even when a FIVe3D scene looks static, it is actually rendering at your current frame rate. Thus, this is enough code to render 3D text in FIVe3D. Add an ENTER_FRAME listener and increment the container.rotationX property every frame and you’ll see what I mean.

Moving On…

Now this is fine for your everyday run-of-the-mill 3D text, but not for the effect that I had in mind. If I had added my text this way, it would have behaved as a single block, each letter forever doomed to stay wedged firmly between its neighbors. No, I had bigger plans for this text.

For this effect, I created a class called MotifCollection3D. Not a very good name, but typography is not my strong suite and I wasn’t quite sure what else to call it. It’s an extension of the aforementioned FIVe3D Sprite3D class, and it contains one DynamicText3D instance for every letter of the word that it’s currently displaying. This is how you instantiate it:

var cloud:MotifCollection3D = new MotifCollection3D( "PIXELWELDERS LLC", HelveticaBold, 30, 0xD34328 );
container.addChild( cloud );

There’s nothing to it. You send the text, the font class (again, included with FIVe3D), the size, and the color. It creates and assembles all the DynamicText3D instances, and then you can treat it like any other Sprite3D. However, it also includes two methods: assemble(), and the thrillingly-named explode().

Calling either of these methods cycles through all the instances of DynamicText3D and tweens them each to a destination using TweenLite. The explode() method was easy: it just chooses a random destination and rotation for each letter. The assemble() function, on the other hand, was a bit trickier; it needs to know the exact width of every letter in order to place them next to each other.

Happily, that is one of the things that’s included with the FIVe3D typography classes. Each letter, number, and punctuation mark in HelveticaBold contains a __width property, accessible like so:

var letterWidth:Number = HelveticaBold.__widths[ "P" ]; // returns the width of the "P" glyph

That’s a start, but it returns the same width regardless of what size the font is being displayed at. After a little experimentation, I found that this code gives the correct glyph width no matter what size the font:

var letterWidth:Number = HelveticaBold.__widths[ "P" ] * ( size / 100 );

I think that pretty much covers anything novel that I may have done. There are additional comments in the code as well, and it’s only two classes anyway: it shouldn’t be too difficult to figure out anything not explicitly laid out here.

Download Source

Pixelwelders FIVe3D Text Cloud

NOTE: You’ll need to download TweenLite and FIVe3D from their respective sites to get this to run. But you probably already knew that.

Best FIVe3D Experiment Yet- Seriously, It’s Awesome

Monday, May 12th, 2008

The FIVe3D examples are starting to fly hot and heavy through the blogosphere, so here’s another contribution. This will probably be the theme of my new portfolio, but I was so impressed with the result that I had to post it. This will be perfect with a bit of scratchy 1920’s horn music.

FIVe3D and TweenLite: Text Cloud

Monday, April 28th, 2008

UPDATE: I have another FIVe3D example/experiment (3D graphing) here. And, if you’re just cruising the web for FIVe3D examples, I have yet another one here.

I can’t seem to get enough of this FIVe3D thing. It’s even becoming natural to capitalize every letter except for that “e” when I write it. Not that I’m blinded to its faults, for there are a few here and there. But for quick 3D text rendering, I have yet to find its equal.

Take today’s experiment, for example. It was originally a Twitter viewer, but I haven’t figured out how to get it working online yet, so I’ve given it some generic text to render. It uses TweenLite for movement, and FIVe3D for rendering. Try clicking around and moving the mouse.

The part of this project that would have been challenging in PV3D or Sandy is the spacing of the letters. It was a great relief to find that FIVe3D is already intimately aware of each letter’s size, since it is rendering them as shapes. Thus, I didn’t have to painstakingly experiment to find the proper spacing.

Once I actually think up a clever tagline, I might just turn this into my site header. This could also be a pretty slick little tag cloud for site content, but I think it might get annoying if this was the only way to find a category. Ah well. A man can dream.

UPDATE
I did indeed turn this into my header. We’ll see how many people play with it.

UPDATE #2
And… I took it back out. Seems that something was weird with IE and Kimili Flash Embed. Or… it could have been user error.

UPDATE #3And… source code is live! With a tutorial/walkthrough, even! Get it here:
FIVe3D TextCloud: AS3 Tutorial and Source

The Art and Beauty of Singletons

Monday, April 14th, 2008

What is a Singleton?

A) In poker, a card that is the only one of its rank.
B) In animal husbandry, the sole surviving offspring of a litter.
C) In astrology, a single planet alone in a hemisphere (or some crap like that).
D) In mathematics, a set with only one member.
E) In England, a small village about 7 miles north of Chichester in West Sussex.

A cute yet tragic Singleton

All of these things share a trait, and that trait is that each is the only one of its kind. If two kittens survive from a litter, neither one is a singleton. If a set has more than one number, it is not a singleton. In works the same way in object-oriented programming; a Singleton is a class that allows only one instance of itself; if there are more than one, that class cannot be a Singleton.

So why would one want a class that only allows one instance of itself? I can think of many applications. A ScoreKeeper class for your game, perhaps, or a Countdown class that keeps track of how much time you have to complete a level. In OS Wars I use a Singleton to keep track of all building resources currently in the game. There’s another one that keeps track of all the units on the battlefield. In fact, the Battlefield itself is a Singleton, because there’s no reason I would ever need more than one.

Another great thing about a Singleton is that, because there is only one, it’s very easy to get to. With a normal object, you have to worry about passing it around to the various classes that might need it. With a Singleton, that’s not necessary. All you need to do is import the class and voilà- there’s your Singleton.

The Village of Singleton

It works this way because the class itself keeps a static reference to the only instance of itself. So instead of calling the constructor to get a reference to a new instance, you call the SingletonClassName.instance method to get a reference to the already-created instance. If that doesn’t make sense, here’s an example. This first piece of code is what a normal ScoreKeeper class would look like. With this structure, you can use that syntax that everyone knows and loves, new ScoreKeeper(), which returns a brand new ScoreKeeper every time it’s called.

package
{
	public class ScoreKeeper
	{
		public function ScoreKeeper()
		{
			trace( "new ScoreKeeper" );
		}
	}
}

But suppose you wanted to ensure that there was only one ScoreKeeper, and you wanted to be able to easily access it from any location in your program. That means two things: A) the constructor can only be called once, and B) you need to keep track of the new ScoreKeeper that one time the constructor does get called. What good is having one instance of a class if you can’t get to it? So here’s the Singleton version of the above class:

package
{
	public class ScoreKeeper
	{
		private static var _instance:ScoreKeeper;
 
		public static function get instance()
		{
			if ( !_instance )
			{
				_instance = new ScoreKeeper();
			}
 
			return _instance;
		}
 
		public function ScoreKeeper()
		{
			trace( "new ScoreKeeper!" );
		}	
	}
}

There are two differences here: the static variable _instance and the static method get instance(). The _instance variable is where the actual instance of this class is stored. And the get instance() method, of course, enables you to access this instance. So to access this Singleton, you would use:

ScoreKeeper.instance;

And to call any methods or properties of the Singleton, you would use this syntax:

ScoreKeeper.instance.addScore( 50 );
trace( ScoreKeeper.instance.score );

This of course assumes that your class has a public method called addScore() and a public property called score. You can get to any public methods or properties this way.

This also adds one more layer, called lazy initialization. Look in the get instance() method, and notice that before it returns a reference to the Singleton, it checks to see if that reference exists. If so, it simply returns it. If not, it creates it first and then returns it. Either way, you’re guaranteed to get the one existing instance.

There is one problem remaining- if you were so inclined, you could still call the constructor without going through get instance(), which would of course result in two Singletons. And as we discussed above, making two of something makes it not a Singleton anymore. So how can we prevent this? There are a few ways I’ve seen floating around, but the simplest is this:

package
{
	public class ScoreKeeper
	{
		private static var _instance:ScoreKeeper;
 
		public static function get instance()
		{
			if ( !_instance )
			{
				_instance = new ScoreKeeper();
			}
 
			return _instance;
		}
 
		public function ScoreKeeper()
		{
			if ( _instance )
			{
				throw new Error( "Singleton already exists- use get instance() to access" );
			} else {
				trace( "new ScoreKeeper!" );
			}
		}	
	}
}

The new lines are in the constructor. The get instance() method still only calls the constructor once, but if you forget it’s a Singleton and call the constructor later, you get a runtime error.

There are also a couple more complicated ways of ensuring that your Singleton is in fact a Singleton, but I haven’t lost too much sleep over over it. I usually even leave out the check in the constructor. Just remember that if it has _instance and get instance(), and a big comment up at the top that says “SINGLETON!”, it’s probably a Singleton.

AS3 Earthquake Class v1.0

Monday, March 24th, 2008

I’ve noticed that there are a lot of small things that can save you time when designing and coding a game. Stuff that wouldn’t take long to code, but if someone’s already done it, why bother?

So in that glorious spirit of apathy, I present to you the Pixelwelders Earthquake class. This is just a simple little class that allows you to create an earthquake (or explosion, or invasion, or whatever) in your game. You just feed it a DisplayObject, the intensity of the quake, and the duration in seconds, and voilá. This is the syntax:

Earthquake.go( displayObject:DisplayObject, intensity:Number, seconds:Number ): void

And this is a two-line example:

import com.pixelwelders.fx.Earthquake;
Earthquake.go( gojira, 10, 1 );

And this is the result. Notice that each time you click, the earthquake is slightly different. Scroll down to download the class.

Download the class (and the above example) here.

AS3 A* Pathfinding Engine (v1.0)

Friday, March 21st, 2008

She ain’t much to look at, but she sure do work. Honestly, I’m not exactly sure how it works. A recursive function is a fierce and fickle mistress.

Pathfinding engine v1.0

Actually, I do know how it works; I was just startled at how fast it came together. There are a lot of great resources on the subject, as well. Here’s the one I used:

A* Tutorial for Beginners

And if you’d like to play around with it, just click the image.

The real problem I have with it is that it’s pretty short-sighted. Units don’t see a wall until they’re right on top of it. Obviously this makes sense for a lot of units- sometimes you don’t know where you’re going until you get there. But I think I’m going to try some smoothing algorithms to remove some waypoints and get those paths a little more natural-looking.