|
Pushing outside of a tile collision. |
DaGamesta
Member #13,887
January 2012
|
So, in my game I have a 16x16 grid and collisions via rectangles to simplify things. However, the player is not locked to a grid and therefore can have a vertical and horizontal speed. Because it's on a 16x16 grid, it's easy to move the player's x/y position so as to move outside of whatever collision the player is currently in. (with a wall, for example) However, I can't seem to figure out how to determine, in the case of there being both a vertical and horizontal shift in position that leads to a collision, whether to shift the player vertically or horizontally to move outside of the collision. Any ideas? |
AMCerasoli
Member #11,955
May 2010
|
Edit... hahahaha my bad... I was going to create a new thread... Sorry.
|
J-Gamer
Member #12,491
January 2011
|
I don't know if you can generalize this, but here's an approach if he's going NW: Check whether his upper-left corner is going to hit the bottom of the tile he's colliding with, and if he does, you can set his y coordinate to something where he doesn't collide anymore(player.y = tile.y + tile.h) and set his y speed to 0, so he won't collide with it anymore(or make him bounce, whatever). The same goes for the tiles right side, but switch y with x and h with w. Now, to know which side he's going to hit, you can solve that with a pretty easy equation: int x_0 = -(player.x_speed*player.y)/player.y_speed + player.x; if(x_0 > tile.x && x_0 < tile.x + tile.w) { //Player collides with bottom } else { //Player collides with right side }
" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo |
DaGamesta
Member #13,887
January 2012
|
Ah, yes, determining whether or not there was a horizontal or vertical collision beforehand... Personally it's easier to simply record a prevX and prevY before calculating movement and use that instead of the equation you showed. The issue with that is that it's possible to be colliding neither vertically or horizontally with an object the moment before you collide with it. That would be the case that I'm having issues with, what to do in such cases, I mean. I'm not sure I just wanna default to being pushed horizontally or vertically out of the collision in such cases since it may look kind of strange. |
J-Gamer
Member #12,491
January 2011
|
You might let the player bounce instead: invert the colliding speed and multiply it with a certain factor(because there will always be some energy loss in a collision) " There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo |
DaGamesta
Member #13,887
January 2012
|
That would have the same issues, regarding whether I should be inverting horizontally or vertically, as that is how it would really bounce off of a flat surface. In other words, either vspeed *= -1 or hspeed *= -1, not both. That, and this is an action rpg overhead adventure game, having the player bounce would be ridiculous, vspeed and hspeed was just a method of getting my point across, I don't actually assign a speed to my character, I just move him. |
weapon_S
Member #7,859
October 2006
|
{"name":"605399","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/0\/60c90f9ec480f0cd21958995504d392a.png","w":631,"h":340,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/0\/60c90f9ec480f0cd21958995504d392a"} |
DaGamesta
Member #13,887
January 2012
|
The picture you show is in the case of a wall, I'm talking about determining whether the x or the y position should be appended in the case of a collision between one rectangle and another. The actual appending of the position is easy after that. At any rate, in the meantime I've just defaulted to appending the x position by default, and it doesn't seem to look as horrible as I thought, though I'd still be interested in this topic in case I made some more complicated game in the future. |
J-Gamer
Member #12,491
January 2011
|
You need to determine which side it's going to hit. You can work that out with the technique I showed you before. If it hits the x-aligned side, you want to change the y value, else change the x value. " There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo |
weapon_S
Member #7,859
October 2006
|
I felt really 'educational' last night. The solution showed in the picture is actually 'wrong'. I suspect you use the same solution... J-Gamer said: You need to determine which side it's going to hit. Wrong. 'Right': Treat the speed as a two dimensional vector/variable. You shouldn't 'add a value based on what kind of collision'. You should 'roll back the object on it's trajectory'; thus you always handle vertical and horizontal speed: in some cases one of them will be zero. 1//Time is relative to beginning of timestep i.e. not absolute; time * speed = distance traveled in this timestep.
2float ct1 = one_timestep; //first time of collision
3
4//Find minimum time of collision
5for(all horizontal){
6 float found_horizontal_collision_time;
7 if( found_horizontal_collision_time < ct1 )
8 ct1 = found_horizontal_collision_time
9}
10
11for(all vertical){
12 float found_vertical_collision_time;
13 if( found_vertical_collision_time < ct1 )
14 ct1 = found_vertical_collision_time
15}
16
17x_pos = (int) floor(x_speed * ct1);
18y_pos = (int) floor(y_speed * ct1);
19//You can also 'roll back' using negative speed... but it will get the same result.
If you want (real) bounce, you'll have to really use (simple) vector math.
|
Gabriel Campos
Member #12,034
June 2010
|
In other post reynaldo said... "Make a rectangle class. Make a RectanglesOverlap function. Give your blocks and your player a rectangle. Use the RectanglesOverlap function. Test the future position. If it won't overlap anything, then it is safe to move there. If it will overlap something, reduce it's velocity in that direction until it would no longer overlap. Continue to check against all remaining objects. And try not to put everything on one line." I use this and think that is the best way to check collion in tile maps... any doubt ask..
|
DaGamesta
Member #13,887
January 2012
|
I'd like to point out that I considered that option, but it doesn't seem efficient enough. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Computers can do millions of calculations per second. It'll be efficient enough for most purposes. If it actually gets to the point where it is not, you have other methods to reduce the number of checks performed. 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 |
|