Skip to content

Commit f8e3313

Browse files
committed
Making CCPhysicsBody.type automatically deferred in a collision callback.
Former-commit-id: 5f81023
1 parent f256ba8 commit f8e3313

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

UnitTests/CCPhysicsTests.m

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#import "CCPhysics+ObjectiveChipmunk.h"
1313

1414

15-
@interface CCPhysicsTests : XCTestCase
15+
@interface CCPhysicsTests : XCTestCase <CCPhysicsCollisionDelegate>
1616

1717
@end
1818

@@ -378,6 +378,8 @@ -(void)testDynamicAnchorPoint
378378

379379
node.rotation = 90;
380380
XCTAssert(ccpDistance(node.position, CGPointZero) == 0.0, @"");
381+
382+
[physicsNode onExit];
381383
}
382384

383385
-(void)testStaticAnchorPoint
@@ -399,6 +401,8 @@ -(void)testStaticAnchorPoint
399401

400402
node.rotation = 90;
401403
XCTAssert(ccpDistance(node.position, CGPointZero) == 0.0, @"");
404+
405+
[physicsNode onExit];
402406
}
403407

404408
-(void)testCollisionGroups
@@ -428,6 +432,8 @@ -(void)testCollisionGroups
428432
// Both nodes should be at (0, 0)
429433
XCTAssertTrue(CGPointEqualToPoint(node1.position, CGPointZero) , @"");
430434
XCTAssertTrue(CGPointEqualToPoint(node2.position, CGPointZero) , @"");
435+
436+
[physicsNode onExit];
431437
}
432438

433439
-(void)testAffectedByGravity
@@ -461,6 +467,8 @@ -(void)testAffectedByGravity
461467

462468
// Node2 should stay at (0, 0)
463469
XCTAssertTrue(node2.position.y == 0.0, @"");
470+
471+
[physicsNode onExit];
464472
}
465473

466474
-(void)testAllowsRotation
@@ -542,6 +550,8 @@ -(void)testAllowsRotation
542550

543551
XCTAssert(node.physicsBody.body.moment < INFINITY, @"");
544552
}
553+
554+
[physicsNode onExit];
545555
}
546556

547557
-(void)testBodyType
@@ -671,6 +681,50 @@ -(void)testBreakingJoints
671681
XCTAssert(!joint2.valid, @"");
672682
XCTAssert(joint3.valid, @"");
673683
XCTAssert(joint4.valid, @"");
684+
685+
[physics onExit];
686+
}
687+
688+
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair theStaticOne:(CCNode *)nodeA theDynamicOne:(CCNode *)nodeB
689+
{
690+
nodeB.physicsBody.type = CCPhysicsBodyTypeStatic;
691+
692+
// TODO not sure if we should hide the deferred nature or not... Hrm.
693+
XCTAssertEqual(nodeB.physicsBody.type, CCPhysicsBodyTypeDynamic, @"");
694+
695+
return FALSE;
696+
}
697+
698+
-(void)testBodyTypeCollisions
699+
{
700+
CCPhysicsNode *physicsNode = [CCPhysicsNode node];
701+
physicsNode.collisionDelegate = self;
702+
physicsNode.gravity = ccp(0, -100);
703+
704+
CCNode *node1 = [CCNode node];
705+
node1.physicsBody = [CCPhysicsBody bodyWithCircleOfRadius:1.0 andCenter:CGPointZero];
706+
node1.physicsBody.type = CCPhysicsBodyTypeStatic;
707+
node1.physicsBody.collisionType = @"theStaticOne";
708+
[physicsNode addChild:node1];
709+
710+
CCNode *node2 = [CCNode node];
711+
node2.position = ccp(0, 10);
712+
node2.physicsBody = [CCPhysicsBody bodyWithCircleOfRadius:1.0 andCenter:CGPointZero];
713+
node2.physicsBody.type = CCPhysicsBodyTypeDynamic;
714+
node2.physicsBody.collisionType = @"theDynamicOne";
715+
[physicsNode addChild:node2];
716+
717+
// Force entering the scene to set up the physics objects.
718+
[physicsNode onEnter];
719+
720+
// Step the physics for a while.
721+
for(int i=0; i<100; i++){
722+
[physicsNode fixedUpdate:1.0/100.0];
723+
}
724+
725+
XCTAssertEqual(node2.physicsBody.type, CCPhysicsBodyTypeStatic, @"");
726+
727+
[physicsNode onExit];
674728
}
675729

676730
// TODO

cocos2d/CCPhysicsBody.m

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,16 @@ -(void)setAllowsRotation:(BOOL)allowsRotation
246246
static cpBodyType ToChipmunkBodyType[] = {CP_BODY_TYPE_DYNAMIC, /*CP_BODY_TYPE_KINEMATIC,*/ CP_BODY_TYPE_STATIC};
247247

248248
-(CCPhysicsBodyType)type {return ToCocosBodyType[_body.type];}
249-
-(void)setType:(CCPhysicsBodyType)type {_body.type = ToChipmunkBodyType[type];}
249+
-(void)setType:(CCPhysicsBodyType)type
250+
{
251+
ChipmunkSpace *space = self.physicsNode.space;
252+
if(space && cpSpaceIsLocked(space.space)){
253+
// Chipmunk body type cannot be changed from within a callback, need to make this safe.
254+
[space addPostStepBlock:^{_body.type = ToChipmunkBodyType[type];} key:self];
255+
} else {
256+
_body.type = ToChipmunkBodyType[type];
257+
}
258+
}
250259

251260
//MARK: Collision and Contact:
252261

0 commit comments

Comments
 (0)