Cocos2d的ChipMunk

ChipMunk

直接了当点,算是给大家普及概念,ChipMunk 就是一个物理引擎,类似BOX2D 这种,chipmunk本是一个独立的开源项目,用纯c编写.cocos2d同时整合了chipmunk和box2d两个物理引擎.相比之下,chipmunk更轻量易用。


介绍点简单的概念:

space:这是一个虚拟出物理空间,所有刚体(body),形状(shape),连接(joint)都在这个空间里发生物理事件.
body:刚体.在物理上,刚体是被抽象为一个物理例子实体单元去看待的,但是它不同与真正的粒子,因为刚体可以有形状(shape)并且可以旋转.另 外,刚体上附带着最基本的物理属性:
shape:刚体的形状.刚体间发生碰撞,是以刚体的形状外延为碰撞临界的.一个刚体可以附加多个shape形成复杂的刚体外形.同属于一个刚体的形状之 间不会发生碰撞.
joint:连接,两个以上的刚体连接在一起,比如一条锁链,是由多个刚体的铁环组成的.具体joint的使用,暂时还没深入研究.


Chipmunk是怎样工作的?
Chipmunk在一个“虚拟的Chipmunk空间”中模拟了物理行为。而你需要做的是:
在这个空间内添加物体。
例如:表示动物,花朵或者布偶的形状。
告诉Chipmunk这些物体上受到了哪些力的作用。
例如:重力,风,外星人的引力光线,等等。
偶尔给Chipmunk一段时间来更新模拟结果。
例如:Chipmunk可能会运算出一个动物相比上个时刻掉落了一段距离,一朵鲜花在风中微微倾斜,Gonzo可能被拉向空中。
 根据物理模拟的结果更新你“真实”的Cocos2D世界。
例如:设置你的动物,鲜花,或者布偶精灵的位置,使它们与Chipmunk模拟的虚拟物体位置相同。
上面需要理解的最关键的点是:Chipmunk空间和Cocos2D空间完全不同。
Bodies and Shapes 刚体和形状
在你深入研究代码之前,还有一点需要理解:Chipmunk的刚体和形状的概念。
一个Chipmunk刚体代表了Chipmunk虚拟世界中的一个物体。刚体可以包含一个或多个Chipmunk形状来表示其几何定义,如下图所示。
这幅图展示了我们用来表示猫咪床的Chipmunk刚体。它包含三个Chipmunk形状——床的左侧部分,右侧部分和床的底部。
有两种Chipmunk刚体:
动态刚体是可以移动的——大多数情况下会用到。
静态刚体永远不会移动——它们通常被用于制作游戏中的地面和其它永久静止的装置。
对于每个Chipmunk刚体,你可以定义它的质量。质量越大,它移动起来就越困难,并且变的很重。
当你创建形状时,你可以制定它们是矩形盒,圆形,多边形,段落(有厚度的直线段)。对于每个形状,你可以设定下面一些属性:
弹性:代表物体的弹力如何。如果设置为0,它就一点弹性没有。如果设置为1,物体会以相同的反弹力回弹。如果设置大于1,那么会以更大的力回弹!
摩擦:表示物体有多滑。如果设置为0,它就会相当光滑。如果设置为1或更高,那么它就一点都不滑。



Cocos2d-x Chipmunk示例代码概览
这是你第一次看到如何向Chipmunk场景中添加物体,因此,让我们一段一段地学习。
创造一些墙,确保物体不会掉出屏幕。
向Chipmunk空间添加各种形状。
设定触摸事件,实现点击屏幕时可以添加精灵。
下面的工程在cocos2d-x的示例工程中被命名为ChipmunkTest。
创建Chipmunk空间
下面这一步创建一个虚拟的Chipmunk空间,用来模拟物理的运行。
用一个对象cpSpace来表示Chipmunk空间——你只需要创建并初始化它。
切换到头文件(这里是:ChipmunkTest.h),做如下更改:

  
  
  
  
  1. // At top of file
  2. #include "chipmunk.h"
  3. // Inside @interface
  4. cpSpace* m_pSpace;

在这里,你只需要引入chipmunk头文件,然后声明一个实例变量来记录Chipmunk空间,因为你会经常使用它!
然后切换到cpp文件(ChipmunkTest.cpp),做如下修改:

  
  
  
  
  1. void ChipmunkTestLayer::initPhysics()
  2. {
  3. #if CC_ENABLE_CHIPMUNK_INTEGRATION
  4. // init chipmunk
  5. //cpInitChipmunk();
  6. m_pSpace = cpSpaceNew();
  7. m_pSpace->gravity = cpv(0, -100);
  8. // Physics debug layer
  9. m_pDebugLayer = CCPhysicsDebugNode::create(m_pSpace);
  10. this->addChild(m_pDebugLayer, Z_PHYSICS_DEBUG);
  11. #endif
  12. }

