box2D 物理引擎例子

#ifndef __HELLOWORLD_SCENE_H__

#define __HELLOWORLD_SCENE_H__


#include "cocos2d.h"


#include "Box2D/Box2D.h"


#include "SimpleAudioEngine.h"


class HelloWorld : public cocos2d::CCLayer

{

public:

    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone

    virtual bool init();

    

    // there's no 'id' in cpp, so we recommand to return the exactly class pointer

    static cocos2d::CCScene* scene();

    

    // a selector callback

    void menuCloseCallback(CCObject* pSender);

    b2World *world;

    void ccTouchesEnded( cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent );

    

    void update( float dt );//随时触发事件这里的dt就是你运行程序左下角三行数中的第二行数字

    void addNewSpriteWithCoords( cocos2d::CCPoint point, cocos2d::CCSprite *sprite );//添加精灵

    // implement the "static node()" method manually

    CREATE_FUNC(HelloWorld);

};


#endif // __HELLOWORLD_SCENE_H__










#include "HelloWorldScene.h"

#define PTM_RATIO 32//像素与米的比例,在物理引擎中单位是MKS【米、千克、米】这里是为游戏中像素和物理世界中的米转换做的准备

using namespace cocos2d;


CCScene* HelloWorld::scene()

{

    CCScene * scene = NULL;

    do

    {

        // 'scene' is an autorelease object

        scene = CCScene::create();

        CC_BREAK_IF(! scene);

        

        // 'layer' is an autorelease object

        HelloWorld *layer = HelloWorld::create();

        CC_BREAK_IF(! layer);

        

        // add layer as a child to scene

        scene->addChild(layer);

    } while (0);

    

    // return the scene

    return scene;

}


// on "init" you need to initialize your instance

bool HelloWorld::init()

{

    bool bRet = false;

    do

    {

        //

        // super init first

        //

        

        CC_BREAK_IF(! CCLayer::init());

        

        //

        // add your codes below...

        //

        

        // 1. Add a menu item with "X" image, which is clicked to quit the program.

        

        // Create a "close" menu item with close icon, it's an auto release object.

        CCMenuItemImage *pCloseItem = CCMenuItemImage::create(

                                                              "CloseNormal.png",

                                                              "CloseSelected.png",

                                                              this,

                                                              menu_selector(HelloWorld::menuCloseCallback));

        CC_BREAK_IF(! pCloseItem);

        

        // Place the menu item bottom-right conner.

        pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));

        

        // Create a menu with the "close" menu item, it's an auto release object.

        CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);

        pMenu->setPosition(CCPointZero);

        CC_BREAK_IF(! pMenu);

        

        // Add the menu to HelloWorld layer as a child layer.

        this->addChild(pMenu, 1);

        

        // 2. Add a label shows "Hello World".

        

        // Create a label and initialize with string "Hello World".

        CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);

        CC_BREAK_IF(! pLabel);

        

        // Get window size and place the label upper.

        CCSize size = CCDirector::sharedDirector()->getWinSize();

        pLabel->setPosition(ccp(size.width / 2, size.height - 50));

        

        // Add the label to HelloWorld layer as a child layer.

        this->addChild(pLabel, 1);

        

        // 3. Add add a splash screen, show the cocos2d splash image.

        CCSprite* pSprite = CCSprite::create("HelloWorld.png");

        CC_BREAK_IF(! pSprite);

        

        // Place the sprite on the center of the screen

        pSprite->setPosition(ccp(size.width/2, size.height/2));

        CCLog("aaaaaaaaaaaaaaaaaaa");

        CCLog("x %f ,y %f",pCloseItem->getPosition().x,pCloseItem->getPosition().y);

        CCLog("bbbbbbbbbbbbbbbbbbbbb");

        //pCloseItem->setAnchorPoint(ccp(0,1));

        CCLog("x %f ,y %f", pCloseItem->getAnchorPointInPoints().x,pCloseItem->getAnchorPointInPoints().y);

        CCPoint point = pCloseItem->convertToWorldSpace(ccp(pCloseItem->getAnchorPointInPoints().x,pCloseItem->getAnchorPointInPoints().y));

        CCLog("x %f ,y %f", point.x,point.y);

        point = pCloseItem->convertToNodeSpace(ccp(point.x,point.y));

        CCLog("x %f ,y %f", point.x,point.y);

        //CCLog("x %f ,y %f",pCloseItem->getContentSize().width/2,pCloseItem->getContentSize().width/2);

        // Add the sprite to HelloWorld layer as a child layer.

        this->addChild(pSprite, 0);

        b2Vec2 gravity;

        gravity.Set(0.0f,-10.0f);

        world = new b2World( gravity );//创建世界,gravity可以理解为万有引力,物理中的g

        

        CCSize winSize = CCDirector::sharedDirector()->getWinSize();

        b2BodyDef groundBodyDef;

        groundBodyDef.position.Set(0, 0); // bottom-left corner

        // Call the body factory which allocates memory for the ground body

        // from a pool and creates the ground box shape (also from a pool).

        // The body is also added to the world.

        // 创建身体

        b2Body* groundBody = world->CreateBody(&groundBodyDef);

        // Define the ground box shape.

        //创建地面形状:在屏幕四周创建了刚体防止物理世界中的刚体超屏

        b2EdgeShape groundBox;

        // bottom

        groundBox.Set(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO,0));

        groundBody->CreateFixture(&groundBox,0);

        // top

        groundBox.Set(b2Vec2(0,winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO,winSize.height/PTM_RATIO));

        groundBody->CreateFixture(&groundBox,0);

        // left

        groundBox.Set(b2Vec2(0,winSize.height/PTM_RATIO), b2Vec2(0,0));

        groundBody->CreateFixture(&groundBox,0);

        // right

        groundBox.Set(b2Vec2(winSize.width/PTM_RATIO,winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO,0));

        groundBody->CreateFixture(&groundBox,0);

        

        this->setTouchEnabled(true);

        this->setAccelerometerEnabled(true);

        

        this->scheduleUpdate();//执行update函数

        bRet = true;

    } while (0);

    

    return bRet;

}


