Archive for the ‘Code’ Category

21
May 10

FlxBitmapFont – A Bitmap Font class for Flixel 2 released

Today I released my FlxBitmapFont package to Google Code. This allows you to use bitmap fonts directly in your Flixel 2 games:

The bitmap fonts are just an extension of a Flixel Sprite, meaning you can throw them around, collide with them, scale them, rotate them and generally cause havoc. Or of course they could just be UI elements, proving a score/lives count. But at least the choice is yours :)

11 fonts are included, 2 sample programs and comprehensive documentation in the form of a PDF file. I’ve also published that here on my blog: http://www.photonstorm.com/flxbitmapfont and I will update both my blog and the Google Code archive as needed.

Anyway I hope you have fonty fun with this! Look out for a number of new Flixel classes from me in the coming months, or catch me on the flixel forums where I help moderate the place.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

22
Mar 10

Dealing with the FlxU.overlap kill in Flixel 2

FlxU.overlap in Flixel 2 uses the new FlxQuadTree to handle collisions. It allows you to pass in either a single object (say an FlxSprite), a group of objects (FlxGroup), or even a group of groups! To be honest the more you give it, the more useful it proves to be.

However it’s got one annoying side-effect: if you don’t specify a custom function to deal with the collision, it will kill() your objects. This is often a far from ideal end result. For example if you had a bullet and an enemy being compared – you may want the bullet to be killed instantly, but the enemy to be only “hurt” by this, reducing it’s health.

The only way I’ve found to do this so far is to override the “kill” method of FlxSprite (in my Enemy class) and then perform the logic in there. Reduce health, update animation, health < 0, then kill it for real.

This isn’t ideal, but it certainly works – so if you’re stuck in a similar bind with FlxU.overlap, this may help.

Also it’s worth mentioning (as this caught me out too) – if you do specify a custom function for overlap, make sure it returns a Boolean. False will ignore the overlap, true will say you’ve dealt with it. If you don’t return this value it appears to default to killing your objects again.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

19
Mar 10

FlxSnake – A simple Snake game for Flixel 2.23+

I’ve been playing with Flixel a lot recently, and over on the forums someone was having trouble getting a “snake” game to work. I always applaud people who “start simple”, rather than diving in the deep end and sinking without trace.

So I spent lunch time today knocking together a simple snake game in Flixel 2.23.

There are no graphics (just blocks), but it shows how to use an FlxGroup to handle single to many collision checks, simple sprite controls and of course a basic snake game mechanic. The whole thing is just one single class file with no external requirements.

It’s up on my GitHub account here: http://github.com/photonstorm/FlxSnake

And if you want to join in, the forum thread is here: http://flixel.org/forums/index.php?topic=1261.0 (I’m a moderator on the Flixel forums, so drop by and say hi!)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

15
Mar 10

The 8-bit Rocket auto-biography is out

20 man months of work.

Copious amounts of writing, editing, re-writing, re-editing and editing once more.

Stacks of demo games and hundreds of lines of quality source code.

All to make this the finest 650+ pages of AS3 game development ever commited to dead tree.

Jeff and Steve, the 8-bit Dynamic Duo have done it! Their book is finally out …

The Essential Guide to Flash Games: Building Interactive Entertainment with ActionScript

Despite having a slightly odd title (how many games have you ever played that weren’t interactive?!) this book looks awesome. I’ve pre-ordered my copy from Amazon UK and will give it a proper write-up when received. I have major respect for people who hold down full-time jobs / families, and still manage to produce such a mammoth book as this.

There is a bit of blurb on the Friends of Ed web site about it, although not as much as I would have liked. For example no contents listing, no sample chapter, a poor quality cover image and no index even. Given how many books on web development FoEd produce it begs the question why their own site is so shit. But I digress (and hopefully they will update this page over time). So for now the best place to learn about the contents is from the horses mouth so to speak, here on the 8-bit Rocket.

Congrats Jeff and Steve – I wish you all the best with sales. All you have to do now is stop calling my games advergames and the world will be perfect ;)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

25
Feb 10

Save MovieClip as PNG Example

A couple of guys on Twitter asked me if I would write-up how I generate PNG files from MovieClips in my SWF, at run-time. So I put this example together and am sharing it here.

We use this technique in our virtual world WebbliWorld to save a PNG version of the users avatars after they have customised them. But there are all kinds of other reasons you may need this. My example includes two methods: Saving the PNG locally using the local file system, and Saving the PNG to a web server using AMFPHP.

This technique requires Flash Player 10 and the Adobe AS3 Core Lib.

Here's a very simple example (included in the zip download below):

