|
This thread is locked; no one can reply to it. |
1
2
|
Mappy collision detection |
Matias Persson
Member #15,093
May 2013
|
Hello there, I have recently jumped into programming, as I have always dreamed about making my own game + I love programming . Though I am stuck with a problem I cannot quite solve. I have been searching throughout the net, and I cannot seem to find the solution. I am trying to make collision detection with Mappy for Allegro 5 converted by Neil. Do you have any suggestions |
Edgar Reynaldo
Major Reynaldo
May 2007
|
If you don't post any code or tell us what you're doing that isn't working and what you want it to do then we can't help you. :/ My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Arthur Kalliokoski
Second in Command
February 2005
|
Nobody's linked this in awhile. They all watch too much MSNBC... they get ideas. |
Matias Persson
Member #15,093
May 2013
|
Sorry, I meant to post the code, but completely forgot it @Arthur Kalliokoski, there is no need to be rude, it could simply be a mistake which it turned out to be. The code is quite ugly, I know that. But again I am just learning. Main.cpp: http://pastebin.com/UvpWWzW5 Refresher: I am stuck on making Collision Detection with Mappy. You can see how I tried to do it in the code.. |
Arthur Kalliokoski
Second in Command
February 2005
|
Matias Persson said: Arthur Kalliokoski, there is no need to be rude TFA said: hackers have a reputation for meeting simple questions with what looks like hostility or arrogance. It sometimes looks like we're reflexively rude to newbies and the ignorant. But this isn't really true.
They all watch too much MSNBC... they get ideas. |
Matias Persson
Member #15,093
May 2013
|
Arthur, I already know this. I have been on "Hackforums" many times, back when I wanted to become a "Hacker", though this has nothing to do with the subject, but in my opinion it is rude. Please do not reply if you cannot help me, instead of coming with rude comments. Does anyone else besides Arthur have any suggestions, as he obviously does not intend to help me? |
Mark Oates
Member #1,146
March 2001
|
Arthur! Since when were you dubbed "Second in Command"? Totally deserve it. -- |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Here's his collision detection function, int collided(int x, int y) { BLKSTR *blockdata; blockdata = MapGetBlock(x/mapblockwidth, y/mapblockheight); return (blockdata->tl || blockdata->tr || blockdata->bl || blockdata->br); } and here's the movement code, 1void MovePlayerUp(Player &player)
2{
3 if(!(collided(player.y, player.y)))
4 {
5 player.y -= player.speed;
6 }
7 if(player.y < 0)
8 player.y = 0;
9}
10void MovePlayerDown(Player &player)
11{
12 if(!(collided(player.y + 35, player.y)))
13 {
14 player.y += player.speed;
15 }
16 if(player.y > HEIGHT)
17 player.y = HEIGHT;
18}
19void MovePlayerLeft(Player &player)
20{
21 if(!(collided(player.x, player.y)))
22 {
23 player.animationRow = 1;
24 player.x -= player.speed;
25 }
26 if(player.x < 0)
27 player.x = 0;
28}
29void MovePlayerRight(Player &player)
30{
31 if(!(collided(player.x + 26, player.y)))
32 {
33 player.animationRow = 0;
34 player.x += player.speed;
35 }
36 if(player.x > WIDTH)
37 player.x = WIDTH;
38}
I think it should be closer to something like this for example : But really, you need to test each leading corner, not just one of them. Ie... if you're moving right you need to check the top right through bottom right side where it would be when it moved in the future. Right now you are checking when the right side is already on the block, and only then can you move, which means you can't move at all? Is that what is happening? Get a min and max tile x and y of the position where your character would be if you moved it and nothing was there. Then loop over that area and see if any of the BLKSTR's at those spots are impassable. 1
2bool IsSolid(BLKSTR* block) {
3 return (block->tl || block->tr || block->bl || block->br);
4}
5
6bool collided(Player& player) {
7 int minx = (player.GetLeftX() + player.XSpeed())/mapblockwidth;
8 int miny = (player.GetTopY() + player.YSpeed())/mapblockheight;
9 int maxx = (player.GetRightX() + player.XSpeed())/mapblockwidth;
10 int maxy = (player.GetBottomY() + player.YSpeed())/mapblockheight;
11
12 for (int tilex = minx ; tilex <= maxx ; ++tilex) {
13 for (int tiley = miny ; tiley <= maxy ; ++tiley) {
14 BLKSTR* block = MapGetBlock(tilex , tiley);
15 if (IsSolid(block)) {return true;}
16 }
17 }
18 return false;
19}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Dizzy Egg
Member #10,824
March 2009
|
Matias Persson said: back when I wanted to become a "Hacker" Christ
---------------------------------------------------- |
Arvidsson
Member #4,603
May 2004
|
Matias Persson said: Does anyone else besides Arthur have any suggestions, as he obviously does not intend to help me? He DID help you Asking smart questions increases the chance of anyone helping you. You could have refined your question in the way that Edgar basically did for you, by posting only code snippets that is relevant to the problem you are having. In other words, welcome to allegro.cc
|
Matias Persson
Member #15,093
May 2013
|
Arvidsson, my question was clear. At least clear enough. English is not my first language, so I'm not very good at elaborating my questions, but at least they're clear enough to understand. Also, I don't know how post the snippets on this forum & I don't even know how to quote @Edgar, I tried to use the two functions in my code, it didn't work out quite well :O? |
Arthur Kalliokoski
Second in Command
February 2005
|
Matias Persson said: Arvidsson, my question was clear. At least clear enough. English is not my first language, so I'm not very good at elaborating my questions, but at least they're clear enough to understand. Your English seems perfectly fine to me, it's just that an answer to your question could fill a book. Quote: I don't know how post the snippets on this forum & I don't even know how to quote {"name":"607505","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/b\/3b2637cef9ec106e33a0e231506fc6d2.png","w":376,"h":225,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/b\/3b2637cef9ec106e33a0e231506fc6d2"} They all watch too much MSNBC... they get ideas. |
Matias Persson
Member #15,093
May 2013
|
Arthur Kalliokoski said: Your English seems perfectly fine to me, it's just that an answer to your question could fill a book. My English may seem fine, as it actually is But I'm not very good at breaking stuff down in English, like explaining myself Also, thank you for helping me with the formatting. On topic: Does anyone have any other solutions? I can't seem to figure out what Edgar explained to me |
Neil Walker
Member #210
April 2000
|
Hello, A map is made up of tiles, quite probably you are using 32x32 pixels per tile. Each tile is also called a block. To work in blocks, e.g. to get tile at 5,5 it is 5,5. To get a pixel version it is 5*BLOCK_WIDTH, 5*BLOCK_WITDH, e.g. in this case 160,x160 A screen might only show 800x600 so can fit 25x16 tiles at a time. Your player sprite will be working most likely in pixels, so if it's at 160,160 then it is also at tile location 5,5 with a 32 pixel tile. Mappy provides functions to get blocks and find blocks using pixels and tile locations (but as above it's easy enough to figure out). When you are drawing your map to the screen you first work out what part of the map to display, i.e. if you are at pixel location 2000,2000 then you will need to offset the starting point (MapDraw functions) to the players position minus whatever calculation you have made for displaying the player (e.g. centred on screen) you might end up working out to display from tile location 50,50 Now for collision, you know where the player is, e.g. 160,160 so get the block at this position (either using the pixel or block mapgetblock functions). This block is a struct. Use the data you've provided for each block to work out whether it's a collision block or not, e.g. I use tl to indicate is a collision, etc. Any clearer? Neil. wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Matias Persson said: @Edgar, I tried to use the two functions in my code, it didn't work out quite well :O? This is what they're talking about - you're being way too vague. What didn't work? Have you set up your map yet? Which member of the BLKSTR do you use to indicate it is solid? That is the one you need to test for, and perhaps not all of them. It depends entirely on how you set up your map. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Matias Persson
Member #15,093
May 2013
|
Alright, let's see. I made my map this is what it looks like in mappy This is what I did step for step in Mappy: I ran the code posted above, and it runs perfectly. The map works and all, but the collision doesn't work. I can walk into the ground if I wanted to. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Yes, but did you set the properties for each tile? Are there any solid tiles in your map? And what struct member did you use to indicate solidity? That is entirely up to you and we can't help you write a collision function until you do that and tell us about it. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Matias Persson
Member #15,093
May 2013
|
:O Solid blocks, where in mappy can I use that? |
Neil Walker
Member #210
April 2000
|
Mappy does not have collision detection, it is just a bunch of block. When you edit a block in mappy ignore where it says 'collision' for the four checkboxes, they aren't collision flags, they just called them that. Basically for every block/tile in mappy you can give it some data which varies from a number of booleans, a couple of shorts and a few ints and longs, e.g. imagine you have a block which is a struct: struct MAPPYBLOCK { boolean tl, tr, bl, br; short data1; short data2; int int1; int int2; long long1; long long2; } You assign whatever you want to these via the mappy editor and they mean whatever you want them to mean. In a map I made for example I made data1 to be an enum, e.g. Then for data1 I set a tile to be 0,1,2,3, etc You can use tl/tr/bl/br for the same thing if you want. It doesn't matter. What matters is you get the block data (using the MapGetBlock function) for the location the player is about to go onto then look at the data and see if any of the data matches. Does that make sense? Where I've got MappyStruct it's something like BLOCK_STR, I can't remember. Neil. wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie |
Matias Persson
Member #15,093
May 2013
|
Yeah, but I mean how do I make different blocks in mappy? |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Double click on one of the tiles displayed on the upper right in your tile set. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Matias Persson
Member #15,093
May 2013
|
:O I'm having problems again Code: 1bool IsSolid(BLKSTR* block) {
2 switch(block->user1)
3 {
4 case 0:
5 return false;
6 break;
7 case 1:
8 return true;
9 break;
10 }
11}
12
13bool collided() {
14 int minx = (x + speed)/mapblockwidth;
15 int miny = (y + speed)/mapblockheight;
16 int maxx = (x + 30 + speed)/mapblockwidth;
17 int maxy = (y + 30 + speed)/mapblockheight;
18
19 for (int tilex = minx ; tilex <= maxx ; ++tilex)
20 {
21 for (int tiley = miny ; tiley <= maxy ; ++tiley) {
22 BLKSTR* block = MapGetBlock(tilex , tiley);
23 if (IsSolid(block))
24 {
25 return true;
26 }
27 }
28 }
29 return false;
30}
1 if(al_key_down(&keyState, ALLEGRO_KEY_DOWN))
2 {
3 active = true;
4 if(!(collided))
5 y += speed;
6 dir = DOWN;
7 }
8 else if(al_key_down(&keyState, ALLEGRO_KEY_UP))
9 {
10 active = true;
11 if(!(collided))
12 y -= speed;
13 dir = UP;
14 }
15
16 if(al_key_down(&keyState, ALLEGRO_KEY_LEFT))
17 {
18 active = true;
19 if(!(collided))
20 x -= speed;
21 dir = LEFT;
22 }
23 else if(al_key_down(&keyState, ALLEGRO_KEY_RIGHT))
24 {
25 active = true;
26 if(!(collided))
27 x += speed;
28 dir = RIGHT;
29 }
Note: I set the user1 to 0 for the walkable tile & to 1 for the non-walkable tile. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Matias Persson said:
if(al_key_down(&keyState, ALLEGRO_KEY_DOWN)) { active = true;
You're actually comparing the address of the collided function to true or false there..., not calling the function()... You need to modify it a bit : 1bool collided(int newxspeed , int newyspeed) {
2 int minx = (x + newxspeed)/mapblockwidth;
3 int miny = (y + newyspeed)/mapblockheight;
4 int maxx = (x + 30 + newxspeed)/mapblockwidth;
5 int maxy = (y + 30 + newyspeed)/mapblockheight;
6
7 for (int tilex = minx ; tilex <= maxx ; ++tilex)
8 {
9 for (int tiley = miny ; tiley <= maxy ; ++tiley) {
10 BLKSTR* block = MapGetBlock(tilex , tiley);
11 if (IsSolid(block))
12 {
13 return true;
14 }
15 }
16 }
17 return false;
18}
19
20//...
21 int newxspeed = 0;
22 int newyspeed = 0;
23 if (al_key_down(&keyState , ALLEGRO_KEY_DOWN)) {newyspeed = speed;}
24 if (al_key_down(&keyState , ALLEGRO_KEY_UP)) {newyspeed = -speed;}
25 if (al_key_down(&keyState , ALLEGRO_KEY_LEFT)) {newxspeed = -speed;}
26 if (al_key_down(&keyState , ALLEGRO_KEY_RIGHT)) {newxspeed = speed;}
27
28 if (collided(newxspeed , 0)) {newxspeed = 0;}
29 if (collided(0 , newyspeed)) {newyspeed = 0;}
30
31 playerx += newxspeed;
32 playery += newyspeed;
This way it always checks the future position of the player against the map. If it collides x-wise, the x-speed is negated, and if it collides y-wise the y-speed is negated. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Matias Persson
Member #15,093
May 2013
|
Oh, I see. You know, I've been learning Allegro for about a week now, and I still don't know why I couldn't figure it out :O. But now it makes sense -.-. |
|
1
2
|