在cocos2d中使用box2d物理引擎

来源:互联网 发布:js去掉div边框 编辑:程序博客网 时间:2024/05/17 02:33

虽然是英文网页,但是教程简单明了,看过之后cocos2d中的box2d用法将一目了然。所以值得收藏学习。

转自:http://www.codeandweb.com/blog/2011/03/26/cocos2d-box2d

Tutorial: cocos2d + box2d

在cocos2d中使用box2d物理引擎 - ♂苹果 - 眼睛想旅行

PhysicsEditor with cocos2d and box2d

This is a short tutorial how to use PhysicsEditor together with cocos2d and box2d as physics engine. The project is bases on the box2d template project which comes with cocos2d. The project is complete - it contains cocos2d and everything you need for a quick start.

Structure:

  • Classes - example classes to for the demo
  • libs - cocos2d, box2d and other sources
  • PhysicsEditorSources - the plist loader for box2d
  • Resources - the sprites

The main folder contains the shapedefs.pes file which is the file for PhysicsEditor. You can open this to experiment with parameters and add new sprites to the project.

Setting up box2d

First you need to create the b2World object which runs the complete simulation:

首先你要创建一个b2World,也就是要创键一个世界对象,有了这个对象你才可以通过世界对象去创建后边要创建的物体。

// Define the gravity vector.
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
 
// Do we want to let bodies sleep?
// This will speed up the physics simulation
bool doSleep = true;
 
// Construct a world object, which will hold
// and simulate the rigid bodies.
world = new b2World(gravity, doSleep);
world->SetContinuousPhysics(true);

In the demo I also add some floor shapes which are created programmatically (not shown here).

然后后创建一个地面物体。

Preparing the GB2ShapeCache

Next we need to set up the GB2ShapeCache and load the plist file with the shapes created with PhysicsEditor.(这个PhysicsEditor是原网页的一个植入广告,下扁博文我会讲解box2D的这个形状相关的东西,以及用这个PhysicsEditor生的plist文件的xml解析过程,懂了这个,你自已都可以开发一个PhysicsEditor软件了。网上也有别的关于形状的功能简单一点的软件,自已搜cocos2d工具大全

接着会加载形状的plist文件到缓存中,这个形状plist文件是用物理形状编辑器生成的。这个软件我知道,网上有一大堆。你可以在网上搜cocos2d工具大全。

[[GB2ShapeCache sharedShapeCache]
addShapesWithFile:@"shapedefs.plist"];

Make sure the plist file is in your resources.

Create a CCSprite and attach it to a b2Body

With that done we can create a CCSprite and add it to the current scene:

下边会创建一个精灵,并加入到场景。[self addChild:sprite]; 这个是把精灵填加到场景中的。玩过cocos2d的这个都知道,他这里没有设置精灵坐标,那就是默认的0,0坐标了。

CCSprite *sprite = [CCSprite spriteWithFile:@"object.png"];
[self addChild:sprite];

(I did not use CCBatchNode in this example because I wanted to keep the demo simple and independent from TexturePacker.)(很明显这个 TexturePacker也是原网站的植入广告。对于精灵的这种图片,其实有很多解决方案的,也有不用花钱的

(我没有使用精灵缓存,是为了让试程序看起来更简单明了)

Next is to create a b2Body object. We create a b2_dynamicBody which means that the object will be controlled by box2d. We also set the position and which is very important we also set the userData field to the CCSprite we created in the step before:

接下来创建一个b2Body对象,也就是一个物体对象了。创建的是一个b2_dynamicBody类型意思是,这个物体精灵受box2d控制。设置了物体的初始坐标,这个非常重要,在创建物体之前,设置物体定义的usetData赋值为精灵。

b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
 
bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
bodyDef.userData = sprite;
b2Body *body = world->CreateBody(&bodyDef);

With that done we own a b2Body which has no fixtures or shape yet. We now use the GB2ShapeCache to attach the fixtures created with PhysicsEditor. If you simply dragged the object.png onto PhysicsEditor it's name in the plist file will be object.

Create the body, then add the shape to the body:

这时我们已经有了b2Body物体,但是还没有形状。我们现在要把形状缓存中的形状和物体连上。在PhysicsEditor 物体形状编器中,我们设置我们精灵形状的名字是object.现在我们把形状设置到物体上。

 

[[GB2ShapeCache sharedShapeCache]
addFixturesToBody:body forShapeName:"object"];

The last step is to set the anchor point for the CCSprite. PhysicsEditor allows you to set and edit anchor points. If you don't do this the b2Body and the sprite displayed might have some offset which results in a strange behavior.
最后一步是设置精灵的锚点到形状的锚点坐标上。

[sprite setAnchorPoint:[
[GB2ShapeCache sharedShapeCache]
anchorPointForShape:"object"]];

Simulating the b2World

Now we have the physics in place but also need to update sprites by setting them to the position of the b2Body object and adjust rotation. We do this in the tick routine which we set up to be called from cocos2d's scheduler for each frame (during init)

运行模拟世界。我们要设置物理引擎的帧更新时钟。在cocos2d的init方法中我们使用scheduler定时器来到达我们的目的。

[self schedule: @selector(tick:)];

In the tick we need to simulate the world. box2d does several iteration simulating small time steps and moving the bodies for each of them. Adjusting the values might give you better collision detection and physics behavior but might also result in longer calculation times.
After stepping the world we need to adjust each CCSprite according to the b2Body. We do this by iterating over all bodies in the world. Remember that we stored the CCSprite's pointer in the userdata field of the b2Body. This is how we can adjust them:
下边是定时器运行方法中的bos2D模拟器运行代码。

-(void) tick: (ccTime) dt
{
    int32 velocityIterations = 8;
    int32 positionIterations = 1;
    world->Step(dt, velocityIterations, positionIterations);
 
    for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
    {
        if (b->GetUserData() != NULL)
        {
            CCSprite *myActor = (CCSprite*)b->GetUserData();
            myActor.position = CGPointMake(
            b->GetPosition().x * PTM_RATIO,
            b->GetPosition().y * PTM_RATIO );
            myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
        }
    }
}


What next

Start playing with PhysicsEditor. E.g. adjust the parameters like bounce, friction to see the sprites bounce and jump.
The complete demo project including resouces and all you need to get started can be found in the Examples folder in the dmg file.
 

Source code available for download

The source code is available on github. Either clone it using git:
git clone git@github.com:AndreasLoew/PhysicsEditor-Cocos2d-Box2d.git
or download one of the archives:
去原网站下载demo吧:http://www.codeandweb.com/blog/2011/03/26/cocos2d-box2d
文中的英文我也有不认识的单词,但是代码我可以看的懂。这可是一件很神奇的事情。
阅读全文
0 0