天天看点

【cocos2d-x】 Box2d的使用----弹球小例子

cocos2d-x 版本2.2.1

MainSecen.h

//
//  MainScene.h
//  Box2DTest
//
//  Created by xu on 14-1-25.
//
//

#ifndef __Box2DTest__MainScene__
#define __Box2DTest__MainScene__

#include <iostream>

#include "cocos2d.h"
#include "Box2D.h"

USING_NS_CC;

class MainScene : public CCLayer{
public:
    MainScene();
    ~MainScene();
    
    virtual bool init();
    
    static CCScene* scene();
    
    void initViews();
    
    CREATE_FUNC(MainScene);
    
    void tick(float dt);

private:
    b2World* _world;
    b2Body* _body;
    
    CCSprite* _ball;
};

#endif /* defined(__Box2DTest__MainScene__) */

           

MainSecen.cpp

//
//  MainScene.cpp
//  Box2DTest
//
//  Created by xu on 14-1-25.
//
//
#define PTM_RATIO 32
#include "MainScene.h"

MainScene::MainScene(){
    
}

MainScene::~MainScene(){
    _body = NULL;
    _world = NULL;
}

bool MainScene::init(){
    bool sRet = false;
    
    do {
        CC_BREAK_IF(!CCLayer::init());
        
        initViews();
        
        sRet = true;
        
    } while (0);
    
    return sRet;
}

CCScene* MainScene::scene(){

    CCScene* sc = NULL;
    
    do {
        sc = CCScene::create();
        
        CC_BREAK_IF(!sc);
        
        MainScene* layer = MainScene::create();
        
        CC_BREAK_IF(!layer);
        
        sc->addChild(layer);
        
    } while (0);
    
    return sc;

}

void MainScene::initViews(){
    
    CCSize size = CCDirector::sharedDirector()->getWinSize();
    
    _ball = CCSprite::create("Ball.jpg");
    _ball->setPosition(ccp(size.width / 2 ,size.height-100));
    this->addChild(_ball);
    
    //创建世界的重力方向,为Y轴-30。即向下
    b2Vec2 gravity = b2Vec2(0.0f,-30.0f);
    
    //设置世界里的对象是否可以休眠
    
    _world = new b2World(gravity);
    _world->SetAllowSleeping(true);
    
    /*
      1.创建一个body定义结构体,并且指定它应该放在左下角。
     */
    
    //创建世界
    
    b2BodyDef groundBodyDef;
    
    groundBodyDef.position.Set(0, 0);
    
    /*
     2.使用world对象来创建body对象。(注意,这里一定要使用world对象来创建,不能直接new,因为world对象会做一些内存管理操作。)
     */
    
    b2Body* groundBody = _world->CreateBody(&groundBodyDef);
    
    /*
     3.为屏幕的每一个边界创建一个多边形shape。这些“shape”仅仅是一些线段。注意,我们把像素转换成了“meter”。通过除以之前定义的比率来实现的。
     
     4.创建一个fixture定义,指定shape为polygon shape。使用body对象来为每一个shape创建一个fixture对象。
     注意:一个body对象可以包含许许多多的fixture对象。
     */
    
    b2EdgeShape groundEdge; //创建阻挡
    
    groundEdge.Set(b2Vec2(0,size.height/PTM_RATIO),b2Vec2(size.width/PTM_RATIO,size.height/PTM_RATIO));     //top
    groundBody->CreateFixture(&groundEdge,0);
    
    groundEdge.Set(b2Vec2(0,0), b2Vec2(size.width / PTM_RATIO,0));      //bottom
    groundBody->CreateFixture(&groundEdge,0);
    
    groundEdge.Set(b2Vec2(0,0),b2Vec2(0,size.height / PTM_RATIO));      //left
    groundBody->CreateFixture(&groundEdge,0);
    
    groundEdge.Set(b2Vec2(size.width / PTM_RATIO,0),b2Vec2(size.width / PTM_RATIO,size.height/PTM_RATIO));         //right
    groundBody->CreateFixture(&groundEdge,0);

    
    /*
     
     */
    
    b2BodyDef ballBodyDef;
    
    ballBodyDef.type = b2_dynamicBody;
    ballBodyDef.position.Set(size.width / 2 /PTM_RATIO, (size.height - 100)/PTM_RATIO);
    ballBodyDef.userData = _ball;
    _body = _world->CreateBody(&ballBodyDef);
    
    //为小球设置冲量
    
    float boxChangeRate = 20.0f;
    
    b2Vec2 vecT = b2Vec2(_body->GetMass() * ( boxChangeRate),0);
    
    _body->ApplyLinearImpulse(vecT,_body->GetWorldCenter());
    
    b2CircleShape circle ;
    circle.m_radius = 26.0 / PTM_RATIO;
    
    b2FixtureDef ballShapeDef;
    ballShapeDef.shape = &circle;           // 关联的形状
    ballShapeDef.density = 10.1f;            // 密度
    ballShapeDef.friction = 0.2f;           // 摩擦
    ballShapeDef.restitution = 0.9999f;        // 恢复
    
    _body->CreateFixture(&ballShapeDef);    // 创建刚体关联
    
    
    schedule(schedule_selector(MainScene::tick));
    
}

void MainScene::tick(float dt){
    _world->Step(dt, 10, 10);
    for (b2Body* b = _world->GetBodyList(); b; b=b->GetNext()) {
        if(b->GetUserData() != NULL){
            CCSprite *ballData = (CCSprite *)b->GetUserData();
            ballData->setPosition(ccp(b->GetPosition().x * PTM_RATIO,b->GetPosition().y * PTM_RATIO));
            ballData->setRotation(-1 * CC_RADIANS_TO_DEGREES(b->GetAngle()));
        }
    }
}


           

继续阅读