`
445822357
  • 浏览: 771218 次
文章分类
社区版块
存档分类
最新评论

cocos2d-x box2d Demo讲解

 
阅读更多

勤奋努力,持之以恒!

核心概念

Box2D 中有一些基本的对象,这里我们先做一个简要的定义,在随后的文档里会有更详细的描述。

刚体(rigid body)

一块十分坚硬的物质,它上面的任何两点之间的距离都是完全不变的。它们就像钻石那样坚硬。在后面的讨论中,我们用物体(body)来代替刚体。

形状(shape)

一块严格依附于物体(body)的 2D 碰撞几何结构(collision geometry)。形状具有摩擦(friction)和恢复(restitution)的材料性质。

page2image8264page2image8424page2image8584

约束(constraint)

一个约束(constraint)就是消除物体自由度的物理连接。在 2D 中,一个物体有 3 个自由度。如果我们把一个物体钉在墙上(像摆锤那样),那我们就把它约束到了墙上。这样,此物体就只能绕着这个钉子旋转,所以这个约束消除了它 2 个自由度。

接触约束(contact constraint)

一个防止刚体穿透,以及用于模拟摩擦(friction)和恢复(restitution)的特殊约束。你永远都不必创建一个接触约束,它们会自动被 Box2D 创建。

关节(joint)

它是一种用于把两个或多个物体固定到一起的约束。Box2D 支持的关节类型有:旋转,棱柱,距离等等。关节可以支持限制(limits)和马达(motors)。

关节限制(joint limit)

一个关节限制(joint limit)限定了一个关节的运动范围。例如人类的胳膊肘只能做某一范围角度的运动。

关节马达(joint motor)

一个关节马达能依照关节的自由度来驱动所连接的物体。例如,你可以使用一个马达来驱动一个肘的旋转。

世界(world)

一个物理世界就是物体,形状和约束相互作用的集合。Box2D 支持创建多个世界,但这通常是不必要的

//
//  HelloWorldScene.cpp
//  Box2d
//
//  Created by XiangZi on 14-6-23.
//  Copyright __MyCompanyName__ 2014年. All rights reserved.
//
#include "HelloWorldScene.h"

//单位:Box2D中距离以米为单位,质量以公斤为单位,时间以秒为单位。
//屏幕的宽度和高度值除以一个名为 PTM_RATIO 的常量,把像素值转换成了以米为单位来计算长度。

#define PTM_RATIO 32  //PTM_RATIO用于定义32个像素在Box2D世界中等同于1米。

enum {
    kTagParentNode = 1,
};

PhysicsSprite::PhysicsSprite()
: m_pBody(NULL)
{

}

void PhysicsSprite::setPhysicsBody(b2Body * body)
{
    m_pBody = body;
}

//重写isDirty方法,返回YES,目的是让每次layer的update调用后重新绘制PhysicsSprite精灵。
bool PhysicsSprite::isDirty(void)
{
    return true;
}

/*
 重写精灵的矩阵变换方法nodeToParentTransform,模板提供的这个实现,能改变精灵的位置和角度。
 我们会看到,在update函数中,调用了Box2D的Step方法,这个方法根据时间流逝计算出每个刚体的新位置和角度,
 然后在这里被使用最终达到精灵移动旋转的目的。
 */
CCAffineTransform PhysicsSprite::nodeToParentTransform(void)
{
    b2Vec2 pos  = m_pBody->GetPosition();

    float x = pos.x * PTM_RATIO;
    float y = pos.y * PTM_RATIO;

    if ( isIgnoreAnchorPointForPosition() ) {
        x += m_obAnchorPointInPoints.x;
        y += m_obAnchorPointInPoints.y;
    }

    // Make matrix
    float radians = m_pBody->GetAngle();
    float c = cosf(radians);
    float s = sinf(radians);

    if( ! m_obAnchorPointInPoints.equals(CCPointZero) ){
        x += c*-m_obAnchorPointInPoints.x + -s*-m_obAnchorPointInPoints.y;
        y += s*-m_obAnchorPointInPoints.x + c*-m_obAnchorPointInPoints.y;
    }

    // Rot, Translate Matrix
    m_sTransform = CCAffineTransformMake( c,  s,
        -s,    c,
        x,    y );

    return m_sTransform;
}

HelloWorld::HelloWorld()
{
    setTouchEnabled( true );
    setAccelerometerEnabled( true );

    CCSize s = CCDirector::sharedDirector()->getWinSize();
    // init physics
    this->initPhysics();

    CCSpriteBatchNode *parent = CCSpriteBatchNode::create("blocks.png", 100);
    m_pSpriteTexture = parent->getTexture();

    addChild(parent, 0, kTagParentNode);


    addNewSpriteAtPosition(ccp(s.width/2, s.height/2));

    CCLabelTTF *label = CCLabelTTF::create("Tap screen", "Marker Felt", 32);
    addChild(label, 0);
    label->setColor(ccc3(0,0,255));
    label->setPosition(ccp( s.width/2, s.height-50));
    
    scheduleUpdate();
}

HelloWorld::~HelloWorld()
{
    delete world;
    world = NULL;
    
}

void HelloWorld::initPhysics()
{

    CCSize s = CCDirector::sharedDirector()->getWinSize();

    b2Vec2 gravity;
    gravity.Set(0.0f, -10.0f);
    //对Box2D世界进行初始化
    world = new b2World(gravity);
    /*
     会“睡眠”的动态刚体:当施加到某个刚体上的力量小于临界值一段时间以后,这个刚体将会进入“睡眠”状态。
     换句话说,如果某个刚体移动或者旋转的很慢或者根本不在动的话,物理引擎将会把它标记为“睡眠”状态,
     不再对其施加力量,直到新的力量施加到刚体上让其再次移动或者旋转。通过把一些刚体标记为“睡眠”状态,
     物理引擎可以省下很多时间。除非你游戏中的所有动态刚体处于持续的运动中,否则应该把
     SetAllowSleeping变量设置为true。
     */
    world->SetAllowSleeping(true);
    //设置检测连续碰撞
    world->SetContinuousPhysics(true);
    
    //1.创建一个body定义结构体,用以指定body的初始属性,比如位置或者速度。
    b2BodyDef groundBodyDef;
    groundBodyDef.position.Set(0, 0);
    
    //2.调用world对象来创建一个body对象
    b2Body* groundBody = world->CreateBody(&groundBodyDef);
    
    //3.为body对象定义一个shape,用以指定想要仿真的物体的几何形状。
    b2EdgeShape groundBox;

    //4.创建一个fixture定义,同时设置之前创建好的shape为fixture的一个属性,并且设置其它的属性,比如质量或者摩擦力。
    // bottom
    groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);
    // top
    groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);
    // left
    groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(0,0));
    groundBody->CreateFixture(&groundBox,0);
    // right
    groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);
}

void HelloWorld::draw()
{
    //
    // IMPORTANT:
    // This is only for debug purposes
    // It is recommend to disable it
    
    CCLayer::draw();

    ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );

    kmGLPushMatrix();

    world->DrawDebugData();

    kmGLPopMatrix();
}

void HelloWorld::addNewSpriteAtPosition(CCPoint p)
{
    CCNode* parent = getChildByTag(kTagParentNode);
    
    //有一个64x64的精灵表有4种不同的32x32的图像,只是随机挑选其中一个图像。
    int idx = (CCRANDOM_0_1() > .5 ? 0:1);
    int idy = (CCRANDOM_0_1() > .5 ? 0:1);
    PhysicsSprite *sprite = new PhysicsSprite();
    sprite->initWithTexture(m_pSpriteTexture, CCRectMake(32 * idx,32 * idy,32,32));
    sprite->autorelease();
    parent->addChild(sprite);
    sprite->setPosition( CCPointMake( p.x, p.y) );
    
    //1.创建一个body定义结构体,用以指定body的初始属性,比如位置或者速度。
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
    
    //2.调用world对象来创建一个body对象
    b2Body *body = world->CreateBody(&bodyDef);
    
    //3.为body对象定义一个shape,用以指定想要仿真的物体的几何形状。
    b2PolygonShape dynamicBox;
    dynamicBox.SetAsBox(.5f, .5f);//These are mid points for our 1m box
    
    /*4.创建一个fixture定义,同时设置之前创建好的shape为fixture的一个属性,并且设置其它的属性,比如质量或者摩擦力。
     density,friction和restitution参数的意义:
     Density 就是单位体积的质量(密度)。因此,一个对象的密度越大,那么它就有更多的质量,当然就会越难以移动.
     Friction 就是摩擦力。它的范围是0-1.0, 0意味着没有摩擦,1代表最大摩擦,几乎移不动的摩擦。
     Restitution 回复力。它的范围也是0到1.0. 0意味着对象碰撞之后不会反弹,1意味着是完全弹性碰撞,会以同样的速度反弹。
    */
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicBox;    
    fixtureDef.density = 1.0f; //密度
    fixtureDef.friction = 0.3f; //摩擦力
    body->CreateFixture(&fixtureDef);
    
    //调用sprite的setPhysicsBody来为一个sprite设定body。
    sprite->setPhysicsBody(body);
}

//更新每个刚体相关联的精灵的位置和旋转信息
void HelloWorld::update(float dt)
{
    int velocityIterations = 8;
    int positionIterations = 1;
    /*
     Box2D的world是通过定期地调用Step方法来实现动画的。
     Step方法需要三个参数。
     第一个是timeStep,它会告诉Box2D自从上次更新以后已经过去多长时间了,直接影响着刚体会在这一步移动多长距离。
        不建议使用dt来作为timeStep的值,因为dt会上下浮动,刚体就不能以相同的速度移动了。
     第二和第三个参数是迭代次数。它们被用于决定物理模拟的精确程度,也决定着计算刚体移动所需要的时间。
     */
    world->Step(0.015, velocityIterations, positionIterations);
    
    //在物理世界world中遍历每一个刚体body
    for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
    {
        if (b->GetUserData() != NULL) {
            //Synchronize the AtlasSprites position and rotation with the corresponding body
            CCSprite* myActor = (CCSprite*)b->GetUserData();
            myActor->setPosition( CCPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO) ); //单位转换 米->像素
            myActor->setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) ); //单位转换 弧度->角度
        }    
    }
}

void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)
{
    CCSetIterator it;
    CCTouch* touch;
    
    for( it = touches->begin(); it != touches->end(); it++) 
    {
        touch = (CCTouch*)(*it);
        
        if(!touch) break;
        
        CCPoint location = touch->getLocation();
        addNewSpriteAtPosition( location );
    }
}

CCScene* HelloWorld::scene()
{
    CCScene *scene = CCScene::create();
    CCLayer* layer = new HelloWorld();
    scene->addChild(layer);
    layer->release();
    
    return scene;
}



分享到:
评论

相关推荐

    cocos2d-x+lua游戏demo源码

    【cocos2d-x+lua游戏demo源码】是一个基于cocos2d-x游戏引擎和lua脚本语言的游戏示例项目。cocos2d-x是一个跨平台的2D游戏开发框架,广泛应用于移动设备,如iOS和Android。lua是一种轻量级的、面向过程的编程语言,...

    Cocos2d-JS---demo

    Cocos2d-JS 是一个基于 JavaScript 的游戏开发框架,它是 Cocos2d-x 的 JavaScript 版本。这个“Cocos2d-JS---demo”压缩包包含的是使用 Cocos2d-JS 开发的游戏或应用的示例,用于展示其功能和效果。通过将这些 demo...

    Cocos2d-x demo程序

    4. **物理引擎**:Cocos2d-x 集成了Box2D物理引擎,可用于模拟现实世界的物理行为,如重力、碰撞检测等。Demo可能包含了如何设置物理世界、创建刚体和关节的示例。 5. **事件与触摸响应**:Cocos2d-x 支持事件监听...

    cocos2d-X水果忍者效果demo

    在cocos2d-X中,我们可以使用Box2D库来处理物理模拟和碰撞检测。Box2D允许开发者创建物理世界,定义物体的形状、质量、摩擦力等属性,并自动检测它们之间的碰撞。在水果忍者游戏中,水果和刀片的碰撞检测是通过Box2D...

    地球人己阻止不了程序猿们学习cocos2d-x了-学习笔记04 .源码

    如果"FlyGame"涉及到物体碰撞或者物理行为,那么Cocos2d-x的Box2D物理引擎可能会被用到。这将帮助处理游戏中的碰撞检测、重力、弹跳等物理现象。 4. **事件处理(Event Handling)**: Cocos2d-x提供了事件系统,...

    自己写的cocos2d-x的小demo

    6. **物理引擎**:Cocos2d-x集成了Box2D物理引擎,用于处理物体的碰撞检测和物理运动。这对于创建具有真实感的物理效果的游戏非常重要。 7. **音频管理**:Cocos2d-x提供`CCTouchDispatcher`类来处理音频播放,包括...

    cocos2d-x封神榜demo源码

    《cocos2d-x封神榜demo源码》是一个基于cocos2d-x游戏引擎开发的项目,旨在为初学者提供一个深入理解游戏开发过程的实例。cocos2d-x是一个开源的、跨平台的2D游戏开发框架,广泛应用于iOS、Android、Windows等多平台...

    flyGame,cocos2d-x,demo

    cocos2d-x集成了Box2D库,允许开发者创建物理世界,设置刚体、关节、碰撞监听等。这使得游戏中的物体运动更加真实,如飞行物体的轨迹、碰撞效果等。 最后,cocos2d-x的调试和发布流程也是开发者需要掌握的。在...

    cocos2d-x_心之所向demo

    【cocos2d-x_心之所向demo】是一款专为cocos2d-x新手设计的学习资源,包含了丰富的教程和实际的演示项目。cocos2d-x是一个强大的跨平台2D游戏开发框架,它允许开发者使用C++、Lua或JavaScript编写游戏代码,并在iOS...

    使用cocos2d-x-2.0-2.0.4开发的简单跨平台益智类魔塔小游戏

    《使用cocos2d-x-2.0-2.0.4开发的简单跨平台益智类魔塔小游戏》 cocos2d-x是一个开源的游戏开发框架,它基于C++,支持多平台,包括iOS、Android、Windows以及Mac OS等。在本项目中,开发者利用cocos2d-x 2.0.4版本...

    MIPool 小台球 demo Box2d cocos2d-x2.2.3 源代码

    《MIPool小台球Demo基于Box2d与cocos2d-x 2.2.3的源码解析》 本文将深入探讨"MIPool小台球"游戏Demo的源代码,该Demo是利用Box2D物理引擎和cocos2d-x 2.2.3游戏开发框架构建的。Box2D是一个强大的2D物理引擎,广泛...

    Cocos2d-x 摇杆demo

    此外,还可以利用Cocos2d-x的物理引擎(如Box2D)来模拟摇杆的物理行为。 4. **坐标转换**:Cocos2d-x使用屏幕坐标系统,但游戏世界可能有自己的坐标系统。因此,需要将触摸位置转换为游戏世界的坐标,以便正确地...

    基于cocos2d-x 3.8 开发的 愤怒的小鸟demo

    《基于Cocos2d-x 3.8的“愤怒的小鸟”Demo开发详解》 Cocos2d-x是一个跨平台的2D游戏开发框架,它使用C++编写,支持多种操作系统,包括iOS、Android、Windows等。在Cocos2d-x 3.8版本中,开发者可以利用其强大的...

    接盘子cocos2d-x

    6. 物理引擎:虽然这个Demo可能并未使用物理引擎,但Cocos2d-x集成了Box2D,如果游戏需要更复杂的物理交互,如碰撞检测,就可以利用物理引擎来实现。 7. 资源管理:Cocos2d-x有内置的资源加载器,可以方便地加载...

    Cocos2d-html5-v0.5.0-alpha2

    Cocos2d-x是Cocos2d家族的一员,最初是为Objective-C设计的,但随着HTML5的崛起,Cocos2d-x扩展到了HTML5领域,诞生了Cocos2d-html5。这个版本的发布,标志着Cocos2d-x对HTML5生态系统的深入支持,为开发者提供了更...

    cocos2d-x v2.1.1版本的SimpleGame demo

    5. **物理引擎**:如果SimpleGame涉及到物理效果,如碰撞检测,cocos2d-x集成了Box2D物理引擎,可以创建物理世界、定义物理形状,并设置碰撞行为。 6. **资源管理**:`Resources`目录包含了游戏所需的所有资源,如...

    cocos2d-Lua示例demo源码踩虫子-MOD美国大兵

    6. **物理引擎**:cocos2d-x集成了Box2D物理引擎,可以用来模拟物体的碰撞、重力等物理效果。在这个项目中,可能用于实现虫子的运动轨迹和角色之间的碰撞检测。 7. **用户界面(UI)**:cocos2d-Lua提供了创建和...

    cocos2d-x 打飞机源码与资源

    5. **物理引擎**:虽然描述中没有明确提及,但打飞机游戏可能利用了Cocos2d-x内置的Box2D物理引擎,用于处理飞机碰撞、爆炸等物理行为。 6. **用户输入处理**:游戏需要响应用户的触摸或键盘输入,控制飞机移动和...

    ios-cocos2d-objc实现的跑酷游戏.zip

    【描述】提到的"github地址:https://github.com/LLSkittles/cocos2D-iphone-demo"是该项目在GitHub上的存储库,这表明我们可以从这个公开的代码仓库获取到完整的源代码和相关资源。GitHub是一个面向开源及私有软件...

    cocos2d demo

    5. **物理引擎(Box2D)**:cocos2d-x集成了Box2D物理引擎,可以用于创建真实的物理效果,如重力、碰撞检测和物体互动。 6. **事件处理(Event Handling)**:通过事件监听器,开发者可以响应用户的触摸、键盘输入...

Global site tag (gtag.js) - Google Analytics