Sign in to follow this  

whats wrong with my collision reaction

This topic is 3313 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to get movement to work in a simple 2d tile game using AABB's To factor in time I do iterative collision checks.. for wall collision, i just check each tile passed over throughout the whole movement. for object->object collision, i break it into steps based on the width/height of the character. It works great for doing character->wall collision and character->character collision alone... but when you collide and hit both character and wall at the same time (the first if statement is true) then it breaks.. acts jumpy and you're able to walk through character and wall... I basically just check for both collision types, and if one had a collision i move to that point... and if both are detected, I move to the closest collision (as that should happen first..).. if no collisions then I just move to my destination... Why does this work fine except in the first if, where both collisions occurred? Does the distance check to determine which to move to not work for some reason? I hope this is something obvious and dumb I'm missing... maybe just need someone else to look at it... thanks
            CollDetResult objColl = CollisionDetectionObjects(character, gameTime);
            CollDetResult wallColl = CollisionDetectionMap(character, gameTime, map);

            
            if (objColl.DidCollide && wallColl.DidCollide)
            {
                if (Vector2.Distance(objColl.NewPosition, character.Position)
                    < Vector2.Distance(wallColl.NewPosition, character.Position))
                    character.Position = wallColl.NewPosition;
                else
                    character.Position = objColl.NewPosition;

                character.StopMoving();
            }
            else if (objColl.DidCollide)
            {
                character.Position = objColl.NewPosition;
                character.StopMoving();
            }
            else if (wallColl.DidCollide)
            {
                character.Position = wallColl.NewPosition;
                character.StopMoving();
            }
            else
            {
                //both wall and obj should be same here, we can use either
                character.Position = wallColl.NewPosition;
                character.StopMoving();
            }


Share this post


Link to post
Share on other sites
Say character A (the one colliding with both character B and the Wall) has a collision to his left and right (B and Wall, respectively). Where exactly was he supposed to go that it would look right? The only options are either 1) up or down (if there's no floor below him) or 2) don't go through the wall. Going through walls is never gonna look right no matter how you try to do it. Of course that opens up the question of what to do with the character vs. character.

There are many options, some of which include:
- Character A becomes uncollidable to other characters (typically this is accompanied by a flash to denote that nothing can hurt him for a second, which solves the problem of the collision happening 20 times, but use your imagination ;) )
- Character *B* moves out of the way. If you have which character is character B in your "objColl" object, you tell it to handle moving to the new position. This can still lead to difficulties if you have say, 3 characters colliding at the same time next to a wall. There's always a way to fix things though! Absolute worst-case scenerio, restart the collision routine with the updated positions (brute force the beast to function properly since it will most likely hardly ever happen). Or... find a more dynamic solution (probably overkill).

Cheers
-Scott

Share this post


Link to post
Share on other sites
                if (Vector2.Distance(objColl.NewPosition, character.Position)
< Vector2.Distance(wallColl.NewPosition, character.Position))
character.Position = wallColl.NewPosition;
else
character.Position = objColl.NewPosition;


Aren't those two backwards? Shouldn't it move the smaller distance and not the larger distance?

Share this post


Link to post
Share on other sites
Quote:
Original post by popsoftheyear
Say character A (the one colliding with both character B and the Wall) has a collision to his left and right (B and Wall, respectively). Where exactly was he supposed to go that it would look right?


Let me explain better how the implementation of the 2 collision types work...

character->character collision
are both moving? if true, move both characters to 'middle point'
else, move the mobile character to the edge of the immobile character

character->wall collision
move to edge of wall

In this case, the character that is moving should push to the edge of the character that is immobile. If they are both moving, they meet 'halfway'..

I just want collision to be simple like in UO. You hit a wall, you stop. Hit another guy, you stop. 2 guys hit each other, they both stop (no one can be 'pushed' and should ever be able to 'push' someone else under any circumstances).

I have handled my collision exactly like this and it seems to work great, except when I hit both wall and character.


Quote:

- Character A becomes uncollidable to other characters (typically this is accompanied by a flash to denote that nothing can hurt him for a second, which solves the problem of the collision happening 20 times, but use your imagination ;) )


This is not acceptable - characters are not 'hurt' from colliding. They just can't move any further...

Quote:

- Character *B* moves out of the way. If you have which character is character B in your "objColl" object, you tell it to handle moving to the new position. This can still lead to difficulties if you have say, 3 characters colliding at the same time next to a wall. There's always a way to fix things though! Absolute worst-case scenerio, restart the collision routine with the updated positions (brute force the beast to function properly since it will most likely hardly ever happen). Or... find a more dynamic solution (probably overkill).


This is basically what I'm doing now, as per my description above...


Quote:


Aren't those two backwards? Shouldn't it move the smaller distance and not the larger distance?


You're right - good eye. Unfortunately flipping the operand does nothing as I'm still suffering the same problem - In fact I think this was just an error in my pasted code, not actual implementation. I have def. flipped that sign a few times when I started getting desperate to get this thing working [grin]


Anyway.. after stepping away from the code, I believe I know what my problem is..

If both wall & object collision occur, we can't just move to the closest spot as it's still possible a collision of the 'other' type exists on that spot. I think this is a flaw in me doing the 2 collision types independently...

I'm thiking I need to integrate the 2 collision algos. Probably what I need to do is calculate the 'middle edge' - that is, the 'edge' where I will lay flush with both the wall AND the character. Doing them independently just ain't working..

thanks a lot guys for your help and any further suggestions!!!!

Share this post


Link to post
Share on other sites

This topic is 3313 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this