`
tank2308635
  • 浏览: 191693 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

(转)使用Box2d物理系统以及在cocos2d框架添加Box2d物理系统lib包的方法

 
阅读更多

 

Himi 原创,转载请注明!

 

原文地址: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的项目,然后简单的修改:

 

  1. //  
  2. //  HelloWorldLayer.mm  
  3. //  Box2dProject  
  4. //  
  5. //  Created by 华明 李 on 11-9-14.  
  6. //  Himi  
  7. //  
  8. // Import the interfaces  
  9. #import "HelloWorldLayer.h"  
  10.    
  11. #define PTM_RATIO 32  
  12.   
  13. // enums that will be used as tags  
  14. enum {  
  15.     kTagTileMap = 1,   
  16.     kTagAnimation1 = 1,  
  17. };  
  18.   
  19.   
  20. // HelloWorldLayer implementation  
  21. @implementation HelloWorldLayer  
  22.   
  23. +(CCScene *) scene  
  24. {   
  25.     CCScene *scene = [CCScene node];    
  26.     HelloWorldLayer *layer = [HelloWorldLayer node];   
  27.     [scene addChild: layer];   
  28.     return scene;  
  29. }  
  30.   
  31. // on "init" you need to initialize your instance  
  32. -(id) init  
  33. {  
  34.     //初始化中,在屏幕上创建了物理世界,并且创建了在屏幕四周创建了刚体防止物理世界中的刚体超屏  
  35.     //最后并且调用一个tick方法用于让物理世界不断的去模拟  
  36.     if( (self=[super init])) {   
  37.         self.isTouchEnabled = YES;   
  38.         self.isAccelerometerEnabled = YES;   
  39.         CGSize screenSize = [CCDirector sharedDirector].winSize;  
  40.         CCLOG(@"Screen width %0.2f screen height %0.2f",screenSize.width,screenSize.height);   
  41.         // Define the gravity vector.  
  42.         b2Vec2 gravity;  
  43.         gravity.Set(0.0f, -10.0f);  
  44.         bool doSleep = true;    
  45.         world = new b2World(gravity, doSleep);   
  46.         world->SetContinuousPhysics(true);   
  47.         // Debug Draw functions  
  48.         m_debugDraw = new GLESDebugDraw( PTM_RATIO );  
  49.         world->SetDebugDraw(m_debugDraw);   
  50.         uint32 flags = 0;  
  51.         flags += b2DebugDraw::e_shapeBit;   
  52.         m_debugDraw->SetFlags(flags);       
  53.         b2BodyDef groundBodyDef;  
  54.         groundBodyDef.position.Set(0, 0); // bottom-left corner   
  55.         b2Body* groundBody = world->CreateBody(&groundBodyDef);   
  56.         b2PolygonShape groundBox;         
  57.                 // bottom  
  58.         groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(screenSize.width/PTM_RATIO,0));  
  59.         groundBody->CreateFixture(&groundBox,0);  
  60.           
  61.         // top  
  62.         groundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO));  
  63.         groundBody->CreateFixture(&groundBox,0);  
  64.           
  65.         // left  
  66.         groundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(0,0));  
  67.         groundBody->CreateFixture(&groundBox,0);  
  68.           
  69.         // right  
  70.         groundBox.SetAsEdge(b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,0));  
  71.         groundBody->CreateFixture(&groundBox,0);  
  72.           
  73.             
  74.         CCLabelTTF *label = [CCLabelTTF labelWithString:@"Himi" fontName:@"Marker Felt" fontSize:32];  
  75.         [self addChild:label z:0];  
  76.         label.position = ccp( screenSize.width/2, screenSize.height-50);   
  77.         [self schedule: @selector(tick:)];  
  78.     }  
  79.     return self;  
  80. }  
  81.   
  82. //Box2d调试模式,因为物理世界是看不到摸不到的,那么物理世界中的刚体其实也一样无法看到,  
  83. //但是为了便于开发调试,Box2d提供了调试类,主要作用是能将物理世界的所有刚体、关节等都利用线条框出来,  
  84. //这样便于设置你的Body与Sprite之间的位置关系 ----  
  85. -(void) draw  
  86. {  
  87.     glDisable(GL_TEXTURE_2D);  
  88.     glDisableClientState(GL_COLOR_ARRAY);  
  89.     glDisableClientState(GL_TEXTURE_COORD_ARRAY);   
  90.     world->DrawDebugData();   
  91.     // restore default GL states  
  92.     glEnable(GL_TEXTURE_2D);  
  93.     glEnableClientState(GL_COLOR_ARRAY);  
  94.     glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
  95.   
  96. }  
  97. //---添加一个刚体,首先需要创建刚体的皮肤,可以理解这个皮肤是刚体的属性,然后利用皮肤包装出一个刚体  
  98. -(void) addNewSpriteWithCoords:(CGPoint)p sp:(CCSprite*)sprite  
  99. {  
  100.     CCLOG(@"Add sprite %0.2f x %02.f",p.x,p.y);   
  101.     sprite.position = ccp( p.x, p.y);  
  102.     b2BodyDef bodyDef;  
  103.     bodyDef.type = b2_dynamicBody;  
  104.     bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);  
  105.     //将精灵信息赋值给刚体皮肤,这样就能让精灵的运动轨迹与这个即将创建出的刚体在物理世界中的运动轨迹同步  
  106.     bodyDef.userData = sprite;  
  107.     b2Body *body = world->CreateBody(&bodyDef);  
  108.     b2PolygonShape dynamicBox;  
  109.     dynamicBox.SetAsBox(.9f, .9f);   
  110.     b2FixtureDef fixtureDef;  
  111.     fixtureDef.shape = &dynamicBox;   
  112.     fixtureDef.density = 1.0f;  
  113.     fixtureDef.friction = 0.3f;  
  114.     body->CreateFixture(&fixtureDef);  
  115.     //给body施加一个力  
  116.     b2Vec2 force = body->GetWorldVector(b2Vec2(1000.0f, 600.0f));  
  117.     b2Vec2 point = body->GetWorldPoint(b2Vec2(0.4f, 0.4f));  
  118.     body->ApplyForce(force, point);//----------备注1  Himi  
  119. }  
  120.   
  121.   
  122. //此方法中,首先是让物理世界进行物理模拟,然后不断的遍历物理世界中的刚体运动轨迹复制给对应的精灵  
  123. -(void) tick: (ccTime) dt  
  124. {  
  125.       
  126.     int32 velocityIterations = 8;  
  127.     int32 positionIterations = 1;   
  128.     world->Step(dt, velocityIterations, positionIterations);  
  129.     for (b2Body* b = world->GetBodyList(); b; bb = b->GetNext())  
  130.     {  
  131.         if (b->GetUserData() != NULL) {  
  132.             //Synchronize the AtlasSprites position and rotation with the corresponding body  
  133.             CCSprite *myActor = (CCSprite*)b->GetUserData();  
  134.             myActor.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);  
  135.             myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());  
  136.         }     
  137.     }  
  138. }  
  139. //---触屏将添加一个body和精灵,位置为玩家触屏的坐标  
  140. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event  
  141. {  
  142.     for( UITouch *touch in touches ) {  
  143.         CGPoint location = [touch locationInView: [touch view]];   
  144.         location = [[CCDirector sharedDirector] convertToGL: location];  
  145.         CCSprite *sprite =[CCSprite spriteWithFile:@"icon.png"];  
  146.         [self addChild:sprite];  
  147.         [self addNewSpriteWithCoords: location sp:sprite];  
  148.     }  
  149. }  
  150.   
  151. - (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration  
  152. {     
  153.     static float prevX=0prevY=0;  
  154.       
  155.     //#define kFilterFactor 0.05f  
  156.     #define kFilterFactor 1.0f  // don't use filter. the code is here just as an example  
  157.       
  158.     float accelX = (float) acceleration.x * kFilterFactor + (1- kFilterFactor)*prevX;  
  159.     float accelY = (float) acceleration.y * kFilterFactor + (1- kFilterFactor)*prevY;  
  160.     prevX = accelX;  
  161.     prevY = accelY;  
  162.     b2Vec2 gravity( -accelY * 10, accelX * 10);  
  163.     world->SetGravity( gravity );  
  164. }  
  165.    
  166. - (void) dealloc  
  167. {   
  168.     delete world;  
  169.     world = NULL;   
  170.     delete m_debugDraw;   
  171.     [super dealloc];  
  172. }  
  173. @end  

  

 

     这里我只是对重要的方法进行的说明,主要修改的一点地方在备注1这里,我这里对每次玩家触摸屏幕的地方创建的刚体都进行施加了一个力,让刚体进行运动,那么这个运动的轨迹也会根据你设置的物理世界的重力方向发生改变,当前项目中,重力方向垂直下落,没有X轴的变化;

    还要注意一点,由于box2d是c++代码,那么如果你使用box2d的话,首先把你的Delegate.m的类改成Delegate.mm,还有你使用box2d相关代码的实现类(.m)格式的类要改成(.mm)格式才可,这样编译器就会知道是混合代码,否则都当成object-c进行编译就会报错;

运行截图如下:


 

       从图中可以看出,在icon图的周围包围着线段,这个就是Box2d提供的调试绘制,将本无形的刚体绘制出来了;

      这里我不得不说一些童鞋,例如之前我写过Android上的一个自己随手的物理系统小球的例子,我在博文中写了要触屏才创建小球,但是很多童鞋问我项目运行起来没效果有问题,我就崩溃了。。。你们让我

      源码本想上传,但是发现一点击上传资源就悲剧打不开网页,大家可以直接创建一个cocos2d-box2d的项目,然后将HelloWorldLayer.mm中代码换成我上面的代码即可~

分享到:
评论

相关推荐

    box2d物理引擎cocos2d

    同时,还要掌握如何在Cocos2d的场景和层(Layer)中添加和渲染Box2D实体,以及如何在游戏循环中更新物理世界。 通过分析和运行这些示例代码,你可以深入理解如何在2D游戏中实现逼真的物理效果,如碰撞检测、动态...

    cocos2d-x box2d 物理引擎

    本文将深入探讨如何在cocos2d-x项目中集成并使用Box2D物理引擎。 1. **cocos2d-x简介** cocos2d-x是用C++编写的,基于cocos2d-x Objective-C版本的跨平台游戏开发框架。它支持iOS、Android、Windows、Mac等多个...

    PhysicsEditor-Cocos2d-x-Box2d-master.zip_box2D_cocos2d_cocos2d x

    通过学习这个项目,开发者可以掌握如何在Cocos2d-x游戏中导入并使用Box2D物理系统,以及如何利用PhysicsEditor进行物理世界的可视化设计。这种结合不仅适用于创建基础的2D游戏,对于复杂的物理谜题、平台跳跃或者...

    在cocos2d里面如何使用物理引擎box2d

    ### 在cocos2d中使用物理引擎Box2D:弹球应用详解 #### 一、简介 在cocos2d框架中集成Box2D物理引擎是游戏开发中常见且重要的技术之一,尤其对于那些需要真实物理效果的游戏而言更是如此。Box2D是一个开源的2D物理...

    《Box2dDemo》(Cocos2d-js)

    《Box2dDemo》是基于Cocos2d-js框架实现的一个物理引擎示例项目,它展示了如何使用Box2d库来模拟2D物理世界。Box2d是一个强大的开源物理引擎,广泛应用于游戏开发,可以创建复杂的动态场景,如碰撞检测、重力影响等...

    瘸腿蛤蟆笔记42-cocos2d-x-3.2 Box2d物理引擎Motor Joint代码

    Cocos2d-x是一个广泛使用的2D游戏开发框架,它支持多种物理引擎,其中包括Box2d。Box2d是一款功能强大的2D物理引擎,被许多游戏开发者所青睐。在Cocos2d-x 3.2版本中,开发者可以利用Box2d引擎来创建复杂的物理效果...

    box2d开发说明(cocos2d for iphone)

    cocos2d for iPhone是一个广泛使用的iOS游戏开发框架,Box2D可以无缝集成到该框架中,为iOS平台的游戏添加复杂的物理效果。开发者可以通过以下步骤集成Box2D: 1. **安装Box2D:**首先需要将Box2D库导入到cocos2d ...

    cocos2d-x使用box2d来做碰撞检测

    为了使Cocos2d-x的精灵与Box2D实体关联,我们可以使用`SetUserData`方法将自定义数据(如精灵指针)存储在Box2D身体上,然后在接触监听器中访问这些数据。 最后,别忘了在每个游戏循环中更新Box2D世界: ```cpp ...

    cocos2dx_box2d实例1

    总结,"cocos2dx_box2d实例1"是一个综合性的教程,旨在教会开发者如何在cocos2dx环境中使用Box2D进行物理模拟,并通过瓦片地图创建出具有交互性的积木世界。通过这个实例,我们可以学习到如何集成物理引擎,处理物理...

    瘸腿蛤蟆笔记39-cocos2d-x-3.2 Box2d物理引擎自由落体代码

    在本篇中,我们将深入探讨使用Cocos2d-x 3.2框架集成Box2D物理引擎实现自由落体效果的编程技术。Cocos2d-x是一个广泛使用的开源游戏开发框架,它支持多种平台,包括iOS、Android以及桌面系统。Box2D是一个强大的2D...

    cocos2d-x用box2d实现弹弓游戏

    总结来说,使用cocos2d-x和Box2D构建弹弓游戏,需要理解物理引擎的基本概念,熟悉cocos2d-x的API,以及掌握用户输入处理和UI设计。通过合理的物体建模、力的施加和事件处理,我们可以创建出一款既有趣又有挑战性的...

    cocos2dx-3.0+Box2D例子

    本教程将深入探讨如何在cocos2dx 3.0版本中直接使用Box2D的API接口,而不是依赖cocos2dx内置的物理系统,以实现更灵活和精确的物理模拟。 一、cocos2dx 3.0基础 cocos2dx 3.0是cocos2dx的一个重要升级,它引入了...

    cocos2d-x box2d入门示例

    在游戏开发领域,cocos2d-x是一款广泛使用的2D游戏引擎,而Box2D则是一款强大的物理模拟库。将两者结合,可以轻松实现游戏中的真实物理效果,如碰撞检测、重力模拟等。本文将通过"Box2dTEST2"这个示例项目,深入浅出...

    cocos2d-x box2d 弹球

    在这个"弹球"项目中,开发者利用了Cocos2d-x的图形功能和Box2D的物理模拟能力,创建了一个类似"打砖块"(Breakout)的游戏。"Breakout"是一款经典的街机游戏,玩家通过控制一个挡板反弹球来击碎屏幕上方的砖块。 **...

    基于Cocos2dx + box2d 实现的愤怒的小鸟Demo

    4. **动画与物理模拟的结合**:Cocos2dx的动画系统可以与Box2D的物理模拟协同工作,让游戏对象既有视觉上的平滑移动,又遵循物理规则。 5. **用户交互**:在“愤怒的小鸟”中,玩家通过触摸屏幕控制弹弓发射小鸟。...

    box2d物理引擎使用情况

    10. **集成到游戏框架**:将Box2D与游戏引擎如Unity、Cocos2d-x或其他自定义框架集成也是开发者需要掌握的一项技能,这涉及到API调用、数据结构的转换以及事件处理的协调。 总的来说,Box2D物理引擎提供了强大的2D...

    IOS 开发源码:cocos2dx+box2d的库和演示实例

    在这个示例中,开发者可以学习如何将Box2D集成到cocos2d-x项目中,以及如何利用Box2D进行物理模拟。通常,这个Demo会展示如何创建物理世界,定义物体的物理属性(质量、形状、摩擦系数等),设置重力,处理碰撞事件...

    cocos2d-x box2d 弹球2

    1. **集成Box2D到cocos2d-x项目**:要使用Box2D,你需要先将其库文件添加到cocos2d-x项目中,并正确配置编译选项。这通常涉及设置链接器路径、包含目录以及库依赖。 2. **创建物理世界**:在游戏初始化阶段,我们...

Global site tag (gtag.js) - Google Analytics