Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Enable map layers other than base layer?

This thread is locked; no one can reply to it. rss feed Print
Enable map layers other than base layer?
nicmo1
Member #11,818
April 2010

First off, I'm pretty new to the whole game programming thing.
I've been successful with my class's assignments so far, which have all been fairly simple for me. Finally, we are moving into some cool material...

Our final assignment for the semester is to make a platform scroller with multiple levels, each consisting of multiple layers, etc.

I am using Dev-C++, Allegro library, and Mappy to make the game.
I've put together a couple maps, and I can successfully put them into the textbook's example platform scroller's code, but I run into problems if the map is multiple layers. It will only show the lowest (0) layer.

My question probably has a pretty simple answer, but I'm having trouble figuring it out. I basically want to know how to enable the other layers of whatever map is loaded.

Any help or direction is greatly appreciated!

Felix-The-Ghost
Member #9,729
April 2008
avatar

You're problem is bound to be code-based
(Meaning we can't help you until you post some code in <code>code here</code> tags.

Also, don't use Dev C++. I used it for like a year until I realized it was horribly outdated and dead. Use Code::Blocks instead.

==========================
<--- The ghost with the most!
---------------------------
[Website] [Youtube]

OnlineCop
Member #7,919
October 2006
avatar

When you draw the tiles to the screen (or better yet, to a buffer which you later transfer all-at-once to the screen) using blit() or draw_sprite()?

I have never used mappy, so I can't provide any insight into its mechanism for handling layers. I would assume that it stores them in either a vector or an array.

If that's the case, simple iteration would do the trick:

for (layer = 0; layer < num_layers; ++layer)
{
  for (row = 0; row < screen_width; ++row)
  {
    for (col = 0; col < screen_height; ++col)
    {
      if (all_layers[layer].value > 0)
        draw_sprite(buffer, all_layers[layer].tilemap[all_layers[layer].value], col, row);
    }
  }
}

Of course, as Felix mentioned, it will help if you can tell us what you've done so far, even if you give us a few lines of your current drawing routines.

nicmo1
Member #11,818
April 2010

Here is the code for the main file...
Remember, I didn't code this myself, this is from one of the textbook's examples...
However, I do follow and understand most of what is going on.

I just loaded my map (map2.fmp) instead of the one the book used.
I have the map loaded, it's scrolling, and collision detection seems to be working.

I just can't figure out how to turn on other layers of the map.
(Mappy exports each map and all its layers into a .fmp file.)

#SelectExpand
1#include <stdio.h> 2#include <allegro.h> 3#include "mappyal.h" 4 5#define MODE GFX_AUTODETECT_WINDOWED 6#define WIDTH 640 7#define HEIGHT 480 8#define JUMPIT 1600 9 10//define the sprite structure 11typedef struct SPRITE 12{ 13 int dir, alive; 14 int x,y; 15 int width,height; 16 int xspeed,yspeed; 17 int xdelay,ydelay; 18 int xcount,ycount; 19 int curframe,maxframe,animdir; 20 int framecount,framedelay; 21}SPRITE; 22 23//declare the bitmaps and sprites 24BITMAP *player_image[8]; 25SPRITE *player; 26BITMAP *buffer; 27BITMAP *temp; 28 29 30//tile grabber 31BITMAP *grabframe(BITMAP *source, 32 int width, int height, 33 int startx, int starty, 34 int columns, int frame) 35{ 36 BITMAP *temp = create_bitmap(width,height); 37 int x = startx + (frame % columns) * width; 38 int y = starty + (frame / columns) * height; 39 blit(source,temp,x,y,0,0,width,height); 40 return temp; 41} 42 43 44int collided(int x, int y) 45{ 46 BLKSTR *blockdata; 47 blockdata = MapGetBlock(x/mapblockwidth, y/mapblockheight); 48 return blockdata->tl; 49} 50 51 52int main (void) 53{ 54 int mapxoff, mapyoff; 55 int oldpy, oldpx; 56 int facing = 0; 57 int jump = JUMPIT; 58 int n; 59 60 allegro_init(); 61 install_timer(); 62 install_keyboard(); 63 set_color_depth(16); 64 set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0); 65 66 temp = load_bitmap("guy.bmp", NULL); 67 for (n=0; n<8; n++) 68 player_image[n] = grabframe(temp,50,64,0,0,8,n); 69 destroy_bitmap(temp); 70 71 player = malloc(sizeof(SPRITE)); 72 player->x = 80; 73 player->y = 100; 74 player->curframe=0; 75 player->framecount=0; 76 player->framedelay=6; 77 player->maxframe=7; 78 player->width=player_image[0]->w; 79 player->height=player_image[0]->h; 80 81 //load the map 82 MapLoad("map2.fmp"); 83 84 //create the double buffer 85 buffer = create_bitmap (WIDTH, HEIGHT); 86 clear(buffer); 87 88 //main loop 89 while (!key[KEY_ESC]) 90 { 91 92 oldpy = player->y; 93 oldpx = player->x; 94 95 if (key[KEY_RIGHT]) 96 { 97 facing = 1; 98 player->x+=5; 99 if (++player->framecount > player->framedelay) 100 { 101 player->framecount=0; 102 if (++player->curframe > player->maxframe) 103 player->curframe=1; 104 } 105 } 106 else if (key[KEY_LEFT]) 107 { 108 facing = 0; 109 player->x-=2; 110 if (++player->framecount > player->framedelay) 111 { 112 player->framecount=0; 113 if (++player->curframe > player->maxframe) 114 player->curframe=1; 115 } 116 } 117 else player->curframe=0; 118 119 //handle jumping 120 if (jump==JUMPIT) 121 { 122 if (!collided(player->x + player->width/2, 123 player->y + player->height + 5)) 124 jump = 0; 125 126 if (key[KEY_SPACE]) 127 jump = 30; 128 } 129 else 130 { 131 player->y -= jump/3; 132 jump--; 133 } 134 135 if (jump<0) 136 { 137 if (collided(player->x + player->width/2, 138 player->y + player->height)) 139 { 140 jump = JUMPIT; 141 while (collided(player->x + player->width/2, 142 player->y + player->height)) 143 player->y -= 2; 144 } 145 } 146 147 //check for collided with foreground tiles 148 if (!facing) 149 { 150 if (collided(player->x, player->y + player->height)) 151 player->x = oldpx; 152 } 153 else 154 { 155 if (collided(player->x + player->width, 156 player->y + player->height)) 157 player->x = oldpx; 158 } 159 160 //update the map scroll position 161 mapxoff = player->x + player->width/2 - WIDTH/2 + 10; 162 mapyoff = player->y + player->height/2 - HEIGHT/2 + 10; 163 164 165 //avoid moving beyond the map edge 166 if (mapxoff < 0) mapxoff = 0; 167 if (mapxoff > (mapwidth * mapblockwidth - WIDTH)) 168 mapxoff = mapwidth * mapblockwidth - WIDTH; 169 if (mapyoff < 0) 170 mapyoff = 0; 171 if (mapyoff > (mapheight * mapblockheight - HEIGHT)) 172 mapyoff = mapheight * mapblockheight - HEIGHT; 173 174 //draw the background tiles 175 MapDrawBG(buffer, mapxoff, mapyoff, 0, 0, WIDTH-1, HEIGHT-1); 176 177 //draw foreground tiles 178 MapDrawFG(buffer, mapxoff, mapyoff, 0, 0, WIDTH-1, HEIGHT-1, 0); 179 180 //draw the player's sprite 181 if (facing) 182 draw_sprite(buffer, player_image[player->curframe], 183 (player->x-mapxoff), (player->y-mapyoff+1)); 184 else 185 draw_sprite_h_flip(buffer, player_image[player->curframe], 186 (player->x-mapxoff), (player->y-mapyoff)); 187 188 //blit the double buffer 189 vsync(); 190 acquire_screen(); 191 blit(buffer, screen, 0, 0, 0, 0, WIDTH-1, HEIGHT-1); 192 release_screen(); 193 194 } //while 195 196 for (n=0; n<8; n++) 197 destroy_bitmap(player_image[n]); 198 free(player); 199 destroy_bitmap(buffer); 200 MapFreeMem (); 201 allegro_exit(); 202 return 0; 203} 204END_OF_MAIN()

OnlineCop
Member #7,919
October 2006
avatar

You are using two functions, MapDrawBG() and MapDrawFG() (lines 175 and 178). I assume that these functions give you your background (or a main background image with "tiles" in the foreground?).

Since I can't see what those functions are doing, I'm going to assume that the problem lies in the fact that you're not calling a function for each additional layer that needs to be drawn.

Within those functions, they probably point to the portion of data that was read in from your map2.fmp file, and converted into a tilemap. If that was loaded into only a single layer, and all the rest discarded, then you'll want to modify the MapLoad() function to load in for each desired layer.

If MapLoad() loads things in correctly, but you simply don't access the other layers (like I said earlier: because you don't have any other layer-drawing functions than MapDrawBG() and MapDrawFG() ), then you should create them.

