cocos2d-x 之 CCPhysicsSprite 基于物理引擎的Sprite

勤奋努力,持之以恒!

box2d简单介绍可参阅:http://blog.csdn.net/song_hui_xiang/article/details/34116399

写这篇文章主要是说明:对一个刚体施加一个力,用 GetWorldVector() 与不用的区别。刚开始学习box2d,因为这个问题被虐了好几天,贴出来一是分享,二是备忘。下面直接上代码:

.h

//
//  Game.h
//  HeroJump
//
//  Created by XiangZi on 14-6-27.
//
//

#ifndef __HeroJump__Game__
#define __HeroJump__Game__

#include "cocos2d.h"
#include "Box2D.h"
#include "cocos-ext.h"//用CCPhysicsSprite类需要导入此头文件
using namespace std;
USING_NS_CC_EXT;
USING_NS_CC;

enum GameTag{
    kTag,
};
enum MenuTag{
    
};
enum GamezOrder{
    zOrder,
};

class Game : public CCLayer {
public:
    ~Game();
    Game();
    static CCScene* scene();
    void initPhysics();
    virtual void draw();
    void update(float dt);
    CCPhysicsSprite* createNewPhysicsSprite(const char *imageName);
    
    virtual void onEnter();
    virtual void onExit();
    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
private:
    b2World* world;
    CCSize size;
};

#endif /* defined(__HeroJump__Game__) */


.cpp

//
//  Game.cpp
//  HeroJump
//
//  Created by XiangZi on 14-6-27.
//
//

#include "Game.h"

#define PTM_RATIO 32

Game::Game()
{
    setAccelerometerEnabled( true );
    size = CCDirector::sharedDirector()->getWinSize();
    //创建物理世界
    b2Vec2 gravity;
    gravity.Set(0.0f, -10.0f);
    world = new b2World(gravity);
    world->SetAllowSleeping(true);
    world->SetContinuousPhysics(true);
    
    b2BodyDef groundBodyDef;
    groundBodyDef.position.Set(0, 0);
    b2Body* groundBody = world->CreateBody(&groundBodyDef);
    b2EdgeShape groundBox;
    // bottom
    groundBox.Set(b2Vec2(0,0), b2Vec2(size.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);
    // top
    groundBox.Set(b2Vec2(0,size.height/PTM_RATIO), b2Vec2(size.width/PTM_RATIO,size.height/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);
    // left
    groundBox.Set(b2Vec2(0,size.height/PTM_RATIO), b2Vec2(0,0));
    groundBody->CreateFixture(&groundBox,0);
    // right
    groundBox.Set(b2Vec2(size.width/PTM_RATIO,size.height/PTM_RATIO), b2Vec2(size.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);
    
    this->initPhysics();
    scheduleUpdate();
}
Game::~Game()
{
    delete world;
    world = NULL;
}

void Game::initPhysics()
{
    CCPhysicsSprite* sprite = createNewPhysicsSprite("Icon.png");
    sprite->setPosition(ccp(size.width/2, size.height/2));
    this->addChild(sprite,1,1234);
}

//封装此方法用于创建一物理精灵
CCPhysicsSprite* Game::createNewPhysicsSprite(const char *imageName)
{
    CCPhysicsSprite* physicsSprite = CCPhysicsSprite::create(imageName);
    
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    
    b2Body* body = world->CreateBody(&bodyDef);
    
    b2PolygonShape polygonShape;
    polygonShape.SetAsBox(physicsSprite->getContentSize().width/PTM_RATIO/2, physicsSprite->getContentSize().height/PTM_RATIO/2);
    
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &polygonShape;
    fixtureDef.density = 5.5f;
    fixtureDef.friction = 0.3f;
    fixtureDef.restitution = 0.1f;
    body->CreateFixture(&fixtureDef);
    
    physicsSprite->setPTMRatio(PTM_RATIO);
    physicsSprite->setB2Body(body);
    
    return physicsSprite;
}


bool Game::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
    CCPoint point = pTouch->getLocation();
    CCPhysicsSprite* sprite = (CCPhysicsSprite*)this->getChildByTag(1234);
    b2Body* body = sprite->getB2Body();
    
    float gravityX = 5.0f;
    float gravityY = 10.0f;
    
    //给body施加一个力。 GetWorldCenter()方法用来获取刚体的重心。
    //b2Vec2 force = body->GetWorldVector(b2Vec2(-gravityX,gravityY));  以此body的坐标系计算向量,body有转动向量方向也会随之转动。
    b2Vec2 force = b2Vec2(-gravityX,gravityY); //以整个wrold世界的坐标系计算向量,不随单个body装动而转动。
    
    if (point.x < size.width/2) {//点击屏幕左半边给予一个左上的速度
        force.x = -gravityX;
    }else{//点击屏幕右半边给予一个右上的速度
        force.x = gravityX;
    }
    //直接影响刚体的速度。setLinearVelocity添加的速度会覆盖刚体原有的速度。
    body->SetLinearVelocity(b2Vec2_zero);
    body->SetAngularVelocity(0);
    body->SetAwake(true);
    body->SetLinearVelocity(force);
    
    return true;
}
void Game::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent){}
void Game::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent){}

void Game::onEnter()
{
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, false);
    CCLayer::onEnter();
}
void Game::onExit()
{
    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
    CCLayer::onExit();
}
void Game::update(float dt)
{
    int velocityIterations = 8;
    int positionIterations = 1;
    world->Step(1.0f/60.0f, velocityIterations, positionIterations);
}
void Game::draw()
{
    CCLayer::draw();
    ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
    kmGLPushMatrix();
    world->DrawDebugData();
    kmGLPopMatrix();
}
CCScene* Game::scene()
{
    CCScene *scene = CCScene::create();
    CCLayer* layer = new Game();
    scene->addChild(layer);
    layer->release();
    return scene;
}


你可能感兴趣的:(cocos2d-x 之 CCPhysicsSprite 基于物理引擎的Sprite)