[?李華明Himi?](http://www.himigame.com/about-himi)原創,轉載務必在明顯處注明:
轉載自[【黑米GameDev街區】](http://www.himigame.com/)?原文鏈接:?[http://www.himigame.com/iphone-cocos2d/474.html](http://www.himigame.com/iphone-cocos2d/474.html "【iOS-Cocos2d游戲開發之十一】使用Box2d物理系統以及在cocos2d框架添加Box2d物理系統lib包的方法")> [](http://blog.csdn.net/xiaominghimi/article/details/6776096)
上一節講述了粒子的相關問題,當然啦,不示弱,今天繼續將物理系統給大家進行簡單的介紹和講述;
首先先介紹,如何在cocos2d中加入box2d開發lib包,因為一般使用cocos2d引擎進行開發游戲時,大家創建項目都會選用cocos2d框架,而不是直接采用物理系統的cocos2d框架,但是后期忽然需要在項目中使用物理系統(這種情況很經常發生,至于為什么,童鞋們都懂得~),OK,首先創建一個普通的cocos2d項目;

OK,加入box2d->lib步驟如下:
1.首先將box2d的lib包拷貝到剛創建的項目下,然后右鍵項目的libs文件夾進行導入項目中;(如果你沒有box2d的lib包,那就新建一個cocos2d-box2d的項目就有了)
2.雙擊你的項目名默認打開配置信息窗口,點擊Build Settings標簽,然后在頁面中找到”Search Paths“一欄,然后在“User Header Search Paths”中添加“xx/libs”;這里的XX是你的項目名稱;緊接著在“User Header Search Paths”一項的上面設置“Always Serch Paths”的選項 為YES,默認為NO;這里務必要設置;

3.最后commadn+B (我用的xcode For lion)編譯項目代碼,如果提示編譯成功,OK,可以使用啦;
下面我來給大家簡單的介紹以下如何在cocos2d中使用Box2d物理系統,雖然關于Box2d的相關資料和教程很少,但是這里我也不會很詳細的介紹和解釋,因為我即將上市的Android游戲開發書籍中已經對Box2d進行了很詳細的講解和兩個物理小游戲實戰,所以這里就大概的介紹下一些重要的方法;
便于講解,這里我直接使用Xcode直接創建一個cocos2d-Box2d的項目,然后簡單的修改:
~~~
//
// HelloWorldLayer.mm
// Box2dProject
//
// Created by 華明 李 on 11-9-14.
// Himi
//
// Import the interfaces
#import "HelloWorldLayer.h"
#define PTM_RATIO 32
// enums that will be used as tags
enum {
kTagTileMap = 1,
kTagAnimation1 = 1,
};
// HelloWorldLayer implementation
@implementation HelloWorldLayer
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild: layer];
return scene;
}
// on "init" you need to initialize your instance
-(id) init
{
//初始化中,在屏幕上創建了物理世界,并且創建了在屏幕四周創建了剛體防止物理世界中的剛體超屏
//最后并且調用一個tick方法用于讓物理世界不斷的去模擬
if( (self=[super init])) {
self.isTouchEnabled = YES;
self.isAccelerometerEnabled = YES;
CGSize screenSize = [CCDirector sharedDirector].winSize;
CCLOG(@"Screen width %0.2f screen height %0.2f",screenSize.width,screenSize.height);
// Define the gravity vector.
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
bool doSleep = true;
world = new b2World(gravity, doSleep);
world->SetContinuousPhysics(true);
// Debug Draw functions
m_debugDraw = new GLESDebugDraw( PTM_RATIO );
world->SetDebugDraw(m_debugDraw);
uint32 flags = 0;
flags += b2DebugDraw::e_shapeBit;
m_debugDraw->SetFlags(flags);
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0, 0); // bottom-left corner
b2Body* groundBody = world->CreateBody(&groundBodyDef);
b2PolygonShape groundBox;
// bottom
groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(screenSize.width/PTM_RATIO,0));
groundBody->CreateFixture(&groundBox,0);
// top
groundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO));
groundBody->CreateFixture(&groundBox,0);
// left
groundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(0,0));
groundBody->CreateFixture(&groundBox,0);
// right
groundBox.SetAsEdge(b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,0));
groundBody->CreateFixture(&groundBox,0);
CCLabelTTF *label = [CCLabelTTF labelWithString:@"Himi" fontName:@"Marker Felt" fontSize:32];
[self addChild:label z:0];
label.position = ccp( screenSize.width/2, screenSize.height-50);
[self schedule: @selector(tick:)];
}
return self;
}
//Box2d調試模式,因為物理世界是看不到摸不到的,那么物理世界中的剛體其實也一樣無法看到,
//但是為了便于開發調試,Box2d提供了調試類,主要作用是能將物理世界的所有剛體、關節等都利用線條框出來,
//這樣便于設置你的Body與Sprite之間的位置關系 ----
-(void) draw
{
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
world->DrawDebugData();
// restore default GL states
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
//---添加一個剛體,首先需要創建剛體的皮膚,可以理解這個皮膚是剛體的屬性,然后利用皮膚包裝出一個剛體
-(void) addNewSpriteWithCoords:(CGPoint)p sp:(CCSprite*)sprite
{
CCLOG(@"Add sprite %0.2f x %02.f",p.x,p.y);
sprite.position = ccp( p.x, p.y);
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
//將精靈信息賦值給剛體皮膚,這樣就能讓精靈的運動軌跡與這個即將創建出的剛體在物理世界中的運動軌跡同步
bodyDef.userData = sprite;
b2Body *body = world->CreateBody(&bodyDef);
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(.9f, .9f);
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
body->CreateFixture(&fixtureDef);
//給body施加一個力
b2Vec2 force = body->GetWorldVector(b2Vec2(1000.0f, 600.0f));
b2Vec2 point = body->GetWorldPoint(b2Vec2(0.4f, 0.4f));
body->ApplyForce(force, point);//----------備注1 Himi
}
//此方法中,首先是讓物理世界進行物理模擬,然后不斷的遍歷物理世界中的剛體運動軌跡復制給對應的精靈
-(void) tick: (ccTime) dt
{
int32 velocityIterations = 8;
int32 positionIterations = 1;
world->Step(dt, velocityIterations, positionIterations);
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
//Synchronize the AtlasSprites position and rotation with the corresponding body
CCSprite *myActor = (CCSprite*)b->GetUserData();
myActor.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
//---觸屏將添加一個body和精靈,位置為玩家觸屏的坐標
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
for( UITouch *touch in touches ) {
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
CCSprite *sprite =[CCSprite spriteWithFile:@"icon.png"];
[self addChild:sprite];
[self addNewSpriteWithCoords: location sp:sprite];
}
}
- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
static float prevX=0, prevY=0;
//#define kFilterFactor 0.05f
#define kFilterFactor 1.0f // don't use filter. the code is here just as an example
float accelX = (float) acceleration.x * kFilterFactor + (1- kFilterFactor)*prevX;
float accelY = (float) acceleration.y * kFilterFactor + (1- kFilterFactor)*prevY;
prevX = accelX;
prevY = accelY;
b2Vec2 gravity( -accelY * 10, accelX * 10);
world->SetGravity( gravity );
}
- (void) dealloc
{
delete world;
world = NULL;
delete m_debugDraw;
[super dealloc];
}
@end
~~~
這里我只是對重要的方法進行的說明,主要修改的一點地方在**備注1**這里,我這里對每次玩家觸摸屏幕的地方創建的剛體都進行施加了一個力,讓剛體進行運動,那么這個運動的軌跡也會根據你設置的物理世界的重力方向發生改變,當前項目中,重力方向垂直下落,沒有X軸的變化;
還要注意一點,由于box2d是c++代碼,那么如果你使用box2d的話,首先把你的Delegate.m的類改成Delegate.mm,還有你使用box2d相關代碼的實現類(.m)格式的類要改成(.mm)格式才可,這樣編譯器就會知道是混合代碼,否則都當成object-c進行編譯就會報錯;
運行截圖如下:

