Sprite sheet creating animation from non-sequential frames

Is it possible to create sprite sequences from frames that are not in sequence in the sprite sheet?

For example. I have some sprites that share a common first frame. I’d like to use this frame without duplicating it in my sprite sheet.

I’d like to define an array of frame numbers and make that a sequence I can display with prepare() and play(). [import]uid: 98652 topic_id: 20357 reply_id: 320357[/import]

Currently this isn’t possible in such a way, no - although you could write your own code to animate through frames set in an array it would be handled in your own function without the usual play() api.

Peach :slight_smile: [import]uid: 52491 topic_id: 20357 reply_id: 79666[/import]

suppose you could chain the sequences together - ie play the common part of the sprite first and use events to wait for the last frame before replacing the sprite with another playing the rest of the animation. dunno how that would work in terms of what it looks like on screen. [import]uid: 74338 topic_id: 20357 reply_id: 79721[/import]

You can have multiple frame entries in the lua that reference the same graphic area in the sprite sheet. I do this a lot in my application. Some tools like TexturePacker will do this automatically for you if you have two identical files with different names. Below is simple example of the data file for two 3 frame sprites that share the same first frame

[code]

local SpriteSheet = {}
SpriteSheet.getSpriteSheetData = function ()
return {
frames = {
{
name = “Anim_One_1.png”,
spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },
textureRect = { x = 0, y = 0, width = 10, height = 10 },
spriteSourceSize = { width = 10, height = 10},
spriteTrimmed = false,
textureRotated = false
},
{
name = “Anim_One_2.png”,
spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },
textureRect = { x = 12, y = 0, width = 10, height = 10 },
spriteSourceSize = { width = 10, height = 10},
spriteTrimmed = false,
textureRotated = false
},
{
name = “Anim_One_3.png”,
spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },
textureRect = { x = 24, y = 0, width = 10, height = 10 },
spriteSourceSize = { width = 10, height = 10},
spriteTrimmed = false,
textureRotated = false
},
{
name = “Anim_Two_1.png”,
spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },
textureRect = { x = 0, y = 0, width = 10, height = 10 },
spriteSourceSize = { width = 10, height = 10},
spriteTrimmed = false,
textureRotated = false
},
{
name = “Anim_Two_2.png”,
spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },
textureRect = { x = 0, y = 12, width = 10, height = 10 },
spriteSourceSize = { width = 10, height = 10},
spriteTrimmed = false,
textureRotated = false
},
{
name = “Anim_Two_3.png”,
spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },
textureRect = { x = 12, y = 12, width = 10, height = 10 },
spriteSourceSize = { width = 10, height = 10},
spriteTrimmed = false,
textureRotated = false
},
}
}
end
return SpriteSheet
[/code] [import]uid: 100558 topic_id: 20357 reply_id: 79740[/import]

One cheat that we use is to simply edit the lua file. If your spritesheet is finalized, simply copy and paste frame entries from the lua file at the bottom into the sequence you want to have happen. So for example using the code above you could do something like this…

local SpriteSheet = {}  
SpriteSheet.getSpriteSheetData = function ()  
 return {  
 frames = {  
 {  
 name = "Anim\_One\_1.png",  
 spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },  
 textureRect = { x = 0, y = 0, width = 10, height = 10 },  
 spriteSourceSize = { width = 10, height = 10},  
 spriteTrimmed = false,  
 textureRotated = false  
 },  
 {  
 name = "Anim\_One\_2.png",  
 spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },  
 textureRect = { x = 12, y = 0, width = 10, height = 10 },  
 spriteSourceSize = { width = 10, height = 10},  
 spriteTrimmed = false,  
 textureRotated = false  
 },  
 {  
 name = "Anim\_One\_3.png",  
 spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },  
 textureRect = { x = 24, y = 0, width = 10, height = 10 },  
 spriteSourceSize = { width = 10, height = 10},  
 spriteTrimmed = false,  
 textureRotated = false  
 },  
 {  
 name = "Anim\_Two\_1.png",  
 spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },  
 textureRect = { x = 0, y = 0, width = 10, height = 10 },  
 spriteSourceSize = { width = 10, height = 10},  
 spriteTrimmed = false,  
 textureRotated = false  
 },  
 {  
 name = "Anim\_Two\_2.png",  
 spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },  
 textureRect = { x = 0, y = 12, width = 10, height = 10 },  
 spriteSourceSize = { width = 10, height = 10},  
 spriteTrimmed = false,  
 textureRotated = false  
 },  
 {  
 name = "Anim\_Two\_3.png",  
 spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },  
 textureRect = { x = 12, y = 12, width = 10, height = 10 },  
 spriteSourceSize = { width = 10, height = 10},  
 spriteTrimmed = false,  
 textureRotated = false  
 },  
{  
 name = "Anim\_Two\_3.png",  
 spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },  
 textureRect = { x = 12, y = 12, width = 10, height = 10 },  
 spriteSourceSize = { width = 10, height = 10},  
 spriteTrimmed = false,  
 textureRotated = false  
 },  
 {  
 name = "Anim\_Two\_2.png",  
 spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },  
 textureRect = { x = 0, y = 12, width = 10, height = 10 },  
 spriteSourceSize = { width = 10, height = 10},  
 spriteTrimmed = false,  
 textureRotated = false  
 },  
 {  
 name = "Anim\_Two\_1.png",  
 spriteColorRect = { x = 0, y = 0, width = 10, height = 10 },  
 textureRect = { x = 0, y = 0, width = 10, height = 10 },  
 spriteSourceSize = { width = 10, height = 10},  
 spriteTrimmed = false,  
 textureRotated = false  
 },  
 }  
 }  
