




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Cocos2D苹果游戏开发物理引擎-Box2DBox2D物理引擎是很多著名的iOS游戏背后的驱动力量,比方AngryBirds(愤怒的小鸟)等。游戏开发者可以利用物理引擎创造出更动态和逼真的游戏世界。cocos2d自带了两套物理引擎:Box2D和Chipmunk。两套引擎都是为2D游戏设计的,可以和cocos2d完美整合。Box2D概念BOX2D是一个关于2D游戏的刚体仿真库。程序员可以用它使游戏中的角色灵活移动,并且可以使游戏世界更具有交互性。从游戏引擎角度来看,物理引擎就是一个程序动画〔proceduralanimation〕系统。Box2D用可移植c++编写的。定义在引擎中的大局部类型都有b2的前缀。这样的好处就是足以防止与其它的游戏引擎命名冲突。Box2D与图形渲染系统无关。Box2D
概念
刚体(rigidbody):一块十分坚硬的物质,它上面的任何两点之间的距离都是完全不变的。它们就像钻石那样坚硬。在后面的讨论中,我们用物体(body)来代替刚体。形状〔shape〕:一块严格依附于物体(body)的2D碰撞几何结构(collisiongeometry)。形状具有摩擦(friction)和恢复(restitution)的材料性质。fixture:一个固定装置将一个形状捆绑到一个body上,并添加材料属性,例如密度,摩擦力和恢复。约束〔constraint〕:约束就是一个物理连接,目的是消除body的自由度。在2D中,body中一共有三个自由度〔两个转换坐标和一个旋转坐标〕。触点约束〔contactconstraint〕:一个特殊的约束,目的在于防止侵入刚体,模拟摩擦,恢复。不能创造接触约束,它们是被Box2D自动形成的。关节〔joint〕:这是一个用来将两个或更多的body连接在一起的约束,Box2D支持多种类型的关节。World:物理世界〔physicsworld〕是body,fixtures和约束相互作用的集合刚体物理引擎中存在两种刚体:动态移动的〔dynamic〕和静态的(static)刚体静态刚体不会移动,也不应该移动-因为物理引擎可以依赖静态刚体不会互相碰撞这个特性来做出一些优化。动态刚体会相互碰撞,而且也会和静态刚体碰撞。动态刚体除了拥有位置(position)和旋转(rotation)参数,还有至少3个用于定义动态刚体的参数。密度〔density〕-用于衡量刚体有多重;摩擦力〔friction〕-用于表示刚体在平面上移动时遇到阻力的大小或者有多滑;复原〔restitution〕-用于定义刚体的弹性。物理引擎通过使用力、冲量和扭矩生成动态刚体的变化,而不是直接设置刚体的位置和旋转。在使用物理引擎时不建议直接修改物体的位置和旋转信息,因为如果手动修改物体位置信息的话,物理引擎先前所作的某些假设就会失效。Box2D编程要点单位定义世界定义刚体、形状、fixture同步精灵与物理世界中的刚体碰撞检测释放单位Box2D使用弧度、米、千克、秒为单位Box2D与Cocos2D坐标转换
可以定义常量
#definePTM_RATIO32 Cocos2D=>Box2Dx/PTM_RATIO Box2D=>Cocos2Dx*/PTM_RATIO
定义世界
首先,创立一个世界,每个Box2D程序都将从一个世界对象(worldobject)的创立开始。这是一个管理内存,对象和模拟的中心。b2Vec2gravity;gravity.Set(0.0f,-10.0f);booldoSleep=true;world=newb2World(gravity,doSleep);world->SetContinuousPhysics(true);创立刚体通常由以下步骤来创立刚体:使用位置(position),阻尼(damping)等定义一个物体使用世界对象创立物体使用形状,摩擦,密度等定义fixture在物体上创立fixture创立地面〔一个静态刚体〕第一步:定义物体b2BodyDefgroundBodyDef;groundBodyDef.position.Set(0.0f,0.0f);第二步:创立物体b2Body*groundBody=world-> CreateBody(&groundBodyDef);第三步:定义形状b2PolygonShapegroundBox;groundBox.SetAsBox(50.0f,10.0f);第四步:创立fixturegroundBody->CreateFixture(&groundBox,0.0f);创立一个动态刚体第一步:定义物体b2BodyDefbodyDef;bodyDef.type=b2_dynamicBody;bodyDef.position.Set(0.0f,4.0f);第二步:创立物体 b2Body*body=world-> CreateBody(&bodyDef);第三步:定义形状及fixtureb2PolygonShapedynamicBox;dynamicBox.SetAsBox(1.0f,1.0f);b2FixtureDeffixtureDef;fixtureDef.shape=&dynamicBox;fixtureDef.density=1.0f; //密度fixtureDef.friction=0.3f; //摩擦系数fixtureDef.Restitution=0.1f;//恢复系数第四步:创立fixture body->CreateFixture(&fixtureDef);第五步:设置用户数据Box2D是一个物理引擎,计算的是物理相关的量,与渲染操作无关。目前我们的渲染是使用Cocos2D来完成的,需要有一个途径将Box2D计算的物理结果和Cocos2D的精灵渲染关联起来。Box2D允许我们通过设置用户数据和一个刚体关联。如:CCSprite*sprite=。。。。。。bodyDef.userData=sprite;注:需要在调用createBody之前设置,也可以在创立了body之后,用body->SetUserData(sprite);第六步:给刚体添加力、冲量和力矩让物体移动,需要对其施加力或者冲量。对物体施加力的作用可以通过时间的不断积累来改变物体的运动,而冲量那么是瞬间作用于物体。可以对一个物体应用力,力矩,以及冲量。当应用一个力或冲量时,需要提供一个世界位置。这常常会导致对质心的一个扭矩。Box2D可以通过以下函数来施加对物体的影响voidApplyForce(constb2Vec2&force, constb2Vec2&point);
对刚体施加一个力voidApplyTorque(float32torque);对刚体施加一个绕z轴旋转的力矩,单位是N.mvoidApplyLinearImpulse(constb2Vec2&impulse,constb2Vec2&point);
对刚体施加一个线性冲量voidApplyAngularImpulse(float32impulse);
对刚体施加一个角动量上述函数中的参数中的point指的是力的作用点。这个点需要使用世界坐标系。通过body的函数GetWorldCenter可以得到刚体在世界坐标系中dfe坐标。模拟〔Box2D〕世界我们已经初始化好了地面盒和一个动态盒。现在是让牛顿接手的时刻了。目前只有少数几个问题需要考虑。Box2D中有一些数学代码构成的积分器(integrator),积分器在离散的时间点上模拟物理方程,它将与游戏动画循环一同运行。所以需要为Box2D选取一个时间步,通常来说游戏物理引擎需要至少60Hz的速度,也就是1/60的时间步。float32timeStep=1.0f/60.0f;除了积分器之外,Box2D中还有约束求解器(constraintsolver)。约束求解器用于解决模拟中的所有约束。单个的约束会被完美的求解,然而当求解一个约束的时候,另一个约束求解就会被延后。要得到良好的解,需要迭代所有约束屡次。约束求解器中存在两个阶段:速度阶段和位置阶段。每个阶段有它自己的迭代次数。一个建议的迭代次数如下:int32velocityIterations=8;int32positionIterations=2;注意时间步和迭代数是完全无关的。一个迭代并不是一个子步。一次迭代就是在时间步之中的单次遍历所有约束,可以在单个时间步内屡次遍历约束。现在可以开始模拟循环了,在游戏中模拟循环应该并入游戏循环。每次循环都应该调用b2World::Step,通常调用一次就够了。模拟后,可以遍历每个刚体得到其变化,并用GetUserData方法得到先前设置的精灵,根据刚体的位置和角度变化,改变精灵的相关属性。如下:
int32velocityIterations=8; int32positionIterations=3; world->Step(dt,velocityIterations,positionIterations); //Iterateoverthebodiesinthephysicsworld for(b2Body*b=world->GetBodyList();b;b=b->GetNext()) { if(b->GetUserData()!=NULL){ CSprite*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()); }
清理工作当一个世界对象超出它的作用域,或通过指针将其delete时,所有物体和关节的内存都会被释放。如果自己定义了相关的指针指向物体,形状或关节,应该将这些指针的值设置为NULL,因为它们已经无效了。添加碰撞检测功能接触(contact)是由Box2D创立的用于管理形状间碰撞的对象。接触有不同的种类,它们都派生自b2Contact,用于管理不同类型形状之间的接触。例如,有管理多边形之间碰撞的类,有管理圆形之间碰撞的类。在程序中,碰撞反响是由Box2D完成,不需要程序员干预。但是,有些时候,程序员需要知道哪些物体发生了碰撞,以便做进一步的处理。比方,导弹击中飞机,需要知道哪枚导弹击中了哪架飞机,比把相应的导弹和飞机删除。为此,程序员可以遍历Box2D的接触列表,得到所有发生了接触的刚体。如下代码:-(void)parseContact{b2Vec2contactPoint;contactPoint.SetZero();for(b2Contact*contact=world->GetContactList(); contact;contact=contact->GetNext()){if(contact->GetFixtureA()->GetBody()==contactObj||contact->GetFixtureB()->GetBody()==contactObj){b2Manifold*manifold=contact->GetManifold();switch(manifold->type){caseb2Manifold::e_circles://未使用break;
caseb2Manifold::e_faceA:contactPoint=contact->GetFixtureA()->
GetBody()-> GetWorldPoint(manifold->localPoint);break;caseb2Manifold::e_faceB:contactPoint=contact->GetFixtureB()->
GetBody()->
GetWorldPoint(manifold->localPoint);break;default:break;}}}}碰撞监听Box2D有一个b2ContacListener类,如果想监听碰撞事件,就应该定义一个继承b2ContacListener的类,重写BeginContact和EndContact方法,如下: //ContctListener.h #import"Box2D.h” class
ContactListener:public
b2ContactListener { private: void
BeginContact(b2Contact*contact); void
EndContact(b2Contact*contact);} ;//ContactListener.mm#import"ContactListener.h”#import"cocos2d.h”void
ContactListener::BeginContact(b2Contact*contact){ b2Body*bodyA=contact->GetF
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 健康评估与干预措施的考察试题及答案
- 妇幼保健员考试常见考题试题及答案
- 备战2025健康管理师的常识试题及答案
- 2025年健康管理师考点突破试题及答案
- 融合文化的茶艺师考试试题及答案
- 2025年度网络安全企业员工借调与安全防护服务合同
- 2025年度跨区域公司合并协议书
- 二零二五年度医疗机构卫生监督与评估合同
- 二零二五年度互联网金融服务授权委托书合同
- 2025年度汽车制造企业生产线工人工资合同
- 烟花爆竹仓储企业安全生产风险监测预警系统采购需求
- 医疗器械委托生产管理规程
- 不同类型学生因材施教管理策略研究方案
- 初中美术6-9年级第一学期艺术测评期末试题
- 首都师范大学辅导员考试题库
- 2023年云南省中考数学试卷及解析
- 全科医学科疾病诊疗指南全集诊疗规范
- 安全教育教程大学生安全教育PPT完整全套教学课件
- 小学心理健康教育《第十三课父母的小帮手》
- (通桥【2018】8370)《铁路桥梁快速更换型伸缩缝安装图》
- 2023年东方航空技术应用研发中心有限公司招聘笔试题库含答案解析
评论
0/150
提交评论