SpriteSheet data file explained?

There is an example of a SpriteSheet data file placed in the section that explains how to use them:

http://developer.anscamobile.com/content/game-edition-sprite-sheets

-- test.lua  
module (...)  
   
function getSpriteSheetData()  
   
 local sheet = {  
 frames = {  
 {   
 name = "01.png",   
 spriteColorRect = { x = 38, y = 38, width = 50, height = 50 },   
 textureRect = { x = 2, y = 70, width = 50, height = 50 },   
 spriteSourceSize = { width = 128, height = 128 },   
 spriteTrimmed = true,  
 textureRotated = false  
 },  
   
 {  
 name = "02.png",  
 spriteColorRect = { x = 38, y = 36, width = 50, height = 52 },   
 textureRect = { x = 2, y = 242, width = 50, height = 52 },   
 spriteSourceSize = { width = 128, height = 128 },   
 spriteTrimmed = true,  
 textureRotated = false  
 },  
 }  
 }  
 return sheet  
end   

However, there is no explanation of the meaning of those parameters in there. While textureRect is probably the position and size of the image on the texture, I have no clue what the others should tell me. What is a “spriteColorRect”, a “spriteSourceSize” and why do I have to declare if a sprite has been trimmed or rotated…?

[import]uid: 9644 topic_id: 2749 reply_id: 302749[/import]

Don’t know why nobody answered but my suggestion is that nobody is actually using this feature… well, I don’t wonder why, because there are only two lonely tools available to generate those exotic data sheets needed and one doesn’t even run (TexturePacker crashes on my Intel MacBook) while the other (ZwopTex) seems to generate buggy output (animations are crippled when using with Corona).

So, unfortunately, using sprite sheets with non-uniform images is a no-go as long as there is no decent image packing tool provided. That’s sad, because this could habe been the most powerful feature in Corona to save valuable graphics memory :frowning:

It’s simply the lack of usable image packing tools that makes this nice feature almost completely useless.

However, if anyone’s interested -here’s what I found out:

textureRect:
The rectangle on the sprite sheet image where the (eventually trimmed) image is placed.

spriteSourceSize:
The (untrimmed) original size of the image

spriteColorRect:
The rectangle within the ORIGINAL (untrimmed) image that contains visible pixels.
[import]uid: 9644 topic_id: 2749 reply_id: 8356[/import]

I have not tested spritesheets yet, but I am also very interested in spritesheets with non-uniform images inside. Without this feature working, my game cannot be be built properly, because of the number and size of images involved.

I am going to share my experience as soon as I start adding images to my game… [import]uid: 7356 topic_id: 2749 reply_id: 8362[/import]

In my opinion, there is no way around sprite sheets.

Sprite sheets in general are a *must* since every loaded picture is internally treated like a texture (that means that all images are automatically resized to power-of-2 dimensions, wasting lots of memory). So placing as many graphics as possible in an image file saves a huge amount of graphics memory and -I don’t know if that also is true for Corona 2D- reduces the number of draw calls.

This memory saving is even higher if the graphics that have to be placed on a image are allowed to be trimmed (cut out to get rid of all fully-transparent pixels around a graphic’s visible content).

The memory saving would be even MORE efficient, if the graphics that need to be packed onto an image are allowed to be rotated to fit in the smallest possible gap there (however, Corona doesn’t feature this yet, as far as I know).

Ideally, the “workflow” of this should look like this:

  1. Draw your images (a series of images to be animated or several single images)

  2. Use an image packaging tool to combine those images onto a single texture and have them arranged on the texture as efficient as possible. Images with transparency need to be trimmed (all transparent pixels around a graphic will be cut away so that just the visible stuff remains) in order to reduce the wasted space as much as possible.

  3. Export the combined texture and a data file that tells Corona where to find which graphic on that texture atlas and what dimensions this graphic had before it has been trimmed.

Well, so what’s wrong with using sprite sheets in Corona?

Simply said, there IS no such a tool!!

Ansca itself does not provide one and the only two I could find are next to useless :frowning:

Using “normal” sprite sheets only (with uniform-sized images) do not require an image packaging tool, but are way too inefficient. It would require all your game graphics to have the same size -and it would still waste tons of valuable graphics memory because all the transparent space in the individual image frames would not be cut out).

So where’s the solution here? How can we use this awesome feature without decent working tools to do so?

* desperate mode ON * [import]uid: 9644 topic_id: 2749 reply_id: 8369[/import]

