Cocos2Dx中本来没有物理引擎的,Box2D、Chipmunk这两个物理添加入cocos2dx中,为了模拟出更好的真实游戏世界,好了,看代码例子吧:
typedef enum {
SPRITEBATCHNODE_TAG = 1,
} BatchNodeTag;
MyChipmunkAccelSprite::MyChipmunkAccelSprite() {
}
void MyChipmunkAccelSprite::setPhysicsBody(cpBody *body) {
m_pBody = body;
}
bool MyChipmunkAccelSprite::isDirty() {
return true;
}
CCAffineTransform MyChipmunkAccelSprite::nodeToParentTransform() {
//Version: in Box2D,m_pBody is b2Body
//Version: in Chipmunk,m_pBody is cpBody
float x = m_pBody->p.x;
float y = m_pBody->p.y;
if ( isIgnoreAnchorPointForPosition() ) {
x += m_tAnchorPointInPoints.x;
y += m_tAnchorPointInPoints.y;
}
Make matrix,Version:Box2D
float radians = m_pBody->GetAngle();
float c = cosf(radians);
float s = sinf(radians
// Make matrix,Version:Chipmunk
CCFloat c = m_pBody->rot.x;
CCFloat s = m_pBody->rot.y;
if( ! CCPoint::CCPointEqualToPoint(m_tAnchorPointInPoints, CCPointZero) ){
x += c*-m_tAnchorPointInPoints.x + -s*-m_tAnchorPointInPoints.y;
y += s*-m_tAnchorPointInPoints.x + c*-m_tAnchorPointInPoints.y;
}
// Rot, Translate Matrix
m_tTransform = CCAffineTransformMake( c, s,
-s, c,
x, y );
return m_tTransform;
}
/*
*@MyChipmunkAccelLayer
*/
MyChipmunkAccelLayer::MyChipmunkAccelLayer() {
m_pSpace = 0;
}
MyChipmunkAccelLayer::~MyChipmunkAccelLayer() {
for(int i = 0 ; i < 4 ; i++) {
if(m_Walls[i] != 0) {
cpShapeFree(m_Walls[i]);// after new ,should free the memory
m_Walls[i] = 0;
}
}
if(m_pSpace != 0) {
cpSpaceFree(m_pSpace); // after new ,should free the memory
m_pSpace = 0;
}
}
void MyChipmunkAccelLayer::initLayer() {
CCSize size = CCDirector::sharedDirector()->getWinSize();
m_pSpace = cpSpaceNew();
m_pSpace->gravity =cpv(0, -200.0f); // set the gravity
batch = CCSpriteBatchNode::create("Pea.png", 100);
this->addChild(batch, 1, SPRITEBATCHNODE_TAG);
//set the 4 walls, left ,top ,buttom, right
m_Walls[0] = cpSegmentShapeNew(m_pSpace->staticBody, cpv(0, 0), cpv(size.width, 0), 0.0f);// buttom
m_Walls[1] = cpSegmentShapeNew(m_pSpace->staticBody, cpv(size.width, 0), cpv(size.width, size.height), 0.0f); //right
m_Walls[2] = cpSegmentShapeNew(m_pSpace->staticBody, cpv(size.width, size.height), cpv(0, size.height), 0.0f);//top
m_Walls[3] = cpSegmentShapeNew(m_pSpace->staticBody, cpv(0, size.height), cpv(0, 0), 0.0f);//left
for(int i = 0; i < 4; ++i){
m_Walls[i]->e = 0.5f;
m_Walls[i]->u = 0.5f;
cpSpaceAddStaticShape(m_pSpace, m_Walls[i]);
}
addAnNewSprite(ccp(size.width / 2.0f, size.height / 2.0f));
this->scheduleUpdate();
}
void MyChipmunkAccelLayer::update(float dt) {
int steps = 2;
CCFloat dtime = CCDirector::sharedDirector()->getAnimationInterval() / steps ;
for(int i=0; i < steps; i++){
cpSpaceStep(m_pSpace, dtime);
}
}
void MyChipmunkAccelLayer::onEnter() {
CCLayer::onEnter();
this->setTouchEnabled(true);
this->setAccelerometerEnabled(true);
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, true);
}
void MyChipmunkAccelLayer::onExit() {
CCLayer::onExit();
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
}
void MyChipmunkAccelLayer::addAnNewSprite(const CCPoint &point) {
MyChipmunkAccelSprite *sprite = new MyChipmunkAccelSprite;
sprite->initWithTexture(batch->getTexture());
sprite->setAnchorPoint(ccp(0.5f, 0.5f));
sprite->setPosition(point);
sprite->autorelease();
batch->addChild(sprite, 1);
cpVect verts[] = { //
/*
* the array is the collision of the sprite, the 16 is the size of the sprite's radius
*/
cpv(-16,-16),// left
cpv(-16, 16),// top
cpv( 16, 16),//right
cpv( 16,-16),//bottom
};
cpBody *body = cpBodyNew(3.0f, cpMomentForPoly(3.0f, 4, verts, cpvzero));
body->p = cpv(point.x, point.y);
cpSpaceAddBody(m_pSpace, body); // after init the body, then add the body to the space
cpShape *shape = cpPolyShapeNew(body, 4, verts, cpvzero); //init the shape of the sprite
shape->e = 1.0f;// 弹性系数
shape->u = 0.5f;
cpSpaceAddShape(m_pSpace, shape); // for the sprite, add the shape to the space
sprite->setPhysicsBody(body); // add the shape to the sprite
}
void MyChipmunkAccelLayer::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
}
bool MyChipmunkAccelLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {
CCPoint uiPoint = pTouch->locationInView();
CCPoint glPoint = CCDirector::sharedDirector()->convertToGL(uiPoint);
addAnNewSprite(glPoint);
return true;
}
上面我将两个终点处的解释分别都已注释上。