Sign in to follow this  
jbrennan

Getting 2D Platformer entity collision Correct (side-to-side + jumping/landing on heads)

Recommended Posts

I've been working on a 2D (tile based) 2D platformer for iOS and I've got basic entity collision detection working, but there's just something *not right* about it and I can't quite figure out how to solve it.

There are 2 forms of collision between player entities as I can tell, either the two players (human controlled) are hitting each other side-to-side (i. e. pushing against one another), or one player has jumped on the head of the other player (naturally, if I wanted to expand this to player vs enemy, the effects would be different, but the types of collisions would be identical, just the reaction should be a little different).

In my code I believe I've got the side-to-side code working: If two entities press against one another, then they are both moved back on either side of the intersection rectangle so that they are just pushing on each other.

I also have the "landed on the other player's head" part working.

The real problem is, if the two players are currently pushing up against each other, and one player jumps, then at one point as they're jumping, the height-difference threshold that counts as a "land on head" is passed and then it registers as a jump. As a life-long player of 2D Mario Bros style games, this feels incorrect to me, but I can't quite figure out how to solve it.

My code: (it's really Objective-C but I've put it in pseudo C-style code just to be simpler for non ObjC readers)

[code]

void checkCollisions() {

// For each entity in the scene, compare it with all other entities (but not with one it's already compared against)
for (int i = 0; i < _allGameObjects.count(); i++) {

// GameObject is an Entity
GEGameObject *firstGameObject = _allGameObjects.objectAtIndex(i);


// Don't check against yourself or any previous entity
for (int j = i+1; j < _allGameObjects.count(); j++) {


GEGameObject *secondGameObject = _allGameObjects.objectAtIndex(j);

// Get the collision bounds for both entities, then see if they intersect
// CGRect is a C-struct with an origin Point (x, y) and a Size (w, h)

CGRect firstRect = firstGameObject.collisionBounds();
CGRect secondRect = secondGameObject.collisionBounds();

// Collision of any sort
if (CGRectIntersectsRect(firstRect, secondRect)) {

////////////////////////////////
// //
// Check for jumping first (???)
// //
////////////////////////////////
if (firstRect.origin.y > (secondRect.origin.y + (secondRect.size.height * 0.7))) {

// the top entity could be pretty far down/in to the bottom entity....
firstGameObject.didLandOnEntity(secondGameObject);

} else if (secondRect.origin.y > (firstRect.origin.y + (firstRect.size.height * 0.7))) {

// second entity was actually on top....
secondGameObject.didLandOnEntity.(firstGameObject);

} else if (firstRect.origin.x > secondRect.origin.x && firstRect.origin.x < (secondRect.origin.x + secondRect.size.width)) {

// Hit from the RIGHT

CGRect intersection = CGRectIntersection(firstRect, secondRect);

// The NUDGE just offsets either object back to the left or right
// After the nudging, they are exactly pressing against each other with no intersection
firstGameObject.nudgeToRightOfIntersection(intersection);
secondGameObject.nudgeToLeftOfIntersection(intersection);


} else if ((firstRect.origin.x + firstRect.size.width) > secondRect.origin.x) {
// hit from the LEFT

CGRect intersection = CGRectIntersection(firstRect, secondRect);
secondGameObject.nudgeToRightOfIntersection(intersection);
firstGameObject.nudgeToLeftOfIntersection(intersection);


}
}

}
}
}
[/code]


I think my collision detection code is pretty close, but obviously I'm doing something a little wrong. I really think it's to do with the way my jumps are checked (I wanted to make sure that a jump could happen from an angle (instead of if the falling player had been at a right angle to the player below).

Can someone please help me here? I haven't been able to find many resources on how to do this properly (and thinking like a game developer is new for me). Thanks in advance!

Share this post


Link to post
Share on other sites
You'll probably want to make the direction of movement a factor in collision detection. For example, if a character is moving up (i.e. has started jumping), he can't really be landing on his opponent's head (since "landing" implies that the character is falling or has passed the peak of his jump).

Share this post


Link to post
Share on other sites
[quote name='Anthony Serrano' timestamp='1306947399' post='4818328']
You'll probably want to make the direction of movement a factor in collision detection.
[/quote]

Aha! This worked perfectly, and such a simple solution, too. Boy am I new at this :)

Thanks so much!

Share this post


Link to post
Share on other sites

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