end  
return SpriteSheet  
  

Like I said you’ll to make sure that the spritesheet is finalized because each time you make a tweak in zwoptex or whatever spritesheet progam you use, it will wipe out all your custom frame orders and you’ll have to put them in again by hand. [import]uid: 9840 topic_id: 20357 reply_id: 79748[/import]

Thanks or the replies. I like the Sprite Sheet Data method. But I’m not using a tool liek Zwoptext so I’d have to make the data file by hand.

My solution was to use sprite.newSpriteMultiSet(). This seems to be working so far. I ran into some posts where people described having trouble with this method. It seems to be working well for me. Of course I’m only using a single sprite sheet and creating multiple sets from that.

Using this methods seems to create a new sprite set with the cells in the order they are listed under newSpriteMultiSet. For example, in the set below cell 4 from the actual image is the new cell 1. Cell number 12 in the multi-set would also be image 4 from the original image.

[lua]-- Define a few sprite sets
local tile_set = sprite.newSpriteSet( tile_sheet, 1, 45 )

local tile_set = sprite.newSpriteMultiSet(
{
{ sheet = tile_sheet, frames = { 4, 6, 7, 8, 9, 10 } }, – blue open 1 to 6
{ sheet = tile_sheet, frames = { 10, 9, 8, 7, 6, 4 } }, – blue close 7 to 12
{ sheet = tile_sheet, frames = { 4, 11, 12, 12, 14, 15 } }, – green 13 to 18
{ sheet = tile_sheet, frames = { 15, 14, 13, 12, 11, 4 } }, – 19 to 24
{ sheet = tile_sheet, frames = { 4, 16, 17, 18, 19, 20 } }, – cyan 25 to 30
{ sheet = tile_sheet, frames = { 20, 19, 18, 17, 16, 4 } }, – 31 to 36
{ sheet = tile_sheet, frames = { 4, 21, 22, 23, 24, 25 } }, – red 37 to 42
{ sheet = tile_sheet, frames = { 25, 24, 23, 22, 21, 4 } }, – 43 to 48
{ sheet = tile_sheet, frames = { 4, 26, 27, 28, 29, 30 } }, – orange 49 to 54
{ sheet = tile_sheet, frames = { 30, 29, 28, 27, 26, 4 } }, – 55 to 60
{ sheet = tile_sheet, frames = { 4, 31, 32, 33, 34, 35 } }, – yellow 61 to 66
{ sheet = tile_sheet, frames = { 35, 34, 33, 32, 31, 4 } }, – 67 to 72
{ sheet = tile_sheet, frames = { 2, 5, 36, 37, 38, 39, 40, 41, 42 } } – 73 to 81
}
)[/lua] [import]uid: 98652 topic_id: 20357 reply_id: 79756[/import]

Using newSpriteMultiSet is probably the easier alternative if you made your sprite sheets and data files by hand since it lets you reuse a frame without needing to maintain duplicate data in your data sheet. [import]uid: 100558 topic_id: 20357 reply_id: 79762[/import]

multi set seemed to be a good choice since all of my cells are the same size and all in the same sheet. I don’t all of the extra data. [import]uid: 98652 topic_id: 20357 reply_id: 79766[/import]

Let me throw this into the discussion. Seems that creating multiset creates a new stile set with all of your frames misnumbered.

For example, if you had a set of 9 tiles and you used the following to create several sequences.

[lua]local tile_set = sprite.newSpriteSet( tile_sheet, 1, 9 )

local tile_set = sprite.newSpriteMultiSet(
{
{ sheet = tile_sheet, frames = { 9, 8, 7 } },
{ sheet = tile_sheet, frames = { 2, 4, 6 } }
}
)[/lua]

You would end up with a sprite set containing only 6 frames numbered 9, 8, 7, 2, 4, 6. This means that tiles you might want to use would now be missing or in the wrong position.

To avoid this make a set that contains all of the sprites in original order first and add your special sequences to the end. For example:

[lua]local tile_set = sprite.newSpriteSet( tile_sheet, 1, 9 )

local tile_set = sprite.newSpriteMultiSet(
{
{ sheet = tile_sheet, frames = {1,2,3,4,5,6,7,8,9} },
{ sheet = tile_sheet, frames = { 9, 8, 7 } }, – a
{ sheet = tile_sheet, frames = { 2, 4, 6 } }
}
)[/lua]

The frames in the last two sets would be called up by their number plus the total number of frames. something like

[lua]sprite.add( tile_set, “a”, 10, 3, 200, 1 )[/lua]

[lua]local tile_count = 9
or sprite.add( tile_set, “color_a”, 1 + tile_count, 6, 200, 1 )[/lua] [import]uid: 98652 topic_id: 20357 reply_id: 79821[/import]