Getting the position of a sprite on a spritesheet that has spacing

Started by
6 comments, last by Ashley_H 3 years, 8 months ago

Hi There,

I'm trying to draw a spritesheet on screen which contains 16x16 sprites evenly spaced with a 1px gap between each, however I'm struggling to get the math right in order to take into account the spacing between pixels when working out which sprite needs to be drawn.

The current result I have looks like this:

However it should look something like this:

The issue is because I only have a ID number that corresponds to the sprite that needs to be drawn on screen (The ID corresponds to a specific sprite on the sheet, starting at 0 and incrementing up to the total number of sprites on the sheet). The library I'm using to load the level works out the sprite position on the sprite sheet using this ID number as follows:

// I've hard-coded the values below for easy reading. Usually these are worked out at runtime.

int spritesheet_width = 968;
int spritesheet_height = 526;

int sprite_width = 16;
int sprite_height = 16;

int sprite_id = 110; // During the draw-loop this updates with the ID of the next sprite to draw.

int sprite_X = (sprite_id % (spritesheet_width / sprite_width) * sprite_width;
int sprite_Y = (sprite_id / (spritesheet_width / sprite_width) * sprite_height;

DrawSprite(sprite_X, sprite_Y ...);

I believe this isn't taking into account the spacing between sprites which results in the broken on-screen view. Is there a way I can adjust this math to take the spacing between sprites into account? So far the various options I've tried haven't worked (My math skills are dreadful!). Short of removing all of the spacing from the spritesheet and re-exporting the level, I'm out of ideas.

Thanks in advance!

Advertisement

Html 5, or upgrade your game skills!

The second one is good.

As a starting point, where you are using sprite_width, use sprite_width + spacing instead:

int sprites_per_line = (sprite_sheet_width / (sprite_width + spacing));
int sprite_x = (sprite_id % sprites_per_line) * (sprite_width + spacing);
int sprite_y = (sprite_id / sprites_per_line) * (sprite_height + spacing);

@a light breeze Thanks for the info, I've given that a shot, which has worked for some tiles but others are still incorrect:

From playing around with this before I've tried similar logic to what you describe above to try and work out what column/row the sprite resides on but have so far been unable to find a formula that works for all positions on the sheet.

For additional reference I'm using the Kenney ‘Roguelike’ pack here. The level I'm trying to draw is the example Tiled map that's supplied with the pack (Using SDL2 and tmxlite to load/parse the level file).

Thanks!

Now your individual tiles are rendering correctly, but you are rendering a lot of incorrect tiles. If you check on the sprite sheet, it looks like those on the top row are correct but the others are not. Why is this happening? Because sprites_per_line is incorrect. Why is it incorrect? Because the calculation assumes that there is spacing spacing after every tile, but in the original sprite sheet, there is no spacing to the right of the last tile in a row. You can easily confirm this by printing out the sprites_per_line value and comparing it to the expected value from actually counting the number of tiles per row.

So, how to fix this? Well, the formula I gave would work if there was extra spacing to the right of the sprite sheet, so it should also work if you add that extra spacing to the sprite sheet width. Try this formula instead:

int sprites_per_line = ((sprite_sheet_width + spacing) / (sprite_width + spacing));

Ah-ha! That did it! I completely forgotten to take into account that there was no spacing on the right-hand side as you say above! (facepalm)

Thank you so much for your help!

This topic is closed to new replies.

Advertisement