第一行调用了cpSpaceNew方法来创建一个新的Chipmunk虚拟空间,将其存放到实例变量中。
第二行设置Chipmunk空间的重力为:x轴方向无,y轴方向适当。在这里设定的值将会极大影响游戏中的“正确感觉”。
添加“墙”
对于很多游戏,向Chipmunk空间中添加物体来表示“墙”是非常有用的。比如,在这个游戏中,我们打算创建一个线段形状,从左下延伸到右下。这样做,可以让我们创建的物理碰撞到地面,而不是掉出屏幕!
添加地面,需要到ChipmunkTestLayer::initPhysics()方法中做如下修改:

  
  
  
  
  1. // rogue shapes
  2. // We have to free them manually
  3. //
  4. // bottom
  5. m_pWalls[0] = cpSegmentShapeNew( m_pSpace->staticBody,
  6. cpv(VisibleRect::leftBottom().x,VisibleRect::leftBottom().y),
  7. cpv(VisibleRect::rightBottom().x, VisibleRect::rightBottom().y), 0.0f);
  8. // top
  9. m_pWalls[1] = cpSegmentShapeNew( m_pSpace->staticBody,
  10. cpv(VisibleRect::leftTop().x, VisibleRect::leftTop().y),
  11. cpv(VisibleRect::rightTop().x, VisibleRect::rightTop().y), 0.0f);
  12. // left
  13. m_pWalls[2] = cpSegmentShapeNew( m_pSpace->staticBody,
  14. cpv(VisibleRect::leftBottom().x,VisibleRect::leftBottom().y),
  15. cpv(VisibleRect::leftTop().x,VisibleRect::leftTop().y), 0.0f);
  16. // right
  17. m_pWalls[3] = cpSegmentShapeNew( m_pSpace->staticBody,
  18. cpv(VisibleRect::rightBottom().x, VisibleRect::rightBottom().y),
  19. cpv(VisibleRect::rightTop().x, VisibleRect::rightTop().y), 0.0f);
  20. for( int i=0;i
  21. e = 1.0f;
  22. m_pWalls[i]->u = 1.0f;
  23. cpSpaceAddStaticShape(m_pSpace, m_pWalls[i] );
  24. }

添加刚体/形状
下面,我们将要创建一个helper方法,它用来向场景中添加一个动态(可移动的)Chipmunk刚体。

  
  
  
  
  1. void ChipmunkTestLayer::addNewSpriteAtPosition(CCPoint pos)
  2. {
  3. #if CC_ENABLE_CHIPMUNK_INTEGRATION
  4. int posx, posy;
  5. CCNode *parent = getChildByTag(kTagParentNode);
  6. posx = CCRANDOM_0_1() * 200.0f;
  7. posy = CCRANDOM_0_1() * 200.0f;
  8. posx = (posx % 4) * 85;
  9. posy = (posy % 3) * 121;
  10. int num = 4;
  11. cpVect verts[] = {
  12. cpv(-24,-54),
  13. cpv(-24, 54),
  14. cpv( 24, 54),
  15. cpv( 24,-54),
  16. };
  17. cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero));
  18. body->p = cpv(pos.x, pos.y);
  19. cpSpaceAddBody(m_pSpace, body);
  20. cpShape* shape = cpPolyShapeNew(body, num, verts, cpvzero);
  21. shape->e = 0.5f; shape->u = 0.5f;
  22. cpSpaceAddShape(m_pSpace, shape);
  23. CCPhysicsSprite *sprite = CCPhysicsSprite::createWithTexture(m_pSpriteTexture, CCRectMake(posx, posy, 85, 121));
  24. parent->addChild(sprite);
  25. sprite->setCPBody(body);
  26. sprite->setPosition(pos);
  27. #endif
  28. }

这和第三步看起来十分类似。
你只需要调用cpBodyNew方法就可以在点击屏幕的时候创建一个动态(可移动的)刚体。
设定触摸事件
我们需要在触摸屏幕的时候创建一个新的刚体。我将会向你展示实现此功能最简便的方法。

  
  
  
  
  1. void ChipmunkTestLayer::ccTouchesEnded(CCSet* touches, CCEvent* event)
  2. {
  3. //Add a new body/atlas sprite at the touched location
  4. CCSetIterator it;
  5. CCTouch* touch;
  6. for( it = touches->begin(); it != touches->end(); it++)
  7. {
  8. touch = (CCTouch*)(*it);
  9. if(!touch)
  10. break;
  11. CCPoint location = touch->getLocation();
  12. addNewSpriteAtPosition( location );
  13. }
  14. }

我们在这里调用getLocation,这个方法返回触摸点在Cocos2D坐标系中的位置。最终,我们调用addNewSpriteAtPosition方法来在点击处添加精灵。
编译并运行
编译并运行!如果都正常的话,当你点击屏幕的时候,可以看到刚体掉落到地面,弹起一些,然后再落下.




你可能感兴趣的:(Cocos2d的ChipMunk)