Why do you consider the two tools that you mentioned being useless?

Edit: And thanks for the info. [import]uid: 5712 topic_id: 2749 reply_id: 8371[/import]

@MauMau

Have you tried the “Horse” example, which is referenced in the new spritesheets documentation? In that sample there is a spritesheet that involves images of slightly different sizes (the horse in different animations frames). I have not given any time to this sample yet, but it should work!

[import]uid: 7356 topic_id: 2749 reply_id: 8372[/import]

Download the new GE from here: https://developer.anscamobile.com/downloads/game-edition
Read the docs here: http://developer.anscamobile.com/content/game-edition-sprite-sheets

"The HorseAnimation sample project demonstrates how to use create a sprite sheet from a Lua data descriptor file and source image whose frames are non-uniformly sized and positioned in the sheet. " [import]uid: 7356 topic_id: 2749 reply_id: 8374[/import]

Thanks Mau Mau, I didn’t know that they don’t work as advertized.
Because they are commercial, I was planing to create my own tool anyway. My budget is below zero atm so I can’t spend money on them anyway.

Cheers
Michael [import]uid: 5712 topic_id: 2749 reply_id: 8377[/import]

@MikeHart: As I wrote in my second post: TexturePacker doesn’t even run on my Intel MacBook (crashes on startup), ZwopTex seems to export a buggy data file (animations look kinda cropped in Corona, although I tested several animations and tried all options there). Additionally, both tools are available for Mac only. There is not a single packaging tool available for Windows (which I’d prefer since I use Windows to create my art assets).

I think, Ansca should not leave this to any third-party developers but provide an own, stable tool to make use of this vital feature. If there would be a dozen of tools to choose from out there, I wouldn’t complain. But the usability of this feature rises and falls with those only two tools that are available. That can’t be good.

@Magenda: I couldn’t try the “Horse” example since it’s simply not there! I searched each folder of my Corona SDK and Corona Game Edition installation, but couldn’t find it there. [import]uid: 9644 topic_id: 2749 reply_id: 8373[/import]

@Magenda: thanks for the hint -I totally missed the update…! I tried it again with ZwopTex and it indeed seems to work now o_O However, I still think it’s not a good idea to have only two tools available to be able to use of this feature. I’d feel much better, if there were other choices, too (especially non-commercial ones!).

@MikeHeart: Yes, I also planned to code an own packaging tool that could

  • Sample different images onto one texture
  • Crop the images to get rid of empty pixels around an image’s content
  • Uses a bin-packing algo to place the images as efficient as possible

*BUT* I do desktop apps with BlitzPlus -and that doesn’t support alpha channel PNGs (lol). Otherwise I would have provided this tool for free to the community (because I think things like that will attract more developers to Corona, which would be a benefit for us all).

I am currently looking for a solution to load alpha’ed PNGs into BlitzPlus. However, if I’ll find a way, the tool would be available for Windows only. What really frustrates me is that I already coded a similar tool which could be modified in a day or two -but that’s useless without the ability to load alpha PNGs (that’s one of the reasons why I quit with Blitz). Didn’t find a way yet… will try it with FreeImage lib.
BTW: Mike, if you want to get hands on it, here is a good article about bin-packing methods:
http://blog.tabini.ca/2010/09/optimized-image-display-using-a-bin-packing-algorithm-part-one/

[import]uid: 9644 topic_id: 2749 reply_id: 8384[/import]

Ah, another Blitzer. :slight_smile: I am using BlitzMax, that works good for me. thanks for the link, but Corona doesn’t support it, i think. [import]uid: 5712 topic_id: 2749 reply_id: 8394[/import]

@MauMau

What exactly do you mean by “TexturePacker crashed”? Is it that the application did not start after clicking on the app?

If it is like this its simple: If you read the documentation (which also comes inside the DMG file) You can read that TexturePacker is currently a command line tool.

The reason for deploying it as Application is I wanted it to keep the bundled libraries in one place without spreading them all over your computer. But this does currently not mean that you can start the app by clicking it.

To start TexturePacker you need to launch Terminal.app and use the shell. To create a sprite sheet you simply write

