`
yangping_Account
  • 浏览: 192860 次
  • 性别: Icon_minigender_1
  • 来自: 无锡
社区版块
存档分类
最新评论

使用Box2d物理系统

 
阅读更多

 

原文地址: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; bb = 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中代码换成我上面的代码即可~


分享到:
评论

相关推荐

    BOX2D 物理游戏编程初学者指南 陈文登(高清,带目录)

    高清带目录《Box2D物理游戏编程初学者指南》系统地梳理学习Box2D物理游戏编程的各个知识点,并通过图解、问答、举例等形式深入浅出地讲解初学者觉得晦涩难懂的概念、术语。  《Box2D物理游戏编程初学者指南》最后,...

    box2d物理引擎cocos2d

    在本案例中,我们看到的"box2d物理引擎cocos2d"是Cocos2d集成了Box2D物理引擎的一个实例,它涵盖了Cocos2d的2.x和3.x两个版本。 Box2D引擎的核心概念包括刚体(Bodies)、形状(Shapes)、关节(Joints)和力...

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

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

    Box2D中文手册

    5. **固定时间步长**:Box2D使用固定时间步长来保证物理模拟的稳定性和可预测性,避免了因帧率变化导致的不一致现象。 6. **摩擦力与弹力**:Box2D可以模拟物体间的摩擦力和弹性,使物体之间的相互作用更为真实,...

    Box2D物理游戏编程初学者指南 源文件

    这个"Box2D物理游戏编程初学者指南 源文件"提供了学习Box2D和2D游戏物理编程的基础资源。下面将详细介绍Box2D以及如何使用它进行游戏开发。 1. **Box2D简介**: Box2D是由Ernesto San Pablo开发的,旨在简化2D物理...

    cocos2d-x box2d 物理引擎

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

    Box2D物理游戏编程初学者指南

    《Box2D物理游戏编程初学者指南》这本书是为那些希望掌握2D物理游戏编程技术的人精心编写的。作者陈文凳通过清晰的阐述和丰富的示例,帮助读者理解和应用Box2D的核心概念。 首先,我们要理解Box2D的基本结构。Box2D...

    Box 2D 物理引擎

    Box2D物理引擎源码及中文文档;Box2d有C++,flash和Java等版本。android可以直接使用java版本的Jbox2d,但因为Jbox2d的图形渲染是使用processing库来实现的,所以,在android中使用Jbox2d的时候,图形渲染的工作就...

    as3.0 box2d物理引擎 包括引擎代码和教程和一个例子

    这个压缩包包含的资源是关于AS3.0版本的Box2D物理引擎,其中包括了引擎的源代码、教程以及一个示例项目,可以帮助开发者更好地理解和应用Box2D。 首先,Box2D物理引擎是一个强大的工具,它允许开发者创建具有真实...

    第07章 游戏开发的核心——Box2D物理引擎.zip

    在游戏开发中,通常会使用Box2D的API来创建、更新和销毁物理对象。开发者需要定义物体的属性(如质量、密度、转动惯量),设置初始位置和速度,然后让Box2D的模拟器处理物理计算。在每帧渲染之前,开发者会调用Box2D...

    BOX2D 物理游戏编程初学者指南_扫描版

    通过这本书,初学者不仅能够掌握Box2D物理引擎的基本使用,还能了解到如何将其应用于实际游戏项目中。虽然书中示例基于ActionScript,但Box2D的核心概念在其他语言(如C++)中也是通用的,所以即使读者对C++感兴趣,...

    Box2D物理游戏编程基础

    Box2D 是一款开源的2D物理引擎,广泛应用于游戏开发中,用于模拟现实世界的物理行为。它的设计目标是为开发者提供一个简单、高效且功能强大的物理模拟平台。Box2Dweb是Box2D的JavaScript版本,允许在网页上进行物理...

    box2d物理引擎使用情况

    总的来说,Box2D物理引擎提供了强大的2D物理模拟功能,通过深入理解和熟练运用上述知识点,开发者能够创造出更加逼真、动态的游戏体验。在实际项目中,不断实践和学习,掌握Box2D的高级特性和技巧,将有助于提升游戏...

    box2d物理引擎和资料

    以下是关于Box2D物理引擎的一些关键知识点: 1. **基本概念**: - **刚体(Rigid Bodies)**:Box2D中的基本实体,可以是静态或动态。静态刚体不会受到力的影响,而动态刚体则会受力影响并改变运动状态。 - **...

    Box2D:给你的Qt程序加上物理引擎(包含windows+linux版)

    Box2D是一个流行的开源2D物理引擎,常用于游戏开发和其他需要实时物理模拟的应用中。在本主题中,我们将探讨如何将Box2D集成到Qt应用程序中,为你的项目添加真实的物理效果。Qt是一个功能强大的C++框架,用于创建跨...

    Android Box2d物理世界源码.rar

    这个"Android Box2D物理世界源码"压缩包很可能包含了一整套用于在Android应用中实现2D物理模拟的代码。让我们深入探讨Box2D在Android开发中的应用以及可能的源码结构。 Box2D由Erin Catto创建,它允许开发者模拟...

    Box2D物理引擎使用 拆方块游戏 源代码|No8.rar

    本项目提供的“拆方块游戏”源代码是基于Box2D物理引擎实现的一个实例,旨在帮助开发者理解如何运用Box2D来创建具有真实感的物理效果的游戏。 Box2D引擎的核心在于模拟现实世界的物理现象,如重力、碰撞检测、摩擦...

    AS3.0 Box2D物理引荐

    Box2D是一个开源的2D物理引擎,广泛用于游戏开发、模拟和教育软件,它可以为开发者提供真实的物理效果,如重力、碰撞检测、摩擦力等。在AS3.0(ActionScript 3.0)中,Box2D被用作Flash平台的游戏物理引擎,使开发者...

    laya as3.0使用box2d实现赛车4轮移动demo

    在本文中,我们将深入探讨如何使用Laya AS3.0框架和Box2D物理引擎来创建一个赛车游戏的4轮移动演示。Laya是一个强大的HTML5开发平台,它支持ActionScript 3.0语法,而Box2D则是一个广泛使用的2D物理模拟库,能够帮助...

    box2d中文教程.pdf

    ### Box2D中文教程知识点概览 ...通过以上内容,我们可以看出Box2D是一款功能强大且易于使用的2D物理引擎,非常适合游戏开发者用来模拟真实世界中的物理现象。无论是初学者还是经验丰富的开发者都能从中获益。

Global site tag (gtag.js) - Google Analytics