SpriteGrabber class -SpriteSheets in 2 lines

SpriteGrabber is now in Code Section

FEATURES:

*Mix sprites of different characters, different movements and/or various stationary images in a single SpriteSheet and call them by common image-name prefix (e.g. “hero-”, “background”, “enemy3attack”).

*Rapidly grab and display sprites in 1 line of code - e.g. hero=sprites.getSprite(“hero”, true)

*Conveniently register a sprite’s animation clips - e.g. enemy=sprites.getSprite(“enemy”, true, {stand={1,6,1000,0}, attack={7,6,1000,1}})

*Play a named clip without preparing it - e.g. enemy:playClip(“attack”)

*Normally use all spriteInstance SDK-supported functions - e.g. enemy:pause()/play()

*Start/Stop rendering or transform a given sprite in 1 line of code - e.g. enemy:hide() , enemy:show() , enemy:show(100,100,0.5,“c”)

[import]uid: 7356 topic_id: 3197 reply_id: 303197[/import]

I downloaded your module and tried to use it but I’m getting a weird error:

grabber = require(“SpriteGrabber”)
local chars = grabber.grabSheet(“sprites/chars”)
local hero = chars.grabSprite(“hero”, true)

[lua]Runtime error
/test/SpriteGrabber.lua:192: bad argument #1 to ‘len’ (string expected, got boolean)
stack traceback:
[C]: ?
[C]: in function ‘len’
/test/SpriteGrabber.lua:192: in function 'grabSprite[/lua]

I looked at the module at line 192 and got this:

[lua]local sprLength=string.len(requestedSprite)[/lua]

The odd thing is that requestedSprite *IS* true. I’m not even sure where my sprite name, hero, went. Do you have any ideas?
[import]uid: 10708 topic_id: 3197 reply_id: 9404[/import]

@ZeStuff

What “sprites/chars” stands for? Is it a path tree… ?
The function grabSheet(string) waits for the name of the image that is your spritesheet (e.g. the “uma.png” file that contains a series of images). Specifically the string should be given without the extension (e.g. grabSheet(“uma”) )
The second string (“hero” in your code) should be a part of the name you use for some images which show movements of the same character. For example, if you have :

charJump1.png

charJump16.png
charRun1.png

charRun16.png

the common image-name preffix here is “char” for all movements (frame sets). So your code would be:

[lua]grabber = require(“SpriteGrabber”)
local characters = grabber.grabSheet(“myCharsSpriteSheet”)
local herochar = characters.grabSprite(“char”, true) [/lua] [import]uid: 7356 topic_id: 3197 reply_id: 9413[/import]

sprite/icons is because I was using subfolders. I removed that.

hero refers to hero.png in my spriteSheet. It’s a single sprite with no other image related to it. [import]uid: 10708 topic_id: 3197 reply_id: 9414[/import]

@ZeStuff

The SpriteSheet.png ( or whatever named) + the SpriteSheet.lua files have to be where your main.lua file is. Not in other directories. You can have your images anywhere in your disk. This is how Corona works…

So, having the SpriteSheet.png/lua files in your main.lua directory, and supposing you have a “hero” frame injected in your SpriteSheet.png, you would write:

[lua]local sheet = grabber.grabSheet(“SpriteSheet”)
local hero = sheet.grabSprite(“hero”, true) [/lua]

If that doesn’t help, plz give more info… [import]uid: 7356 topic_id: 3197 reply_id: 9417[/import]

I stripped it to the bare minimum and I still can’t get it to work.

main.lua
[lua]grabber = require(“SpriteGrabber”)

local sheet = grabber.grabSheet(“icons”)
local hero = sheet.grabSprite(“hero”, true)[/lua]

[text]Copyright © 2009-2010 A n s c a , I n c .
Version: 1.0.0
Build: 2010.109
The file sandbox for this project is located at the following folder:
(/var/root/Library/Application Support/Corona Simulator/test-665A98E0E58AE1008D85DE31EE08429B)
Runtime error
/test/SpriteGrabber.lua:192: bad argument #1 to ‘len’ (string expected, got boolean)
stack traceback:
[C]: ?
[C]: in function ‘len’
/test/SpriteGrabber.lua:192: in function ‘grabSprite’
/test/main.lua:4: in main chunk
Runtime error: /test/SpriteGrabber.lua:192: bad argument #1 to ‘len’ (string expected, got boolean)
stack traceback:
[C]: ?
[C]: in function ‘len’
/test/SpriteGrabber.lua:192: in function ‘grabSprite’
/test/main.lua:4: in main chunk

[import]uid: 10708 topic_id: 3197 reply_id: 9419[/import]

I can reproduce this error by changing the code to this:
[lua]grabber = require(“SpriteGrabber”)
local sheet = grabber.grabSheet(“icons”)
local hero = sheet.grabSprite(true, true)[/lua]

which is not your case.
I can’t think of any other tips. Sorry :frowning:

