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;
}
版权声明:本文博主原创文章。博客,未经同意不得转载。
cocos2d-x box2d Demo注解的更多相关文章
- cocos2d之Box2D详细说明 鼠标联合实现
cocos2d之Box2D具体解释 鼠标关节实现 DionysosLai2014-5-7 我们常常要移动物理世界中的某个物体,例如说石头.木块等.假设我们直接改变这些物体的位置,让这些物体尾随我们手指 ...
- Spring3.0 demo (注解自动注入)
这个demo是maven工程,目录结构如下 pom.xml maven依赖 .....省略 <dependency> <groupId>org.springframework& ...
- cocos2d中box2d讲解一
在游戏中我们经常要加入物理碰撞等和物理有关的内容,在游戏中加入物理引擎可以使我们的游戏更加真实,为玩家展示一个更真实的世界,cocos2d-x支持两个物理引擎Box2d和Chipmunk,本文介绍bo ...
- Cocos2d学习之路五(Box2d使用CCPhysicsSprite时编译不通过解决方法)
cocos2d使用box2d引擎,在使用CCPhysicsSprite添加精灵的时候会出现编译不通过错误. 需要注意以下几点: 1.sprite.position=ccp(p.x,p.y);这行代码一 ...
- Visual Studio 2012下Box2D开发环境设置
Cocos2d-x 3.x默认情况下采用的物理引擎是Chipmunk,如果我们要使用Box2D引擎,需要进行一些设置和调整,而且不同的开发平台下这些设置也有所不同.由于本书在此之前介绍的都是基于微软的 ...
- kotlin之注解
注解是用来代码添加元数据的一种手段,要声明一个 注解,需要在类之前添加annotation修饰符 annotation class demo 注解其他属性,可以通过向注解类添加元注解的方式来指定 @T ...
- 【spring boot】SpringBoot初学(6)– aop与自定义注解
前言 github: https://github.com/vergilyn/SpringBootDemo 一.AOP 官方demo:https://github.com/spring-project ...
- 内存管理和@property的属性
内存管理和@property的属性 目录 对内存管理的理解 Objective C内存管理方式 内存的管理 对象的所有权和内存管理原则 合理解决内存管理带来的问题 自动释放池 @property的属性 ...
- 我常用的iphone开发学习网站[原创]
引用地址:http://www.cnblogs.com/fuleying/archive/2011/08/13/2137032.html Google 翻译 Box2d 托德的Box2D的教程! Bo ...
随机推荐
- 《Effective C++ 》学习笔记——条款02
**************************** 一. Accustoming Yourself to C++ **************************** 条款02: Pref ...
- sleep和wait的区别
sleep指线程被调用时,占着CPU不工作,形象地说明为“占着CPU睡觉”,此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制.wait指线程处于进入等待状态,形象地说明为“等待使用C ...
- RESTEasy:@FormParam、@PathParam、@QueryParam、@HeaderParam、@CookieParam、@MatrixParam说明
在第一RESTEasy教程我们已经学习了基本的Web服务和休息我们已经测试了一个简单的REST风格的Web服务.在本教程中,我们将显示如何将Web应用程序元素(形式参数,查询参数和更多)为REST风格 ...
- Codeforces Jzzhu and Sequences(圆形截面)
# include <stdio.h> int f[10]; int main() { int x,y,n,j; while(~scanf("%d%d%d",& ...
- hdu 3790 (最短路径问题dijkstra)
主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790 Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起 ...
- 【C/C++】BinarySearch
/* * BinarySearch.c * * Created on: 2014年6月25日 * Author: wenbo */ #include <stdio.h> int binar ...
- Android---53---多线程下载
采用HttpURLConnection HttpURLConnection从继承URLConnection,它也可以被用来发送到指定的网站GET求 POST求. 办法: int getResponse ...
- Understanding responsibilities is key to good object-oriented design(转)
对象和数据的主要差别就是对象有行为,行为可以看成责任职责(responsibilities以下简称职责)的一种,理解职责是实现好的OO设计的关键.“Understanding responsibili ...
- REST API 基于ACCESS TOKEN
REST API 基于ACCESS TOKEN 的权限解决方案 REST 设计原则是statelessness的,而且但客户端是APP时,从APP发起的请求,不是基于bowers,无法带相同的se ...
- js匀速运动停止条件
匀速运动,怎么让它到达指定位置时停止呢? 原理: 1,物体和目标的差值距离小于等于速度时,即停止 2,接着让物体移动位置等于目标位置 示例:匀速运动停止 html部分 <input type=& ...