勤奋努力,持之以恒。

核心概念

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;
}

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

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

  1. cocos2d之Box2D详细说明 鼠标联合实现

    cocos2d之Box2D具体解释 鼠标关节实现 DionysosLai2014-5-7 我们常常要移动物理世界中的某个物体,例如说石头.木块等.假设我们直接改变这些物体的位置,让这些物体尾随我们手指 ...

  2. Spring3.0 demo (注解自动注入)

    这个demo是maven工程,目录结构如下 pom.xml maven依赖 .....省略 <dependency> <groupId>org.springframework& ...

  3. cocos2d中box2d讲解一

    在游戏中我们经常要加入物理碰撞等和物理有关的内容,在游戏中加入物理引擎可以使我们的游戏更加真实,为玩家展示一个更真实的世界,cocos2d-x支持两个物理引擎Box2d和Chipmunk,本文介绍bo ...

  4. Cocos2d学习之路五(Box2d使用CCPhysicsSprite时编译不通过解决方法)

    cocos2d使用box2d引擎,在使用CCPhysicsSprite添加精灵的时候会出现编译不通过错误. 需要注意以下几点: 1.sprite.position=ccp(p.x,p.y);这行代码一 ...

  5. Visual Studio 2012下Box2D开发环境设置

    Cocos2d-x 3.x默认情况下采用的物理引擎是Chipmunk,如果我们要使用Box2D引擎,需要进行一些设置和调整,而且不同的开发平台下这些设置也有所不同.由于本书在此之前介绍的都是基于微软的 ...

  6. kotlin之注解

    注解是用来代码添加元数据的一种手段,要声明一个 注解,需要在类之前添加annotation修饰符 annotation class demo 注解其他属性,可以通过向注解类添加元注解的方式来指定 @T ...

  7. 【spring boot】SpringBoot初学(6)– aop与自定义注解

    前言 github: https://github.com/vergilyn/SpringBootDemo 一.AOP 官方demo:https://github.com/spring-project ...

  8. 内存管理和@property的属性

    内存管理和@property的属性 目录 对内存管理的理解 Objective C内存管理方式 内存的管理 对象的所有权和内存管理原则 合理解决内存管理带来的问题 自动释放池 @property的属性 ...

  9. 我常用的iphone开发学习网站[原创]

    引用地址:http://www.cnblogs.com/fuleying/archive/2011/08/13/2137032.html Google 翻译 Box2d 托德的Box2D的教程! Bo ...

随机推荐

  1. ActivityGroup简单介绍

    ActivityGroup简单介绍 1.ActivityGroup的核心就是继承了该类,可以通过getLocalActivityManager()得到一个LocalActivityManager 如, ...

  2. java+mysql对于表情的处理

    环境错误: mysql 5.0: utf8编码 jdbc:mysql-connector-java-5.1.5-bin.jar 情符的情况下报错: java.sql.SQLException: Inc ...

  3. tera term 残ALT债券

    Setup -> Keyboard对话框 Meta key变: left 版权声明:本文博客原创文章,博客,未经同意,不得转载.

  4. Hadoop云计算大数据书籍分享

    1. 推荐书名    大数据云计算利器: Hadoop, The Definitive Guide, 1Ed.pdf(第1版)    大数据云计算利器: Hadoop, The Definitive ...

  5. UVA12304 2D Geometry 110 in 1! 计算几何

    计算几何: 堆几何模版就能够了. . .. Description Problem E 2D Geometry 110 in 1! This is a collection of 110 (in bi ...

  6. Android四个多线程分析:MessageQueue实现

    Android四个多线程分析:MessageQueue的实现 罗朝辉 (http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 在前面两篇文章<Android多线 ...

  7. WPF界面设计技巧(8)—自制山寨版CheckListBox

    原文:WPF界面设计技巧(8)-自制山寨版CheckListBox 近年来IT市场山寨横行啊,我们今天也来发扬一下山寨精神,搞个自制的CheckListBox出来. 喏,CheckListBox 就是 ...

  8. 《JavaScript设计模式与开发实践》读书笔记之单例模式

    1.单例模式 保证一个类仅有一个实例,并提供一个访问它的全局访问点 1.1 传统的单例模式 var Singleton=function(name){ this.name=name; } Single ...

  9. Lucene 实例教程(四)之检索方法总结

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本人声明.否则将追究法律责任. 作者: 永恒の_☆ 地址: http://blog.csdn.net/chenghui031 ...

  10. c#为了实现自己的线程池功能(一)

    线程池的技术背景 在面向对象编程中,创建和销毁对象是非常费时间的,由于创建一个对象要获取内存资源或者其他很多其他资源,所以提高服务程序效率的一个手段就是尽可能降低创建和销毁对象的次数.特别是一些非常耗 ...