Saturday, 12 May 2012

A game then...

After messing around with all these different things I figure I'm not really getting any closer to my goal.  So bugger this framework business, it'll grow as I start building GAMES!

To get started then I'm going to make a simple shooter type game.  Most of these games are pretty dull, point and shoot and then upgrade, so I'll be dull and do something like that.  Should be easy enough getting the mechanic together.

First thing is to make the player thing which can move, aim at the mouse and shoot.  Then the enemies which I'd like to be visually damaged, a bit like this dude and zombies game.  I love the way this game plays and the graphics.

Should be a bit more fun then doing framework crap.

Tuesday, 17 April 2012

I'm still not dead :)

In the last four weeks I've been to Nottingham, Northern Ireland, Leipzig and Portsmouth.  Not bad?  Well I also started my new job which is very exciting and I finally started reading Clean Code after finally getting through the hunger games trilogy.

Anyway, I'm not dead!  I'm still trying to develop a framework for churning out games at home. It will happen and you'll get to read about it here!

Wednesday, 21 March 2012

This Robotlegs thing...

It's brilliant! I briefly explained what is was in my last post but my word....it's great!

When you're doing your homebrew little projects at home you fret about how your classes are going to communicate, and how to lay them out nicely and what should be aware of what, etc. Robotlegs does all that for you. The brief blurb on the site states:

"Robotlegs is a pure AS3 micro-architecture (framework) with a light footprint and limited scope. Simply put, Robotlegs is there to help you wire your objects together. It provides the glue that your application needs to easily function in a decoupled way. Through the use of automated metadata based dependency injection Robotlegs removes boilerplate code in an application. By promoting loose coupling and avoiding the use of Singletons and statics in the framework Robotlegs can help you write code that is highly testable."

Did I say it's brilliant?  Well it is!  Instead of thinking of how your classes communicate you start thinking about why you need that class, what it's responsibilities should be and quite often you realise you can decouple it very easily.

The automated dependency injection is frankly amazing!  I don't really know how to explain it very well and it took some tinkering to actually get my head around it.  Each robotlegs project has a Context where you'll describe the relationship and communication through your project, instead of putting a chunk of code in each class you use essentially coupling it to your project.  You are recommended to use interfaces and it makes sense as using the context you can set up tests very easily by using mock / stubs instead of concrete classes.  I am CRAP at explaining this!  Have a look at the first part of the Best Practices page :)

I've written a really crappy simulation of a box falling from the sky to the ground, it's crap..really!  It uses Robotlegs for the framework, AS3Signals for the communication and Box2D for the physics.  At the moment I'm re-writing my core project to use signals and fit into the Robotlegs framework, mostly to help me learn about the S in MVCS (services!) and how to decouple the canvas and blit object for blitting!

There's also a wonderful little tool called Texture Packer someone at work told me about.  I've just got the Pro licence so I'll be re-writing how the image and associated data will be loaded in and passed to the blit renderer!

Starting this blog really made the world of AS3 seem so much more colourful!  So much more to learn!

PS : Poom!

Monday, 12 March 2012

Busy Busy : Research

I'm not dead!  This and next month are probably going to be the busiest I'll have for the year so while I'm not posting I'm doing a lot of research in to a couple of new things :

Robotlegs : This micro-framework is just awesome, it makes all the relationship complications in your project just disappear and gently pushes you towards designing better code.  The documentation (there's a lot) is excellent too!

AS3Signals : Using the flash event system can be a bit of a ball ache sometimes and in most situations can be quite inefficient.  AS3Signals replaces the event backbone you're used to using and replaces it with some wonderfully simple micro-dispatchers!

Box2DFlash : A rigid body physics engine.  You create a world, add some stuff to it, define some rules and off you go.  The create seems a little long winded but looks like fun :)

CleanCode : While I'm not at a computer (on the train) I'm going to start reading this book.  Some common sense bits and bobs but bloody hell its nice to see that someone else who codes has some sense!  I HATE writing comments and this book advocates self commenting code!  Hurray!