I would delete SpriteGrabber.lua and copy-paste it again from the code section (you might have changed something in the code by mistake). Be sure that the module works fine. I just copy-pasted it to be sure and I properly see my sprites animating in my screen. Everything is right with the code.
[import]uid: 7356 topic_id: 3197 reply_id: 9421[/import]

That’s the thing. I recreated the module myself (just a few functions) and I get the same problem.

I’m starting to think my environment is fubar. Yay. :\ [import]uid: 10708 topic_id: 3197 reply_id: 9422[/import]

Wow ok.

I reformatted my MacPro, reinstalled Corona before anything else and re-ran my code.

Got this:
/test/SpriteGrabber.lua:192: bad argument #1 to ‘len’ (string expected, got boolean)
stack traceback:

So yeah… I have no idea why it just won’t work for me :. I’m running Corona 2010.109 by the way. [import]uid: 10708 topic_id: 3197 reply_id: 9547[/import]

@ZeStuff, lets be optimistic, at least you brought some order to the OS. Now, lets continue with the network. Maybe you should change connection provider! ;p
I really can’t translate the debugging output you get. It just doesn’t make sense to me. I would only understand this, if you had a declaration hero = some-conditional within your main, before calling SpriteGrabber. But if you have only the above 3 lines in your main, then I can’t help… sorry.

Nobody else uses SpriteSheets in these forums?

Is everything OK with SpriteGrabber, for you? [import]uid: 7356 topic_id: 3197 reply_id: 9577[/import]

@ZeStuff

Let’s try something else:

  1. Make a new folder in your desktop and name it “horse”.

  2. Open your Corona GE 109 installation directory, go to /SampleCode/HorseAnimation/ and copy these two files: a) uma.png b) uma.lua

  3. Paste the two uma files inside your “horse” folder. Also, open your Text Editor, make a new file “main.lua” and save it (empty) inside the “horse” folder too.

  4. Open SpriteGrabber from the code section and copy paste the module code inside a new text file. Then save it as “SpriteGrabber.lua” inside your “horse” folder.

  5. In your main.lua file, copy and paste this:
    [lua]local grabber = require(“SpriteGrabber”)

local umaSheet=grabber.grabSheet(“uma”)
local horse=umaSheet:grabSprite("",true,{runSlow={1,8,1000,0},runQuick={1,8,300,0}})

horse:playClip(“runSlow”)[/lua]

  1. Save main.lua file and then start Corona with Terminal and open the “horse” project.
    Do you see Uma runnning ??

[import]uid: 7356 topic_id: 3197 reply_id: 9581[/import]

That worked. I was also able to use local horse=umaSheet:grabSprite(“01.png”,true).

I replaced uma.lua with my spritesheet (generated with zwoptex) and got the same line 197 error. I started to think that somehow, the problem could lie in my sheet so I redid it using TexturePacker and… it worked!

I have no idea why it wasn’t working before or why it generated such a weird error message but I finally figured it out. Thank you so much! :slight_smile: I guess I know which sprite software I’ll be buying ;). [import]uid: 10708 topic_id: 3197 reply_id: 9592[/import]

@ZeStuff

I am glad you managed to make it work for you!

You don’t have to (actually, you are not supposed to) give the whole png name for a sprite!
Supposing you wanted to display just the third frame of uma as a static character you can use “03” (since it is named “03”) as the image-name preffix:
[lua]horse=umaSheet:grabSprite(“03”,true)[/lua]

Since *here* all the frames are named by numbers you should give “” as the common name preffix to register the whole animation as a named (e.g. “run”) clip:
[lua]horse=umaSheet:grabSprite("",true,{run={1,8,1000,0}})[/lua]
You will get the first frame on screen, since you gave spriteGrabber a “true” for show sprite immediately. You could place “false” to keep it hidden and show the first frame, when you decide, with:
[lua]horse:show(100,200)[/lua]
and later play the “run” clip:
[lua]horse:playClip(“run”)[/lua]

Finally, you can always play the whole raw animation at the default (SDK) speed, without registering specific clips:
[lua]horse=umaSheet:grabSprite("",true)
horse:play()[/lua]
Actually, sprite:play() just resumes the last playing clip that was paused, but since here we haven’t started playing anything yet it resumes playing the whole animation at default speed.

[lua][/lua]

  1. Regarding Zwoptex:

I don’t see any problems with the output that the trial license of Zwoptex gives. I am using the default publish settings and have just selected “Corona Game Edition” for the Coordinates format. Actually, I guess that the uma spritesheet itself was made with Zwoptex.
[import]uid: 7356 topic_id: 3197 reply_id: 9597[/import]

You don’t have to (actually, you are not supposed to) give the whole png name for a sprite!

I know. I was just copy pasting some stuff and forgot to remove the extension.

Actually, sprite:play() just resumes the last playing clip that was paused, but since here we haven’t started playing anything yet it resumes playing the whole animation at default speed.

Actually, my sheets don’t have animations. They are just tiles either for maps or units.

I don’t see any problems with the output that the trial license of Zwoptex gives. I am using the default publish settings and have just selected “Corona Game Edition” for the Coordinates format. Actually, I guess that the uma spritesheet itself was made with Zwoptex.

My spritesheet lua file had 295 records in it. I’m not sure why it didn’t work. I will probably do a diff of both data files today or tomorrow out of curiosity.

Thanks again for everything. [import]uid: 10708 topic_id: 3197 reply_id: 9609[/import]

Hi Magenda,

Just got back into Corona after an unavoidable lay off from my dev work and SpriteGrabber looks great. I can see how it works and have studied the ‘horse’ example. I must be missing a step somewhere though as I haven’t managed to set up a sprite animation using my own exported sprite sheet from Texture Packer (T.P).
I’ve never used it, or Zwoptex before so can you clarify the process for me. After the sprites are loaded and sorted in T.P I ‘Publish’ them to my project folder ? And both the image and data file should be published, and both named the same, but with correct extensions (.png and .lua).] ?

I’ve tried a few times and I get a blank screen. I’m using the mentioned-above Horse example code, modified to take my own 2 files. Any ideas ?

[import]uid: 7396 topic_id: 3197 reply_id: 9835[/import]

@delta

For publishing spritesheets with TexturePacker take a look at:
http://developer.anscamobile.com/forum/2010/10/18/spritesheet-data-file-explained#comment-8752

The workflow for using SpriteGrabber goes like this:

  1. You draw your images and save them in a folder “images”. The images can be some animation frames with a number suffix after the sprites starting name (e.g. hero01.png … hero16.png) or several single-framed stationary graphics (e.g. button2.png, snow.png, background1.png).

  2. You then open terminal, write "cd " and drag and drop the folder *above* “images” folder (its parent folder). Press enter, so your terminal path is now the parent folder.

  3. Follow the syntax of TP from the link above and write something like this:

TexturePacker images/\*.png --format corona --max-size 1024 

This will take just the images with png extension (replace *.png with *.* to include all image files). TP will make two files with default names: out.png and lua.png inside the parent folder of “images” (the terminal path from which you run the TP command).

  1. Take those two files and place them inside the folder where your main.lua resides.

  2. Inside your main.lua require SpriteGrabber and call its functions to show the sprites. Ask for the sprites with the image names you have inside your “images” folder (without extensions). Supposing you have an image “hero.png” you should write something like this to show the sprite on screen:
    [lua]grabber = require(“SpriteGrabber”)
    local out = grabber.grabSheet(“out”)
    local hero = out.grabSprite(“hero”, true)[/lua]

And for a multi-framed sprite animation you have in “images” folder for an enemy sprite (enemy01.png … enemy16.png) you would continue with:
[lua]…
local enemy = out.grabSprite(“enemy”, true, {moan={1,8,1000,0}, attack={9,8,1000,1}})
enemy:playClip(“moan”)[/lua]

Similarly, you can use Zwoptex or the GUI of TexturePacker to publish spritesheets and use them with SpriteGrabber. Just be carefull to specify that you want the coordinates format to be for Corona and check that you actually get two files: something.png and something.lua
Rotation is currently not supported so untick it in Zwoptex.

[import]uid: 7356 topic_id: 3197 reply_id: 9842[/import]

Thanks for that. I was using the GUI on TexturePacker and all seemed ok… though I may have muddled up the part where you ask for the actual names of the image files that have been packed. I shall try again and try not to speed-read in my haste to learn…

Thanks. [import]uid: 7396 topic_id: 3197 reply_id: 9844[/import]

Yes, the whole concept of SpriteGrabber is to easily bring sprites on screen, from a spritesheet that holds *several* sprites, without continuously referencing spritesheet.lua for the exact table position of each sprite’s frames.

You just tell SpriteGrabber the string you have used as a root-name for your sprite’s frame-images and all the rest is done automatically.

Moreover, you can register all your spite’s animations, with 1 line of code instead of building and adding separate datasets one by one.
Don’t hesitate to ask for any additional help… [import]uid: 7356 topic_id: 3197 reply_id: 9856[/import]

Hi Magenda,

This query isn’t directly related to SpriteGrabber but I’d appreciate any help. Being able to call up any image frame by it’s name is great and I was wondering if this could be applied to my experimental code.
I’d like to take an integer value and use that as the image name. Say for example I have 5 images named simply 1,2,3,4 and 5 in a SpriteSheet. I then have an object that is placed at X position of 1, and is then randomly placed at a position between 1 and 5. Can this objects X position value (i.e 3) be converted to a string ( called “3” ) and that string/name then used in defining the image name for the object, something like…

testObject=testSheet:grabSprite(“3”,true)

Hopefully I’ve explained it clearly. I can see how SpriteGrabber coud do this but I’m insure on the conversion of the integer to a string. [import]uid: 7396 topic_id: 3197 reply_id: 10109[/import]

I came across the Tostring() and String.Format() commands, this could achieve the above ? If so, is one more suitable than the other ? [import]uid: 7396 topic_id: 3197 reply_id: 10125[/import]