That would be my guess at this point.

Thomas Fjellstrom
Member #476
June 2000
avatar

OnlineCop said:

You are using two functions, MapDrawBG() and MapDrawFG() (lines 175 and 178). I assume that these functions give you your background (or a main background image with "tiles" in the foreground?).

It seems he's using an old allegro addon called Mappy to handle the maps.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

nicmo1
Member #11,818
April 2010

I am using Mappy to create the maps and Tile Studio to create the tiles for the maps.
They are both older programs, but I know that they can work accomplish what I need to accomplish.

The first map (map1.fmp) has 2 layers so far:
The background (layer 0) is the sky, clouds, etc.
The foreground (layer 1) is everything else so far...the ground, obstacles, etc.

When I try loading map1, it will show layer 0, the sky and clouds, but the foreground isn't showing.

I attached a couple files that are associated with this example program. They define a lot of things to get the mappy files to work with Allegro...but, being the newb that I am, I'm having trouble figuring out what I need to do...but I'm sure the answer is lying somewhere in those files.

Thanks for the insight so far!

edit - in the REDMEAL.TXT file, it goes over some things.
I see that for the MapDrawFG() on line 178, the only difference from MapDrawBF() on line 175 (which seems to be working) is that the last element passed is an int which specifies which layer to draw. I tried setting it to 1, which the foreground layer is for the map, but it still won't draw it when I run the program. :/