I'm starting to write a really simple Box2D game implementing the Robotlegs framework so I can work out properly how it all fits together (exciting yay!).

Anyway thought I better post something before anyone who reads this loses interest....if anyone actually reads this :P


Thursday, 1 March 2012

Blit vs MovieClip : Introduction

What the hell is this Blit thing I've been banging on about ?  Well Wikipedia goes into a lot of detail about the origin, purpose and method of Bit Blitting but it doesn't really describe the process in AS3 clearly.

In essence Blitting is copying a bitmap from memory to another bitmap for display.  You may remember in an earlier post that I realised I made a total cock up by creating a new Bitmap for each object.  Generally only one bitmap should be used for display although multiple bitmaps can be used to create layers. The bitmaps that are drawn from memory should be stored as efficiently as possible so its a good idea to use BitmapData's.  These can be anything from static objects to animated characters and effects.

Now it's important to understand that to blit properly in AS3 you will be dropping a lot of a the display list functionality that makes life so much easier.  BitmapData doesn't extends DisplayObject so the only DisplayObject that you will be using is the bitmap that you'll be drawing to.  A lot of this functionality can be replicated using the parameters in method we're going to look at : copyPixels() while others can be simulated in other ways.  I'll go over this once I get around to doing it myself :)

It might seem crazy but the improvement in performance is excellent.  In tests (which I'll write up later) show that blitting is around 3 times faster in FPS and allowed the player to render around 10,000 animating and moving objects to stage (it was only 4/5 FPS but try getting that many movieclips on the stage with out the player crashing!).

Right, the concept then.  You'll have a sprite sheet :

source

So you have 25 tiles, each one is essentially a single frame in movieclip.  Playing one after the other will give you an explosion.  Now there are a couple of different methods for storing this bitmap and/or each tile and the guy at 8bitrocket did some nice experiments and examined the benefits of the different types.  The way I see it is that you can cut up the tiles and store individual bitmapData's or store the original bitmapData and the pre-calculated co-ordinate of each tile.  For now we'll talk about storing a point for each tile to make it easier.

You'll also need a bitmap to draw each frame to, I think most people call it a canvas.  As mentioned before this will be the main display and all objects will be drawn to it.  You'll need to clear and redraw it every frame otherwise you'll be left with residual images.  From this bitmap you'll be calling copyPixels()s : 

copyPixels(sourceBitmapData:BitmapData, sourceRect:Rectangle, destPoint:Point, alphaBitmapData:BitmapData = null, alphaPoint:Point = null, mergeAlpha:Boolean = false):void

So you'll be passing it the stored bitmapData, a rectangle that defines the tile shape and pre-calculated position and the point it needs to be copied to.  If it is an animation like above you'll be changing the position of the rectangle each frame to animate it.  The destPoint is important as it will allow you to decide where the object will be displayed on canvas.



What a daft picture that is!  I think it took me about as long to write this post to actually get around to making that thing :)

So although the performance is so much better the work you need to put into creating the framework that is going to support blitting is quite extensive.  Once the framework is in place though you'll be laughing at how much more your games can do compared to standard display list games :)

There will be more posts on SpriteSheets discussing how I actually did it myself and the results from the test.  I also thought of a couple more things I could look into, simple mouse tools, some mathematical tools (Vectors, distances, angles), and some different methods of collision detection (hopefully Separating Axis Thereom and bitmapData.hitTest).  Fun times!

Wednesday, 22 February 2012

AssetManager : Overview

I know I went over this before but might as well go over the AssetManager as it's probably the only core bit of code that I'm going to use in every test.

Essentially the AssetManager will execute loads, manage the queue and dispatch an event when its complete.  It should also be the only place where a getDefinitionByName is called.  I won't post the whole file, I'm hosting them at GoogleCode for that reason.  Here is the AssetManager in the source browser though.

The only bit worth mentioning is the load function :

public function load(toLoad : Object) : void {
 if (toLoad is Asset) {
  queueAsset(Asset(toLoad));
 } else if (toLoad is Array) {
  for each (var asset : Asset in toLoad) {
   queueAsset(asset);
  }
 }
 
 if (!_loaderInProgess) loadNext();
}

