Sign in to follow this  

sprites

This topic is 4218 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've got my terrain rendering down and I'm thinking about sprites now. I implemented a little 3D array, layer 1 for terrain, layer 2 for static world objects and layer 3+ for anything else. Now my question is should all things be tied to specific tiles or should they be independent. Also if they are tied to tiles how am I to move the characters or mobs around the map without them jumping from tile to tile. Is it a smooth scrolling thing like the terrain or do I need to do something else. I have read all of the tutorials and didn’t really see anything useful about object management. also...for rendering everything im using Direc3d....and have a nested loop to do the drawing. Is that the most efficient way to do the drawing? it's a 3D array so For all in x For all in Y For all things to draw draw()

Share this post


Link to post
Share on other sites
Your ideal solution may be different depending on how your game works.

That being said, I have used/am using a combination of both. I am doing an overhead 2d action/RPG (non-isometric like Zelda3) tile based game so it may be different than what you are doing.

My entities all reside in a large list that gets insert sorted by y value when they move. I pop the entity from the list and search from it's last position in the list where to sort it. I also check to see what tile it's new position is on and do the same type of pop/insert on the tile if it is necessary (most times it isn't depending on how populated the area is). The lists are all lists of pointers btw.

My rendering is done from the large list as they are already sorted in drawing order already (and doing it on a per tile basis causes some wierd drawing order issues with neighboring tiles). The AI is figured out on a radius basis to which the smaller lists on the tiles help out. For example certain agressive NPC's attack within a 1-2 tile radius (or box as it happens) while others like guards will notice from up to 8 tiles away if you are so flagged. This is made easy by just traversing the lists of the surrounding tiles instead of the whole list.

I hope that helps a little.

Share this post


Link to post
Share on other sites
I would also like some help on drawing large sprites like say...beds.

Things that take up more than one tile confuse me. If an objects spans more than one tile do i have to figure out which tiles it crosses and make those non walkable? In the case of things standing up...walls and the like..the character just walks behind it...but that doesn't work for things that lay flat on the ground like a bed.

thanks

Share this post


Link to post
Share on other sites
The only thing i have found so far is that i need to define in the meta data that this certain sprite will take up 4 tiles....and i need to make those 4 tiles non walkable. It might get quite annoying to do all of that by hand. I am about to go implement this as its the only solution i have. It just seems a bit primitive.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by nex7
The only thing i have found so far is that i need to define in the meta data that this certain sprite will take up 4 tiles....and i need to make those 4 tiles non walkable. It might get quite annoying to do all of that by hand. I am about to go implement this as its the only solution i have. It just seems a bit primitive.


Large objects that would span multiple tiles are usually cut up into smaller pieces by the artists.

Sprites can cover many tiles. A sprite with the same size as the tiles will cover either 1, 2 or 4 tiles. 1 when it's standing right on top of a tile, 2 when it is moving horizontally or vertically and 4 otherwise. If you want to get the tile coodinate from a sprite, divide the sprite coordinate with the tile size. If you want to check coverage, just check where the 4 corners of the sprite stand. The tiles covered by the sprite will be the box between the 4 corners. (you can mark this area nonwalkable with a double for cycle)

Always use temporary marker bits, that are different from the background, because you have to erase these bits every time the sprite moves and redraw them after the movement. First, this stops the sprite from getting caught on its own 'shadow' and it results in the automagical update of the walkable map. Since you only move 1 sprite at a time, cycling through all moving objects, they will respect both the nonwalkable terrain and each other's shadows.

Viktor

Share this post


Link to post
Share on other sites
So something like a bed that takes up 4 tiles would be cut into 4 pieces and then drawn?

what if its say...a very large monster like a dragon or something. This dragon is drawn and he takes up 8 tiles. His feet are on the corners of the tiles so any tile that he is covering needs to be non walkable. the Parent tile is of course non walkable but how do i know that he takes up 7 other tiles?

Share this post


Link to post
Share on other sites
Actually the dragon would take up an 8 tile standing area with the rest of him extending up...wings and neck and the like. so the sprite actually covers

8 for his standing area and another 4 for his neck and wings....

now the tiles behind his wings and neck are still walkable while the 8 that he is standing over are non walkable.

I am just at a loss as to how to get that into code other than to hardcode the parameters in some sort of meta data for each sprite...

sprite
Height
Width
TileCoverage
Image

Share this post


Link to post
Share on other sites
There are two solutions I can think off:
1. I assume you have map editor [smile]. You may add to every tile bool variable that shows is a tile walkable or not. In map editor simply check or uncheck values.
2. You can make it with pointer to object, so tiles will have pointer that there is some object and make again tile non-walkable. Your object is located on red tile, yellow tiles have reference to object tile.

I'll prefere first solution. It is fast, simple, no precompute.

Share this post


Link to post
Share on other sites
ok so the bed was a bad example....

lets pretend that a wizard animated the bed..and it now has huge teeth and can walk around in our world causing all manner of trouble.

Those walkable tiles have to be updated as our evil bed moves around the world.

The best solution I have come up with is a sort of Walkable Mask...

i would make an 4bit bitmap the size of my world...so say a 2000x4000 bitmap and each monster bed would also come along with a walkable mask... a tiny bitmap that would represent the tiles it takes up. then every time something moves it would blit its walkability mask to the main bitmap and you would have a nice bitreference to check.

if color == red non walkable
if color == blue water..use boat
if color == green walkable terrain
if color == white air must use flying carpet

Share this post


Link to post
Share on other sites
Quote:
Original post by nex7
ok so the bed was a bad example....

lets pretend that a wizard animated the bed..and it now has huge teeth and can walk around in our world causing all manner of trouble.

Those walkable tiles have to be updated as our evil bed moves around the world.

The best solution I have come up with is a sort of Walkable Mask...

i would make an 4bit bitmap the size of my world...so say a 2000x4000 bitmap and each monster bed would also come along with a walkable mask... a tiny bitmap that would represent the tiles it takes up. then every time something moves it would blit its walkability mask to the main bitmap and you would have a nice bitreference to check.

if color == red non walkable
if color == blue water..use boat
if color == green walkable terrain
if color == white air must use flying carpet



hmm personaly I don't like that approach. Here is my thinking: Use one class for terrain and static objects(walls, trees etc) and one class for dynamic objects and players and NPCs (humans, creatures, beds that turns into jaws [smile]etc).
Do it with pointers. Make class that holds all graphic in your game, and on tile just provide a reference to it. With this approach you can have same looking things with different actions.
When rendering on screen do it in two pass. First draw background, then all other things. In first pass also clear(before all movement is made) and fill again values for trigers (after movement is made).
Personaly I tile checking mechanisam I would do something like this:

enum myTriger { trPassable, trNonPassable, trWater, trFlying };
enum tilesize { tsOne, tsTwo, tsThree,tsFour };
class TileProp
{
public:
TileProp(myTriger mt) { m_triger = mt;}
myTriger m_Triger;
};

class tile
{
public:
tile() {m_TileProperties = NULL; }
TileProp *m_TileProperties;
void SetTilePropertie(myTriger type, tilesize size, tile* othertile)
{
switch(size)
{
case tsOne:
{
if(TileProperties)
TileProperties = new TileProp(type);
else
m_TileProperties->m_Triger = type;
}
break;
case tsTwo:
{
// same as tsOne +
// you set pointer for m_TileProperties in NEIGHBOUR tile
// to this->
// neighbour tile:
othertile->m_TileProperties = m_TileProperties;
// etc...
}
break;
}
}
};



in map draw function:

for(int x = 0; x< WIDTH;x++)
for(int y = 0; y< WIDTH;y++)
{
// clear properties
if(tile[x][y]->m_TileProperties)
{
delete tile[x][y]->m_TileProperties;
tile[x][y]->m_TileProperties = NULL;
}
}

then make everything move, players , monsters, etc.
after that you fill again your m_TileProperties values, and then draw
map.

Share this post


Link to post
Share on other sites
ok so that was my first option before the bitmap....

I currently have the concept of Tiles and Sprites in my system now.


So when you say Tilesize...how do you know what the demensions of that tile...


it could be 4 tiles in a straight line...or 4 in a square...or 3tiles up and one to the left.

Share this post


Link to post
Share on other sites
Quote:
Original post by nex7
So when you say Tilesize...how do you know what the demensions of that tile...


it could be 4 tiles in a straight line...or 4 in a square...or 3tiles up and one to the left.


That's why is there :
enum tilesize { tsOne, tsTwo, tsThree,tsFour };
:
you can define with it any shape you like, or even work with WORD:
with WORD you can make mask 0000 0000 0000 0000 (binary)
that in game terms looks like
0000
0000
0000
0000

for empty tile.
for example binary 1000100010001000 in hex is 0x8888.
With simple bit checking you can solve which tile should be trigered.

void SetBit(WORD &data, int bit)
{
int i = 1;
i = i << bit;
data |=i;
}
void ClearBit(WORD &data, int bit)
{
int bitmask = ~(1 << bit);
data &=bitmask;
}
bool IsBitSet(int flags, int checkBit)
{
return (flags & checkBit) == checkBit;
}
bool IsBitClear(int flags, int checkBit)
{
return (flags & checkBit) == 0;
}



Share this post


Link to post
Share on other sites
Why would your bed or dragon need to know how big the tiles are? Seems a bit inflexible to me.

Why not (purely preference on my part I suppose) do 2 checks? One to see if the player has collided with a non walkable tile (quite simple) and another to make sure it hasn't collided with any objects in a (largest object size) radius?

This way you assign bounding geometry (obviously boxes or circles are easiest) to a sprite and then it doesn't matter if the underlying map is top down, isometric, 3d etc. because the bounding geometry is in world coordinates and doesn't care how large a tile is or isn't, just that other objects know where it is.

You need to perform some form of sprite vs sprite collision anyway in most games especially if there are small objects that obviously wouldn't fill an entire tile (bullets for example) so I don't think this would be a bad idea to implement anyway.

Share this post


Link to post
Share on other sites
honestly i hadn't thought about collision detection for this (duh)....walkable tiles applies to terrain and all other objects get a bounding box for which collision detection is calculated.

not sure where my brain was...

Thanks a lot you saved me a lot of code!

Share this post


Link to post
Share on other sites

This topic is 4218 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this