[bash]
TexturePacker assets/*.png --format corona --max-size 1024
[/bash]

This will take all the sprites in your assets folder and create a out.lua and out.png

You can specify the name for the file by adding
[bash]
TexturePacker assets/*.png --format corona --max-size 1024 \
–data sprites.lua --sheet sprites.png
[/bash]

The main advantage is that you can put these command into a simple script and if you update your assets you simply run the script again. And in 2 seconds without any further clicking your sprite sheets are updated!

Upcoming version (beta will be posted during the weekend) will have graphical user interface - I guess that’s what you expected :wink:

By the way: TexturePacker is available for a 20% discount for a short time only. Use coupon code TEXTUREPACKER-FOR-CORONA at the bottom of the order sheet

If you have any questions or problems contact me at andreas {at} code-and-web.de

Cheers
Andreas [import]uid: 9611 topic_id: 2749 reply_id: 8752[/import]

Andreas,

  1. When I use the --trim option the out.lua file comes with some frames having spriteTrimmed = true and others have spriteTrimmed = false. Is this a bug or it just means that some frames were already in such a state that no trimming was needed?

  2. When I use the --no-trim option the out.lua file comes with ALL frames having spriteTrimmed = true (yes, true), except sometimes that 1 or mostly 2 frames have false. I am talking about the same images of question 1. Shouldn’t the key spriteTrimmed be always false when using “no-trim”?

Could you please take a look on this, testing it with a spritesheet that has images from different characters (not an animation series of similar images)?

Thanks!
[import]uid: 7356 topic_id: 2749 reply_id: 9147[/import]

Hi,

  1. If a sprite has exactly the same size before and after trimming the spriteTrimmed is set to false. So trimmed is only set if something changed.

  2. This was a bug in 1.1.1 - its fixed in 2.0.0 TexturePacker and TexturePackerPro. It’s currently beta and will be released soon.

Please contact me if you are interested in beta testing :wink:

Cheers
Andreas

[import]uid: 9611 topic_id: 2749 reply_id: 9206[/import]

@Magenda: Could you please check if TexturePacker(pro) 2.0.0 fixes your problems?
[import]uid: 9611 topic_id: 2749 reply_id: 9440[/import]

@Andreas

It seems to be still there. The following comes with Trim option ticked in GUI.

[lua]function getSpriteSheetData()
local sheet = {
frames = {
{
name = “01.png”,
spriteColorRect = { x = 7, y = 13, width = 48, height = 38 },
textureRect = { x = 41, y = 970, width = 48, height = 38 },
spriteSourceSize = { width = 64, height = 64 },
spriteTrimmed = true,
textureRotated = false
},
{
name = “seeker.png”,
spriteColorRect = { x = 7, y = 13, width = 48, height = 38 },
textureRect = { x = 41, y = 970, width = 48, height = 38 },
spriteSourceSize = { width = 64, height = 64 },
spriteTrimmed = true,
textureRotated = false
},
{
name = “02.png”,
spriteColorRect = { x = 13, y = 9, width = 38, height = 48 },
textureRect = { x = 0, y = 970, width = 38, height = 48 },
spriteSourceSize = { width = 64, height = 64 },
spriteTrimmed = true,
textureRotated = false
},
{
name = “apple.png”,
spriteColorRect = { x = 0, y = 0, width = 281, height = 271 },
textureRect = { x = 727, y = 0, width = 281, height = 271 },
spriteSourceSize = { width = 281, height = 271 },
spriteTrimmed = false,
textureRotated = false
},
{
name = “aquariumbackgroundIPhone.jpg”,
spriteColorRect = { x = 0, y = 0, width = 320, height = 480 },
textureRect = { x = 0, y = 0, width = 320, height = 480 },
spriteSourceSize = { width = 320, height = 480 },
spriteTrimmed = false,
textureRotated = false
},
{
name = “bowling2ball copy.png”,
spriteColorRect = { x = 0, y = 0, width = 201, height = 201 },
textureRect = { x = 636, y = 819, width = 201, height = 201 },
spriteSourceSize = { width = 201, height = 201 },
spriteTrimmed = false,
textureRotated = false
},
{
name = “bowlingball.png”,
spriteColorRect = { x = 0, y = 0, width = 201, height = 201 },
textureRect = { x = 432, y = 819, width = 201, height = 201 },
spriteSourceSize = { width = 201, height = 201 },
spriteTrimmed = false,
textureRotated = false
},
{
name = “cherries.png”,
spriteColorRect = { x = 0, y = 0, width = 361, height = 350 },
textureRect = { x = 363, y = 466, width = 361, height = 350 },
spriteSourceSize = { width = 361, height = 350 },
spriteTrimmed = false,
textureRotated = false
},
{
name = “clock.png”,
spriteColorRect = { x = 15, y = 15, width = 120, height = 120 },
textureRect = { x = 0, y = 847, width = 120, height = 120 },
spriteSourceSize = { width = 150, height = 150 },
spriteTrimmed = true,
textureRotated = false
},
{
name = “fruit03.png”,
spriteColorRect = { x = 0, y = 0, width = 100, height = 100 },
textureRect = { x = 323, y = 363, width = 100, height = 100 },
spriteSourceSize = { width = 100, height = 100 },
spriteTrimmed = false,
textureRotated = false
},
{
name = “fruit04.png”,
spriteColorRect = { x = 0, y = 0, width = 100, height = 100 },
textureRect = { x = 329, y = 847, width = 100, height = 100 },
spriteSourceSize = { width = 100, height = 100 },
spriteTrimmed = false,
textureRotated = false
},
{
name = “fruit1.png”,
spriteColorRect = { x = 0, y = 0, width = 100, height = 100 },
textureRect = { x = 226, y = 847, width = 100, height = 100 },
spriteSourceSize = { width = 100, height = 100 },
spriteTrimmed = false,
textureRotated = false
},
{
name = “fruit2.png”,
spriteColorRect = { x = 0, y = 0, width = 100, height = 100 },
textureRect = { x = 123, y = 847, width = 100, height = 100 },
spriteSourceSize = { width = 100, height = 100 },
spriteTrimmed = false,
textureRotated = false
},
{
name = “peach.png”,
spriteColorRect = { x = 36, y = 35, width = 361, height = 360 },
textureRect = { x = 323, y = 0, width = 361, height = 360 },
spriteSourceSize = { width = 431, height = 430 },
spriteTrimmed = true,
textureRotated = false
},
{
name = “peach2.png”,
spriteColorRect = { x = 35, y = 34, width = 360, height = 361 },
textureRect = { x = 0, y = 483, width = 360, height = 361 },
spriteSourceSize = { width = 430, height = 431 },
spriteTrimmed = true,
textureRotated = false
},
}
}
return sheet
end[/lua] [import]uid: 7356 topic_id: 2749 reply_id: 9441[/import]

But this file is exactly how it should be - or am I missing somehting?

 {  
 name = "peach2.png",  
 spriteColorRect = { x = 35, y = 34, width = 360, height = 361 },  
 textureRect = { x = 0, y = 483, width = 360, height = 361 },  
 spriteSourceSize = { width = 430, height = 431 },  
 spriteTrimmed = true,  
 textureRotated = false  
 },  

spriteSourceSize: 430x431
textureRect: 360x361
spriteTrimmed = true

 {  
 name = "fruit2.png",  
 spriteColorRect = { x = 0, y = 0, width = 100, height = 100 },  
 textureRect = { x = 123, y = 847, width = 100, height = 100 },  
 spriteSourceSize = { width = 100, height = 100 },  
 spriteTrimmed = false,  
 textureRotated = false  
 },  

spriteSourceSize: 100x100
textureRect: 100x100
spriteTrimmed = false

[import]uid: 9611 topic_id: 2749 reply_id: 9454[/import]

@Andreas you are right! The mistake was mine. There is no problem at all!
Some suggestions for the Pro edition:

  1. Give a way to save profiles for the values of options, and save them. One of these profiles should be the Default (load on next session). This is vital, because someone has to change many values each time the app starts.

  2. If you find 1. difficult, please save all the options’ values on project Save. This could substitute functionality of 1.

3)Inform the user (with a label bellow “autosize”) about which “autosize” size was finally decided by TP.

4)This is for both Command-Line and GUI: inform the user about when the writing to the output image has finished, so he can open the file without crashing everything. I have crashed Corona many times, because of this -I push enter on Terminal, TP does its things, I click “run game” in Corona and it crashes, because the spritesheet image is still under construction.

[import]uid: 7356 topic_id: 2749 reply_id: 9486[/import]

  1. Noted but will take some time to implement (needs GUI adjustments)

  2. I guess 1) is better :wink:

  3. Yea - this is something I miss too ;-))

  4. ok - I’ll add some kind of progressbar [import]uid: 9611 topic_id: 2749 reply_id: 9488[/import]

For 4, I see that in GUI the Publish button stays grayed while TP is writing, so we have a sign.

For command line, where we don’t have any sign, you could add a print “SpriteSheets is ready for use” after finishing the write process.

Thanks! [import]uid: 7356 topic_id: 2749 reply_id: 9491[/import]