• Stick Nodes - 100% Complete Go animate some stickfigures. Google Play links: [free] or [pro]. App Store links: [free] or [pro].
Trophiends
Stick Nodes

Get it from: App Store | Google Play | SlideMe | Amazon | Opera

Increase Game Performance By Using Bitmaps

0comments

Hey guys.  I’m going to try a new thing with this blog of mine.  Instead of just rambling on about my own game development news and whatnot, I figure I’ll also throw in a tutorial post every now and then.  Sound good?  Good.

First, a little background.  This concept of using bitmaps instead of the standard MovieClips that everyone is used to came to way back when I first began development on Don’t Panic.  I had run into a strange problem that I hadn’t encountered before in either Weapons on Wheels, Oil Spill Escape, or Christmas Defense.  The problem had to do with the game lagging up very badly when there were more than about 4 or 5 enemies on the screen.

After some help from the FlashGameLicense.com forums, I realized the problem was the enemy MovieClips – the vector graphics for the enemies were just too detailed and thus the game was having a hard time rendering them every frame.  (Vector graphics are essentially just a bunch of math equations that the CPU has to process in order to draw the image on the screen – you could imagine how a bunch of detailed vector graphics could take a toll on your processor.)

Anyway, this is how I came across this method of handling my game art assets.  Ever since I’ve learned about it, I’ve used it for Don’t Panic, the late Hero Dude, and my current WIP – Defective.  This method isn’t exactly blitting (which is slightly more advanced and is another tutorial all together), but sort of a middle-ground between it and the traditional usage of MovieClips.  So, let’s get started, shall we?

The Classes

Alright, now, from here on out, I’m going to be showing you how I utilize this method.  Take from it what you will and use it however you want/need.

To begin, I create two classes:

  1. BMPLoader.as – This class is what “loads” the BitmapData information from your MovieClips and stores it in memory.  (It essentially takes a MovieClip  and outputs a Bitmap of it.)
  2. BMPObject.as – This is what you will extend your game objects as.  For example:

[cc lang=”actionscript3″ escaped=”true”]

package
{

public class Player extends BMPObject
{
}

}

[/cc]

So far, so good.  Now let’s get into what each class does.  Let’s begin with BMPLoader.

BMPLoader.as

Alright, this is the class where all of the magic happens, it’s not very difficult once you just look at what’s going on.  (I’m just going to throw a disclaimer here that from this point on there may very well be optimizations and better ways to do what I’m trying to accomplish.  Feel free to experiment and change things to your needs or even comment on this post telling me what to change.)

Here’s the entire class, commented completely to help you understand it better.

[cc lang=”actionscript3″ escaped=”true”]

