Converting a sprite sheet to individual sprites

Subscribe to Converting a sprite sheet to individual sprites 12 posts

avatar for DrYoshiyahu DrYoshiyahu 678 posts
Flag Post

Does anyone know of a program that can automatically take a sprite sheet, cut it up in accordance to the dimensions I give it, and then save all the individual files seperately? I know Game Maker can do it but the best I can do after I cut it up is save it as a different sheet or an animation.
-Dr. Y

 
avatar for RTL_Shadow RTL_Shadow 1036 posts
Flag Post

Should be relatively easy to do in AS3, don’t use an external program. I’d help but I’m really tired, sorry.

 
avatar for DrYoshiyahu DrYoshiyahu 678 posts
Flag Post

That’s cool, I should be able to do it, I just don’t know how to export image files using AS3, that’s all I need to know.

 
avatar for Danishdragon Danishdragon 370 posts
Flag Post

Just wondering… Why would you want to save them as individual ones?

 
avatar for BobTheCoolGuy BobTheCoolGuy 3773 posts
Flag Post
Originally posted by DrYoshiyahu:

That’s cool, I should be able to do it, I just don’t know how to export image files using AS3, that’s all I need to know.

PNGEncoder and FileReference will do the trick. For FileReference: Only one browse() or save() session can be performed at a time (because only one dialog box can be invoked at a time). In Flash Player, you can only call this method successfully in response to a user event (for example, in an event handler for a mouse click or keypress event). Otherwise, calling this method results in Flash Player throwing an Error exception.

I’m also curious though – aren’t you doing this backwards? :D

 
avatar for DrYoshiyahu DrYoshiyahu 678 posts
Flag Post

I already have the spritesheet made up from back when I used Game Maker, but now it’s Flash, so I need each frame seperately.

 
avatar for skyboy skyboy 6261 posts
Flag Post

Originally posted by DrYoshiyahu:

I already have the spritesheet made up from back when I used Game Maker, but now it’s Flash, so I need each frame seperately.

why not leave it as a spritesheet and animate it with code? copyPixels is easy to use, so is the Rectangle class

 
avatar for DrYoshiyahu DrYoshiyahu 678 posts
Flag Post
Originally posted by skyboy:

why not leave it as a spritesheet and animate it with code? copyPixels is easy to use, so is the Rectangle class

Better still, I’ll just use a 32×32 mask and move the sheet behind it. :P

 
avatar for Lucidius Lucidius 180 posts
Flag Post

While that may be an easier method – it is not the most efficient and hogs up resources.

Lets say you have your player. You’ve got your mask on the sprite, and you are using cacheAsBitmap = true (i hope)…and youve got yourself a rectangle defined to be used in the .scrollRect property of your sprite (or whatever display object) cool cool. But that entire tileSheet is being stored in memory…no big with a single object…but now lets say you have your player, 4 different enemies, and maybe a teammate on the screen – now youve got to have 5-6 entire tileSheet bitmapDatas taking up memory being shuffled around…

That isnt considering map tiles, items, etc as well that may or may not be on that same tilesheet…

copyPixels is your best bet here. Its fast and cheap. just define a simple class called TileSheet that takes in that bitmapData, and define variables that can be used to pick out specific tiles. For example a tileWidth and tileHeight variable that defines how big in pixels each tile is…remember that though it is tempting to write a function in there that returns a specific tile as bitmapData – such is an unnecessary and, in high amounts – needlessly expensive operation. You are better off copying directly from the tileSheet’s bmd from your game/controller class. Instead write a function that returns you a specific Rectangle for use in copyPixels, when you plug in a desired tile number…

It may be hard at first to wrap your head around vars like tilesPerRow, and finding a specific tile just by using a tileNumber…but remember the modulo (%) operator is your friend. Basically you find the ‘row’ (or Y value of the copyPixels sourceRect) by dividing your tileNumber by tilesPerRow….then you find the ‘column’ (or X value of the copyPixels sourceRect) by finding the remainder, of tilesPerRow in tileNumber (tileNumber%tilesPerRow)….you then multiply these two values by the tileHeight and tileWidth to find the top-left point of the sourceRect on the tileSheet bmd, to copyPixels from to your destination (either your sprite or the canvas)….

