Sprite Sheet Best Practices? How to avoid pixel overlap from one frame to another?

Hi All,

I seem to often get a slight overlap of pixels from one frame of a sprite sheet onto an adjacent one when animating through the sprite sheet’s frames which gives a kind of an unpolished/sloppy look to my characters/assets. (you might see the edge of one frame of a character on the edge of the next frame as if the frame isn’t quite centered)

Are there any best practices as far as setting up and using animated sprite sheets? I need to solve this issue before I can ship a polished product!

I had considered building in a few pixels of empty “buffer” around each frame of art but that makes a headache as far as generating a separate physics body to keep the character from “levitating” above the floor (I’m working on a side viewed platformer style game). I can do this as a worst case but I’m expecting that sprite sheet animation would work as I understand it to be designed.

Thanks for any advice anyone has as far as getting sprite sheets to work as expected.

Leaving the gap is actually standard practice, and is really the only way you are going to solve this issue I’m afraid.

The reason is boring and technical but boils down to open GL and how it interpolates between pixels for a smooth amount.

Is there no way you can automate in code removing this 1 pixel border, either from the physics objects themselves or from the sprite frames as they are created with the imagesheet parameters?

FWIW I like to create a unique physics shape and “pin” my sprite images to it. I can understand that folks might find this method less than intuitive, but with minor tweaking you can ensure that physics interacts with the physics shape, and thereby calling changes to the sprite, normally. 

Thank you both for your input!

@rakoonic, when you say “standard practice” do you mean just for Corona or with other solutions as well (not sure how common Open GL is…)? What size buffer do you use per frame? I will experiment to see but interested to know how many pixels you use. I will also look at the sprite sheet parameters to see if there is some way to use the larger size sprites that have the buffer built in but then to display only the “normal”, smaller size.

@Panc software, I do already have a few assets that have separate, “invisible”, physics bodies behind the sprite but was just thinking that wouldn’t be the norm. I guess it might be? Glad to know that you have been doing that.

It is standard practice in a lot of the games industry.

To work out size you also need to factor in what the likely biggest texture size is that all the devices you want to handle support, and then work backwards. Just remember that if you lay out your sprites for the biggest size, to make sure you lay out your graphics and gaps intelligently to handle scaling the image down for the other resolution sizes.

EG if I want, for x4 size (ipad retina, say), and I also want to support 1x, 1.5x, 2x and 3x, then my sprite sizes, the gaps and positioning of everything needs to fall on pixel values that are multiples of 8, so that:

4x = 8 pixel boundaries

3x = 6 pixel boundaries

2x = 4 pixel boundaries

1.5x = 3 pixel boundaries

1x = 2 pixel boundaries

So everything can be scaled and will always end up on discrete pixel edges (assuming you use bilinear or nearest neighbour scaling).

If you don’t care about 3 and 1.5, then you can do it on 4 pixel boundaries, and if you also want to omit 1x (let’s say you only work for tablets) then it could be 2 pixel boundaries etc.

Hi rakoonic, thanks for clarifying how common a practice this is and for shedding some light on how you do this.

The project I’m working on is being developed at the old 480x320 resolution. I’m going for an 8 bit “retro” look (because I like that and it seems most manageable for me to do on my own) so I am only doing things at the “1x” size. So if I follow you I should try out a 2 pixel boundary for my sprites?

Your tip for multiple size assets will be really helpful for future efforts. I appreciate the reference.

Is there anything else I should consider?

Thanks :slight_smile:

If you are only using the single sprite sheet size then a 2 pixel gap is going to be more than fine.

The only other thing that springs to mind is that if you want your pixels to stay pixelly-sharp when zoomed up, don’t forget to do:

display.setDefault( “magTextureFilter”, “nearest” )

so they don’t blur when scaled up.

Hi rakoonic, I appreciate the tip regarding the “nearest neighbor” (to use a Photoshop term) texture filter. I had actually browsed through display.setDefault in the API some time back but without you explaining that in use, it didn’t really mean anything to me. Very good to know!

Glad to know 2 pixels should work. 

Thanks :slight_smile:

If you use Texture Packer to create your spritesheets you can easily add gaps between the sprites.

It also has an export function for corona, so you can use it pretty easy.

Leaving the gap is actually standard practice, and is really the only way you are going to solve this issue I’m afraid.

The reason is boring and technical but boils down to open GL and how it interpolates between pixels for a smooth amount.

Is there no way you can automate in code removing this 1 pixel border, either from the physics objects themselves or from the sprite frames as they are created with the imagesheet parameters?

FWIW I like to create a unique physics shape and “pin” my sprite images to it. I can understand that folks might find this method less than intuitive, but with minor tweaking you can ensure that physics interacts with the physics shape, and thereby calling changes to the sprite, normally. 

Thank you both for your input!

@rakoonic, when you say “standard practice” do you mean just for Corona or with other solutions as well (not sure how common Open GL is…)? What size buffer do you use per frame? I will experiment to see but interested to know how many pixels you use. I will also look at the sprite sheet parameters to see if there is some way to use the larger size sprites that have the buffer built in but then to display only the “normal”, smaller size.

@Panc software, I do already have a few assets that have separate, “invisible”, physics bodies behind the sprite but was just thinking that wouldn’t be the norm. I guess it might be? Glad to know that you have been doing that.

It is standard practice in a lot of the games industry.

To work out size you also need to factor in what the likely biggest texture size is that all the devices you want to handle support, and then work backwards. Just remember that if you lay out your sprites for the biggest size, to make sure you lay out your graphics and gaps intelligently to handle scaling the image down for the other resolution sizes.

EG if I want, for x4 size (ipad retina, say), and I also want to support 1x, 1.5x, 2x and 3x, then my sprite sizes, the gaps and positioning of everything needs to fall on pixel values that are multiples of 8, so that:

4x = 8 pixel boundaries

3x = 6 pixel boundaries

2x = 4 pixel boundaries

1.5x = 3 pixel boundaries

1x = 2 pixel boundaries

So everything can be scaled and will always end up on discrete pixel edges (assuming you use bilinear or nearest neighbour scaling).

If you don’t care about 3 and 1.5, then you can do it on 4 pixel boundaries, and if you also want to omit 1x (let’s say you only work for tablets) then it could be 2 pixel boundaries etc.

Hi rakoonic, thanks for clarifying how common a practice this is and for shedding some light on how you do this.

The project I’m working on is being developed at the old 480x320 resolution. I’m going for an 8 bit “retro” look (because I like that and it seems most manageable for me to do on my own) so I am only doing things at the “1x” size. So if I follow you I should try out a 2 pixel boundary for my sprites?

Your tip for multiple size assets will be really helpful for future efforts. I appreciate the reference.

Is there anything else I should consider?

Thanks :slight_smile:

If you are only using the single sprite sheet size then a 2 pixel gap is going to be more than fine.

The only other thing that springs to mind is that if you want your pixels to stay pixelly-sharp when zoomed up, don’t forget to do:

display.setDefault( “magTextureFilter”, “nearest” )

so they don’t blur when scaled up.

Hi rakoonic, I appreciate the tip regarding the “nearest neighbor” (to use a Photoshop term) texture filter. I had actually browsed through display.setDefault in the API some time back but without you explaining that in use, it didn’t really mean anything to me. Very good to know!

Glad to know 2 pixels should work. 

Thanks :slight_smile:

If you use Texture Packer to create your spritesheets you can easily add gaps between the sprites.

It also has an export function for corona, so you can use it pretty easy.