whats wrong with my collision reaction

Started by
2 comments, last by graveyard filla 15 years, 5 months ago
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();
            }


FTA, my 2D futuristic action MMORPG
Advertisement
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
                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?
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
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!!!!
FTA, my 2D futuristic action MMORPG

This topic is closed to new replies.

Advertisement