Question about sprite tables (or whatever you call them)

Started by
7 comments, last by Ekim_Gram 19 years, 11 months ago
Just to start off...this is what I''m talking about: My question now is this; how do you calculate which image you want to use in that one big image? For example, say I plan on making a game with SDL using these and I want to put one of those clouds out there? How would I go about doing so? I''m guessing it would have to do with the resolutions? This one is 640x400. VG-Force | Ekim Gram Productions
Advertisement
though i've never done something like this before, this is what i'd do. you establish a standard resolution for your "sprite tables", you can throw in Asserts and whatnot so that the game will "gracefully crash" if an artist (or you) submits a table that is of the wrong resolution. you then establish rules that each sprite must be X by Y resolution in the table and likewise establish a rule for how much, if any, empty pixel space will be between sprites. then you can just "label" the sprites in the table with a simple numerical progression. so upper left is 1, and then you count up left to righ and top to bottom. when desiging the level you mark things in your level editor with a simple numerical index to the table. at runtime, loading a sprite is as simple as implrementing a simple algorithm for getting the actual pixel offsets in the table from an index number (very simple math).

given that you know how big the table is, how big the sprites are, and how much empty space is between them, finding an image in the table should be fairly striaght forward.

[EDIT: even easier would be to define images as an X and Y offset in the table. upper left image is 0,0. so the pixel offset would be (xIndex * imageWidth, yIndex * imageHeight) (assuming no space in between images in the table).]

-me

[edited by - Palidine on May 9, 2004 7:31:19 PM]
texture tile structures can be handy. Just store a unique identifier for each tile of the game, made of the parent texture ID, and the index of the tile in the texture. That way, you can quickly get a tile information from it''s GUID, and point straight to the data.

struct CTextureTile{    union    {        u_int m_uTileGuid; // unique identifier of the tile        struct        {            u_int m_uTextureIndex:16; // parent texture index            u_int m_uTileIndex:16;   // tile index inside the texture        };    };    //-----------------------------------------------    // sub texture coordiantes, in pixel coords    //-----------------------------------------------    u_int m_uiTileMinU;     u_int m_uiTileMinV;    u_int m_uiTileMaxU;    u_int m_uiTileMaxV;};


you can then point to a tile data and search for a tile quickly.

the sub-texture coordinates for the tile are in pixel coordinates, but OpenGL, and others, require floating point coordinates (in the range [0->1]). you just have to scale the coordinates by the texture width and height. Or set the texture transform matrix to do the scaling (and maybe add an offset as well) on the texture coordinates automatically for you. I''d prefer the second method, personnaly.

so, in the world editor, it''s simply a matter of assigning the blocks of the environment to a tile GUID, which will be unique, no matter which texture they''re onto.

with the texture file, you''d have a tile file, where each tile in the texture is stored in a list. The generation of the tile texture coordinates is trivial.

Everything is better with Metal.

I use a slightly different approach.
I separate sprite information from sprite table grid information. I load from a file a set of grid descriptions that identifies sprite locations and chaining. Then I load a sprite file with indexes to the grid description to retrieve the correct data. The aim is to avoid storing into the sprite redundant information (especially when using animated sprites).

Example:

Grid description:
;nb frames/frame w & h in pels/start x&y + total frame w&h
4 / 32 64 / 0 0 128 64
; describes a region of four frames within a sprite table
; in the engine, this will be developped into four frame objects referenced from 0 to 3.

Sprite description:
;Multi/Sprite Table ID/pixel unit square width/sprite extent/animation list: GridID-Timing
;Multi defines wether this is an animated sprite, a container sprite or a single sprite
;Pixel unit square width is used for 2D drawing by multiplying by sprite extent.
;Sprite extent is used for 3D drawing: start(x,y) end(x,y). Also holds the anchor point of the sprite.
M / 1 / 32 / -0.5 0 0.5 2 / 0-150 1-150 2-150 3-150
; This sprite is an animated sprite using 4 frames from 0 to 3 and a timing between each frame of 150 ms.

Hope that helps.


Ghostly yours,
Red.
Ghostly yours,Red.
RG has a good idea. I use a config file to tell the program exactly what file to load and what is on that file, including X,Y offsets, width, height, display time, frame number, etc.
I''m still kinda confused. From what I''ve read and tried to make heads or tails of (I really should read it through again) I got this:

Get it''s (x,y) coordinates (I''m guessing the point it the top left corner of it), it''s height & width, the transparency color (I''ll be adding that myself), it''s frame number and how long the frame lasts. How would I go about loading that into an SDL program?

Say each box is 20x20 and I want to load image 1,1 with the top left sprite being 0,0. Would I blit ((20*xPos+)+seperator) ((20*yPos)+seperator) such that xPos and yPos are 1 and the seperator is the white line between the images, onto the screen? And then say it''s next frame is 2,1. Using the formula above would it be ((20*xPos)+seperator) ((20*yPos)+seperator), such that xPos and yPos are 2?


VG-Force | Ekim Gram Productions
If you have all your sprite frames stored linearly in a single file with a one pixel space in between each frame then you can load in each frame image like this:

//this code assumes you already have NumFrames declaredSDL_Surface *g_SpriteTiles = SDL_LoadBMP("SpriteImg.bmp");int g_SpriteWidth = 32;int g_SpriteHeight = 32;SDL_Rect g_SourceTileRect;//set width and height of the sprite framesg_SourceTileRect.w = g_SpriteWidth;g_SourceTileRect.h = g_SpriteHeight;//if your frames are aligned to the top of the image the Y //position will remain constant so can set it outside of the loopg_SourceTileRect.y = 0;SDL_Surface *g_SpriteFrames[NumFrames];for(int i = 0; i < NumFrames; i++){  g_SourceTileRect.x = i * g_SpriteWidth + i;  //now blit this portion of the image to the frames surface  SDL_BlitSurface(g_SpriteFrames[i], &g_SourceTileRect, g_SpriteTiles, NULL);}


If your frame was the third one along then the X position of the top left corner is 3 * sprite width + 3 if you have a 1 pixel space between images, if you had a 2 pixel space you would replace the + i portion of the calculation in the loop with i * 2 instead.
Random question, but are those tiles from Xargon (by epic megagames), or perhaps Jill of the Jungle? They seem to bring back some dim childhood memories.

[edited by - darkhamster on May 10, 2004 5:14:42 PM]


"There is no dark side of the moon really,
As a matter of fact, its all dark."
I got it from the sprite_gpl that I downloaded from somewhere. I''m just using this bitmap in my example. My next project is going to be some stick figure game of some sort, that''s the best I can do with my horrid art skills.


VG-Force | Ekim Gram Productions

This topic is closed to new replies.

Advertisement