Skip to content

Commit b16deea

Browse files
committed
Merge branch 'develop-v3' into 64-bit
Former-commit-id: 1542614
2 parents b1add5e + 9aa36f1 commit b16deea

File tree

7 files changed

+142
-8
lines changed

7 files changed

+142
-8
lines changed

UnitTests/CCPhysicsTests.m

Lines changed: 124 additions & 2 deletions
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

@@ -307,7 +307,7 @@ -(void)testBasicSequences9
307307

308308
TestBasicSequenceHelper(self, physicsNode, parent, node, body);
309309
}
310-
310+
311311
-(void)testBasicSequences10
312312
{
313313
CCPhysicsNode *physicsNode = [CCPhysicsNode node];
@@ -333,6 +333,78 @@ -(void)testBasicSequences10
333333
TestBasicSequenceHelper(self, physicsNode, parent, node, body);
334334
}
335335

336+
-(void)testBasicSequences11
337+
{
338+
CCPhysicsNode *physicsNode = [CCPhysicsNode node];
339+
340+
CCNode *parent = [CCNode node];
341+
parent.contentSize = CGSizeMake(25, 35);
342+
parent.anchorPoint = ccp(0.3, 0.7);
343+
parent.position = ccp(20, 60);
344+
parent.rotation = -15;
345+
parent.scaleX = 1.5;
346+
parent.scaleY = 8.0;
347+
348+
CCNode *node = [CCNode node];
349+
node.contentSize = CGSizeMake(30, 30);
350+
node.anchorPoint = ccp(0,0);
351+
node.position = ccp(100, 100);
352+
node.rotation = 30;
353+
node.scaleX = 2.0;
354+
node.scaleY = 3.0;
355+
356+
CCPhysicsBody *body = [CCPhysicsBody bodyWithCircleOfRadius:1.0 andCenter:CGPointZero];
357+
body.type = CCPhysicsBodyTypeStatic;
358+
359+
TestBasicSequenceHelper(self, physicsNode, parent, node, body);
360+
}
361+
362+
-(void)testDynamicAnchorPoint
363+
{
364+
CCPhysicsNode *physicsNode = [CCPhysicsNode node];
365+
366+
CCNode *node = [CCNode node];
367+
node.contentSize = CGSizeMake(2, 2);
368+
node.anchorPoint = ccp(0.5, 0.5);
369+
XCTAssert(ccpDistance(node.position, CGPointZero) == 0.0, @"");
370+
371+
node.physicsBody = [CCPhysicsBody bodyWithCircleOfRadius:1.0 andCenter:CGPointZero];
372+
node.physicsBody.type = CCPhysicsBodyTypeDynamic;
373+
XCTAssert(ccpDistance(node.position, CGPointZero) == 0.0, @"");
374+
375+
[physicsNode addChild:node];
376+
[physicsNode onEnter];
377+
XCTAssert(ccpDistance(node.position, CGPointZero) == 0.0, @"");
378+
379+
node.rotation = 90;
380+
XCTAssert(ccpDistance(node.position, CGPointZero) == 0.0, @"");
381+
382+
[physicsNode onExit];
383+
}
384+
385+
-(void)testStaticAnchorPoint
386+
{
387+
CCPhysicsNode *physicsNode = [CCPhysicsNode node];
388+
389+
CCNode *node = [CCNode node];
390+
node.contentSize = CGSizeMake(2, 2);
391+
node.anchorPoint = ccp(0.5, 0.5);
392+
XCTAssert(ccpDistance(node.position, CGPointZero) == 0.0, @"");
393+
394+
node.physicsBody = [CCPhysicsBody bodyWithCircleOfRadius:1.0 andCenter:CGPointZero];
395+
node.physicsBody.type = CCPhysicsBodyTypeStatic;
396+
XCTAssert(ccpDistance(node.position, CGPointZero) == 0.0, @"");
397+
398+
[physicsNode addChild:node];
399+
[physicsNode onEnter];
400+
XCTAssert(ccpDistance(node.position, CGPointZero) == 0.0, @"");
401+
402+
node.rotation = 90;
403+
XCTAssert(ccpDistance(node.position, CGPointZero) == 0.0, @"");
404+
405+
[physicsNode onExit];
406+
}
407+
336408
-(void)testCollisionGroups
337409
{
338410
CCPhysicsNode *physicsNode = [CCPhysicsNode node];
@@ -360,6 +432,8 @@ -(void)testCollisionGroups
360432
// Both nodes should be at (0, 0)
361433
XCTAssertTrue(CGPointEqualToPoint(node1.position, CGPointZero) , @"");
362434
XCTAssertTrue(CGPointEqualToPoint(node2.position, CGPointZero) , @"");
435+
436+
[physicsNode onExit];
363437
}
364438

365439
-(void)testAffectedByGravity
@@ -393,6 +467,8 @@ -(void)testAffectedByGravity
393467

394468
// Node2 should stay at (0, 0)
395469
XCTAssertTrue(node2.position.y == 0.0, @"");
470+
471+
[physicsNode onExit];
396472
}
397473

398474
-(void)testAllowsRotation
@@ -474,6 +550,8 @@ -(void)testAllowsRotation
474550

475551
XCTAssert(node.physicsBody.body.moment < INFINITY, @"");
476552
}
553+
554+
[physicsNode onExit];
477555
}
478556

479557
-(void)testBodyType
@@ -603,6 +681,50 @@ -(void)testBreakingJoints
603681
XCTAssert(!joint2.valid, @"");
604682
XCTAssert(joint3.valid, @"");
605683
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];
606728
}
607729

608730
// TODO

cocos2d-ui/CCControl.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ - (id) init
5959

6060
- (void) setTarget:(id)target selector:(SEL)selector
6161
{
62-
__unsafe_unretained id weakTarget = target; // avoid retain cycle
62+
__weak id weakTarget = target; // avoid retain cycle
6363
[self setBlock:^(id sender) {
6464
typedef void (*Func)(id, SEL, id);
6565
((Func)objc_msgSend)(weakTarget, selector, sender);

cocos2d-ui/cocos2d-ui.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#import "CCScrollView.h"
2929
#import "CCTableView.h"
3030
#import "CCTextField.h"
31+
#import "CCSlider.h"
3132

3233
// CCBReader
3334
#import "CCBuilderReader.h"

cocos2d/CCNode.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,11 @@ -(void) setRotation: (float)newRotation
222222
{
223223
CCPhysicsBody *body = GetBodyIfRunning(self);
224224
if(body){
225+
CGPoint position = self.position;
225226
body.absoluteRadians = -CC_DEGREES_TO_RADIANS(newRotation + NodeToPhysicsRotation(self.parent));
227+
228+
// Rotating the body will cause the node to move unless the CoG is the same as the anchor point.
229+
self.position = position;
226230
} else {
227231
_rotationalSkewX = newRotation;
228232
_rotationalSkewY = newRotation;

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

cocos2d/CCPhysicsNode.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ -(BOOL)ignore
9696
/// Internal class used to wrap cpCollisionHandlers
9797
@interface CCPhysicsCollisionHandler : NSObject {
9898
cpCollisionHandler *_handler;
99-
id _delegate;
99+
__weak id _delegate;
100100

101101
// Cache the CCPhysicsNode's collision pair singleton.
102102
CCPhysicsCollisionPair *_collisionPairSingleton;

cocos2d/CCResponderManager.m

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -478,9 +478,7 @@ - (void)cancelResponder:(CCRunningResponder *)responder
478478
// -----------------------------------------------------------------
479479

480480
- (void)mouseDown:(NSEvent *)theEvent button:(CCMouseButton)button
481-
{
482-
NSAssert(![self responderForButton:button], @"Unexpected Mouse State");
483-
481+
{
484482
if (_dirty) [self buildResponderList];
485483

486484
// scan backwards through mouse responders

0 commit comments

Comments
 (0)