You can pass it either an Asset or an Array of Assets which will then be added to the queue, if nothing is loading it will then start the load process with the loadNext() call.

The AssetManager uses to the AssetLoader to load each Asset.  It's a pretty simple class, all it does is instantiate the loader type it requires, adds / removes listeners and throws and errors if it encounters them.  To prevent it being garbage collected it passes itself to the Asset.

Both classes will accept and handle on an Asset object or multiple Asset objects.  Again not much to report here but the Asset class is more a data type.  It stores all the information required to load and access the content.  The only complicated doohickey here would be the isData() getter :

internal function get isData() : Boolean {
 var type : String = _urlRequest.url.substr(_urlRequest.url.length - 4, 4);
 
 switch (type) {
  case ".swf" : 
  case ".png" : 
  case ".jpg" : 
  case ".gif" : 
   return false;
  default :
   return true;
 }
}

This works out from the URL what type of loader to use.  Great eh?

So it's pretty easy to use, you create an instance of the AssetManager, add an event listener so you know when it's complete and pass it a load of Assets to load ::

public function AssetManagerTest(stage : Stage) {
 _stage = stage;
 _stage.addChild(new Profiler());
 
 _loadList = [ new Asset("spritesheets/explosion.xml"), 
     new Asset("spritesheets/explosion.png"),
     new Asset("spriteclips/explosion.swf")  ];
 
 _assetManager = new AssetManager();
 _assetManager.addEventListener(Event.COMPLETE, loadComplete, false, 0, true);
 _assetManager.load(_loadList);
}


To access the content you do so pretty much like you would with a loader, with the content property :

private function loadComplete(e : Event) : void {
 _updateProgressTrigger.stop();
 
 var loadedXML : XML = new XML(_loadList[0].content);
 var loadedBitmap : Bitmap = _loadList[1].content as Bitmap;
 var loadedLinkedLibrary : Class = _assetManager.getClass("Explosion");
 var loadedLinkedMovieClipInstance : MovieClip = new loadedLinkedLibrary();
 
 trace("[AssetManagerTest.loadComplete] |TEST| XML :: " + loadedXML.toXMLString());
 trace("[AssetManagerTest.loadComplete] |TEST| Bitmap :: " + loadedBitmap);
 trace("[AssetManagerTest.loadComplete] |TEST| MovieClip :: " + loadedLinkedMovieClipInstance);
}

You might wonder why I bothered with this?  It's basically to wrap the entire loading process into a nice little bundle which I can use whenever I want.  I may make this a singleton class so it can be accessed anywhere but I'd rather managed the access to it.  It also means if I need to update the way I load things I can do it one place.

Right I've uploaded a downloadable zip which has all of these classes in them and a test swf so you can see the result.  Let me know if you have any problems (if in fact anyone actually reads this!).

I'm sure loads of it will get updated as I progress along the project work flow (there isn't one yet :]).  Pretty basic stuff.  Next post I'll get into the blitting package and hopefully that will be more interesting.


Tuesday, 21 February 2012

SyntaxHighlighter

Wahey!!  Managed to figure out how to use SyntaxHighlighter.  This marvellous little do dad formats your code into a nice little code thingy :)

package {
 import flash.display.Sprite;
 import tests.BlitVSClip;
 
 /**
  * @author Charlie MacIsaac
  */
 
 [SWF(width = "800", height = "600", backgroundColor = "#000000", frameRate = "25")]
 
 public class Launcher extends Sprite {
  
  private var _memGauge : MemoryGauge;
  
  public function Launcher() : void {
   _memGauge = new MemoryGauge();
   
   runBlitVSClipTest();
  }
  
  private var _blitVSClipTest : BlitVSClip;
  private function runBlitVSClipTest() : void {
   _blitVSClipTest = new BlitVSClip(_memGauge, stage);
  }
 }
}

I used BloggerMint to figure out how to add it to the blog.  It's a really neat way of doing it!

So, finally got code showing and my project hosted, now I just need to follow through and create those downloads and link them here for the first few tests!  Should be fun :)