Essentially it all boils down to this:

1) When you are ready to save your image, create a Bitmap version of your MovieClip.

Actionscript:
  1. private function getMovieClipAsBitmap():Bitmap
  2. {
  3. var bounds:Rectangle = theMovieClip.getBounds(theMovieClip);
  4.  
  5. //    The * 2 is because we're scaling the clip up by a factor of two, to result in a larger PNG
  6. //    If you don't need this, remove it and comment out the m.scale call below
  7. var theBitmap:Bitmap = new Bitmap(new BitmapData(bounds.width * 2, bounds.height * 2, true, 0x0));
  8.  
  9. var m:Matrix = new Matrix(1, 0, 0, 1, -bounds.x, -bounds.y);
  10.  
  11. //    Simply scale the matrix to make a bigger PNG. Here we are doubling it. Comment this out if you don't need it.
  12. m.scale(2, 2);
  13.  
  14. //    Need to crop the PNG to a given size? Pass it a Rectangle as the 5th parameter to draw()
  15. //var r:Rectangle = new Rectangle(0, 0, 50, 40);
  16.  
  17. theBitmap.bitmapData.draw(theMovieClip, m, null, null, null, true);
  18.  
  19. return theBitmap;
  20. }

2) Convert this Bitmap to a ByteArray.

Actionscript:
  1. private function getMovieClipAsByteArrayPNG():ByteArray
  2. {
  3. var data:Bitmap = getMovieClipAsBitmap();
  4.  
  5. var ba:ByteArray = PNGEncoder.encode(data.bitmapData);
  6.  
  7. return ba;
  8. }

3) Send this ByteArray to either the local filesystem, or AMFPHP.

Actionscript:
  1. //    Uses FileReference to save the PNG locally to the hard drive (see "saveToServer" for an alternative)
  2. private function saveLocalPNG(event:MouseEvent):void
  3. {
  4. var ba:ByteArray = getMovieClipAsByteArrayPNG();
  5.  
  6. file.save(ba, "BirdyNamNam.png");
  7. }

Complete source code is included in the zip file including an AMFPHP PHP script for saving on a web server.

Hope someone finds this useful.

Download the Soure Code zip.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

23
Feb 10

Blockparty 2010 Invtro and the Opensource demo engine evoTinyEngine

Blockparty is an annual demo party held in the US, and 2010's is about to hit in a few months time. As with all good demo parties there is usually an invitation demo to announce it, and to whet the appetite somewhat. This year EvoFlash created this little beauty, and of course it's AS3 to the core:

I've not been to a demo party since 1999, but boy does this make me wish I could be there. Nice one guys, nice one.

There are some lovely effects as you'd expect. Evoflash have been at this for years now, and obviously have a highly streamlined demo pipeline going on. With impressive pre and post render effects; gorgeous blooms, radial blurs, reflections and shadowing. And what's more - they have released it as open source, free for demo coding plebs like me to use!

Called evoTinyEngine it's a small framework that offers you three core elements: Assets, the main Engine and Modifiers. The Modifiers can be stacked up on-top of each other. The Engine handles the construction and destruction of all the Modifiers for you, and there are some really nice things ready to use. Everything is based on 16th note beats, which allows for tight syncing with the audio in your demo.

I haven't dug through the code much yet but I'd be willing to bet there are some insane routines in there, that would be well worth studying for game development as well as demos.

