Search code examples
c++graphicsspriteallegroallegro5

Allegro 5 drawing a bitmap over a primitive


I've recently tried making an inventory system in allegro 5, where I draw a grid of squares 20x20 and drag-drop items around. The problem is, I can see the item sprite going under the actual grid that I drew, which is an unwanted effect. Here's my code:

if(draw)
        {
            draw = false;
            al_draw_bitmap(image, item.posx, item.posy, 0);

            if(mouseKey)
               {
                   grab = true;
                   item.posx = mouse.posx - (item.boundx-5);
                   item.posy = mouse.posy - (item.boundy-5);
               }

            else if(mouseKey == false && grab == true)
            {
                for(int i = 0; i < mouse.posx; i += 20)
                {
                    if(i < mouse.posx)
                        item.posx = i;
                }
                for(int j = 0; j < mouse.posy; j += 20)
                {
                    if(j < mouse.posy)
                    {
                        item.posy = j;
                    }
                }
                grab = false;
            }

            for(int i = 0; i <= width; i += 20)
            {
                al_draw_line(i, 0, i, height, al_map_rgb(0, 0, 0), 1);
                al_draw_line(0, i, width, i, al_map_rgb(0, 0, 0), 1);
            }

            al_flip_display();
            al_clear_to_color(al_map_rgb(40,40,40));
        }

(I know it's terribly written and un-optimized but I wrote it in about 10 minutes simply as a test)

How can I make it so the item sprite does not display the lines over it? Here's an example of my problem if I was too vague:

My problem

I'm using Codeblocks IDE on windows XP


Solution

  • Unless you fiddle with OpenGL settings, you're going to always get the things you draw last on top. So in this case, simply move al_draw_bitmap(image, item.posx, item.posy, 0); to be directly above al_flip_display().

    Note that you will have some problems because you are manipulating item.posx and item.posy in that section, so you'd have to first cache the results:

    int x = item.posx;
    int y = item.posy;
    
    // ... 
    
    al_draw_bitmap(image, x, y, 0);
    al_flip_display();
    

    However, that's just a bandaid over the larger problem: you shouldn't be changing anything inside your drawing block. The entire if/else block should be elsewhere. i.e.:

    if (event timer is a game tick)
    {
      do all logic stuff
      draw = true
    }
    
    if (draw)
    {
      do all drawing stuff
      draw = false;
    }