SpriteGrabber class -SpriteSheets in 2 lines

I want pass another param more to “grabber:grabSprite” with a group to add like:

[lua]imgFondo = optionsSheet:grabSprite(“imgOptions” … SGsuffix … “.png”, false, {dumyclip = {1, 1, 1, 1}}, group)[/lua]

I want forgot the [lua]group:insert(imgFondo)[/lua]

Regards. [import]uid: 11749 topic_id: 3197 reply_id: 28246[/import]

Well, SpriteGrabber doesn’t do that automatically but let me tell you why…

The philosophy behind Lua itself is “keep it simple”. The whole language is an absolute minimum set of bricks to help you build your own functionality. Other languages offer myriads of built-in capabilities but that makes them heavy, difficult and not flexible.

In the same spirit, there are dozens of things that someone could add as an argument to a sprite call, using SpriteGrabber. But then, imagine how awful the syntax of SG would be.

So, SG just acts as an absolute minimum path to easily use what the SDK “sprite” collection offers. You can built more functionality on top of SG calls within your custom functions. This makes SG easier to be understood and be used, without unnecessary candies that don’t suit to everyone’s needs.

A simple function that could help in your situation is something like the following:

[lua] function makeSprite(args)
local visible
if args.position then
visible = true
else visible = false
end
local mysheet = grabber.grabSheet(args, sheetname)
local mysprite = mysheet:grabSprite(args.spritename, visible, args.clips)
args.group:insert(mysprite)
return mysprite
end[/lua]

Within your code you can call this function like this:

[lua] local aSprite = makeSprite({
sheetname=“myicons”,
spritename=“iconSettings”,
clips={idle={1,1,1,1}, hover={2,8,200,1}},
group= sceneGroup, – a group within your code
position={100,200},
})[/lua]

You can place the function within a “funcs.lua” module (ask me how if you don’t know) and call makeSprite() from everywhere within your project. Also you can automate the fill of such function calls within your Text Editor so that only the values should be typed.

Moreover, you can mix and match other features of SpriteGrabber and make a full object builder function so that you describe the whole behavior of a sprite object from within a simple function call (like playing this clip onTouch() and go to that scene onRelease() and run these transitions every n secs and…). This can be done with adding methods (lua functions) to your sprite (ask me how if you want). A complete behavior set can be described within a table that you pass to your builder as “args”.

I personally use many similar “builder” functions in my project and it works beautifully, without significant performance cost.

Finally, let me emphasize the following:

The greatest advantage of using your own custom “builder” functions is that you add a layer of protection between your code and others’ code (SDK apis, SG, other modules). This layer saves you from having to change something in 100 places within your project if the SDK changes or you decide that things should be done with a different way. With a builder function you just change the builder and everything continues to work, without any changes in your levels/scenes.

Hope that helps!

PS: You can always vote for SpriteGrabber if you like it. :slight_smile: [import]uid: 7356 topic_id: 3197 reply_id: 28289[/import]

Hello,

I have a sprite of Zwoptex with 7 frame to which I want to access individually. depending on a listener called one of the frames.

as I can get this effect?
I understand that SpriteGrabber only allows access to two ways of looking at the sprite.

would be possible to define something like:

local nevia=mainSprites:grabSprite(“nevia”,true,{ one={1,1,1300,1}, two={2,2,1000,1}, three={3,3,1000,1}})

and then access each call-type

if … Then
nevia: playClip (“a”)
elseif… then
nevia: playClip (“three”)
end

thank you very much
greetings
[import]uid: 13461 topic_id: 3197 reply_id: 29496[/import]

@franalfonso

Hi!

Supposing you want to show just 1 individual frame instead of an animation you can help yourself defining the individual frames as clips with a function like this:

[lua]function makeClips(num)
local clips = {}
for i = 1, num do
clips[“f” … i] = { i, 1, 1, 1 }
end
return clips
end

myspritesheet = grabber.grabSheet(“mysheetname”)
mysprite = myspritesheet:grabSprite(“spritename”,true,makeClips(7))

– later, inside your listener, you can call:

–set “number” to be whatever from 1 to 7, according to a game logic
local number=7
–play the corresponding clip
mysprite:playClip(“f”…number)[/lua]

Is that what you are looking for? If not, plz provide some more info about what you want to achieve and we can find out together how to implement it.

Cheers [import]uid: 7356 topic_id: 3197 reply_id: 29526[/import]

Hello Magenda,

thank you very much. worked.
but now there is a new problem.

within this function may be one of the clip is 4 frames?

would:
makeClips (8)

and
clips [“f” … i] = {i, 1, 1, 1}
where the values ??would be … {8,11,1000,1}

Is this possible?

thank you very much, [import]uid: 13461 topic_id: 3197 reply_id: 30168[/import]

@franalfonso

You are welcome!

Do you mean something like this:

[lua]function makeClips(num)
local clips = {}
for i = 1, num do
clips[“f” … i] = { i, 1, 1, 1 }
end
return clips
end

myspritesheet = grabber.grabSheet(“mysheetname”)
local clips = makeClips(8)
clips[8] = {8,4,1000,1}
mysprite = myspritesheet:grabSprite(“spritename”, true, clips)

– later, inside your listener, you can call:

–set “number” to be whatever from 1 to 8, according to a game logic
local number=8
–play the corresponding clip
mysprite:playClip(“f”…number)[/lua]

Have in mind the following points:

The code above presumes you have a spritesheet with 11 frames at least.

You can populate the clips table automatically with a function and just change a specific value to what you really want with an additional assignment on top of the first one.

Be sure that you understand the second value of a clip’s table: it doesn’t mean the ending frame but instead the number of frames you want to play beginning from the starting frame. So I guess you don’t want to give {8,11,1000,1} but instead {8,4,1000,1}.

You can change whatever you want to the clips table but be sure to finish your changes before you give that table to the “grabSprite” function. Don’t define a sprite’s clip after you have defined the sprite itself.

Hope that helps. Tell me if not… [import]uid: 7356 topic_id: 3197 reply_id: 30203[/import]

Hello Magenda,

sorry to be so heavy … you are very kind

I know it can not be happening but when I log in:
local number = 8 (for example)
mySprite: playClip (“f” … number)

I access the file spriteSheet No 8 but not what I have loaded in the clip [8], what in this case would be:
clips [8] = {} 8,4,1000,1 a clip with an animation of 8 frames from 8 to 11

¿?

and abuse and a bit of confidence … I can use drag mySprite?

thank you very much.
greetings
[import]uid: 13461 topic_id: 3197 reply_id: 30311[/import]

@franalfonso

Forgive me if I don’t properly understand your questions. My mother language is not English too!

Let’s try again…

When you give: clips[8]={8,4,1000,1} you tell SpriteGrabber to set the eight animation clip as a series of 4 frames starting from frame 8 (and be played for 1000 milliseconds for just 1 time). This requires that in your spritesheet you have included at least 11 images. The second number in the table is the number of frames to be played and the first number is the starting frame (from which frame you want to start the counting).

Another example: If you want to define the 2nd animation clip to start from frame 200 and play the next 40 frames for 5 times within 3 seconds, you would give clips[2]={200,40,3000,5}

Does this make better sense to you now?
About your second question, help me better understand it please. Do you want to drag a sprite with your finger on the screen? This has nothing to do with SpriteGrabber. I think there is an other module that helps you do this. Just search “drag object with finger” or something inside the forums.

If you can’t properly setup SpriteGrabber to play the frames you desire, please upload your project somewhere (e.g. dropbox or cloudapp) for me to take a look. Just be sure to describe me what frames you want to use for each clip.

Cheers [import]uid: 7356 topic_id: 3197 reply_id: 30316[/import]

thank you very much for your time Magenda.

Another example: If you want to define the 2nd animation clip from frame 200 to start and play the next 40 frames for 5 times Within 3 seconds, You Would Give clips [2] = {} 200,40,3000,5

following this example … what you’re running the call:

local number = 2
mySprite: playClip (“f” … number)

this “playClip” is showing me the file n º 200 of spriteSheet. and understand that what should be the animation mostar images from the 200 to 240 in a time of 3 seconds and repeat 5 times

this is code I have …

makeClips function (num)
= {} local clips
for i = 1, num do
clips [“f” … i] = {i, 1, 1, 1}
end
return clips
end
grabber.grabSheet myspritesheet = ("neviaSprite)
local clips = makeClips (12)
clips [13] = {} 1,3,1000,1
mySprite = myspritesheet: grabSprite (“Nevia”, true, clips)
mySprite: show (450.400)


local function tocaNevia(event)
local phase = event.phase
if “ended” == phase then
print(“toca NEVIA”)

local number=13
mysprite:playClip(“f”…number)
if (cristalEntero) then
audio.play(cristal)
cristalEntero = false
end
cristalRoto.alpha = 1

end
end
[import]uid: 13461 topic_id: 3197 reply_id: 30319[/import]

The following seems ok to me, syntactically, provided that you have included 12 images that their names begin with “Nevia” in your spritesheet.
[lua]function makeClips(num)
local clips = {}
for i = 1, num do
clips[“f” … i] = { i, 1, 1, 1 }
end
return clips
end

local myspritesheet = grabber.grabSheet(“neviaSprite”)
local clips = makeClips(12)
clips[13] = { 1, 3, 1000, 1 }
local mySprite = myspritesheet:grabSprite(“Nevia”, true, clips)
mySprite:show(200, 200)
local function tocaNevia(event)
local phase = event.phase
if “ended” == phase then
print(“toca NEVIA”)

local number = 13
mysprite:playClip(“f” … number)
if (cristalEntero) then
audio.play(cristal)
cristalEntero = false
end
cristalRoto.alpha = 1
end
end[/lua]

Is it ok now? [import]uid: 7356 topic_id: 3197 reply_id: 30356[/import]

Hello!

no, it does not work.
the file. lua really gets the zwoptex is as follows

module(…)
function getSpriteSheetData()

local sheet = {
frames = {

{
name = “nevia10.png”,
spriteColorRect = { x = 28, y = 36, width = 479, height = 539 },
textureRect = { x = 1070, y = 2, width = 479, height = 539 },
spriteSourceSize = { width = 583, height = 575 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia11.png”,
spriteColorRect = { x = 30, y = 0, width = 535, height = 575 },
textureRect = { x = 2, y = 2, width = 535, height = 575 },
spriteSourceSize = { width = 583, height = 575 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia12.png”,
spriteColorRect = { x = 37, y = 0, width = 529, height = 575 },
textureRect = { x = 539, y = 2, width = 529, height = 575 },
spriteSourceSize = { width = 583, height = 575 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia1.png”,
spriteColorRect = { x = 5, y = 70, width = 409, height = 500 },
textureRect = { x = 888, y = 1115, width = 409, height = 500 },
spriteSourceSize = { width = 513, height = 570 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia2.png”,
spriteColorRect = { x = 5, y = 0, width = 459, height = 570 },
textureRect = { x = 1070, y = 543, width = 459, height = 570 },
spriteSourceSize = { width = 513, height = 570 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia3.png”,
spriteColorRect = { x = 5, y = 2, width = 437, height = 568 },
textureRect = { x = 2, y = 1057, width = 437, height = 568 },
spriteSourceSize = { width = 513, height = 570 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia4.png”,
spriteColorRect = { x = 5, y = 58, width = 445, height = 512 },
textureRect = { x = 441, y = 1057, width = 445, height = 512 },
spriteSourceSize = { width = 513, height = 570 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia5.png”,
spriteColorRect = { x = 5, y = 72, width = 409, height = 498 },
textureRect = { x = 1531, y = 543, width = 409, height = 498 },
spriteSourceSize = { width = 513, height = 570 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia6.png”,
spriteColorRect = { x = 5, y = 94, width = 453, height = 476 },
textureRect = { x = 2, y = 579, width = 453, height = 476 },
spriteSourceSize = { width = 513, height = 570 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia7.png”,
spriteColorRect = { x = 5, y = 70, width = 409, height = 500 },
textureRect = { x = 1299, y = 1115, width = 409, height = 500 },
spriteSourceSize = { width = 513, height = 570 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia8.png”,
spriteColorRect = { x = 5, y = 86, width = 409, height = 484 },
textureRect = { x = 1551, y = 2, width = 409, height = 484 },
spriteSourceSize = { width = 513, height = 570 },
spriteTrimmed = true,
textureRotated = false
},

{
name = “nevia9.png”,
spriteColorRect = { x = 8, y = 100, width = 445, height = 470 },
textureRect = { x = 457, y = 579, width = 445, height = 470 },
spriteSourceSize = { width = 513, height = 570 },
spriteTrimmed = true,
textureRotated = false
},

}
}

return sheet
end


I have two problems:

1 .- The clip 13 which should make the animation from frame 1 and 3 more in a time of 1 second … does not run. but for any combination of frames does not work, another example with values??:
clips [13] = {4, 4, 1000, 1}

2 .- other calls to the clips, for example, the clip [3] called me to Frame:
name = “nevia12.png” [import]uid: 13461 topic_id: 3197 reply_id: 30934[/import]

@franalfonso

It seems that your .lua file is not properly sorted.

You can try two things:

Rebuild your spritesheet.png + spritesheet.lua files within Zwoptex but be sure that you have set the “Sort on” option at the left panel to “Name”. Try again your code and see if that solves the problem.

If the problem is still there, you can upload your zipped project to www.getcloudapp.com or wherever you like for me to take a look in your project and see what I can do. Be sure to include a folder with your raw image files (those which you used to build the spritesheet).

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

Do you have an example of the work flow using Zwoptex? I see you have a link for texture packer. Thanks! [import]uid: 8780 topic_id: 3197 reply_id: 34123[/import]

@staytoooned

There is no special work flow. Just select “Sort on” = “Name” from the Zwoptex left panel. Don’t tick the “Can Rotate” option there.

In the “Publish Settings” select the CoronaSDK format for the output. There is nothing else to be mentioned.

Do you have any issues with generating your spritesheet? [import]uid: 7356 topic_id: 3197 reply_id: 34130[/import]

After the sprite animation finishes, how do I go back to the first frame? Thanks! [import]uid: 8780 topic_id: 3197 reply_id: 36104[/import]

You can assign a clip that has just the first frame in it (e.g wait={1,1,1,1}) and play it whenever you want. [import]uid: 7356 topic_id: 3197 reply_id: 36122[/import]

I’m experimenting with Texture Packer now and I want to know how I can add physics to the sprite elements? I’m building a table like this:

local function balloonset()

local balloonitems = {}
local balloonSprites=grabber.grabSheet(“balloons”)
balloonitems = balloons()
for index, value in ipairs(balloonitems) do
local balloon = balloonitems[index].item
local number = balloonitems[index].asset
local posX = balloonitems[index].posX
local posY = balloonitems[index].posY

balloongroup[index] = balloonSprites:grabSprite(balloon, true)
balloongroup[index].myName = balloon
balloongroup[index].number = number
balloongroup[index].startPosX = posX
balloongroup[index].startPosY = posY
balloongroup[index].x = posX
balloongroup[index].y = posY
–balloongroup[index]:addEventListener(“touch”,drag)
physics.setDrawMode( “hybrid” ) --so you can see the shape outline
physics.addBody( balloon, { bounce = 0.5, radius = 45, shape=balloon:getShape() } )

–physics.addBody(balloon, { bounce = 0.5, radius = 45 })

numberGroup:insert(balloongroup[index] )
end
end [import]uid: 8780 topic_id: 3197 reply_id: 36321[/import]

Thanks for helping me out! [import]uid: 8780 topic_id: 3197 reply_id: 36322[/import]

Do you find any difficulties with adding a sprite body to the physics engine? I don’t use physics, but the following bugs list may help you from some headaches…

http://developer.anscamobile.com/forum/2011/03/21/why-sprite-library-needs-urgent-debugging [import]uid: 7356 topic_id: 3197 reply_id: 37018[/import]

Hi Magenda - first of all, great work with the module, it certainly makes working with spritesheets alot more convenient. Am currently using said module in a game I’m working on, so kudos to you again.

Experienced a little problem though -

This game level I have runs perfectly well with spritegrabber, no problems at all. When the director transitions back to the menu screen, I call

playerSheet:remove ();

to remove the sprites from memory.

When I return back to the game level and continue playing as normal, the simulator throws this one error. Here’s an excerpt :

Runtime error  
 ...spritegrabber.lua:266: attempt to call method 'prepare' (a nil value)  
stack traceback:  
 [C]: in function 'prepare'  
 ...spritegrabber.lua:266: in function 'playClip'  
 ...scene\_game.lua:184: in function 'gameOver'  
 ...scene\_game.lua:206: in function ...  

From what I understand, it can’t run the prepare function because the clip parameter is nil.

However, it is the exact game level that worked without a problem the first time around, so I’m thinking perhaps I’m not removing the sprites from memory properly, but I’m not sure. Also, this only occurs when I attempt to play a death animation, but other animations seems to work as normal.

Would appreciate any input you have on this! [import]uid: 63884 topic_id: 3197 reply_id: 39433[/import]