package
{
// Imports for this class.
// Nothing more to say really ;).
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.geom.Rectangle;

public class BMPLoader
{
// This is an important part of this class.
// Here is where I declare a Vector of type
// BitmapData for EACH MovieClip that I will
// be transforming into a Bitmap. So I’d have
// one for Bullet, Coin, Enemy, etc. Here I
// have one for the Player graphic, just for
// this example. Also important – note how the
// Vector is PUBLIC and not private.
public var vecPlayer:Vector.<BitmapData>;
// This class also needs a DisplayObject which
// will act as the reference to the coordinate
// space to use. This may sound confusing, just
// use a reference to the Level, World, Stage –
// whatever the “global parent” is.
private var levelRef:DisplayObject;

// The constructor doesn’t do anything other than
// assign the “global parent” variable a value. This
// is important to do!
public function BMPLoader(_levelRef:DisplayObject)
{
levelRef = _levelRef;
}

// This destroy() function is more of a personal thing
// I add to each of my classes in order to clean up and
// help for garbage disposal and the freeing of memory.
// Think of it as the opposite of the constructor – the
// destructor, it cleans up the objects and prepares it
// for deletion. Here all I do is null all of the Vectors
// I’ve created as well as my “global parent” reference.
public function destroy():void
{
vecPlayer = null;
levelRef = null;
}

// The load() function – here’s where all of the magic happens.
// This functions takes two parameters, a MovieClip (to transform
// into BitmapData) and a String (which is the name of the Vector
// in which we will store this BitmapData).
public function load(mc:MovieClip, vecString:String):void
{
// First check if the Vector is already populated, if so, skip
// and don’t bother. If the Vector is already populated, this means
// that this MovieClip has already been loaded into memory before. Cool!
// ———————————————————————
if (this[vecString] != null) return;

// Alright, so the Vector isn’t already populated. Okay, so take the
// Vector and initialize it.  Then, fill the Vector with the return
// value of a new function, convertMCToBitmapData().
// ————————————————-
this[vecString] = new Vector.<BitmapData>;
this[vecString] = convertMCToBitmapData(mc);
}

// Alright. This is the function that manipulates the MovieClip into BitmapData.
// It first takes the MovieClip and iterates through all of it’s frames. While it
// does this, the function takes notw of the maximum width and height of the
// MovieClip. This maximum width and height is then used in the second part of
// the function where BitmapData object is initialized (it requires a width/height
// parameter). After this, the built-in draw() function is used to convert each
// frame of the MovieClip into BitmapData. Finally, this BitmapData is pushed into
// a Vector which is eventually returned as the result of this function.
private function convertMCToBitmapData(mc:MovieClip):Vector.<BitmapData>
{
// Initialize variables we’ll need for this function.
// Not much to go into here, as we’ll see these all later.
// ——————————————————-
var curFrame:int = 1;
var maxWidth:int = 1;
var maxHeight:int = 1;
var boundsWidth:int = 1;
var boundsHeight:int = 1;
var bmpData:BitmapData;
var vec:Vector.<BitmapData>;
vec = new Vector.<BitmapData>();

// Alright, first part of this function.  Time to get the
// maximum width and height of the MovieClip. Using a while
// loop, we will iterate through each frame of the MovieClip,
// noting the maximum width/height we come across. (This is
// where that “global parent” reference is used, since the
// getBounds() function requires it.
// ———————————
while (curFrame <= mc.totalFrames)
{
mc.gotoAndStop(curFrame);
boundsWidth = mc.getBounds(levelRef).width;
boundsHeight = mc.getBounds(levelRef).height;
if (boundsWidth > maxWidth) maxWidth = boundsWidth;
if (boundsHeight > maxHeight) maxHeight = boundsHeight;
curFrame++;
}

// Now that we have the maximum width/height stored appropriately
// inside of maxWidth and maxHeight, it’s time to move onto the next
// part. Here we are once again using a while loop to iterate through
// each frame in order to translate each frame of the MovieClip into
// BitmapData using the draw() function.
// ————————————-
curFrame = 1;
while (curFrame <= mc.totalFrames)
{
mc.gotoAndStop(curFrame);
bmpData = new BitmapData(maxWidth, maxHeight, true, 0x00000000);
bmpData.draw(mc);
vec.push(bmpData);
curFrame++;
}

// Finally, return the Vector of BitmapData.
// —————————————–
return vec;
}

}

}

[/cc]

Now let’s move on to the next class, BMPObject.

BMPObject.as

This class will be extended from all of your game objects that will be utilizing Bitmaps instead of traditional MovieClips.  So, for example, the Player class, Bullet class, etc.  The real purpose of this class is to make it easy for you to assign a Vector of BitmapData from the BMPLoader class (above) to a particular object as well as make it easy for you to iterate through said Vector to animate the Bitmap – just as if it were a MovieClip.  Here’s the entire class – again fully commented.

[cc lang=”actionscript3″ escaped=”true”]

package
{
// Imports for this class.
// Nothing more to say really ;).
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;

public class BMPObject extends Sprite
{
// Here are the properties of this class. Note how
// they’re all PROTECTED – this is important. The Vector
// “vecMyBitmap” will reference a Vector in the BMPLoader
// class and will hold the BitmapData of this object.  The
// “bmp” variable will be the Bitmap – the actual “face” of
// this object. Finally, the last variable, “bmpFrame,” simply
// stores the current position in the vector (used for animation).
protected var vecMyBitmap:Vector.<BitmapData>;
protected var bmp:Bitmap;
protected var bmpFrame:int = 0;

// The constructor does nothing.
// Very simple, no?
public function BMPObject()
{
}

// Again, the destroy() function, just a personal
// preference of mine to help with garbage disposal
// and the freeing of memory. Here I just remove the
// Bitmap and null the Vector and Bitmap.
public function destroy():void
{
vecMyBitmap = null;
if (bmp)
{
removeChild(bmp);
bmp = null;
}
}

// The setupBitmap() function is called to, well, setup
// the Bitmap for this object. It takes the first value in
// the Vector of BitmapData and creates a Bitmap out of it.
// The Bitmap is then added as a child to this object and then
// moved so it is centered properly.
protected function setupBitmap():void
{
bmp = new Bitmap(vecMyBitmap[bmpFrame]);
addChild(bmp);
bmp.x = -bmp.width * 0.5;
bmp.y = -bmp.height * 0.5;
}

// The animateBitmap() function, well… take a guess what
// it does. It animates the Bitmap by iterating through the
// “frames” of the Vector (and loops to the beginning when it
// reaches the end.
protected function animateBitmap():void
{
// Move position along in the vector.
// ———————————-
if (bmpFrame < vecMyBitmap.length-1) bmpFrame++;
else bmpFrame = 0;
// Change bitmapData of bitmap.
// —————————–
bmp.bitmapData = vecMyBitmap[bmpFrame];
}

}

}