(Now let's see if this blog post kicks off a 20+ comment flame war about "is it really a demo?" yadda yadda ... ;)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

06
Jan 10

Access LiveDocs locally with Doc v3.0.1

Although the code-insight features of FlashDevelop help a lot, you can't beat a good AS3 reference - and I use Adobe LiveDocs almost exclusively for this. Although I have a Firefox search plugin that gives me quick access to it, I have still always wanted a decent local copy that offered the same benefits my browser does, but faster.

Thanks to the magic of Twitter (cheers @kode80) today I found such a beast in the shape of an AIR app called Doc?

Doc? allows you to view, search and bookmark all your favourite ASDocs. But the biggest feature for me is that on-line docs can be downloaded and stored locally too. This means that the docs for things like Away3D, Flint, Papervision, Adobe CoreLib, TweenMax or anything else that has ASDoc documentation can be added to your local books collection.

Adding a remote ASDoc

Adding new books couldn't be more simple. Just start-up Doc?, click the settings icon in the top-right and select ""Add Remote ASDoc". You'll be asked for some details. Here they are for the Stardust Particles system:

Note: when adding URLs be sure to specify a directory, and don't have the index.html on the end.

Doc? will then download and index the files, storing them locally.

Be advised that on large sets of documentation this can take a while. Indexing the AS3 Language Reference took nearly 10 minutes, and that's on an Intel Quad Core Q9950 @ 2.83GHz with 8GB RAM. Doc? stores the indexes in a local SQLite database.

Once downloaded and indexed the docs are available from the Books menu, ready for easy and fast local searching!

Here you can see I searched for "Radius" specifically in the Stardust book, and am viewing the CollisionRadius page. You can search across all books, highlight results in the text, include title and/or content in the search and even bookmark sections you know you return to often.

The tree view display has icons depending on the style of result - the green "C" circle icon means it's a Class, but it also shows packages, methods, constants, interface and others.

AS3 Language Reference

One of the first things I recommend you do is download the ActionScript3 Language Reference zip from the Adobe web site (5.8MB). Unzip it somewhere and use the "Add Local Book" Settings option to add it. It will still need to be indexed (and this takes a long time), but it's better to grab the zip as it can often have more up to date docs vs. those installed with CS4.

I'm quite sure that this app will save me a lot of time vs. digging through browser bookmarks.

Visit the Doc? web site

All I'd like to see now is this built into FlashDevelop, so F1 searched within Doc? :)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

16
Dec 09

FlodEx 1.01 – SidMon, Future Composer and BP SoundMod supported

Christian has been busy! FlodPro was already the best Amiga module replay library available for AS3. But not content with that he went and added support for 3 new chip-tune formats: SidMon, Future Composer and BP SoundMod.

As a special Christmas present for those who visit this blog I whipped up this little demo, showcasing 6 tunes, 2 of each newly supported format.

Hit the jump to see the demo in action :)

(more...)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

01
Oct 09

DarkCubes released – Retro 16-bit demoscene gameyness

Away3D is an awesome 3D library for Flash. Flod is an awesome library for replaying tracker music in Flash. Throw those two things together with my inner-geek upbringing of the 80s and you get DarkCubes. I grew up drip-fed on ST/Amiga demo effects, and this random little 3D game is what I banged out during a couple of lunch breaks and some hours last night.

DarkCubes Credits

I actually wrote DarkCubes back in 2000 on the PC/Windows using DarkBASIC (hence the title of the game). So I had the code and figured it would make a good first experiment for Away3D. A bit of messing around, a bit of swearing, and lots of fiddling later and this tiny puzzler was born.

The logo is from the original PC game and was made by Yann 'Kohai' Parmentier. The music is by Adam Sikorski (DSX of TRSI), 505 of Checkpoint and Toodeloo of the Dead Hackers Society. The rest by yours truly.

Lots of keys do stuff in-game, so have a fiddle! (1-5 changes the music for example, D turns on Debug info, 7-9 change texture, etc. Read the scroller for the full list).

I make no apologies for this beating shitty spec  Netbooks / PCs over the head with a giant CPU grinding axe. Deal with it. It's hardly the end of the world.

DarkCubes In-game

Click here to play (sorry no pre-loader, but it's only 1MB in size)

Enjoy ;)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

17
Sep 09

Flickr Water Painting Demo

Flickr Water Painting I had an idea for a game where you had to restore colour to the world, by speeding around in a boat and dropping colour bombs onto the greyscale picture below. I thought it'd be fun if the images were pulled in from Flickr dynamically, creating a constant ever-changing sea of levels.

A few hours and a prototype later, and I realise it's not actually going to work after all. There's just no easy way to control what comes back from Flickr - you can't search for images which just have "Big" sizes available, and you can't easily exclude black and white images, which totally ruin the painting part of the game! There are also commercial issues with the Flickr API Keys needed to search and request images. So in the end what was a nice idea in theory, turned out to be a bit crappy in reality.

However I was left a random but pretty prototype. I've removed the boat/gameplay element, so it's just the water painting demo hooked into Flickr.

Lots of pictures come back with "Image not available", so just search again. If it seems to hang for a while after clicking Search, then just search again! Paint with the left mouse button. Sometimes it works right away, and sometimes only on the third or so attempt.

[kml_flashembed publishmethod="dynamic" fversion="10.0.0" movie="http://sandbox.photonstorm.com/painterFlickr.swf" width="640" height="480" targetclass="flashmovie"]

One of my artist friends commented that this made him look at the use of colour in a whole different light. He said that as you start filling the image in, the colours that come through are often totally different to what you'd expect - and when the colour is presented in low volumes it can often look very wrong. As if your brain has substituted the colours for you, and when they don't match it gets confused.

I think there's something quite calming / feng shui about it all personally.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

15
Sep 09

