Archive for the ‘AS3’ Category

MN SWF Camp Presentation

Tuesday, April 7th, 2009

Yesterday was a lot of fun as I got to present to the local MN.SWF group at their annual code camp they hold.

I presented a simple game of Simon off of my good friend Brad Bollinger.  Both presentations went great and complimented each other well.  If you attended talk or if you are curious about the presentation and files, you can download the code and presentation.  
Download the code here
Download the power point slides

Ginger: Using it for uniform sprite sheet rendering

Saturday, February 21st, 2009

Panayoti over at Urban Squall runs a fantastic blog called Game Poetry, there he posts great advice on all things for Flash gaming.  One of his posts found here is about improving performance with animated bitmaps.  In a nutshell it describes a code project that he has started up to create and manage bitmap animations from a sprite sheet.  At the end of the post he sent out a call to developers to help him out with specification for external data for creating animations.  I helped out and came up with my own, however it is now dated.  ;-)

Despite that I am encouraging you to check out the blog post and the project to whom ever wants a simple and clean implementation of managing animated bitmaps in your games or apps.  You can check out my implementation here.

Basically all that is happening in this example project is under the trycatchgames folder is my implementation of Urban Squall’s bitmap animation framework, which has since been updated.  In the Main class you can see how I am using XML to define an animation, create it using the animation builder, add it to the controller and play it.  By using the unified animation controller we are able to add one to many bitmap animations and retrieve them when needed.  It should also be noted that even if you don’t have rotation in your sprite sheet that you are able to add rotation if you so desire.  On bitmap animation creation you are able to specify the number of degrees in your rotation.

Check out the example project and the newest one in the Urban Squall code repo found here.

Analyzing Sound in AS3

Tuesday, January 6th, 2009

I have been wanting to build a game that builds worlds/enemies/properties off a given music file for some time.  There are some decent games out there that are making such strides, one of which is Tube Rockers.  I like that game because it involves people making custom tracks to music videos found on You Tube.  Pretty cool.

However, with Flash 10 we have the ability, with the users permission, to read and write to their hard drive.  Finally.  I know I can say this for every Flash/Flex developer out there that we have been waiting for this since… well… Flash was created really.  And now without round tripping to the server!  Yay!

Analyzing sound in Flash has been around since SoundMixer.computeSpectrum() was introduced in Flash 8.  Using this, along with the read capabilities of Flash 10 we can bring in any mp3 a user would like to play in a game.  This is where the idea stems from.  Try Catch Games (www.trycatchgames.com) my casual game company is currently concepting such a music game, more on that to come.

Now to talk about sound.  Here are some stats:

Human Hearing: 20 to 20,000 Hz

Bass: 20 Hz - 250 Hz Mids: 250 Hz - 6 kHz Highs: 5 kHz - 20 kHz

Bass Drum: 50 Hz - 5.5 kHz Thump: 50 Hz - 100 Hz Punch/Slap: 2.5 kHz - 5 kHz

Cymbals: 300 Hz - 17 kHz Presence: 10 kHz - 14 kHz

Snare: 100 Hz - 12 kHz Center: 1 kHz Tight: 5 kHz - 6 kHz Crack: 8 kHz - 10 kHz

Toms: 4 kHz - 5.5 kHz and 9 kHz - 10 kHz

***

I am going to assume that readers of this blog know a thing or two about sound.  If not, check out a wiki and come back.

A lot of you are probably asking “What does this guy know about Flash that I don’t to analyze sound?”.  Really the answer is, nothing.  I just want to give out some information that I have found out to further your journey into building better Flash games or apps.  Let’s jump in.

Checking out the computeSpectrum method in the SoundMixer object you will find a few params:
computeSpectrum(outputArray:ByteArray, FFTMode:Boolean = false, stretchFactor:int = 0)

The params I am going to focus on are the last two and what to do with that data.  First, for the data that I want I set FFTMode to true because I am interested in the frequency spectrum instead of the raw sound wave.  With this frequency data I want to filter out (as best as possible) values that tell me when something is happening.  This “something” would be a beat, vocals or guitar.  Now I have to say from the onset that my filtering isn’t really that great…yet.  But I believe with the capabilities of extracting raw sound data from an MP3 and computeSpectrum (or one or the other) will help me accomplish my goal more accurately.  For now, I am analyzing on-the-fly and averaging values based on what I think a beat is.

The next param is the stretchFactor.  I believe this to be important to be tweaked as we can drill down to the frequencies that are interesting to us.  In my experiment I am using the values of 3 and 5, which give us a stretch to the frequencies of 5512 and 1378 respectively.  Now I obviously use the 1378 frequency stretch for testing for sound data in the lower spectrum (which covers a lot of sound actually) which is mostly beats, bass guitar and some voice depending on the music.  The higher one, 5512, would be used for higher frequencies like violin and female voice.

For some simple formulas in finding these frequency ranges I have hard coded x and y point values.  This can be found by the frequency max limit, which for the lower one would be 1378, then divide that by 512, as this is the number of channels.  You will find that each “slice” will be about 2.69.  This means that within each of these slices it will cover a particular frequency range.  In the case of covering 0Hz - 100Hz you would divide 100 by 2.69 to find how many slices it occupies.  In my experiment I would sometimes give or take a few slices in some cases.

I know none of this is ground breaking, but I did my fair share of searching and no one has talked about it.  My experiment that I did off of this research is a simple on-the-fly averaging music program that does a little filtering and displays a square when the grouped slices go over the average.  Currently, I am not going to share the source code as its a work in progress but if you would like to check it out contact me directly: nate |at| trycatchgames |dot| com

<a href=”http://trycatchgames.com/SoundAnalyze/bin/SoundAnalyze.swf”>If you would like to check out my experiment do so here.</a>

Implementing the Kongregate High Score API

Monday, December 15th, 2008

I consider myself an “alright” programmer. So when something that is supposed to be simple in programming frustrates me, I feel like a complete moron. Enter the Kongregate API, chances are if you are reading this post you have dealt with it in some fashion. Now if the documentation was all over the place and split up (and done in an actual OOP example) it might actually make some since. Hence the reason for this post. I hope to clear things up a bit.

First, to check out the documentation here. Nice huh? Well hopefully I don’t screw it up more. You will notice that there are few options to which you can implement said API. I recommend the SWC since you can have code hinting and its right there at your disposal. Or you can go with downloading it remotely (this post does not deal with the component). If you decide to download it at runtime check out this guys post. If you do go with that dude’s way make sure you listen to the KongregateEvent.COMPLETE event. (this is what threw me off completely)

Ok, so this is going to be short and sweet. When you use the SWC way I recommend having a reference to it that you can access from anywhere. Let’s not argue about OOP practices and evil singletons, just roll with it. I like to throw a reference to it in my “Model” which I have access to anywhere, this could be said about any class that you are storing persistent data through out your game. Then in your “Main” or Document class make a new KongregateAPI (NOT getInstance() like the docs say and then listen for the KongregateEvent.COMPLETE event. Those two things completely threw me off because I heard different stories from different sources… as dumb as that makes me look. Then finally where you want submit a score do so in your “Results” class. (Imports NOT included in code, I assume you are just putting those in)

In your “Model”:
public var kongregate:KongregateAPI;

In your “Main” or Document Class:
Security.allowDomain('http://www.kongregate.com');
_model = Model.getInstance();
_model.kongregate = new KongregateAPI();
_model.kongregate.addEventListener(KongregateEvent.COMPLETE, kongInit);
stage.addChild(_model.kongregate);

private function kongInit(event:Event):void {
_model.kongregate.services.connect();
}

In your “Results” Class:
_model = Model.getInstance();
_model.kongregate.scores.submit(_score);