[/cc]

Still with me here?  Good, because we’re pretty much done at this point, now we just get to use the two classes we’ve created!

How to use these classes

Alright, now we get to the good part.  How do you use these classes?  It’s simple, really.

First, you obviously need to initialize the BMPLoader class.  I typically do this in the parent of all of my game objects, typically the Level object or something.

[cc lang=”actionscript3″ escaped=”true”]

bmpLoader = new BMPLoader(this);

[/cc]

Then just place this code in the constructor (or init() or whatever) function of your game object (your Player, Bullet, Coin, etc):

[cc lang=”actionscript3″ escaped=”true”]

bmpLoader.load(new PlayerSkin(), “vecPlayer”); // Obviously change these to your needs.
vecMyBitmap = bmpLoader.vecPlayer;
setupBitmap();

[/cc]

As the comment says in the code, obviously change new PlayerSkin() to the MovieClip you wish to turn into BitmapData and vecPlayer to the name of the Vector inside of BMPLoader in which to store said BitmapData.

Then, in your game object’s loop function, you can simply call the animateBitmap() function and the BMPObject class will animate your object just as if it were a MovieClip. Neat, huh?

Conclusion

Now, there are three major things you must remember by utilizing this method:

  1. In order to be able to convert a MovieClip into BitmapData – the MovieClip’s registration point must be set to (0,0).  To avoid clipping, your MovieClip art must at no point in any of it’s frames extend less than the x = 0 or y = 0 point.  If it does, the BMPLoader class will produce a Bitmap of your MovieClip which is clipped (and not very pretty-looking).
  2. Be aware to not attempt to populate a Vector in the BMPLoader that doesn’t exist or you’ll obviously get an error.  For example, doing bmpLoader.load(new PlayerSkin(), “vecPlayer”); and not having a vecPlayer object in BMPLoader will cause you some problems.
  3. Since your game will no longer be using crisp-looking vector-based graphics, you may encounter times in your game where your art doesn’t look as good as it does in the Flash IDE when you were drawing it.  This is normal, since you’re now using Bitmaps. Your art will look perfectly fine as long as you don’t zoom in or rotate it during gameplay.  I’m not saying you can’t do those things, but if you do the art will become slightly jagged-looking.  Not necessarily ugly (unless you zoom in 100x’s or something), but it’ll be noticeable.

Alright, I think I’m done here. I hope if you found this article by Googling a problem you’ve been having that it’s helped you out.  If not, tough noogies.  Well, either that or leave a comment and I’ll see if I can help ;).

I’ve been writing this post for two hours now.  That’s insane (for me).  Excuse me while I go rest my back and watch some TV before dinner.

PS – Today’s the 1 month anniversary of my back surgery.  Pretty cool, huh?

PPS – First Weekly Game Update in a long time scheduled for tomorrow.  Pretty cool, huh?

PPPS – Pretty cool, huh?

Don’t Panic Released on NewGrounds

4comments

Hey guys.  Now that I’m feeling better, I’ve finally gotten around to uploading Don’t Panic to NewGrounds.  I could’ve uploaded it sometime back in the middle of May (since ArmorGames had a period of exclusivity for a month) but since I was in the process of getting my back torn open, I decided to wait it out.

Anyway, go check it out and help me out by voting 5.  I really appreciate it because it really does help!

On unrelated news, I’ll have a new post in the coming days about what’s going on with Defective, including pictures!  Pictures!

Hello World!

3comments

WatSo… what’s been going on with you guys?  Me?  Oh, nothing much…

Alright, I’m going to try to sum up my past 4 weeks in as little words as I can, mostly because I really feel like going to lay back down again.

On May 25th, I was lucky enough to go down to the Hospital for Special Surgery in New York City to have my back torn open and my spine slapped around a little.  Why?  Well, really-long-story-short, mainly due to chronic back pain due to the way my spine had grown and positioned itself.  The pain had started roughly 5 years ago and as a result sitting, standing, or walking for too long of a period really took a toll on me.

