Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Rendering Sprites by order of screen position.

This thread is locked; no one can reply to it. rss feed Print
Rendering Sprites by order of screen position.
alexius wronka
Member #15,571
April 2014

I'm currently having a great time creating a 2D overhead Zelda esq game using C++ and Allegro 5.

However my game is more of a Beyond Oasis perspective then a Zelda Perspective and objects need to appear behind other objects when they have a higher y position and above when they have a lower y position. I have gotten it to work with one object on the other. I created and if/else depending on the y coordinate of the one object.

How would I go about creating this function using every moving object in the game. How can I define the two y variables within the class to create a correct draw order?

Right now I have all characters except the user character inherit all x,y coordinates from a base class. What do I need to do so that I can have two characters who inherit the same x,y to interact?

I got the suggestion to using an SLT container and algorithm std::sort function. I understand how to sort the values using these tools but how do I then sort the functions themselves.

For example:

I have these functions to draw:

bush[1].DrawBush(bushImage);
bush[2].DrawBush(bushImage);
rock[1].DrawRock(rockImage);
aBear[1].DrawsBear(bearImage2);
pigs[1].DrawPig(pigImage);
pigs[2].DrawPig(pigImage);
gremlin[1].DrawGremlins(gremlinImage);
toad[1].DrawToad(toadImage);
reginald->DrawVanJohnson(reginaldImage);

I created a variable to define where I would want them to switch order. int ysort. However, how can I connect the entire function whatever.drawwhater(); with this variable and sort them at the same time.

StevenVI
Member #562
July 2000
avatar

I hope that your final game won't have hardcoded arrays for all the objects. You'll want to allocate them all dynamically based on maps and scripts. :)

This is a general overview of how an engine I worked on did it:

  • Remove the drawing methods from your sprite objects, they should not be concerned with the view (what you see), but rather just the model (data) and possibly control (how they interact with the world, though I would separate that out as well).

  • In your base class, in addition to keeping the x and y coordinates, also have a reference to the bitmap that should be drawn for the current frame for that object. Perhaps a method like ALLEGRO_BITMAP* getCurrentFrame().

  • Create a master drawing method in your engine which utilizes the getCurrentFrame() method of each object to draw the scene.

By this point you should have a scene with everything drawing, but it hasn't addressed the sorting problem yet:

  • Store all game objects which are currently visible in a list (for example, std::vector)

  • Sort that list by y coordinate each frame

  • Iterate over the sorted list to draw each object

I know it's rather high level, feel free to follow up with questions. :)

__________________________________________________
Skoobalon Software
[ Lander! v2.5 ] [ Zonic the Hog v1.1 ] [ Raid 2 v1.0 ]

alexius wronka
Member #15,571
April 2014

StevenVI,

so help me out here because I'm semi-new to game programming. I can place a getfuction in a vector?

For example
int YPostions[]= {pig.y, guy.y, man,y}
std::vector<int> yvector (yPostions)

and then I can sort this?

And then I guess I have to ask how does this then determine the placement of all the characters on the map.

StevenVI
Member #562
July 2000
avatar

I might be completely misunderstanding what you're asking. But I wrote a little demo program to demonstrate how you would sort a vector of Sprite objects:

#SelectExpand
1#include <iostream> 2#include <algorithm> 3#include <vector> 4 5// The Sprite class, the base class for all sprites 6// Should look nicer than this, as this is just a quick demonstration :) 7class Sprite { 8public: 9 Sprite(int x, int y) { this->x = x; this->y = y; } 10 int x; 11 int y; 12}; 13 14// Comparator function for comparing the y value of sprites 15bool spriteCompareByY(Sprite* s1, Sprite* s2) { 16 return s1->y < s2->y; 17} 18 19int main() { 20 // Create a vector of sprites that are not ordered by y coordinate 21 std::vector<Sprite*> sprites; 22 sprites.push_back(new Sprite(0, 0)); 23 sprites.push_back(new Sprite(10, 10)); 24 sprites.push_back(new Sprite(-10, 10)); 25 sprites.push_back(new Sprite(0, 5)); 26 sprites.push_back(new Sprite(2, 3)); 27 28 // Sort the vector using the comparator function 29 std::sort(sprites.begin(), sprites.end(), spriteCompareByY); 30 31 // Output to verify results 32 std::cout << "Sprites sorted by y values:" << std::endl; 33 for (std::vector<Sprite*>::iterator it = sprites.begin(); it != sprites.end(); ++it) { 34 std::cout << (*it)->x << ", " << (*it)->y << std::endl; 35 } 36 37 return 0; 38}

Output:

Sprites sorted by y values:
0, 0
2, 3
0, 5
10, 10
-10, 10

Edit: So in the same manner that I iterated over the sorted vector to output the coordinates, you would do something like that to draw them to the screen.

__________________________________________________
Skoobalon Software
[ Lander! v2.5 ] [ Zonic the Hog v1.1 ] [ Raid 2 v1.0 ]

Go to: