Sign in to follow this  
lodoss118

render order

Recommended Posts

hi don't have enough programming experiuence with sorting and searching algorithms but i got something like this for my rendering method renderChars() { char[0] = renderKen(); char[1] = renderRyu(); etc } i am trying to make a scrolling beat em up, i know the last element gets drawn first, so how do i sort according to the y value of the main char or enemies i.e the main char could be ken so if ryu->y is less than ken->y, draw ken first etc any examples would help thanks

Share this post


Link to post
Share on other sites
What's wrong with:

renderChars()
{
if(ken->y > ryu->y)
{
char[0] = renderKen();
char[1] = renderRyu();
}
else
{
char[1] = renderKen();
char[0] = renderRyu();
}
}


?

Share this post


Link to post
Share on other sites
Use the STL. It provides classes for tracking a bunch of objects (known as "container" classes - such as list, vector, queue, stack, etc), and provides a bunch of algorithms for things like sorting and searching.

Share this post


Link to post
Share on other sites
is it possible to demonstrate to me a quick example of this i heard of the built in library for queues deqeues list etc but never used them?

Share this post


Link to post
Share on other sites
OK, sure. We'll need to suppose some things about your game first though.

Let's suppose that what we're looking at is, instead of a character renderer or suchlike, just a generalised system for rendering sprites. That allows you to use it for characters, powerups, special effects... whatever you like.

The way it's going to work will be like this: Your renderer is going to have a list of the sprites that it needs to draw (that it keeps from frame to frame, because the set of sprites that you need to draw in one frame are usually the same set that you need to draw the next frame). Each of your enemies or characters or whatever-the-heck-you-likes that are graphically visible (i.e. aren't invisible objects like triggers or spawn points) will have a pointer to an entry in this list. If the object moves or changes state, it goes through the pointer and updates the relevant information about where its sprite should be and which frame of animation it should display.

When it comes to actually rendering all these objects, you've got every sprite in a nice list and you can use a predicated sort (a sort where you provide code that tells the sort algorithm how to compare two entries) to sort them however you like - by depth, by spritesheet, etc.

