`
rayln
  • 浏览: 414546 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Cocos2d与chipmunk的使用

阅读更多
新建一个cocos2d-chipmunk项目
首先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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics