天天看點

手把手教你制作一款Box2D小遊戲(三)



接着我們先來重寫ContactListener:

類聲明:

#import "Box2D.h"

class ContactListener : public b2ContactListener

{

public:

      voidBeginContact(b2Contact* contact);

      voidPreSolve(b2Contact* contact, const b2Manifold* oldManifold);

      voidPostSolve(b2Contact* contact, const b2ContactImpulse* impulse);

      voidEndContact(b2Contact* contact);

};

類定義:

#import "ContactListener.h"

#import "cocos2d.h"

#import "GameLayer.h"

void ContactListener::BeginContact(b2Contact*contact)

{

    b2Body* body =contact->GetFixtureA()->GetBody();

    NSNumber* userData =(NSNumber*)(body->GetUserData());

    if (userData == nil) {

        return;

    }

    int tag = [userDataintValue];

    if (tag == -1) {

        body= contact->GetFixtureB()->GetBody();

        userData= (NSNumber*)(body->GetUserData());

        if(userData == nil) {

            return;

        }

        tag= [userData intValue];

        if(tag == -2) {

            return;

        }

    }

    int lastScoredStep =[[GameLayer gameLayer] lastScoredStep];

    if (lastScoredStep == -1){

        [GameLayergameLayer].lastScoredStep = tag;

        return;

    } else if (lastScoredStep!= tag) {

        [GameLayergameLayer].lastScoredStep = tag;

        [[GameLayergameLayer] addScore];

    }

}

void ContactListener::PreSolve(b2Contact* contact,const b2Manifold* oldManifold){}

void ContactListener::PostSolve(b2Contact*contact, const b2ContactImpulse* impulse){}

void ContactListener::EndContact(b2Contact*contact){}

這裡我們重寫了BeginContact方法,當有剛體之間的碰撞發生時,我們通過判斷兩個剛體的類型來判斷是否得分,剛體類型的判斷就用的是我們前面的tag,注意這裡我們做了判斷,由于我們沒有為牆體指定tag,是以當牆體的userData轉換為NSNumber指針時為nil,這時候就沒有必要再做判斷了,并且我們為了防止重複記分,例如小球連續兩次碰到目前Block(例如小球碰撞之後彈起又碰撞,或者遇到高矮台階的那種Block),這時候就通過lastScoredStep來比較,lastScoredStep始終記錄前一次得分的StepBlock。

最後我們來定義Ball類:

聲明如下:

#import "CCNode.h"

#import "cocos2d.h"

#import "Box2D.h"

@interface Ball : CCNode{

    float screenWidth;

    float screenHeight;

    b2Body* body;

    CCSprite* shape;

}

+ (Ball*)ball;

- (void)reset;

- (void)pushLeft;

- (void)pushRight;

@end

定義:

#import "Ball.h"

#import "cocos2d.h"

#import "GB2ShapeCache.h"

#import "TagDefinitions.h"

#import "GameLayer.h"

@implementation Ball

+ (Ball*)ball{

    return [[[Ball alloc]init] autorelease];

}

- (id)init{

    if (self = [super init]) {

        //screendimensions

        CGSizescreenSize = [[CCDirector sharedDirector] winSize];

        screenHeight= screenSize.height;

        screenWidth= screenSize.width;

        shape= [CCPhysicsSprite spriteWithFile:@"ball.png"];

        shape.anchorPoint= ccp(0.5f, 0.5f);

        CGPointposition = ccp(screenWidth*0.5f, screenHeight*0.5f+50);

        b2BodyDefbodyDef;

        bodyDef.type= b2_dynamicBody;

        bodyDef.userData= [NSNumber numberWithInteger:-1];

        bodyDef.position.Set(position.x/PTM_RATIO,position.y/PTM_RATIO);

        body= [[GameLayer gameLayer] sharedWorld]->CreateBody(&bodyDef);

        [[GB2ShapeCachesharedShapeCache] addFixturesToBody:body forShapeName:@"ball"];

        [shapesetPTMRatio:PTM_RATIO];

        [shapesetB2Body:body];

        [shapesetPosition:position];

        [selfaddChild:shape];

    }

    return self;

}

- (void)pushLeft{

    b2Vec2 force;

    force.Set(-4.0f, 0);

    body->ApplyForceToCenter(force);

}

- (void)pushRight{

    b2Vec2 force;

    force.Set(4.0f, 0);

    body->ApplyForceToCenter(force);

}

- (void)reset{

    CGPoint position =ccp(screenWidth*0.5f, screenHeight*0.5f+50);

    b2Vec2 pos;

    pos.Set(position.x/PTM_RATIO,position.y/PTM_RATIO);

    body->SetTransform(pos,0);

    [shapesetPosition:position];

}

- (CGPoint)position{

    return shape.position;

}

@end

小球的圖檔素材:

手把手教你制作一款Box2D小遊戲(三)

小球類比較簡單,通過ApplyForceToCenter來對小球施力即可。

這樣我們的遊戲就基本制作完成了,限于篇幅,我們沒有列出各個類的dealloc方法,請讀者補充完成,釋放資源。此外,還可以添加一些音效,添加開始界面和GameOver界面等等。

教程就到這裡,如果有問題,歡迎留言~