The surgery itself lasted about 7 to 8 hours and resulted in some spinal fusion and two metal rods being placed inside of me.  I was in the hospital from Wednesday (the 25th) to Monday afternoon (May 30th).  I proceeded to spend the next week practically glued to my bed, in a good amount of pain and discomfort.

Let’s fast-forward to today, now.  The back pain from the surgery is okay, nothing too bad.  I have a pretty long scar from the bottom of my neck down to my lower back which looks pretty damn awesome.  However, I’m still nowhere near being able to get back to my normal routine.

Sitting or standing is really rough, which is why I’m still spending the majority of my day lying down in my bed and not at the computer.  It’s not only because of the back pain, though.  A side effect of this surgery is that my stomach (and practically my whole digestive system) hates me.  I don’t want to go into detail, but lets just say I’m having loads of trouble evacuating, if you catch my drift.  That and I go about my days feeling bloated and all around miserable.

I think I’ll stop here, there’s not much more to say.  I’m looking forward to when I feel good enough to sit at my desk for longer than 20 minutes without having to then hobble over to my bed and lay down to recuperate, but who knows how long until then.  The doctor has told me that in 6 months I should be back to normal.  The next check-up appointment I have with him is in 2 months, where I’m sure he’ll prescribe some physical therapy for me.

I know you’re all jealous.  Sucks to be you.

PS – I actually have dabbled with Defective a bit, a little bit here and a little bit there.  I was able to create a basic particle system which looks really nice.  I’ve also done lots of planning on my notebook since I spend all day doing nothing.  I’m really excited about this game.

PPS – I plan on uploading Don’t Panic to NewGrounds tomorrow.  I’ve waited long enough for anyone to get back to me about adding Medals to the game, so screw it.  Get ready to vote 5!

Weekly Game Update – “Defective” #2

0comments

Some solid progress was made last week.  It feels good to actually have some time to work on my own stuff since college is over now.  Let’s get into it.

Flash Game Development Update

General Stuff:

Alright, the game is still very new.  I’m still getting new ideas and throwing new ideas out every day.  (I have at least a dozen little post-it-type notes on the side of my desk here, all filled with ideas and thoughts I’ve had.)

This past week was primarily spent two ways (regarding this game):

  1. Drawing game art
  2. Getting the hang of recording for Youtube.

I also did a little programming (which I’ll link to at the bottom of this post) but I didn’t spend a lot of time with it.

But yeah, Youtube, I’d really like to start uploading videos every week of me just working on the game.  Right now it’s easy, it’s all graphics.  Later on I don’t know what I’m going to do when 90% of what I do is just programming.  Maybe I’ll release weekly videos of what the current build of the game looks like or something, we’ll see.

Accomplished:

  • Finally got some nice-looking drawings of the 5 main enemy ships completed.
  • A working build of the game was successfully completed (user is able to control the player).

To-Do

  • Design the player and multiple other minion-type enemies.
  • Begin nailing down some of the gameplay ideas/mechanics on paper.
  • Give the player the ability to shoot.

Alrighty.  So that’s that.  Now let’s get into some stuff that some of you might actually care about.

Defective Enemies

I kinda want an orange enemy, but eh.

Firstly, if you didn’t see my previous post, I have released a video on Youtube showing me going through the design process while I attempt to create the red enemy.  I’ve since released a second video showing me drawing both the yellow enemy and a minion-type enemy.  Go check them out and tell me what you think.

Next up, I’m just going to let you play with what I have to far of the game.  Now don’t get your hopes up, it’s pretty bland.  (No, seriously, it’s as bland as it can possibly be.)

After I completed build 1, I realized I was doing something very wrong.  I was programming the player’s ship as if it were a car and not a free-floating space object.

For whatever reason, it took me an embarrassing amount of time to go from Build 1 to Build 2, I just couldn’t wrap my head around the math that was required to get the player to be able to freely spin around while going in the same direction.  (You’ll see what I’m talking about when you look at the two builds.)  It’s still not 100% right (well, it works like I want, just the code isn’t optimal).

Alright, I think I’m done here.

There might be no “Weekly Game Update” post next Sunday, just throwing that out there for the two of you that read this.  LOL!

Drawing Stuff for “Defective”

3comments

I know, a post that isn’t a “Weekly Game Update.”  I’m freaked out too.

Defective Youtube Video

Anyway, I figured I’d let you guys know I just uploaded a video to Youtube showing me working on some art for my upcoming game, Defective.

Check it out here.

I might make more of these if I see people are interested, it was kind of fun.