勤奋努力,持之以恒!
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;
}