首先AppDelegate.m中加入
- (void)applicationDidFinishLaunching:(UIApplication *)application{ cpInitChipmunk(); }
初始化!!
然后添加类
TestWorld.h
// // TestWorld.h // TestPiking // // Created by Rayln Guan on 10/3/13. // Copyright 2013 __MyCompanyName__. All rights reserved. // #import <Foundation/Foundation.h> #import "cocos2d.h" #import "chipmunk.h" #import "TestSprite.h" #import "TestSprite2.h" @interface TestWorld : CCLayerColor { cpSpace *space; cpShape *wall[4]; } + (CCScene *)scene; @end
// // TestWorld.m // TestPiking // // Created by Rayln Guan on 10/3/13. // Copyright 2013 __MyCompanyName__. All rights reserved. // #import "TestWorld.h" @implementation TestWorld + (CCScene *)scene{ TestWorld *t = [TestWorld node]; CCScene *s = [CCScene node]; [s addChild: t]; return s; } - (id)init{ if(self = [self initWithColor:ccc4(166, 166, 166, 255)]){ self.isAccelerometerEnabled = YES; self.isTouchEnabled = YES; //init physics [self initPhysics]; [self initSprite]; [self scheduleUpdate]; } return self; } -(void) initSprite{ TestSprite *t1 = [[TestSprite alloc] initWithSpace:space]; [self addChild:t1 z:0 tag:1]; TestSprite2 *t2 = [[TestSprite2 alloc] initWithSpace:space]; [self addChild:t2 z:0 tag:1]; } //该方法是触发chipmunk的重新渲染 -(void) update:(ccTime)time{ // Should use a fixed size step based on the animation interval. int steps = 2; CGFloat dt = [[CCDirector sharedDirector] animationInterval]/(CGFloat)steps; for(int i=0; i<steps; i++){ cpSpaceStep(space, dt); } } -(void) initPhysics{ CGSize s = [[CCDirector sharedDirector] winSize]; //创建一个space space = cpSpaceNew(); //设置一个重力的x,y,即是垂直和横向的重力 space->gravity = ccp(10, 10); //物理空间设定默认的碰撞回调函数,它的设置是针对全局的,也就是物理空间里任何对象的碰撞都会执行设定的回调函数 //cpSpaceSetDefaultCollisionHandler //设定自定义的碰撞回调规则 cpSpaceAddCollisionHandler(space, 1, 2, begin, NULL, NULL, NULL, NULL); //设置四面墙壁 wall[0] = cpSegmentShapeNew( space->staticBody, cpv(0,0), cpv(s.width,0), 0.0f); // top wall[1] = cpSegmentShapeNew( space->staticBody, cpv(0,s.height), cpv(s.width,s.height), 0.0f); // left wall[2] = cpSegmentShapeNew( space->staticBody, cpv(0,0), cpv(0,s.height), 0.0f); // right wall[3] = cpSegmentShapeNew( space->staticBody, cpv(s.width,0), cpv(s.width,s.height), 0.0f); for( int i=0;i<4;i++) { //摩擦力 cpShapeSetElasticity( wall[i], 1.0f ); //反作用力 cpShapeSetFriction( wall[i], 1.0f ); cpSpaceAddStaticShape(space, wall[i] ); } } 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取出是哪两个shape发生了碰撞,a,b是emery还是bullet,与之前设置回调函数时的第2,3参数的顺序有关 CP_ARBITER_GET_SHAPES(arb, a, b); NSLog(@"begin collision p_x:%1.1f p_y:%1.1f",a->body->p.x,a->body->p.y); NSLog(@"%i, %i", a->collision_type, b->collision_type); // additions and removals can't be done in a normal callback. // Schedule a post step callback to do it. // Use the hook as t he key and pass along the arbiter. //我们不能直接在begin函数里面释放刚体或者shape,要等chipmunk做完必要的计算后才能释放。cpSpaceAddPostStepCallback用来安全的完成这个步骤 cpSpaceAddPostStepCallback(space, (cpPostStepFunc)postStepRemove, a, NULL); // The object is dead, don't process the collision further //返回1是物体撞击事件有效 //返回0是物体撞击事件无效 return 1; } //碰撞的处理函数 static void postStepRemove(cpSpace *space, cpShape *shape, void *unused) { TestSprite *sprite = shape->data; assert(sprite.tag == 1); if( sprite ) { //[sprite removeFromParentAndCleanup:YES]; } } @end
// // TestSprite.h // TestPiking // // Created by Rayln Guan on 10/3/13. // Copyright 2013 __MyCompanyName__. All rights reserved. // #import <Foundation/Foundation.h> #import "cocos2d.h" #import "chipmunk.h" @interface TestSprite : CCSprite { cpSpace *space; cpShape *shape; cpBody *body; } - (id)initWithSpace:(cpSpace *)space; - (void)setShape:(cpSpace *)space; @end
// // TestSprite.m // TestPiking // // Created by Rayln Guan on 10/3/13. // Copyright 2013 __MyCompanyName__. All rights reserved. // #import "TestSprite.h" @implementation TestSprite - (id)initWithSpace:(cpSpace *)space_{ if (self = [self initWithFile:@"Icon-72.png"]) { self.position = ccp(100, 100); self.tag = 1; int num = 4; CGPoint vers[4] = { ccp(-36, -36), ccp(-36, 36), ccp(36, 36), ccp(36, -36) }; space = space_; //cpBodyNew创建一个刚体,参数如下:刚性质量,刚性惯性值。 //惯性值的计算使用chipmunk提供的cpMomentForPoly助手函数,参数如下:刚体质量。多边形点数量。多边形点的坐标集。偏移量,会作用到每个点,设为CGPointZero会让事情简单很多。 body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, vers, CGPointZero)); //设置body的位置 body->p = ccp(100, 100); cpSpaceAddBody(space, body); shape = cpPolyShapeNew(body, num, vers, CGPointZero); //自定义一个类型,用于回调函数用,否则不会回调 shape->collision_type = 1; //shape->e = .5f;shape->u = .5f; shape->data = self; cpSpaceAddShape(space, shape); //cpSpaceAddStaticShape(space, shape); //cpSpaceSetGravity( space, cpv(0, -100) ); } return self; } - (void)setShape:(cpSpace *)space_{ //shape = shape_; space = space_; } //重写该方法,返回YES,这样可以触发nodeToParentTransform方法 - (BOOL)dirty{ return YES; } //重烩Sprite,如果不懂什么意思,可以直接用该方法 -(CGAffineTransform) nodeToParentTransform { CGFloat x = body->p.x; CGFloat y = body->p.y; if ( ignoreAnchorPointForPosition_ ) { x += anchorPointInPoints_.x; y += anchorPointInPoints_.y; } // Make matrix CGFloat c = body->rot.x; CGFloat s = 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_; } - (void)removeFromParentAndCleanup:(BOOL)cleanup{ // cpSpaceRemoveBody(space, shape->body); // cpBodyFree(shape->body); // // cpSpaceRemoveShape(space, shape); // cpShapeFree(shape); [super removeFromParentAndCleanup:cleanup]; } @end