Creating MovieClips dynamically at run-time using the Linkage Class

linkageI found myself needing to create a MovieClip dynamically at run-time. But all I had was a string representation of its Class, as set in the Linkage properties for the Symbol. In my situation the string had been stored in an xml file. Now you could use a standard switch/case block to do this, checking the string and creating a new MovieClip as required. But in this case there were hundreds of possible things it could have been, and it seemed a very "hacky" way to do it.

So how do you go about creating an actual display object from just the Linkage Class value? Thankfully it's pretty easy, and this new bit of code now sits happily in my "everyday functions" collection!

Edit: Updated to be a little more robust, and removed an un-needed cast:

Actionscript:
  1. public function createMovieClipFromLinkageValue(linkageValue:String):MovieClip
  2. {
  3.     try
  4.     {
  5.         var libraryReference:Class = getDefinitionByName(linkageValue) as Class;
  6.     }
  7.     catch (error:ReferenceError)
  8.     {
  9.         trace(error);
  10.     }
  11.  
  12.     if (libraryReference)
  13.     {
  14.         return new libraryReference();
  15.     }
  16.  
  17.     return new MovieClip;
  18. }
  19.  
  20. var newClip:MovieClip = createMovieClipFromLinkageValue("playerFishMC");

Make sure you have imported flash.utils.getDefinitionByName.

Simply pass this function the Linkage value as entered in the IDE, and it'll spit a MovieClip back at you (providing it was a MovieClip in the first place). I'm sure you can see how to extend it to return a Sprite instead, should you require that.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

23
Apr 09

SourceBinder – pure AS3 awesomeness!

SourceBinder

Quite out of the blue I received an invite to the SourceBinder project tonight. I honestly couldn't even remember what it was, but after a couple of minutes playing I was hooked!

If you are experienced with node based creation tools, like FilterForge for example, then you'll have a good idea what this is about. Basically it's an FP10 visual creation tool - you can create your own nodes (or use many of the public ones up there) and chain them together to create stunning visual effects. Loads of libraries are built in already like JigFlashLib, Tweener, Flint and PV3d, so nodes can be created using these.

SourceBinder Example

Nodes can perform tasks such as colour changing, mouse input, sound handling, PV3D creation and loads more. They are simple AS3 classes (which you can edit live online). You chain them together using a neat drag and drop interface, the final "display renderer" node being responsible for the output.

It's just great - I urge you to try it!

http://sourcebinder.org

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

07
Apr 09

Particle Worm Explosion

I was messing around tonight with the explosion code I wrote for Infinite Ammo, with a squiggly "worm like" behaviour and created the following weirdness. Click anywhere to set off an explosion. Click as much as you like to create total mayhem!

[kml_flashembed fversion="9.0.0" movie="/swfs/eskaflow.swf" targetclass="flashmovie" publishmethod="static" width="600" height="400"]Get Adobe Flash player

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

11
Mar 09

Infinite Ammo 4k Source Code Released

Infinite Ammo 4k

Well everyone else seems to be blogging about the release of their 4k games, so I'm doing so too :) I managed to get mine finished and submitted on-time. I don't expect it to win a thing (results are in 3 days time), but I had great fun participating all the same.

I have created a games page entry for it, and in a slightly unusual move for me I have released the full source code for the game too. You can get it from it's games page. What you learn from it I have no idea. At the very least there's a pretty explosion / particle system, and a massively optimised and compressed Tween engine! Or you could just skim down through the code, shaking your head thinking "and he ENJOYED coding this?!" :)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

28
Feb 09

How do you extract a Sprite back out of a ByteArray?

I should probably post this into some AS forums (and will do so later), but I had to get this out there quickly and it's bugging the hell out of me:

In short, how do you extract a Sprite from a ByteArray? (or any kind of display object for that matter).

I can write the object just fine, and read it back into a variable, but I'll be blown if I can then convert that back into what it was originally.

Here are my attempts so far:

Actionscript:
  1. var test:Sprite = new Sprite();
  2. test.graphics.beginFill(0xff0000);
  3. test.graphics.drawRect(0,0,64,64);
  4. test.graphics.endFill();
  5.  
  6. //addChild(test); // to test, works fine
  7.  
  8. var b:ByteArray = new ByteArray();
  9.  
  10. trace(b.length);    //    0 bytes
  11.  
  12. b.writeObject(test);
  13.  
  14. trace(b.length);    //    754 bytes, so our Sprite is definitely in there
  15.  
  16. //    Reset the pointer
  17. b.position = 0;
  18.  
  19. trace(b.position);    //    0 as I'd expect
  20.  
  21. var newTest:Sprite;
  22. //newTest = b.readObject() as Sprite;    //    Ends up being null
  23. //newTest = Sprite(b.readObject());    // Type Coercion failed error
  24. //trace(newTest);
  25. //addChild(newTest);    //    and kaboom, constant "Parameter child must be non-null." errors :(
  26.  
  27. var take2:Object = b.readObject();
  28. trace(take2);    // ok take2 contains an object, but how can I get the Sprite out of it?
  29.  
  30. trace(b.position);    //    754, so it has definitely read it all

