接着我們先來重寫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
小球的圖檔素材:
小球類比較簡單,通過ApplyForceToCenter來對小球施力即可。
這樣我們的遊戲就基本制作完成了,限于篇幅,我們沒有列出各個類的dealloc方法,請讀者補充完成,釋放資源。此外,還可以添加一些音效,添加開始界面和GameOver界面等等。
教程就到這裡,如果有問題,歡迎留言~