void HelloWorld::menuCloseCallback(CCObject* pSender)

{

    // "close" menu item clicked

    CCDirector::sharedDirector()->end();

}


void HelloWorld::update( float dt )//注意,之前2dx的版本是用ccTime的,在2.0.3版本中,用float类型

{

    int32 velocityIterations = 8;

    int32 positionIteratoins = 1;

    world->Step( dt, velocityIterations, positionIteratoins);

    for( b2Body *b = world->GetBodyList();b;b = b->GetNext() )

    {

        if(b->GetUserData() != NULL)

        {

            CCSprite *myActor = (CCSprite*)b->GetUserData();

            //,

            myActor->setPosition(ccp((b->GetPosition().x )* PTM_RATIO,b->GetPosition().y * PTM_RATIO));//设置精灵位置

            myActor->setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) );//设置精灵旋转方向

        }

    }

    

}

void HelloWorld::addNewSpriteWithCoords( CCPoint point, CCSprite *sprite )

{

    CCLOG("Add sprite %0.2f x %02.f",point.x,point.y);

    sprite->setPosition(point);

    b2BodyDef bodyDef;//定义刚体

    bodyDef.type = b2_dynamicBody;//使刚体能够在力的作用下运行,刚体有三种:静态的、运动的、动态的

    bodyDef.position.Set( point.x/PTM_RATIO, point.y/PTM_RATIO);//设置刚体的初始位置

    bodyDef.userData = sprite;

    b2Body *body = world->CreateBody( &bodyDef );

    //b2PolygonShape dynamicBox;

    //dynamicBox.SetAsBox(.9f,.9f);

    b2CircleShape dynamicBox;

    dynamicBox.m_radius = 18.0f/PTM_RATIO;//设置半径

    b2FixtureDef fixtureDef;

    fixtureDef.shape = &dynamicBox;//绑定形状

    fixtureDef.density = 1.0f;//设置密度

    fixtureDef.friction = 0.3f;//设置摩擦,当然还可以设置恢复,即反弹,这里我就不一一赘述

    body->CreateFixture( &fixtureDef );

    

    //body施加一个力

    b2Vec2 force = body->GetWorldVector(b2Vec2(00.0f,0.0f));

    b2Vec2 point_force = body->GetWorldPoint( b2Vec2(0.4f,0.4f) );

    body->ApplyForce(force,point_force);

}


void HelloWorld::ccTouchesEnded( CCSet *pTouches, CCEvent *pEvent)

{

    

    CCLog("bb");

    int count = pTouches->count();

    for( CCSetIterator iterTouch = pTouches->begin();iterTouch != pTouches->end();iterTouch++)

    {

        CCTouch *touch = (CCTouch *)*iterTouch;

        cocos2d::CCPoint location = touch->getLocation();

        CCSprite *sprite = CCSprite::create("candy.png");

        this->addChild(sprite);

        this->addNewSpriteWithCoords( location, sprite );

    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值