赞
踩
初始化整个chipmunk系统,只需做一次。// init chipmunk cpInitChipmunk();
HelloWorldLayer包含了一个cpSpace,每个layer对应一个space,这很好理解,layer自己管理自己的space,不同的layer的space会不一样。space的生命周期由layer管理。@interface HelloWorldLayer : CCLayerColor { cpSpace *space_; // strong ref } @end @interface PhysicsSprite : CCSprite { cpShape *shape_; // strong ref cpSpace *space_; // weak ref } -(void) setPhysicsShape:(cpShape *)shape space:(cpSpace *)space;
重写dirty方法,返回YES,目的是让每次layer的update调用后重新绘制PhysicsSprite精灵。-(BOOL) dirty { return YES; }
重写精灵的矩阵变换方法nodeToParentTransform,模板提供的这个实现,能改变精灵的位置和角度。shape_->body->p和shape_->body->rot分别是刚体的位置坐标和角度。我们会看到,在update函数中,调用了chipmunk的cpSpaceStep方法,这个方法根据时间流逝计算出每个刚体的新位置和角度,然后在这里被使用最终达到精灵移动旋转的目的。-(CGAffineTransform) nodeToParentTransform { CGFloat x = shape_->body->p.x; CGFloat y = shape_->body->p.y; if ( !isRelativeAnchorPoint_ ) { x += anchorPointInPoints_.x; y += anchorPointInPoints_.y; } // Make matrix CGFloat c = shape_->body->rot.x; CGFloat s = shape_->body->rot.y; if( ! CGPointEqualToPoint(anchorPointInPoints_, CGPointZero) ){ x += c*-anchorPointInPoints_.x + -s*-anchorPointInPoints_.y; y += s*-anchorPointInPoints_.x + c*-anchorPointInPoints_.y; } // Translate, Rot, anchor Matrix transform_ = CGAffineTransformMake( c, s, -s, c, x, y ); return transform_; }
重写removeFromParentAndCleanup方法。(void) removeFromParentAndCleanup:(BOOL)cleanup { cpSpaceRemoveBody(space_, shape_->body); cpBodyFree(shape_->body); cpSpaceRemoveShape(space_, shape_); cpShapeFree(shape_); [super removeFromParentAndCleanup:cleanup]; }
-(id) init { if( (self=[super initWithColor:ccc4(166, 166, 166, 255)])) { // enable events self.isTouchEnabled = YES; self.isAccelerometerEnabled = YES; CGSize s = [[CCDirector sharedDirector] winSize]; // title CCLabelTTF *label = [CCLabelTTF labelWithString:@"Touch the screen"
fontName:@"Marker Felt" fontSize:36]; label.position = ccp( s.width / 2, s.height - 30); [self addChild:label z:0]; // reset button [self createResetButton]; // init physics [self initPhysics]; [self addNewEmeryAtPosition:ccp(240,160)]; [self scheduleUpdate]; } return self; }
-(void) initPhysics { //CGSize s = [[CCDirector sharedDirector] winSize]; space_ = cpSpaceNew(); // set to zero space_->gravity = ccp(0, 0); cpSpaceAddCollisionHandler(space_, kTagBulletNode, kTagEmeryNode, begin, NULL, NULL, NULL, NULL); }
-(void) addNewEmeryAtPosition:(CGPoint)pos { PhysicsSprite *sprite = [PhysicsSprite spriteWithFile:@"triangle.png" rect:CGRectMake(0, 0, 50, 50)]; sprite.position = pos; sprite.tag = kTagEmeryNode; [self addChild:sprite]; int num = 3; CGPoint verts[] = { ccp(-25,-25), ccp(0, 25), ccp(25, -25), }; cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, CGPointZero)); body->p = pos; cpSpaceAddBody(space_, body); cpShape* shape = cpPolyShapeNew(body, num, verts, CGPointZero); shape->collision_type = kTagEmeryNode; shape->data = sprite; //shape->e = 0.5f; shape->u = 0.5f; cpSpaceAddShape(space_, shape); [sprite setPhysicsShape:shape space:space_]; }
static int begin(cpArbiter *arb, cpSpace *space, void *unused) { // Get pointers to the two bodies in the collision pair and define local variables for them. // Their order matches the order of the collision types passed // to the collision handler this function was defined for CP_ARBITER_GET_SHAPES(arb, a, b); // additions and removals can't be done in a normal callback. // Schedule a post step callback to do it. // Use the hook as the key and pass along the arbiter. cpSpaceAddPostStepCallback(space, (cpPostStepFunc)postStepRemove, a, NULL); // The object is dead, don't process the collision further return 0; }
shape->data保存了精灵实例。static void postStepRemove(cpSpace *space, cpShape *shape, void *unused) { PhysicsSprite *sprite = shape->data; assert(sprite.tag == kTagBulletNode); if( sprite ) { [sprite removeFromParentAndCleanup:YES]; } }
按钮事件触发以后,创建了一个新的包含HelloWorldLayer 的Scene,来取代当前Scene。CCScene *s = [CCScene node]; id child = [HelloWorldLayer node]; [s addChild:child]; [[CCDirector sharedDirector] replaceScene: s];
cpSpaceEachBody和cpSpaceEachShape是两个遍历方法,遍历space中的所有body和shape,并为每个找到的body或shape调用处理回调函数。- (void)dealloc { cpSpaceEachBody(space_, spaceBodyCallback, NULL); cpSpaceEachShape(space_, spaceShapeCallback, NULL); cpSpaceFree( space_ ); [super dealloc]; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。