Dario ff
Member #10,065
August 2008
avatar

A whole .zip of the folder with the map file and the needed bitmaps would be good for having something to test. If you don't want to do that for X reason, I guess I'll just read the code.

TranslatorHack 2010, a human translation chain in a.cc.
My games: [GiftCraft] - [Blocky Rhythm[SH2011]] - [Elven Revolution] - [Dune Smasher!]

StevenVI
Member #562
July 2000
avatar

I used Mappy for the game Trashman. (It's not very good, don't feel obligated to look at it, but the source code is provided.)

Here is the drawing code I used:

MapChangeLayer(0);
MapDrawBG(buffer, camera.x, camera.y, 133, 79, (314-67)*2+3, (234-40)*2+3);

MapChangeLayer(1);
MapDrawFG(buffer, camera.x, camera.y, 133, 79, (314-67)*2+3, (234-40)*2+3, 0);

(This excerpt was taken from main.cpp in the source distribution.) The magic numbers should just be to place it in the game window. My map had two layers.

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

nicmo1
Member #11,818
April 2010

Dario ff and StevenVI,

Thanks a lot for the replies.
I think what StevenVI posted has me on the right track.

Although I still do not SEE the foreground tiles, they must be there,
because as the character runs along, he collides with the boxes that
he is supposed to collide with. They're just invisible.

Any ideas?

I will attach a .rar of the folder and all its contents here.
Thanks so much, guys. :)

ps - StevenVI, thanks much for the link to your game! I appreciate that. I'm sure it will come in handy and give me some ideas of what I need to do to accomplish certain things.

BUMP -- Anyone? Why would the foreground layer be invisible, but still make the player collide with things???? ???

Go to: