|
Smooth scrolling collision |
Lance5057
Member #12,864
May 2011
|
Ok I'm making a top down style game that uses smooth scrolling that goes 2 pixels per frame. The issue is that the collision doesn't work well. If I put the character on a single tile surrounded by walls he can still wiggle around inside or if he goes around an edge it'll often cut the corner and wind up in the wall. I can't figure out how to fix this no matter what I try. Movement code 1 //+++Key_UP++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
2 if(key[KEY_UP])
3 {
4 if(levelCurrent[levelx+10][levely+10]==1)
5 {
6 if(y<0){
7 levely--;
8 y=32;
9 }
10 y-=2;
11 }
12 }
13 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
14
15 //+++Key_DOWN++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
16 if(key[KEY_DOWN])
17 {
18 if(levelCurrent[levelx+10][levely+11]==1)
19 {
20 if(y>32){
21 levely++;
22 y=0;
23 }
24 y+=2;
25 }
26
27 }
28 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
29
30 //+++Key_LEFT++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
31 if(key[KEY_LEFT])
32 {
33 if(levelCurrent[levelx+10][levely+10]==1)
34 {
35 if(x<0){
36 levelx--;
37 x=32;
38 }
39 x-=2;
40 }
41 }
42 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
43
44 //+++Key_RIGHT+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
45 if(key[KEY_RIGHT])
46 {
47 if(levelCurrent[levelx+11][levely+10]==1)
48 {
49 if(x>32){
50 levelx++;
51 x=0;
52 }
53 x+=2;
54 }
55 }
56 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
Drawing code //draw levelCurrent chunk al_set_target_bitmap(buffer); for(b=-1;b<21;b++){ for(c=-1;c<21;c++){ if(b*32-y>=0&& b*32-y<=640&& c*32-x>=0&& c*32-x<=640&& levelCurrent[c+levelx][b+levely]==1){ al_draw_bitmap(wall,(c*32)-x,(b*32)-y+32,0); } } } Any help would be greatly appreciated. Thanks |
OnlineCop
Member #7,919
October 2006
|
I'm having a hard time understanding what your current movement code is doing. You have your levelCurrent array with both levelx and levely, but there doesn't appear to be any indication of what it does. You can usually do one of two things: I've always stored things like walls, other characters, etc. as individual objects, and then just iterate over those objects to see when things are trying to collide. struct Object { unsigned int x, y; unsigned int width, height; // ... }; Create your objects (your walls, your characters, etc.) off of something like this. Then, when you try to move onto it, you test it like this: for (i = 0; i < number_of_objects_on_screen; ++i) { if (is_collision(my_player, the_object[i], direction_my_player_is_moving) == true) // Handle what should happen when it collides, like preventing it from moving }
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Create a rectangle class. Give your player and your walls a rectangle object. When you do collision, check whether the future player rectangle overlaps the wall rectangles for each wall that your player could be near. 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 |
weapon_S
Member #7,859
October 2006
|
Separate actions/input from movement/physics; and separate level coordinates from screen coordinates. Make functions/structs/classes that do that for you. |
Lance5057
Member #12,864
May 2011
|
Huh I never actually thought of doing the collision checking separate from the movement. Thanks for your help. |
Audric
Member #907
January 2001
|
No, checking collision as a prerequisite to movement is fine. Many people do the collision check after the movement has taken place, and then they see they can't determine how to move the character back into non-collision place. About your code, there's certainly an issue with the mix of [levelx+10][levely+10], [levelx+11][levely+10]. What are 10 and 11 ? 1// character_width and character_height are the size of the player in pixels
2if(key[KEY_UP])
3{
4 // Check the pixel that is 2px above character: is it on a walkable tile
5 if(levelCurrent[x/32][(y-2)/32]==1)
6 {
7 y-=2;
8 }
9}
10if(key[KEY_DOWN])
11{
12 // Check the pixel that is 2px below character: is it on a walkable tile
13 if(levelCurrent[x/32][(y+(character_height-1)+2)/32]==1)
14 {
15 y+=2;
16 }
17}
18if(key[KEY_LEFT])
19{
20 if(levelCurrent[(x-2)/32][y/32]==1)
21 {
22 x-=2;
23 }
24}
25if(key[KEY_RIGHT])
26{
27 if(levelCurrent[(x+(character_width-1)+2)/32][y/32]==1)
28 {
29 x+=2;
30 }
31}
edit Wait, I noticed my version is too simplified for full x and y freedom of movement. As long as the character is smaller than one tile, you can use checks: if(key[KEY_UP]) { // Check the 2 pixels that are above the character's top angles if(levelCurrent[x/32][(y-2)/32]==1 && levelCurrent[(x+(character_width-1))/32][(y-2)/32]==1) y-=2; } if(key[KEY_DOWN]) { // Check the 2 pixels that are below the character's bottom angles if(levelCurrent[x/32][(y+(character_height-1)+2)/32]==1 && levelCurrent[(x+(character_width-1))/32][(y+(character_height-1)+2)/32]==1) y+=2; }
... |
Lance5057
Member #12,864
May 2011
|
I'm just gonna post here again since I'm having issues with scrolling still. 2nd issue is now whenever I move once I'm fully on a tile I'll jump to the next tile and then I can move normally till I pass another tile. It's kinda hard to explain but it basically looks like I'm jumping a tile everytime the array shifts. I'll post the new code cause I've changed some things: Movement Code: 1//+++Key_UP++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
2 if(key[KEY_UP])
3 {
4 if(levelCurrent[x/32][(y-2)/32].walkable==1 && levelCurrent[(x+(32-1))/32][(y-2)/32].walkable==1)
5 {
6 y--;
7 }
8 }
9
10 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
11
12 //+++Key_DOWN++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
13 if(key[KEY_DOWN])
14 {
15 y++;
16 }
17 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
18
19 //+++Key_LEFT++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
20 if(key[KEY_LEFT])
21 {
22 x--;
23 }
24 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
25
26 //+++Key_RIGHT+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
27 if(key[KEY_RIGHT])
28 {
29 x++;
30 }
31 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
Drawing Code: //draw levelCurrent chunk for(b=0;b<20;b++){ for(c=0;c<20;c++){ if(b+(y/32)<21&& b+(y/32)>-1&& c+(x/32)<21&& c+(x/32)>-1&& levelCurrent[c+(x/32)][b+(y/32)].walkable==1){ al_draw_bitmap(wall,(c*32)-x,(b*32)-y+32,0); } } }
|
weapon_S
Member #7,859
October 2006
|
I don't see where your player gets drawn. (Or is it fixed in the center or something?) Am I right to assume the dimensions of your character are also 32x32? Quote: (x+(32-1))/32
What does this do... in the code for y directional collision? |
Lance5057
Member #12,864
May 2011
|
Character gets drawn at the center at 320,352. Yes all my sprites so far are 32x32. Here's everything I've got so far: (The size limit wouldn't let me post it all so I added an attachement) |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Lance5057 said: Looking at the (x+(32-1))/32 Im not entirely sure what thats use is. It was given to me above and I just used it. x + (32 - 1) is the right edge of your sprite. After dividing it by 32, it is the grid location of the right edge of your sprite. Files.zip : main.cpp lines 207-213 said:
if(key[KEY_UP]) { if(levelCurrent[x/32][(y-2)/32].walkable==1 && levelCurrent[(x+(32-1))/32][(y-2)/32].walkable==1) { y-=2; } }
This code tests whether the future position of the top left and top right corners of your sprite is walkable. You need to do the same thing for the other three directions. When moving down, test the bottom left and bottom right corners of your sprite against their grid locations. When moving left, test the top left and bottom left corners of the sprite. When moving right, test the top right and bottom right corners of the sprite. 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 |
Lance5057
Member #12,864
May 2011
|
Ok I found the error in the collision. I forgot to add in the characters x and y so it was him colliding not the top left corner of the screen. I'm still having the issue where the map jumps whole tiles on occasion though. |
|