Ummm someone, please help? :)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

26
Feb 09

(Spoiler!) Play test my 4kb Game Competition entry

My 4kb Game Competition entry is very nearly finished. I'm in the final "tweaking" stages, trying to get the last few small bugs out, and iron the gameplay a little so it's less "random" and even more progressive.

The game is a twitch shooter based (loosley!) on Geometry Wars and requires some pretty mad flying skillz to last more than 30 seconds. The idea is literally to see what kind of score you can get. Here's a screenie:

Infinite Ammo

There are 10 different baddies, "boss waves", bullet power-ups and particle explosion effects galore! (I went a bit over the top in all honesty). I'd love to have added sound, but I'm pushed to the limit of my 4096 bytes shackles already.

I know the game isn't quite as "playable" as it should be, and I'll work on that in the final few days left before I need to submit to the contest. I also know I don't have a chance of winning (having seen some of the other entries lined-up!), but it was bloody great fun to code anyway.

And so as a sneak peak to you here's the latest beta to play. Comments welcome (but please do bear in mind this whole game had to fit into 4096 bytes, so don't go requesting anything insane ok?!)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

18
Feb 09

4k Game Contest – Some useful tips

4kOk so after the embarrassment of my first post on this subject, I wanted to present some findings that may help you out on your quest for smaller SWF sizes. More importantly, I know for a fact these all worked for me!

For those who didn't read the previous post: I've been working on my entry for the 4k Game Competition, and have found the following information during the course of my coding:

Keep Event Listeners out of the constructor

I have a whole bunch of init stuff in my constructor (creating game graphics, setting up variables, etc) and at the end I kicked off the game by starting up the main events (keyboard, mouse, etc). But by moving the event listeners to their own function, and calling that function from the constructor, it reduced the size of the SWF.

If you know the size of something, use it! Avoid references where possible

When creating a Rectangle I passed in the width and height of a bitmap by reference (bulletBitmap.width). By removing this and passing in the actual known width of the bitmap (6) it saved a massive 20 bytes from the ActionScript code.

Before: bulletRect = new Rectangle(0, 0, bulletBitmap.width, bulletBitmap.height);

After: bulletRect = new Rectangle(0, 0, 6, 6);

Here's another example where being explicit saves bytes:

Before: fullRect = stage.getRect(stage);

After: fullRect = new Rectangle(0, 0, 550, 400);

This saved us 6 bytes.

Make Bitmaps Transparent

I create a bitmap the size of my Stage to hold the game background in. It looks like this:

gridBitmap = new Bitmap(new BitmapData(550, 400, true, 0x0));

Now I don't need this bitmap to be transparent (the 3rd parameter) as it sits at the bottom of the display list. But by setting the transparent parameter to "false" it increased the size by 3 bytes.

Even default values take-up space

Object instantiation is expensive in AS3, so it's best to pre-calc objects you need in your main loops at the start. However who would have thought that the following:

zeroPoint = new Point(0, 0);

takes up 1 extra byte than:

zeroPoint = new Point();

Even though 0,0 are the defaults for the Point object. Every byte counts!

Avoid Array references in for loops

I have a loop in the game that checks through a pool of baddies (standard Array containing a custom Object that extends a Sprite). I started out doing it like this:

for (var a:int = 0; a < baddiePool.length; a++)

and then ...

baddiePool[a].value = newValue;

But by pulling out the array element first at the top of the loop, then referencing that, I saved a massive 33 bytes in total:

ba = baddiePool[a];
ba.value = newValue;

Smaller than a ternary

Thanks to Kevin Luck for this one :) If you need to run a standard if/else on a value where it could be equal to zero then it can be shortened to:

x = lx || Math.random() * 550;

In the code above, x = lx unless lx = 0, in which case set x to Math.random() * 550. This is 3 bytes smaller than using a ternary/if-else equivalent.

Hopefully the above will help out those also entering the competition. Feel free to comment and add more tips!

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

18
Feb 09

4k Game Contest – and a word about ternary operations in AS3

4k Edit: Thanks to Kevin Luck for pointing out a flaw with the code in my original post (there was an extra assignment taking place, which caused the byte count to increase). Remove that and ternary will match if/else on a bytes-used basis. I'll keep this post up here regardless, just ignore everything from this point on :)
(more...)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

19
Sep 08

Is “Pixel Blitting” in AS3 really worth the effort?

While planning some new routines for the PixelBlitz engine tonight one thing struck me - is it actually worth it?

There are a number of articles across the web about pixel blitting in AS3 (most of them at 8-bit Rocket :) but I did wonder if anyone had actually done some tests to see just what difference it makes in real-world terms.

After all, why mess around "blitting" things about if using a Sprite or MovieClip is just as fast anyway? Infact you could easily argue that using a native Flash display object gives you far more control (as you get to play with scaling, alpha, rotation, animation, sound events and more, easily).

Another thing also struck me - when building up the display for render the AVM will automatically use a dirty rectangles system. If you've got two overlapping movieclips then it won't waste time drawing pixels that would otherwise be obscured by the one in front. Traditional blitting on the other hand doesn't care about this, it'll gleefully copyPixel() until the cows come home, pasting image after image on-top of each other (PixelBlitz suffers from this issue too).

[ Side note: It's true we could add a similar dirty rectangles system to Pixel Blitz, to avoid copying data when it's guaranteed to be overwritten further up the chain - but this is not something we've found a fast way to do yet (the potential alpha channel of a bitmap causing the most problems), the overhead of sorting and checking for overlaps is always taking longer than just brute-force copying everything each time (if you can help, email me!) ]

Tonight I decided to write two simple tests. They would measure the speed of the AVMs dirty rectangle system vs. raw bitmapdata copypixel power. I was interested in 3 things - the overall time it took to run the test, the amount of memory it used and the average fps rate.

The Tests

I took a 550 x 400 sized stage published at 30 fps. All tests were run using the Debug version of the Player (9.0 r 124). The test consisted of creating an array of X number of sprites (to test the AVM) and PixelSprites (to test blitting). Each sprite was 50x50 in size and contained an alpha channel. I then drew all of the sprites onto the stage and moved them along by 4 pixels per frame, if they hit the left of the stage they wrapped around to the right again. The Sprites had cacheAsBitmap set to true (see note below)

Then I ran the tests multiple times, with varying numbers of fish, for varying durations, recording the data at each step and averaging it out.

I agree that this is in no way a truly "scientific" test, but I wanted a general "feeling" as a result, to see if this was an avenue still worth walking down or not.

The Results

With 500 sprites both the standard Sprite and the blit method kept a solid 30 fps frame rate. Using Sprites consumed 15MB of RAM, using blits 11MB.

At 1000 sprites we're still at a consistent 30 fps, but there is noticeable "tearing" in the visuals as the sprites move across the stage. It's not terrible, but you can easily see it. The standard method is now using 20MB while the blit is using 14MB.

2500 sprites and we see both techniques struggle to keep-up with the 30 fps rate. The traditional Sprites actually outpace the blitting at 23 fps vs 21 fps, but the memory consumption is more than doubled, 35MB vs. 15MB.

At 5000 sprites they are both starting to feel the strain, each level pegging at 12 fps. But the standard Sprites technique is using a staggering 58MB, while the blit is only up to 20MB.

7,500 sprites all moving at once and both techiques are virtually bought to their knees managing just 8 fps each. Given the amount of data moving this isn't totally surprising. The blit technique at this point is literally copying 18.7 million pixels around in memory. The AVMs internal dirty rectangle is feeling the full force of what's going on however, and is now consuming 237MB of RAM vs. the blit techniques 25MB.

10,000 sprites crashes the Debug player for both versions, it literally runs out of memory :)

cacheAsBitmap

As I mentioned at the start, the Sprite version had cacheAsBitmap set to true. This is the main cause of the huge amount of RAM being used. As our Sprite only contained a single Bitmap this wasn't needed. By removing this setting the amount of RAM used dropped, ending up only a few MB higher than the straight blit method.

Our Findings

So what can we pull from this?

First of all, the AVM dirty rectangles implementation is pretty damn sweet! But brute-force blitting is equally as fast in this test case. Logic tells us that adding redraw aware optimisation to our blit engine should increase this gap in our favour significantly.

NEVER enable cacheAsBitmap on a Sprite or MovieClip if all it contains is bitmap data.

The blit engine uses less memory. If you need to cache vector Sprites in your game, then it uses considerably less memory!

No-one really needs a game with 7,500 fish swimming around in it ;)

