Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » RPG game movement

This thread is locked; no one can reply to it. rss feed Print
RPG game movement
Antone333
Member #15,545
March 2014

Ok so my previous post here https://www.allegro.cc/forums/thread/614751
i was trying to figure out movement of my character in a game.

well i got him moving!

extremely slowly, but moving. and now i know how to do collision detection with all the other tiles in my game so it is a huge step but... he moves so painfully slow! Does anyone know how i can fix this?

please go ahead and test out the game as it is so far. be patient. like i said. painfully slow.

#SelectExpand
1//Drawing the map looks like this 2 3if(Redraw && al_is_event_queue_empty(EventQueue) || ForceRedraw) 4 { 5 Redraw = false; 6 ForceRedraw = false; 7 8 for(int Drawx = 0; Drawx < MapX; Drawx++) 9 { 10 for(int Drawy = 0; Drawy < MapY; Drawy++) 11 { 12 al_set_target_backbuffer(GameDisplay); 13 al_draw_bitmap_region(TileSheet, Map[Drawy][Drawx] * TileSize, 0, TileSize, 32, Drawx * TileSize, 14 Drawy * TileSize, 0); 15 } 16 } 17 for(int Drawx = 0; Drawx < MapX; Drawx++) 18 { 19 for(int Drawy = 0; Drawy < MapY; Drawy++) 20 { 21 al_convert_mask_to_alpha(PlayerTileSheet, al_map_rgb(255, 0, 255)); 22 al_draw_bitmap_region(PlayerTileSheet, PlayerMap[Drawy][Drawx] * TileSize, 0, TileSize, 32, Drawx * TileSize, 23 Drawy * TileSize, 0); 24 } 25 } 26 } 27 28 29//movement looks like this 30 31if(Event.type == ALLEGRO_EVENT_KEY_DOWN) 32 { 33 switch(Event.keyboard.keycode) 34 { 35 case ALLEGRO_KEY_UP: 36 Y2 = Y - 1; 37 38 if(PlayerMap[Y2][X] == 5) 39 { 40 PlayerMap[Y][X] = 5; 41 Y--; 42 PlayerMap[Y][X] = 0; 43 ForceRedraw = true; 44 } 45 break;

Thomas Fjellstrom
Member #476
June 2000
avatar

add a call to al_hold_bitmap_drawing above your draw loops. That should help a little.

Also that al_set_target_backbuffer only needs to be called once, and only if you changed the target bitmap previously (it is automatically set to the last created display).

--
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

Antone333
Member #15,545
March 2014

Ok. i will add that and try removing the bitmap buffers. Thanks.

this is where i draw the tiles that only contain the player npc and enemy tiles. but i believe, if i am not mistaken i do need to have equal blank tiles for the amount of map tiles there are. otherwise it cycles back through. The only reason i do it this way is because it was how i knew i could get it working.

so like this?

#SelectExpand
1 al_hold_bitmap_drawing(true); 2 for(int DrawX = 0; DrawX < MapX; DrawX++) 3 { 4 for(int DrawY = 0; DrawY < MapY; DrawY++) 5 { 6 al_convert_mask_to_alpha(PlayerTileSheet, al_map_rgb(255, 0, 255)); 7 al_draw_bitmap_region(PlayerTileSheet, PlayerMap[DrawY][DrawX] * TileSize, 0, TileSize, 32, DrawX * TileSize, 8 DrawY * TileSize, 0); 9 } 10 } 11 al_hold_bitmap_drawing(false);

it doesnt really help me too much.
its not that my computer is having a hard time with it on its own right? its a decent computer. but ive had it for probably 6 years. i dont really know too much about it. but is having to redraw the tiles over and over like that just a lot to handle?

Thomas Fjellstrom
Member #476
June 2000
avatar

It should be capable of hundreds or thousands of tiles without held drawing. With held drawing you should get a lot more. But the tiles need to be in as few tile sheets or atlases as is possible for held drawing to help.

--
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

pkrcel
Member #14,001
February 2012

Seems he is drawing from a single parent bitmap thou.

I suspect there might be some other reasons like MEMORY BITMAPS....when do you load your bitmaps Antone?

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Aaron Bolyard
Member #7,537
July 2006
avatar

This line: al_convert_mask_to_alpha(PlayerTileSheet, al_map_rgb(255, 0, 255));

You only need to call it once (such as when you load the bitmap), not every time you draw the bitmap.

pkrcel
Member #14,001
February 2012

facepalm , I should at least have noted :-[

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Antone333
Member #15,545
March 2014

@Aaron Bolyard
That made the biggest difference. Thank you very much. its definitely better. But still a bit slow.

I have posted my code if anyone wants to take a look again.

Drawing of character happens at 476 and then movement happens in the function below. the maps are all the way down at the bottom.

Aaron Bolyard
Member #7,537
July 2006
avatar

The problem is that you're loading bitmaps into the wrong displays.

When you load bitmaps that are drawn with the GameDisplay, call al_set_target_backbuffer(GameDisplay); When you load bitmaps that are drawn with ToolbarDisplay, call al_set_target_backbuffer(ToolbarDisplay); The same goes for the rest of your displays.

pkrcel
Member #14,001
February 2012

When using a bitmap which is not owned from the current display (but another), what happens behind the scenes? is that copied to memory?

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

LennyLen
Member #5,313
December 2004
avatar

pkrcel said:

When using a bitmap which is not owned from the current display (but another), what happens behind the scenes? is that copied to memory?

I'm no expert on A5, but if they were created with the video bitmap flag set, then they should never be converted to memory bitmaps. If so, then something very stupid is going on.

Thomas Fjellstrom
Member #476
June 2000
avatar

Something stupid is going on. Textures and thus bitmaps are tied directly to a context/display. Using a bitmap on a display it isn't attached to will use memory drawing. It'll either come from the memory copy that is kept by gl or allegro in the case of dx. Or it'll have to lock the bitmap, then copy the data to ram then upload to the display.

There are extensions that allow sharing resources between displays but I'm not sure how well they work.

--
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

pkrcel
Member #14,001
February 2012

I'm sorry Tomasy but I kinda fail to understand.

What you say that is textures cannot be shared between different A5 displays (contexts) due to the very nature of the undelying gfx APIs and thus they are in this example program by Antone333 actually drawn from a memory copy?

Also:

Or it'll have to lock the bitmap, then copy the data to ram then upload to the display.

If this can be true, basically you'd have a slowdown only the first time the display is drawn with a not-owned texture, but then all successive draw calls should perform ok, no?

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Antone333
Member #15,545
March 2014

@Aaron Bolyard

i already do that. i noticed that i had forgotten to do it with the equipment and the inventory displays but that doesnt matter as they are not even open most of the time while i am testing this.

Thomas Fjellstrom
Member #476
June 2000
avatar

pkrcel said:

If this can be true, basically you'd have a slowdown only the first time the display is drawn with a not-owned texture, but then all successive draw calls should perform ok, no?

no. It doesn't create a new texture tied to that display. It only draws the contents to the display.

--
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

Antone333
Member #15,545
March 2014

Just reposting my entire project. still slow. but it works and im still happy with it.

pkrcel
Member #14,001
February 2012

no. It doesn't create a new texture tied to that display. It only draws the contents to the display.

Understood; I instead thought that the back&forth copy was actually a MOVE to tie the texture to new context (detaching it from the previous one).

EDIT:

Antone333 said:

i already do that.

It doesn't seem to me, you load all the bitmaps in the beginning of Game() and they are tied to toolbardisplay most probably dince it is the last created display.

This for the aforementioned reasons will KILL the performance.

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Antone333
Member #15,545
March 2014

does anyone have any other ideas?

pkrcel
Member #14,001
February 2012

Please see my edit above, you definitely are using slow memory bitmaps

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Antone333
Member #15,545
March 2014

Oh. i see what you mean now i think.

i got mixed up between loading and actually drawing.
/
/
/
/
Yup. that did it. Wow. hah. so i moved the loading of the images into where i actually create the new displays.

looks like this:

InventoryDisplay = al_create_display(160, 160);
al_set_window_title(InventoryDisplay, "Inventory");
al_set_target_backbuffer(InventoryDisplay); sets display here
ALLEGRO_BITMAP *InventoryImage = NULL; this i should probably move back to where it was. yes? i saw that now that i copied it here.
InventoryImage = al_load_bitmap("Inventory.png"); loads here
al_draw_bitmap(InventoryImage, 0, 0, 0); draws here
InventoryState = false;
InventoryRegister = true;

also i should probably make a little single time if statement. because i dont need to be loading in those maps every singly time. right?

also getting rid of the force redraw helps too. It was making it so when i press the arrow keys a little fast the player stops being drawn and then jumps to the final position.

the little lag and then jump still happens every so often but im ok with that for now.

Thank you all so very much!

pkrcel
Member #14,001
February 2012

Just remember to set the target backbuffer to the actual desired backbuffer before loading each batch of bitmaps, you SURELY do not need to load the bitmaps each and every time you draw (quite the opposite!! )

In principle you can set the target backbuffer a gazillion times with no side effect...

BUT

I strongly suggest you use only ONE display and manage the multiple views inside that (maybe with the aid of a GUI library), or simply arrange the current "displays" in a single fied view for starters.

The multple windows setup is not that bad...but pollutes the taskbar and the desktop environment quite badly, and it is not a single bit comfortable.

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Antone333
Member #15,545
March 2014

ok. i can do that. the only reason i did it with multiple displays to begin with was im not really sure how to make the map move as the character does. so i just fit everything into their own displays. but i guess what i can do is just keep that up and make the game display bigger to fit everything inside. unless i can keep the player in the center of the screen. but again. i dont know how to do that.

What i personally would like the best is to have the toolbar items get displayed in the center of the screen allow for you to do stuff there and then get closed when done. but like i said. i have no idea how to do any of that.
/
/
/
/
/
I think that will be for another time though. For now i am going to continue with what i know how to do.

pkrcel
Member #14,001
February 2012

Antone333 said:

I think that will be for another time though. For now i am going to continue with what i know how to do.

Great, that's how things should roll out.

Most of what you are trying to "emulate" using multiple displays is usually done through a proper GUI system (either you program it or use a good third party library).

In your case, for starters, I'd think a fixed layout for the current displays which have the map in the center, and I'd study a way to do this:

Quote:

unless i can keep the player in the center of the screen. but again. i dont know how to do that.

Once done things would get a lot simplier about graphics, at least IMO.

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Antone333
Member #15,545
March 2014

yeah im sure it would be a lot easier that way. Right now i just finished making new pngs for the different tool bar images. they are going to go at the bottom of the game display.

I know that keeping the player in the center of the screen requires you to offset the map and i did that once by just drawing the player in the middle and moving the map around the player, but i have no idea how to do tile collision that way. so i did it with the 2 arrays. one to draw the map and one to draw the players map for collision.

Go to: