-
Notifications
You must be signed in to change notification settings - Fork 0
Using SpriteSheets & Sprites in Camo
#summary * This is out of date and refers to version 2.0 of the framework. A update is coming soon. *
The main feature of the framework is the SpriteSheet system (located in the [http://code.google.com/p/flash-camouflage/source/browse/#svn/trunk/FlashCamouflage2/src/camo/core/decal camo.core.decal] package); made up of [http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/decal/Sheet.as Sheet] and [http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/decal/Decal.as Decal] classes. The SpriteSheet concept was inspired by the F*Sprites you would get with model airplanes. Each model kit would contain sheets of graphics and on each sheet you could peal off a decal and place it on the model. Camo’s version of the SpriteSheet allow you to load in external images, cut out decals, and skin you application with the Decals. The following diagram will help when explaining the relationship between the three classes:
= Details =
SpriteSheets
The [http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/decal/SpriteSheet.as SpriteSheet] is the manager for the sprite system. It handles the xml that defines a list of sheet images and coordinates for cutting out each Spri. Once this data is set, the SpriteSheet goes out and gets all the images it needs for the Sheet images.
The SpriteSheet makes use of a special load manager called the [http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/managers/BitmapLoaderManager.as?r=220 BitmapLoadManager] ([http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/managers camo.core.managers]). This class automatically goes out an loads anything flagged to be preloaded. Once the images are loaded, the SpriteSheet is ready to be used. If a page is not flagged to be preloaded but is requested, it will be added to the load queue. Decals can still be requested before the page images are fully loaded. The SpriteSheet will use a Decal’s width and hight to generate a proxy graphic (a temporary black placeholder graphic) that will be replaced once the corresponding Sheet has been loaded.
Sheet
Loaded images get stored inside of a Dictionary within the SpriteSheet as individual Sheets. Each Sheet’s key come from its id defined in the XML. At any time you can get a Sheet by calling getSheet. The Sheet extends the [http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/decal/AbstractCamoBitmap.as AbstractCamoBitmap] and inherits the sample method. When you request a sample, you must pass it a Rectangle that defines the x, y, width, and height of the area to cut out. BitmapData is return and in the case of a SpriteSheet, that BitmapData is then placed into the constructor of a new Decal. Lets take a look at some sample xml for setting up a SpriteSheet:
{{{
skin.gif
<decal id=“bg” sheet=“skin” x=“417” y = “1” w=“26” h=“52”
scale9Grid=“1,1,24,50”/>
}}}
Sample SpriteSheet XML
The above SpriteSheet XML is broken up into two main nodes, one for Sheets and the other for Decals. Each Sheet node contains an id (unique reference name), preload (true or false), w (width) and h (height) attributes along with the path to file. On Startup, the SpriteSheet requests a list of all the sheet nodes flagged to be preloaded and begins loading each src image. The baseURL attribute, located in the sheets node, is added to the url of each page’s src when making the load request. You can leave this empty and point each src directly to an absolute url if your images are not located in the same directory.
The decals node defines how each decal should be cut out. A decal node has an id (unique name for lookups), page (name of page where decal will be cut out from^1^ ), x, y, w, and h. There is also a special attribute called scale9Grid that can be used for defining resize scaling instructions.
To use this XML, simply pass it into a SpriteSheetConfig’s constructor which in turn gets passing into a SpriteSheet’s constructor. SpriteSheets store the SpriteSheetConfig instance (accessible through the config getter) that parses and manages the SpriteSheet xml. Lets take a look at how Sheets and Decal extend the AbstractCamoBitmap.
AbstractCamoBitmap
Every class that extends the AbstractCamoBitmap has access to the sample method. The only parameter it accepts is a Rectangle that defines the area to copy BitmapData from. The SpriteSheetConfig manages converting decal node attributes into usable data by creating a [http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/configs/DecalConfig.as?r=220 DecalConfig] ([http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/configs/?r=220 camo.core.configs]).
http://flashartofwar.com/wp-content/uploads/2009/01/camo_display.gif
The inheritance tree for AbstractCamoBitmap, Sheet, CamoBitmap and Decal.
DecalConfig
In Camo, Config classes ([http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/configs/?r=220 camo.core.configs]) help parse, store, organize and manipulate complex data like xml and objects. All config classes extend the [http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/configs/AbstractConfig.as?r=220 AbstractConfig] which provides two functions: dump (tracing out the properties of a class to the console or output window for debugging) and clone (used to create a copy of the instance’s properties and values). This notion of taking an Object or XML, putting it inside of a config class, and having a main class typed to the config is an important concept used throughout the framework
Decal
So now you have seen how we get xml data into a SpriteSheet, lets talk about how to retrieve Decal instances. When you call getDecal, you pass in the id of a Decal so the SpriteSheet’s template can create its corresponding DecalConfig. You can check if a decal exists by calling the SpriteSheet’s hasDecal method. Once a Decal is requested, the SpriteSheet takes the DecalConfig, looks up its page id, and creates a new Decal instance. The diagram below illustrates the process:
http://flashartofwar.com/wp-content/uploads/2009/01/decal_sheet_system.gif
This shows how a Decal is sampled from a Sheet by using the coordinates of a DecalConfig.
A Decal is a special type of [http://code.google.com/p/flash-camouflage/source/browse/trunk/FlashCamouflage2/src/camo/core/decal/CamoBitmap.as?r=220 CamoBitmap] that contains a reference to the Sheet it was cut out from. This connection allows the Decal to receive updates from its parent Sheet. Since the Sheet extends the Bitmap class, you can change its BitmapData at any time. Decals listen for CHANGE events from their parent Sheet and once an event is received, it resamples the Sheet and updates the Decal’s BitmapData^2^. Imagine being able to reskin an entire application by changing the BitmapData in a single Decal Sheet Page? All the Sheet’s children will atomically refresh. Here is a diagram to illustrate how this works:
http://flashartofwar.com/wp-content/uploads/2009/01/sheet_update_event.gif
Changing the BitmapData of a Sheet will fire a COMPLETE event telling all children Decals to update.
With Flash Camouflage’s SpriteSheet system, you can reduce your applications memory footprint by consolidating smaller images into larger sheets. Any graphic you would embed in a class or place in a FLA’s library can be stored in a single SpriteSheet and be spread over multiple Sheets depending on your needs^3^. Since Sheets can be set up to only load when requested, you can load in application graphics exactly when you need them; cutting down the initial startup and load time.
1 The framework handles looking up sheets by name so it should refer to the sheet’s id defined in the xml. Sheet id names should be unique to avoid conflicts.
2 The Decal’s detach method will remove the connection to its parent Sheet.
3 When it comes to designing your decal sheets, you should consider grouping images that do not have transparency into single jpg or gif image. Images with transparency should be grouped together as pngs. Since pngs are larger, it helps to break these sheets up as small as possible in the order of importance. This will help cut down on load times and optimize the streaming in of your Sheets.