cocos2d-x box2d Demo注解

勤奋努力,持之以恒。

核心概念

Box2D 中有一些主要的对象,这里我们先做一个简要的定义,在随后的文档里会有更具体的描写叙述。

刚体(rigid body)

一块十分坚硬的物质,它上面的不论什么两点之间的距离都是全然不变的。

它们就像钻石那样坚硬。

在后面的讨论中,我们用物体(body)来取代刚体。

形状(shape)

一块严格依附于物体(body)的 2D 碰撞几何结构(collision geometry)。

形状具有摩擦(friction)和恢复(restitution)的材料性质。

约束(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;
}

版权声明:本文博主原创文章。博客,未经同意不得转载。

时间: 2024-12-27 09:45:34

cocos2d-x box2d Demo注解的相关文章

spring security入门教程 demo注解

http://www.mossle.com/docs/springsecurity3/html/ns-config.html#ns-minimal 这是3.0的中文文档,写的比较详细,还有<spring in action>最新版也有一章专门是讲这个的.在学习的过程下载了spring security的github上面的demo,其中tutorial-xml是最简单的demo了.在源码里我把里面的一些重要的地方都详细注解了,做个备忘. ps:demo的logout似乎不能用,有bug. 链接:

Visual Studio 2012下Box2D开发环境设置

Cocos2d-x 3.x默认情况下采用的物理引擎是Chipmunk,如果我们要使用Box2D引擎,需要进行一些设置和调整,而且不同的开发平台下这些设置也有所不同.由于本书在此之前介绍的都是基于微软的Visual Studio 2012下开发的Win32平台,所以这一节我们介绍Visual Studio 2012下Box2D开发环境设置.这些需要设置和调整的方面包括如下:在解决方案中添加libBox2D库工程.添加libBox2D库引用.开启Box2D预编译开关. 1.在解决方案中添加libBo

COCOS2DX学习之box2d物理引擎在VS2012中的配置

因为vs中并没有继承box2dz游戏物理引擎,所以在开发有关box2d的游戏的时候,要自己将这个引擎添加进去.首先在解决方案中添加一个已经存在的项目,这个项目的路径就是你创建的cocos2dx项目的目录里面cocos2d\external\Box2D\proj.win32这个文件夹下面的一个vs工程,把它添加进去编译好,就会看到proj.win32\Debug.win32中有了Box2d的库. 之后,将生成的box2d的库添加到项目属性的连接器中即可 tool是我创建的coocs2dx项目 CO

注解配置

注解配置 一.注解配置使用 配置 servlvet 的映射路径, 全都在 web.xml 文件中, 非常不方便维护. 注解就是在每个 servlet 之上进行路径的配置 总结: 使用注解配置 servlet的映射路径: @WebServlet 使用注解配置过滤器: @WebFilter 使用注解配置监听器: @WebListener 注解配置映射路径Demo: 注解配置 servlet 1 @WebServlet(urlPatterns= {"/emp/*","/dept/*

IOS游戏开发相关网站

首先记录并分享下我收集到的几个自学时最常用到的一些网站链接. 直接进入正题: 1-Stack Overflow http://stackoverflow.com/ 这个是国外类似于百度知道的网站,但是专注于回答程序开发相关问题,我有非常多的问题都是通过在这里查询解决的,这是我们百度知道所不知道的事情. 2-iOS Developer Library http://developer.apple.com/library/ios/navigation/#section=Resource%20Type

iOS开发小工具

基本上在Mac Appstore里面都有,很多是免费的.因为某种原因要重装Mac系统(这么多年来首次重装Mac系统),特意整理了下备忘. 1.AppIcon: 可以瞬间把图片转换为应用所需要的Icon(Icon-72.png,[email protected],[email protected]) 2.Resizer: 方便把-hd,@2x之类的图片压缩,特别适合配合cocos2d使用 3.Dash 查看各种语言和API的参考文档,C,C++,OBJ-C,cocos2d,cocos2d-x,co

Java知识总结:Java反射机制(用实例理解)

概念理解: 反射是指一类应用,它们能够自描述和自控制.也就是说,这类应用通过采用某种机制来 实现对自己行为的描述( self-representation )和检测( examination) ,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. Java中的反射是一个强大的工具,他能够创建灵活的代码,这些 代码可以在运行时装配,无需在组件之间进行链接,发射允许在编写和执行时,使程序代码能够接入装载到 JVM 中的类的内部信息 .而不是源代码中选定的类协作的代码.这使发射

仿经典《超级玛丽》游戏源码

仿经典<超级玛丽>游戏源码,该游戏很类似我们小时候经常玩的一种超级玛丽游戏的,该游戏很好地模仿了该游戏的,非常不错的,而且也很逼真的,游戏的源码可以很好地锻炼新手的学习cocos2d和box2d的,如果想做手游开发类似这样的游戏的朋友,不妨可以了解一下吧.<ignore_js_op>   <ignore_js_op> <ignore_js_op> <ignore_js_op> 详细说明:http://ios.662p.com/thread-112

史上最全的IOS电子书PDF制作

本人背靠海量纸质图书,可以制作各种纸质书籍的电子化,有需要可以Q:1481449626 <iOS编程 第3版 针对Xcode 4.3 Big Nerd Ranch培训系列>作者:JoeConway,AaronHillegass著:夏伟频译 页数:589 出版社:武汉市:华中科技大学出版社 出版日期:2013.01 简介:<iOS编程(第3版)>更新了iOS5和Xcode4.3的内容.全书涵盖了开发iOS应用的方方面面.从Objective-C基础知识到新增加的语言特性:从AppKi