By doing this you only need a single instance of the tileSheet in bitmapData form, stored in a single instance of TileSheet that is passed to all entities that need it…very cheap indeed.

 
avatar for DrYoshiyahu DrYoshiyahu 678 posts
Flag Post

You misunderstand me, it’s not one tilesheet with everything I’ll need on it. Imagine an army with 150 different troops, and each one has its own 96×128 tilesheet at 8 bpp. The troops are all identical in size and shape so all I need is one Class for all the troops, so that no matter which tilesheet I use, I can use the same function. Besides, there’ll be a limit of 20 or so in the game at any one time. So each of those 20 troops only has a 2.3kb sheet to move around. But I’ll see how it goes and if it starts to lag at all I’ll try using copyPixels. Of course I’ll need 150 bitmapDatas for that.

Explain cacheAsBitmap to me though, I’ve never used it.
For the record, what I have currently are PNGs that I put into the troop’s movieclip (each one has their own mc) and just added the mask in the editor, I have a “Friendly” Class with all the functions to which the troop is added as a child to.

 
avatar for Lucidius Lucidius 180 posts
Flag Post

I’ll try to be more clear:

If youve got a bunch of instances of one class with its own 96×128 tileSheet, thats a waste. Ideally they should only have a bitmapData that is of the tile width and tile height – if any bitmapData at all! (more on this later)

Even with 20 troops, thats
96×128 = 12288*20 or 245,760 pixels being stored
versus (assuming 32×32 tiles)
32×32 = 1024*20 or 20,480 pixels being stored (or about 1/10th)

You misunderstood the concept of a tileSheet holding class. You only create it once for each particular tileSheet. So solderTileSheet:TileSheet mageTileSheet:TileSheet orcTileSheet:TileSheet. You pass this to each instance of solder, mage, and orc (say they are all Sprites) for their use. So even with 20 soldiers, there is still only ONE tileSheet between them, versus 20 personal tileSheets that they each shift around according to their current tile…

You will not need 150 bitmapDatas for a copyPixels operations for each ‘unit’, unless you plan on having a bitmap inside each sprite…

By the way, use Sprites instead of MovieClips, if you are not using the timeline at all. (I.e. doing pure code in flashDevelop) they are MUCH, much faster and cheaper and are fully qualified as display objects.

..You only need one copyPixel operation per unit. Whether you are doing this operation within each Sprite, into its personal bitmapData, or straight from the tileSheet to your screen-sized canvasBitmapData (a technique called blitting)…its very very fast. Once you try it I doubt you will go back to something else…but like you said maybe you wont need it. Depends on how many effects and everything you will have going on at once, or if you are going for something simple and can get away with a little waste ;)

Even with a personal 32×32 bitmapData for each of your units its still 1/10~ the size of having each unit have its own tileSheet…Like I mentioned if you want to go the extra mile for those cheap/older machines out there (a good chunk of audience), you can get away with only one instance of each tileSheet using copyPixels.

By the way, if you have 150 different troops, you will have to be storing each of those tileSheets/bitmapDatas on the user’s RAM regardless (as embedded into the swf). Why not keep it at that? (rather than those, PLUS a tileSheet for each unit that is actually on the field)

Since you are using straight bmd you dont need cacheAsBitmap…its only useful for non-dynamic vector-art inside a displayObject that is being masked (what it does is keep the whole thing from being processed every frame, but instead just what is inside the mask) As the name suggests its just converting the vector to a bitmapData and rendering to the masked area.

Anyways, if anything please use Sprites instead of movieclips :3 Just know that with pure blitting you can get up to 1000 objects moving around on screen taking mayyyybe 20MB mem max at 30 fps

 
avatar for DrYoshiyahu DrYoshiyahu 678 posts
Flag Post

Alright thanks man, will do. :)