Skip to content

Commit

Permalink
Implement OrbitalElement method to determine whether to collide
Browse files Browse the repository at this point in the history
  • Loading branch information
jdetloff committed May 26, 2013
1 parent f07da16 commit 3990d17
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 45 deletions.
52 changes: 10 additions & 42 deletions GraceWorld/OneWayEdgeCollisionDetector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#import "Box2d/Box2D.h"
#import "OrbitalElement.h"
#import "OrbitalSurface.h"
#import "OrbitalRect.h"
#include "OneWayEdgeCollisionDetector.h"
Expand All @@ -21,14 +22,16 @@ int locationOfPointRelativeToEdge(b2Vec2 point, b2Body *edgeBody) {


void OneWayEdgeCollisionDetector::BeginContact(b2Contact *contact) {
if (ContactIsFromBelow(contact)) {
b2Body *platformBody = this->GetBodyFromContact(contact, false);
OrbitalElement *platform = (__bridge OrbitalElement *)platformBody->GetUserData();

BOOL playerShouldCollide = [player shouldCollidePlayer:player withElement:platform contact:contact];
if (playerShouldCollide) {
[player beginContact:contact];
}

b2Body *platform = this->GetBodyFromContact(contact, false);
NSObject *obj = (__bridge NSObject *)platform->GetUserData();
if ([obj isKindOfClass:[OrbitalRect class]]) {
[(OrbitalRect *)obj boyBeganContact];
if ([platform isKindOfClass:[OrbitalRect class]]) {
[(OrbitalRect *)platform boyBeganContact];
}
}

Expand Down Expand Up @@ -57,8 +60,6 @@ void OneWayEdgeCollisionDetector::PreSolve(b2Contact* contact, const b2Manifold*
return;
}

bool solid = ContactIsFromBelow(contact);

b2Body *platform = this->GetBodyFromContact(contact, false);
OrbitalSurface *surface = (__bridge OrbitalSurface *)platform->GetUserData();
if (surface) {
Expand All @@ -72,9 +73,9 @@ void OneWayEdgeCollisionDetector::PreSolve(b2Contact* contact, const b2Manifold*
[surface boyMadeContactOnSide:direction];
}

BOOL playerShouldCollide = [player shouldCollidePlayer:player withElement:surface contact:contact];

b2Vec2 boyVelocity = collidingBoy->GetLinearVelocity();
if (boyVelocity.y <= 0.01 && solid && (!surface || surface.allowsCollision)) {
if (playerShouldCollide && (!surface || surface.allowsCollision)) {
return;
}

Expand All @@ -100,36 +101,3 @@ b2Body* OneWayEdgeCollisionDetector::GetBodyFromContact(b2Contact *contact, bool

void OneWayEdgeCollisionDetector::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) {
}


bool OneWayEdgeCollisionDetector::ContactIsFromBelow(b2Contact *contact) {
b2Vec2 boyPosition = player.physicsBody->GetPosition();
b2PolygonShape *boyShape = (b2PolygonShape *)player.physicsBody->GetFixtureList()->GetShape();

b2Vec2 lowestVertex = boyShape->GetVertex(0);
NSInteger vertexCount = boyShape->GetVertexCount();
for (int i = 1; i < vertexCount; i++) {
b2Vec2 vertex = boyShape->GetVertex(i);
if (vertex.y > lowestVertex.y) {
lowestVertex = vertex;
}
}

static const CGFloat footError = 0.2;
CGFloat footPosition = boyPosition.y - lowestVertex.y + footError;

int numPoints = contact->GetManifold()->pointCount;

BOOL solid = NO;

b2WorldManifold worldManifold;
contact->GetWorldManifold( &worldManifold );
for (int i = 0; i < numPoints; i++) {
if (worldManifold.points[i].y < footPosition) {
solid = YES;
break;
}
}

return solid;
}
6 changes: 4 additions & 2 deletions GraceWorld/OrbitalElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
#import "Box2d/Box2d.h"
#import <Foundation/Foundation.h>


@class PlayerPhysicsWrapper;
@interface OrbitalElement : NSObject

@property (nonatomic, assign) b2Body *physicsBody;

@end
- (BOOL)shouldCollidePlayer:(PlayerPhysicsWrapper *)boy withElement:(OrbitalElement *)element contact:(b2Contact *)contact;

@end
4 changes: 4 additions & 0 deletions GraceWorld/OrbitalElement.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@

@implementation OrbitalElement

- (BOOL)shouldCollidePlayer:(PlayerPhysicsWrapper *)boy withElement:(OrbitalElement *)element contact:(b2Contact *)contact {
return YES;
}

@end
46 changes: 45 additions & 1 deletion GraceWorld/PlayerPhysicsWrapper.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ @implementation PlayerPhysicsWrapper {
BOOL _standing;
}

- (id)initWithb2Body:(b2Body *)body {
- (id)init {
self = [super init];
if (self) {
_bottomContacts = [[NSMutableArray alloc] init];
Expand All @@ -24,6 +24,50 @@ - (id)initWithb2Body:(b2Body *)body {
}


- (BOOL)shouldCollidePlayer:(PlayerPhysicsWrapper *)boy withElement:(OrbitalElement *)element contact:(b2Contact *)contact {
if (contact->GetFixtureA() == _sensorFixture || contact->GetFixtureB() == _sensorFixture) {
return NO;
}

BOOL solid = [self contactIsFromBelow:contact];
b2Vec2 boyVelocity = self.physicsBody->GetLinearVelocity();
return (boyVelocity.y <= 0.01 && solid);
}


- (BOOL)contactIsFromBelow:(b2Contact *)contact {
b2Vec2 boyPosition = self.physicsBody->GetPosition();
b2PolygonShape *boyShape = (b2PolygonShape *)self.physicsBody->GetFixtureList()->GetShape();

b2Vec2 lowestVertex = boyShape->GetVertex(0);
NSInteger vertexCount = boyShape->GetVertexCount();
for (int i = 1; i < vertexCount; i++) {
b2Vec2 vertex = boyShape->GetVertex(i);
if (vertex.y > lowestVertex.y) {
lowestVertex = vertex;
}
}

static const CGFloat footError = 0.2;
CGFloat footPosition = boyPosition.y - lowestVertex.y + footError;

int numPoints = contact->GetManifold()->pointCount;

BOOL solid = NO;

b2WorldManifold worldManifold;
contact->GetWorldManifold( &worldManifold );
for (int i = 0; i < numPoints; i++) {
if (worldManifold.points[i].y < footPosition) {
solid = YES;
break;
}
}

return solid;
}


- (void)beginContact:(b2Contact *)contact {
NSValue *val = [NSValue valueWithPointer:contact];
[_bottomContacts addObject:val];
Expand Down

0 comments on commit 3990d17

Please sign in to comment.