從圖中可以看出,在icon圖的周圍包圍著線段,這個就是Box2d提供的調試繪制,將本無形的剛體繪制出來了;
這里我不得不說一些童鞋,例如之前我寫過Android上的一個自己隨手的物理系統小球的例子,我在博文中寫了要觸屏才創建小球,但是很多童鞋問我項目運行起來沒效果有問題,我就崩潰了。。。你們讓我
源碼本想上傳,但是發現一點擊上傳資源就悲劇打不開網頁,大家可以直接創建一個cocos2d-box2d的項目,然后將HelloWorldLayer.mm中代碼換成我上面的代碼即可~
? ? ? ?
- 前言
- 【Iphone 游戲開發】游戲引擎剖析
- [Object-C語言隨筆之一]Mac os 下搭建iOS開發環境
- [Object-C語言隨筆之二] 《NSLog》常用的打印調試語句與自動排版
- [Object-C語言隨筆之三] 類的創建和實例化以及函數的添加和調用!
- [Object-C語言隨筆之四]創建視圖并繪制簡單圖形
- 【iOS-Cocos2d游戲開發之一】搭建cocos2d游戲引擎環境HelloWorld!
- 【iOS-Cocos2d游戲開發之二】Cocos2D 游戲開發資源貼(教程以及源碼)
- 【iOS-Cocos2d游戲開發之三】CCScene切換的所有特效(28種)以及設置屏幕橫豎屏!
- 【iOS-Cocos2d游戲開發之四】獨自收集Cocos2d提供的字體!共57種(有對照的字體圖)
- 【iOS-Cocos2d游戲開發之五】多觸點與觸屏事件詳解(單一監聽、事件分發)【11月28日更新】
- 【iOS-Cocos2d游戲開發之六】對觸屏事件追加講解,解決無法觸發ccTouchMoved事件[重要!]
- 【iOS-Cocos2d游戲開發之七】在cocos2d中添加/刪除系統組件,并解決View設置透明會影響View中的其他組件的問題!【11月28日更新解決添加組件Cocos2d動畫停止播放的BUG】
- 【iOS-Cocos2d游戲開發之八】開啟高清(960*640)模式問題與解答、圖片適配以及設置iphone橫豎屏
- 【iOS-Cocos2d游戲開發之九】講解CCSpriteBatchNode與TP工具的".pvr.ccz",".plist"共用的終極精靈優化及注意事項!
- 【iOS-Cocos2d游戲開發之十】添加粒子系統特效并解決粒子特效與Layer之間的坐標問題;
- 【iOS-Cocos2d游戲開發之十一】使用Box2d物理系統以及在cocos2d框架添加Box2d物理系統lib包的方法
- 【iOS-Cocos2d游戲開發之十二】淺析使用C++/C/OC進行iOS游戲混編出現“failed with exit”問題與小結;
- 【iOS-Cocos2d游戲開發之十三】CCSprite利用Bezier(貝塞爾)做拋物線動作并讓CCSprite同時播放兩個Action動作!
- 【iOS-Cocos2d游戲開發之十四】音頻/音效/視頻播放(利用Cocos2D-iPhone-Extensions嵌入Cocos2d進行視頻播放!)
- 【iOS-Cocos2d游戲開發之十五】詳解CCProgressTimer 進度條并修改cocos2d源碼實現“理想”游戲進度條!
- 【iOS-Cocos2d游戲開發之十六】添加本地通知(UILocalNotification)以及添加系統組件滾動視圖(UIScrollView)!【2011年11月15日更新】
- 【iOS-Cocos2d游戲開發之十七】靈活使用精靈可視區域(TextureRect)與錨點(anchorPoint),并結合可視區域與錨點制作進度條!
- 【iOS開發必備指南合集】申請企業級IDP、真機調試、游戲接入GameCenter 指南(實現仿官方的成就提示)、游戲接入OpenFeint指南;
- 【iOS-Cocos2d游戲開發之十八】解決滾屏背景/拼接地圖有黑邊(縫隙)/動畫播放出現毛邊以及禁止游戲中自動鎖屏問題!【2011年12月18日補充】
- 【iOS開發必收藏】詳解iOS應用程序內使用IAP/StoreKit付費、沙盒(SandBox)測試、創建測試賬號流程!【2012-12-11日更新獲取"產品付費數量等于0的問題"】
- 【iOS-cocos2d-X 游戲開發之一】在Mac下結合Xcode搭建Cocos2d-X開發環境!
- 【iOS-cocos2d-X 游戲開發之二】【必看篇】總結闡述Cocos2d-X與Cocos2d-iphone區別;
- 【iOS-Cocos2d游戲開發之十九】游戲數據存儲的四種常用方式NSKeyedArchiver/NSUserDefaults/Write寫入/SQLite3
- 【iOS-Cocos2d游戲開發之二十】精靈的基礎知識點總匯(位圖操作/貼圖更換/重排z軸等)以及利用CCSprite與CCLayerColor制作簡單遮蓋層!
- 【iOS-Cocos2d游戲開發之二十一 】自定義精靈類并為你的精靈設置攻擊幀(指定開始幀)以及擴展Cocos2d源碼的CCAnimation簡化動畫創建!
- 【iOS-Cocos2d游戲開發之二十二 】CCSpeed實現CCAnimate動畫進行時設置慢動作以及設置游戲加減速進行(塔防游戲必備)!
- 【iOS-cocos2d-X 游戲開發之三】Mac下配置Android NDK環境并搭建Cocos2d-x環境并Eclipse正常編譯運行Cocos2dX自帶TestsDemo項目!
- 【iOS-cocos2d-X 游戲開發之四】Cocos2dX創建Android NDK新項目并編譯導入Eclipse中正常運行!
- 【iOS-cocos2d-X 游戲開發之五】游戲存儲之Cocos2dX自帶CCUserDefault類詳解;
- 【iOS-cocos2d-X 游戲開發之六】使用Base64算法對Cocos2dX自帶CCUserDefault游戲存儲數據編碼!
- 【iOS-cocos2d-X 游戲開發之七】整合Cocos2dX的Android項目到Xcode項目中,Xcode編寫&編譯代碼,Android導入打包運行即可!
- 【iOS-iap防護】驗證用戶付費收據!拒絕iap Cracker!拒絕iap Free!讓iphone越獄用戶無從下手!【2012年5月2日更新防護iap Free的方法】
- 【COCOS2DX-LUA 腳本開發之一】在Cocos2dX游戲中使用Lua腳本進行游戲開發(基礎篇)并介紹腳本在游戲中詳細用途!
- 【iOS-cocos2d-X 游戲開發之九】Cocos2dx利用CCSAXParser解析xml數據&CCMutableDictionary使用與注意!
- 【iOS-cocos2d-X 游戲開發之十】自定義CCSprite/Layer/CCNode及靜態類模版&自定義類細節說明&Cocos2dx觸屏事件講解
- 【iOS-cocos2d-X 游戲開發之十一】New CCSprite()帶來的錯誤&使用CCUserDefault及pvr.ccz在Cocos2dx中要注意!
- 【iOS-cocos2d-X 游戲開發之十二】自定義Cocos2dx搖桿(增強Joystick),增加搖桿跟隨用戶觸點作為搖桿坐標,讓搖桿不再死板!
- 【iOS-cocos2d-X 游戲開發之十三】詳細講解在Xcode中利用預編譯并通過Jni調用Android的Java層代碼(cocos2dx里訪問調用Android函數)!
- 【iOS-cocos2d-X 游戲開發之十四】Xcode中c++&Object-C混編,詳細介紹如何在cocos2dx中訪問object函數以及Apple Api
- 【iOS-cocos2d-X 游戲開發之十五】Cocos2dx中響應Android的Back(返回)與Menu(小房子)事件&&Cocos2dx自動釋放粒子內存函數!
- 【iOS-cocos2d-X 游戲開發之十六】配置你的Cocos2dx項目編譯后的Android自動使用(-hd)高清圖&設置Android自適應屏幕、縮放比例方法!
- 【Cocoa(mac) Application 開發系列之四】動作編輯器(Cocos2dx)制作流程詳解及附上響應鼠標滾軸事件、反轉坐標系、導入/創建資源目錄等知識點代碼!
- 【Cocos2d-X(2.x) 游戲開發系列之一】cocos2dx(v2.x)與(v1.x)的一些常用函數區別講解!在2.x版CCFileData類被去除等
- 【Cocos2d-X(2.x) 游戲開發系列之二】cocos2dx最新2.0.1版本跨平臺整合NDK+Xcode,Xcode編寫&編譯代碼,Android導入打包運行即可!
- 【Cocos2dX(2.x)_Lua開發之三】★重要必看篇★在Lua中使用自定義精靈(Lua腳本與自創建類之間的訪問)及Lua基礎講解
- 【Cocos2d-X(2.x) 游戲開發系列之三】最新版本cocos2d­2.0­x­2.0.2使用新資源加載策略!不再沿用-hd、-ipad、-ipadhd添加后綴方式
- 【Cocos2d-X(1.x 2.x) 修復篇】iOS6 中 libcurl.a 無法通過armv7s編譯以及iOS6中無法正常游戲橫屏的解決方法
- 【Cocos2d-X(1.x 2.x) 】iOS6與iphone5適相關設置隨筆(解決第三方類庫無法通過armv7s編譯的方法、添加Default-568h@2x.png)