Maybe the test wasn't "real world" enough - even at the 1000 sprite level (at which both methods kept a 30 fps frame rate) we were still moving 2.5 million pixels around a 550 x 400 stage. That's enough to fill the stage 11 times over (and still have some spare). Is this likely in a real game? Well no, I don't believe so - but it isn't that far off either. Games are getting bigger (we published one at 800x600 today for example), and if you had a game featuring multiple layers going on (foreground, player, background, distance, etc) with alpha showing through them all, then it doesn't take long to start using pixels in the millions range.

There are instances when I believe it's just easier to deal with things on a blit level - for example building up a large n-way scrolling tilemap, where you constantly need to redraw the scroll buffers. Doing the same by placing (and updating) hundreds of Sprites would be an exercise in pain I wouldn't wish on anyone.

Is a combination of both worlds the way to go? Quite possibly. While I loathe using the timeline (or Movieclips in general) for anything, they do offer Flash animators a rich featured tool-set that let's them create vibrant moving games. Whereas the blit method requires graphic artists trained in the way of the pixel, and I believe those are a dying (and expensive) breed indeed. Creating quality animations at that level is time-consuming and costly. But as we've seen, animating on a vector level introduces both resource and speed issues into your game.

What about collision detection? Well we all know this pretty much sucks in Flash. So we have to roll our own methods anyway. For pixel perfect collision detection we need to inspect the elements on a pixel level (surprise surprise), at least with the blit technique we're already operating on that level, so there's no extra draw() overhead involved.

Conclusion

Are AS3 Sprites "evil" for those of you trying to create arcade style games? No, I don't believe so. They can hold their own in the speed stakes thanks to the power of the AVM, but you do have to watch yourself and be very careful re: memory consumption.

Is "blitting" really that much faster the using normal Sprites? No, it isn't. It does have less memory overhead and a "cleaner" feel to it, but it's no speed demon in comparison.

Would a hybrid solution work? (i.e. a fully blitted tilemap with Movieclips characters on-top) - yes, absolutely!

Don't feel that because you have travelled down the "blit" route you need to have the whole game living there. If you can mix and match your game logic and most importantly your collision systems, then there's no harm in splitting these elements up, using both at once.

P.S. If you've got some ideas or concepts on optimising blit level drawing, please get in touch. I've been reading a lot about this recently (what I can find at least) but it's always good to pick someone's brain.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

16
Sep 08

BlitzMouse right-click capture example

sergej wrote a comment to my BlitzMouse post saying that if you right-clicked the custom pointer gets lost until the page is refreshed. Here is some simple code to work around this.

In your main SWF make sure you import ContextMenu and ContextMenuEvent. Then add 2 new global vars:

Actionscript:
  1. private var rightClickContext:ContextMenu;
  2. private var contextOpen:Boolean;

and within your init (or constructor) add this:

Actionscript:
  1. rightClickContext = new ContextMenu();
  2. this.contextMenu = rightClickContext;
  3. rightClickContext.addEventListener(ContextMenuEvent.MENU_SELECT, contextMenuOpen, false, 0, true);

"this" is a Sprite in this case, but any valid display object (that has access to the contextMenu) will do. The "contextMenuOpen" function is literally just the following:

Actionscript:
  1. private function contextMenuOpen(event:ContextMenuEvent):void
  2. {
  3. contextOpen = true;
  4. }

and finally, in your main game loop, just check the state of this var and reset accordingly:

Actionscript:
  1. if (contextOpen && mouse.isDown)
  2. {
  3. mouse.hide();
  4. }

When the context menu is opened (by a right-click on Windows) it fires the ContextMenuEvent.MENU_SELECT event, which we capture and set a boolean for accordingly. While the menu is open we can do nothing about the standard mouse pointer, but in our main loop we can listen out for a mouse click (mouse.isDown) and then hide the pointer again accordingly.

I've not tested this on a Mac (where you can command-click to get the context menu up) so if anyone reading can do so, please let me know if it works.

The SWF below should allow you access to the context menu, but upon clicking the SWF again the custom pointer should return (assuming you click within the limit zone!)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

30
Aug 08

PixelBlitz Engine Update: AutoScroll support with demo

Just a small update to the PixelBlitz Engine today, but a pretty cool one!

I'm creating an intense shoot-em-up game as my water shed test of the PB engine. Each day I get to add a few more features to PB that makes the game closer to reality. Once I have reached that point I know we'll have something truly useful on our hands :)

Today I added in a backdrop behind my ships and thought "damn, that ought to scroll" - but I figured that PB ought to handle the scrolling for me, automatically - just set it and forget it. So that is what I've added to the engine tonight.

It's a piece of piss to use:

Actionscript:
  1. // Continuously scroll this PixelSprite to the left by 4 pixels per frame
  2. pixelsprite.autoScroll(PixelSprite.SCROLL_LEFT, 4);

Which allowed me to create the following demo in around 20 lines of code:

I'm quite pleased with how this is shaping up :) You can autoscroll any PixelSprite, with full transparency preserved (so they can be overlaid on-top of other PixelSprites for true glass-window scrolling effects). The PB engine takes care of making the scroll seamless for you, and you can modify the speed on-the-fly (although I'd recommend not to do it every frame if you've got a lot going on).

The only issue is that scaling an auto scrolling PixelSprite will mess it up, so I'll need to remedy that.

It's now the weekend, but if i get some spare time I plan on continuing my task of fixing the left over issues before cracking on with collision groups and sprite mask tests.

Here is the source + FLA.
You'll need to checkout latest revision (v21) of PixelBlitz from Google Code to compile it though.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

14
Aug 08

Hi-Res – SWF performance stats with style

Ricardo Cabello released a really nifty stats tracker the other day. Just download the Stats.as file from his Google Code site, create the following folder structure: net / hires / utils and place the Stats.as file into that. Once done you can import the package into your own code and make use of it.

The end result? A beautiful little real-time performance display that looks like this:

Hi-Res Stats

The FPS gives you a current and maximum frame rate count (the maximum is derived from the stage frame rate setting). The MS is a micro-second counter. MEM is the total memory (in MB) your SWF is using.

The cute little graph below that is a historical visualisation of these three things, so you can watch for spikes / peaks during activity. You can click the top/bottom of the stats to increase/decrease the stage framerate.

Using it is as simple as adding one line of code:

addChild( new Stats() );

All I'd say is remember to make sure this happens on the TOP of all of the rest of your display list items.

Link: Hi-Res Stats Google Code page

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

04
Aug 08

Demo FX Lib

Somewhat inspired by my previous vectorball tests, and also from unearthing a load of my old demo source code, I decided to start porting some of the effects to AS3 into a single easy-to-use library, Demo FX Lib. Today I coded a nice image "drop down" effect, and a comprehensive 3D starfield routine. I'm very pleased with the starfield as it's both smooth and versatile, you can literally tweak every value as it's running, for some nice real-time effects.

The object of these effects is that you can literally pull them into your game as needed. None of them mess with the stage, all of them return (and work on) either a single bitmap or sprite, so can slot-in easily to an existing system. I want to add a classic scroll-text system, plasma and some other traditional effects before I release the library.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

17
Apr 08

AS3 Going’s On

Flash on the Beach 2008 is coming September 28th. See you there!

Francis Cheng has a fascinating blog entry about the new way you can use Object Initialisers in ECMA4

Jack over at GreenSock has released two great new classes: TransformMatrixProxy and ColorTransformProxy - being a Shockingly Green Club GreenSock member I already had these :) but it's great to see them in the wild.

The uber-particle system Flint has been updated to version 1.0.1. This new build changes the way the renderers work, allowing you to now specify how large the render target is (before it was the full stage size). Release 1.0 also included particle flocking, which is great fun! Definitely check it out.

Over on the Adventures in Actionscript blog a new entry gives away the full source to a feature-rich AS3 pre-loader that includes MochiAd, MochiBot, simple Domain locking and a Vista style glossy progress bar. A nice little package. You can get the progress bar on its own if the rest doesn't appeal to you.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon

15
Apr 08

NetStream bytesTotal weirdness

While working on a custom video player project today I noticed a strange anomoly with the bytesTotal value returned by a NetStream object loading data from a local cache.

The first time you play a remote FLV via NetStream the bytesTotal result is correct, it's the size of the file as sent by the server. However once the FLV is in the users local cache, and the SWF was reloaded, the bytesTotal value was reporting a size of 4 GB exactly until the stream had "settled down", and then it returned the correct value. This seemed to take a second or so at most, but it still meant that my code needed changing to cope with it.

After making the connection I was storing the bytesTotal value in a uint. An event based check was comparing this uint with the bytesLoaded value waiting for them to equal each other (i.e. get to 100% downloaded). Of course this would never happen, because it was waiting for 4GB worth of data to download.

So rather than assigning the value to a variable I'm now simply comparing bytesTotal directly with bytesLoaded and then setting a Boolean if they match (downloadComplete = true) to avoid future comparisons.

Even so, it was an interesting oddity I thought worth reminding myself of in the future. Hence this blog entry :)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit Post to StumbleUpon