Jump to content
  • Advertisement
Sign in to follow this  

Z-Layer change

This topic is 2113 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

In a 2D isometric game, the player can be either behind a tree or in front of the tree.

I understand that in order to implement something like that, I need to draw the objects that are furthest away first and the objects that are closest to the screen last, but I don't know how to express that in C++.


How do I change the draw order of the objects during run time?

Like, when the player starts out behind the tree and then walks in front of the tree then I need to change "draw tree before player" to "draw tree after player"

I don't know how to write that at all.


Please help


(I'm using SFML and C++)

Share this post

Link to post
Share on other sites

Sort by Y position. In isometric, ignore the "altitude" of the sprite during the sorting, so jumping up doesn't affect the draw order, even though it does affect the Y position on screen. Any sorting algorithm will do. I keep my sprites in a linked list, and use an insertion sort where I traverse the list backward and rebuild it every frame, because it's simple and fast. If no sprites have changed order, it's linear time. Worst case is if they all completely reversed order, where it would be O(n2) time. But even that wouldn't be a big deal unless you have a ton of sprites, and most games it would never happen anyway.

void SpriteSystemYSort()
    Sprite *sprite = gSpriteActiveListHead;
    Sprite *activeListTail;

    if (sprite == NULL || sprite->next == NULL)
        return;    // No sorting to be done unless there's more than one sprite

    // Start from the tail of the list, for minimal insert time if the order hasn't changed since last frame
        sprite = sprite->next;

    // Rebuild the active list in Y sorted order. Start by adding the first sprite, to save a couple null checks in the loop
    gSpriteActiveListHead = activeListTail = sprite;
    sprite = sprite->prev;
    gSpriteActiveListHead->prev = gSpriteActiveListHead->next = NULL;
        Sprite *prev = sprite->prev;
        Sprite *insert = gSpriteActiveListHead;

        while(insert != NULL && insert->pos.y > sprite->pos.y)
            insert = insert->next;

        if (insert == NULL)
            sprite->prev = activeListTail;
            sprite->next = NULL;
            activeListTail->next = sprite;
            activeListTail = sprite;

        else if (insert == gSpriteActiveListHead)
            sprite->prev = NULL;
            sprite->next = gSpriteActiveListHead;
            gSpriteActiveListHead->prev = sprite;
            gSpriteActiveListHead = sprite;
            sprite->prev = insert->prev;
            sprite->next = insert;
            insert->prev->next = sprite;
            insert->prev = sprite;

        sprite = prev;

Share this post

Link to post
Share on other sites

Sort by Y position.


Or, if you want to avoid sorting for e.g. solid opague characters, you can do this to convert to a relative z-position:

float z = -(vPos.y - m_vScreenPos.y) / INT_MAX); // the "-" depends on how your viewport is set up

Where vPos is the position of the sprite/character, and m_vScreenPos is the position of the camera. Now you can just draw in random order with the z-buffer enabled, while for transparent sprite, you have little choice than to explicitely sort by y-position.

Edited by Juliean

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!