您的位置:首页 > 移动开发 > Cocos引擎

Cocos2d-x简单Box2d代码示例|点击碰撞>HelloWorldScene.cpp<代码演示>

2014-03-19 15:54 876 查看
#include "HelloWorldScene.h"

#include "SimpleAudioEngine.h"

#define PTM_RATIO 32

#define GET_WINSIZE CCDirector::sharedDirector()->getWinSize()

enum {

    
 kTagParentNode =
1,

};

using namespace
cocos2d;

using namespace
CocosDenshion;

USING_NS_CC;

//struct fuc and init elements
PhysicsSprite::PhysicsSprite():m_pBody(NULL){

    
}

//setter machine
void
PhysicsSprite::setPhysicsBody(b2Body *body){

   
m_pBody = body;

    
}
bool
PhysicsSprite::isDirty(){

    return
true;

}

//parentNode trasform

CCAffineTransform PhysicsSprite::nodeToParentTransform(){

    b2Vec2 pos =
m_pBody->GetPosition();//get Postion By b2body
   
float x = pos.x *
PTM_RATIO;//x
   
float y = pos.x *
PTM_RATIO;//y

    //analiys

    if (isIgnoreAnchorPointForPosition()) {

        x+=m_obAnchorPointInPoints.x;

        y+=m_obAnchorPointInPoints.y;
    }

    

    //make matix
   
float radians = m_pBody->GetAngle();
   
float c = cosf(radians);//正弦
   
float s = sinf(radians);//余弦

    

    if (m_obAnchorPointInPoints.equals(CCPointZero))
{

        x += c * - m_obAnchorPointInPoints.x + -s * -
m_obAnchorPointInPoints.y;

        y += s * - m_obAnchorPointInPoints.x + c * -m_obAnchorPointInPoints.y;
    }

    

    //Rot,Translate Matrix
   
m_sTransform = CCAffineTransformMake(c,s,-s,c,x,y);

    return
m_sTransform;
}

//HelloWorld structFuc
HelloWorld::HelloWorld(){

    setTouchEnabled(true);//abled touch

    setAccelerometerEnabled(true);//able remote

    

    

    CCSize s =
GET_WINSIZE;

    //初始化物理系统

    this->initPhysics();

    CCSpriteBatchNode *parent =
CCSpriteBatchNode::create("bloks.png",100);
   
m_pSpriteTexture = parent->getTexture();

    addChild(parent,kTagParentNode);

    //position

    addNewSpriteAtPosition(ccp(s.width/2,s.height/2));

    

    CCLabelTTF *label =
CCLabelTTF::create("Tap Screen",
"Marker Felt", 32);
   
addChild(label,0);
    label->setColor(ccc3(0,
0, 255));
    label->setPosition(ccp(s.width/2, s.height/2-50));

    scheduleUpdate();
}

//析构
HelloWorld::~HelloWorld(){

   
delete world;
   
world = NULL;

    

//    delete m_debugDraw;

    
}
void
HelloWorld::initPhysics(){

    CCSize s =
GET_WINSIZE;
   
b2Vec2 gravity;
    gravity.Set(0.0f, -10.0f);
   
world = new
b2World(gravity);

    

    //DO we want to let bodies sleep:

    world->SetAllowSleeping(true);

    world->SetContinuousPhysics(true);

    

    //m_debugDrae = new GLESDEbugDraw(PTM_RATIO);

//    world->SetDebugDraw(m_debugDraw);
   
uint32 flags = 0;
    flags +=
b2Draw::e_shapeBit;

//    flags += b2Draw::e_jointBit;

//    flags += b2Draw::e_pairBit;

//    flags += b2Draw::e_centerOfMassBit;

//    flags += b2Draw::e_aabbBit;

    

    //define the ground body
   
b2BodyDef groundBodyDef;
    groundBodyDef.position.Set(0,
0);//bottom-left center

    

    //call the body factory which allocates memory for the gound body

    //from a pool and created the ground box shape(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(s.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);

    //top
    groundBox.Set(b2Vec2(0,s.height/PTM_RATIO),b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);

    //left
    groundBox.Set(b2Vec2(0, s.height/PTM_RATIO),
b2Vec2(0,0));
    groundBody->CreateFixture(&groundBox,0);

    //right
    groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO),
b2Vec2(s.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);
}

void
HelloWorld::draw(){

    //Important;

    //This is only for debug purposes

    //It is recommend to disable it

    //本方法用于调试Box2d
   
CCLayer::draw();

    ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position);

    kmGLPushMatrix();

    world->DrawDebugData();

    kmGLPopMatrix();

    
}
void
HelloWorld::addNewSpriteAtPosition(CCPoint point){

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

    CCNode *parent =
getChildByTag(kTagParentNode);

    //This is just randomly picking one of the images
   
int idx = (CCRANDOM_0_1()>
.5 ? 0 :
1);
   
int idy = (CCRANDOM_0_1()>
.5 ? 0 :
1);

    PhysicsSprite *sprite =
new
PhysicsSprite();
    sprite->initWithTexture(m_pSpriteTexture,CCRectMake(32
* idx, 32 *idy, 32,
32));
    sprite->autorelease();
    parent->addChild(sprite);

    

    //Define the dynamic body

    //Set up 1m squared box in the physics world
   
b2BodyDef bodyDef;
    bodyDef.type =
b2_dynamicBody;
    bodyDef.position.Set(point.x/PTM_RATIO,point.y/PTM_RATIO);

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

    //Define another box shape for our dynamic body
   
b2PolygonShape dynamicBox;

    //This is the middle points for our 1m box
    dynamicBox.SetAsBox(0.5f,
.5f);

    //Define the dynamic body fixture
   
b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicBox;//体积
    fixtureDef.density =
1.0f;//密度
    fixtureDef.friction =
0.3f;
    body->CreateFixture(&fixtureDef);
    sprite->setPhysicsBody(body);
}
void
HelloWorld::update(float dt){

    //It is recommended that a fixed time step is used with Box2D for stabliity

    //of the simulation,however,we are using a variable time step here

    //You need to make an informed choice, the follow URL is useful

    //http://gafferongames.com/game-physics/fix-your-timestep/
   
int velocityIterations =
8;
   
int positionIterations =
1;

    //Instruct the world to perform a single step of simulation .It is

    //generally best to keep the time step ad iterations fixed;
   
world->Step(dt, velocityIterations,positionIterations);

    

    //Iterations over the bodies in the Physics world
   
for (b2Body *b =
world->GetBodyList(); b; b = b->GetNext()) {
       
if (b->GetUserData() !=
NULL) {
           
CCSprite *myActor = (CCSprite *)b->GetUserData();
            myActor->setPosition(CCPointMake(b->GetPosition().x
* PTM_RATIO,
                                             b->GetPosition().y *PTM_RATIO));
            myActor->setRotation(-1*CC_RADIANS_TO_DEGREES(b->GetAngle()));
        }
    }
}
void
HelloWorld::ccTouchesEnded(CCSet *touches,CCEvent *event){

    //Add a new body /atlas sprite at the touched location

    CCSetIterator it;
   
CCTouch *touch;
   
for (it = touches->begin(); it!= touches->end(); it++) {
        touch = (CCTouch *)(* it);
       
if (!touch) {
           
break;
        }
       
CCPoint location = touch->getLocationInView();
        location =
CCDirector::sharedDirector()->convertToGL(location);

        addNewSpriteAtPosition(location);
    }

}

CCScene* HelloWorld::scene(){
   
CCScene *scene = CCScene::create();
   
CCLayer *layer = new
HelloWorld();
    scene->addChild(layer);
    layer->release();
   
return scene;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