What you end up with is something like the following. (This is off the top of my head to convey an idea, it probably doesn't compile):



// The data we store for each sprite - just enough to render it
struct SpriteData
{
int left, top, right, bottom; // position in worldspace - could do width/height instead of right/bottom if you prefer
int zOrder; // draw order relative to other sprites - lower numbers are drawn last
int animationID; // ID number of the animation this sprite is playing
int animationFrame; // frame number within the animation
};

class SpriteRenderer
{
private:

// the list of sprites
std::list<SpriteData*> sprites;

// a function used to compare two sprites, for sorting
static bool CompareSprites(const SpriteData*& s1, const SpriteData*& s2)
{
// push sprites with high zOrders to the beginning of the list so they are drawn first
return (s1.zOrder > s2.zOrder);
}

public:

// create a new sprite entry in the list and return a pointer to the caller
static SpriteData* CreateSprite()
{
SpriteData* s = new SpriteData();
sprites.push_back(s);
return s;
}

// delete an entry from the list
static void RemoveSprite(SpriteData* s)
{
sprites.remove(s);
delete s;
}

// render all the sprites
static void Render()
{
// sort the sprite list, using our custom compare function
sprites.sort(CompareSprites);
// loop through all the sprites, first to last
for(std::list<SpriteData*>::iterator it = sprites.begin(); it != sprites.end(); ++it)
{
const SpriteData* thisSprite = (*it);
// .
// .
// .
// Do what you need to do to render the sprite given the info in thisSprite
// .
// .
// .
}
}
}

// Elsewhere, in a game object somewhere - say a character

MyCharacter::MyCharacter()
{
/* ... stuff ... */
m_Sprite = SpriteRenderer::CreateSprite();
}

void MyCharacter::Update()
{

/* ... stuff ... */

if(userInput->PlayerIsPressingKey(KEY_JUMP))
{
m_Sprite->animationID = ANIMATION_JUMP;
m_Sprite->animationFrame = 0;
}

/* ... more stuff ... */

m_Sprite->left = m_Position.x - 32;
m_Sprite->top = m_Position.y - 32;
m_Sprite->right = m_Position.x + 32;
m_Sprite->bottom = m_Position.y + 32;
m_Sprite->animationFrame++;

}

Share this post


Link to post
Share on other sites
i see what ur getting at , this what i did for my game (no cool sprite manager like above though) so u can see my shitty code :(

http://rapidshare.de/files/18391896/genesis_Engine.rar.html

that is my source i suppose if i did it like the above i would have to change the whole engine thingy, note i am using a directx wrapper to make my game.

Share this post


Link to post
Share on other sites
hi i am trying to implement the above sprite list class but for the
sprites.sort(CompareSprites) how would that work or what should i put in it, i did this

void AnimatedSprite::Render(const SpriteData*& s1, const SpriteData*& s2)
{
sprites.sort(CompareSprites(s1, s2));
}

but i get an error?

Share this post


Link to post
Share on other sites
how would i implement the DXUSPRITE using the above method?


struct SpriteData
{
int left, top, right, bottom; // position in worldspace - could do width/height instead of right/bottom if you prefer
int zOrder; // draw order relative to other sprites - lower numbers are drawn last
int animationID; // ID number of the animation this sprite is playing
int animationFrame; // frame number within the animation
DXUIMAGE image;
DXUSPRITE sprite;
};


SpriteData* AnimatedSprite::CreateSprite(TCHAR *path, int z, float posx, float posy, int r, int g, int b)
{
SpriteData* s = new SpriteData();
DXULoadImage(&s->image, path, DXURGB(r, g, b));
DXUSetSprite(&s->image, &s->sprite, posx, posy);
sprites.push_back(s);
return s;
}

void AnimatedSprite::RemoveSprite(SpriteData *s)
{
DXUReleaseImage(&s->image);
DXUReleaseSprite(&s->sprite);
sprites.remove(s);
delete s;
}

void AnimatedSprite::Render(/*const SpriteData*& s1, const SpriteData*& s2*/)
{
//sprites.sort(CompareSprites(s1, s2));

// loop through all the sprites, first to last
for(std::list<SpriteData*>::iterator it = sprites.begin(); it != sprites.end(); ++it)
{

SpriteData* thisSprite = (*it);

DXUMoveSprite(&thisSprite->sprite, thisSprite->sprite.x, thisSprite->sprite.y);
DXUDrawSprite(&thisSprite->sprite);

}
}

Share this post


Link to post
Share on other sites
Quote:
Original post by superpig
OK, sure. We'll need to suppose some things about your game first though.

Let's suppose that what we're looking at is, instead of a character renderer or suchlike, just a generalised system for rendering sprites. That allows you to use it for characters, powerups, special effects... whatever you like.

The way it's going to work will be like this: Your renderer is going to have a list of the sprites that it needs to draw (that it keeps from frame to frame, because the set of sprites that you need to draw in one frame are usually the same set that you need to draw the next frame). Each of your enemies or characters or whatever-the-heck-you-likes that are graphically visible (i.e. aren't invisible objects like triggers or spawn points) will have a pointer to an entry in this list. If the object moves or changes state, it goes through the pointer and updates the relevant information about where its sprite should be and which frame of animation it should display.

When it comes to actually rendering all these objects, you've got every sprite in a nice list and you can use a predicated sort (a sort where you provide code that tells the sort algorithm how to compare two entries) to sort them however you like - by depth, by spritesheet, etc.

What you end up with is something like the following. (This is off the top of my head to convey an idea, it probably doesn't compile):

*** Source Snippet Removed ***



oooh thank you, i was wondering exactly how to go about doing this; i was basically doing what you were except i didn't have a list object, instead i had a vector

although, won't sorting every cpu cycle be really intensive?


anyway thanks ill have to check it out more later ^^

Share this post


Link to post
Share on other sites
Quote:
Original post by -justin-
oooh thank you, i was wondering exactly how to go about doing this; i was basically doing what you were except i didn't have a list object, instead i had a vector

A vector should be fine for it as well. The reason I'd use a list instead of a vector is because a vector guarantees that elements will be contiguous (i.e. laid out next to one another) in memory, and we don't really need that property - the list lets us squeeze our sprites into any gap large enough, while the vector will only use a chunk of memory big enough for all the sprites at once.

Quote:

although, won't sorting every cpu cycle be really intensive?
It won't be that intensive, because it's not every cycle - it's every frame - and because there won't be that many objects in the list. However, if you're really worried - and you've measured the time that the sort is taking and believe it to be in need of improvement - then you could possibly write a faster sort routine that takes advantage of the fact that the list won't change much from frame to frame. You could scan through the list from start to end, and if an entry is a higher priority than the object before it, shift it backwards until it's in the right place (repeat until you reach the end).

When the list is already sorted, it'll take cN time (where N is the number of items in the list and c is the time taken to check that an item is correct and move on). When you've got one item that is in the wrong place, it'll take cN + dM time (where M is the number of positions it needs to move - usually only one or two - and d is the cost of moving it one place). In the worst case, where the list is in reverse order, the algorithm would be O(n^2).

Quote:
Original post by lodoss118
hi i am trying to implement the above sprite list class but for the
sprites.sort(CompareSprites) how would that work or what should i put in it, i did this

void AnimatedSprite::Render(const SpriteData*& s1, const SpriteData*& s2)
{
sprites.sort(CompareSprites(s1, s2));
}

but i get an error?

It looks like you're mixing up the CompareSprites function with the Render function. Look at the arguments: why would the render function take two sprites?

As for the DXUSPRITE stuff, I can't actually find any class by that name. Can you check the name, or point me to a reference?

Share this post


Link to post
Share on other sites
basically the DXU functions are from a direct x wrapper called DXU

u can easily set up sprites etc with it

DXUIMAGE imgage;
DXUSPRITE sprite;

DXULoadImage();
DXUSetImage()
DXUDrawSprite() etc all take parameters,

from the game i posted above there is no DXUsprite class the DXU functions r just calling from the wrapper, but i was wondering how i would create what u posted using the DXUIMAGE and DXUSPRITE objects, if u look in my class u will see i have a class called animatedSprited, which uses these functions but i want it to be in a list type thing that i can easly sort depening which char is higher via y values so that char will be drawn first like in those final fight games?.

Share this post


Link to post
Share on other sites

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