Box2D物理碰撞基础知识

上传人:pu****.1 文档编号:567627068 上传时间:2024-07-21 格式:PPT 页数:17 大小:39KB
返回 下载 相关 举报
Box2D物理碰撞基础知识_第1页
第1页 / 共17页
Box2D物理碰撞基础知识_第2页
第2页 / 共17页
Box2D物理碰撞基础知识_第3页
第3页 / 共17页
Box2D物理碰撞基础知识_第4页
第4页 / 共17页
Box2D物理碰撞基础知识_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《Box2D物理碰撞基础知识》由会员分享,可在线阅读,更多相关《Box2D物理碰撞基础知识(17页珍藏版)》请在金锄头文库上搜索。

1、Box2DAuthor:李不凡Blog:GamesHome:QQ:871826122Company:北京星模实训有限公司Website:Box2D简介Box2D是一个用于游戏的2D刚体仿真库。它可以使游戏中物体的运动更加逼真。Box2d有C+,flash和Java等版本。Box2D会自动管理各个物体的碰撞,弹跳等物理状态,我们只需要创建各种刚体。创建刚体可以通过来创建。b2Shape.SetAsBox(width,height)指的是物体的半宽和半高,所以在计算时都要乘以2。由于Box2D本身的限制,运算时要进行长度换算。Box2D核心概念刚体体(rigid body)一块十分坚硬的物质,它上

2、面的任何两点之间的距离都是完全不变的。它们就像钻石那样坚硬。形状形状(shape)一块严格依附于物体(body)的2D碰撞几何结构(collisiongeometry)。形状具有摩擦(friction)和恢复(restitution)的材料性质。约束束(constraint)一个约束(constraint)就是消除物体自由度的物理连接。在2D中,一个物体有3个自由度。如果我们把一个物体钉在墙上(像摆那样),那我们就把它约束到了墙上。这样,此物体就只能绕着这个钉子旋转,所以这个约束消除了它2个自由度。接触接触约束束(contact constraint)一个防止刚体穿透,以及用于模拟摩擦(fri

3、ction)和恢复(restitution)的特殊约束。你永远都不必创建一个接触约束,它们会自动被Box2D创建。关关节(joint)它是一种用于把两个或多个物体固定到一起的约束。Box2D支持的关节类型有:旋转,棱柱,距离等等。关节可以支持限制(limits)和马达(motors)。关关节限制限制(joint limit) 一个关节限制(jointlimit)限定了一个关节的运动范围。例如人类的胳膊肘只能做某一范围角度的运动。关关节马达达(joint motor)一个关节马达能依照关节的自由度来驱动所连接的物体。例如,你可以使用一个马达来驱动一个肘的旋转。世界世界(world)一个物理世界就

4、是物体,形状和约束相互作用的集合。Box2D支持创建多个世界,但这通常是不必要的。积分器分器(integrator)积分器在离散的时间点上模拟物理方程,它将与游戏动画循环一同运行。通常来说游戏物理引擎需要至少60Hz的速度,也就是1/60的时间步。约束求解器束求解器(constraint solver)约束求解器用于解决模拟中的所有约束,一次一个。要得到良好的解,需要迭代所有约束多次。建议的Box2D迭代次数是10次。Box2D注意事项全局的对象的构造函数作了三件事情:1、一个在b2AABB类中的实例构建的坐标系统2、一个定义重力的向量,这是一个b2Vec2类构建的实例。3、一个布尔变量来定义

5、对象是否沉迷。(如果你设置为true,对象将会沉迷)。4、执行Step()函数,每一帧都会更新所有的Body在world中的位置。5、Box2D中的单位为米,30像素=1米。所以在box2D中经常会看到坐标点乘以30,这样就不奇怪为什么用30而不是15或者20的了。Box2DBody创建好World后,可以向World内部添加任何球体或者盒子,以及你想到的任何形状的东西,那我就需要定义一个Body。一个一个body体大概需要做体大概需要做2-4件事情:件事情:1、定义一个形状2、一个(x,y)的位置3、角度4、一个预制的Sprite对象 其中其中3、4是可是可选操作操作。这里我可能不会讲到Bo

6、x2D内设的一些画图类库,因为我们在实际的操作中,可能用的都是自定义的。内设的类库一般用来模拟比较好,进行实际开发可能不适合,所以大家有想研究内设画图类库的可能需要自己去研究一下了。Box2Db2ShapeDef如果你想在你的游戏或者其他的什么中具有一些有特色的东西,你可以通过综合形状定义Body来制作一个Sprite。形状的定义,有3种类型的形状定义,他们都是扩展的b2ShapeDef基类。b2BoxDef类具有具有4个重要的属性个重要的属性:1、SetAsBox(设定边框):这是一个向量,本质上说他就是一个形状的中心坐标2、Density(密度):在碰撞的等式中使用密度*面积=质量,密度如

7、果是0或者null,将会是一个静止的对象。3、Friction(摩擦力):这用来计算两个对象之间的摩擦,可以在之间调整它们。4、Restitution(弹性):这是调整对象弹性程度的属性,可以在之间调整它们。b2CircleDef类中有一个不同的属性,代替SetAsBox是他的Radius(半径)。b2PolyDef类具有一个顶点数组(最大是8)来代替SetAsBox和Radius。这些顶点都是b2Vec2类型的对象。以下通过实例来讲述Box2D的基本用法,在打开源文件在打开源文件进行行测试时,需要把需要把Box2D的的类库放在目放在目录下面,程序才能正常运行下面,程序才能正常运行。Box2D

8、HelloWorldHelloWorld实例中会讲述Box2D的基础用法。1、准备好Box2D类库2、在画自己的形状时,如果不想自己给自己添乱,定义的形状width或者height尽量都能被30整除,这样便于我们的计算3、按前面的讲述,我们需要创建的全局变量里面要有一个World,记分器、约束求解器。同样还要准备一个盒子(b2AABB)、重力(gravity)、是否能睡眠(doSleep)4、添加形状需要用到b2Body、b2BodyDef、b2PolygonDef(多边形)、b2CircleDef(圆形)这几个常用的类。Hello World里面的里面的难点点应该就是第就是第4点,希望大家能

9、注意一下,点,希望大家能注意一下,如果自己做例子如果自己做例子时Rect与与Circle应该怎怎样添加。例子中添加。例子中创建了静建了静态地地面与面与动态的物体。的物体。upData函数函数让整个世界运整个世界运转起来,你可能不需要起来,你可能不需要知道知道for循循环里面到底是怎么运作的,只需要知道里面到底是怎么运作的,只需要知道这个个for循循环让这个个对象开始在世界中象开始在世界中进行模行模拟就可以了就可以了(这个个for循循环是必是必须的的)。Box2D鼠标与刚体交互之移除选中刚体此示例在HelloWorld的基础之上进行扩展,关键操作为getBodyAtMouse()函数,早起看过C

10、+版本而写的此函数。现在网络上可能也能搜到类似的,但是都讲的不是很详细。不过这个函数你有可能不需要到底是怎样运行,仅仅知道这个函数返回与鼠标点相交的刚体就可以了。下面解释一下getBodyAtMouse()函数的机制机制:当鼠当鼠标点点击时,得到当前鼠,得到当前鼠标的坐的坐标点,在此鼠点,在此鼠标点点产生一个生一个很小的很小的刚体,半径在内就有效,然后遍体,半径在内就有效,然后遍历整个世界内部与小整个世界内部与小刚体体产生碰撞的生碰撞的刚体,最后返回碰撞的体,最后返回碰撞的刚体。返回的体。返回的刚体都是唯一体都是唯一的,的,说唯一是因唯一是因为世界内部的世界内部的对象都是象都是刚体,既然是体,

11、既然是刚体,就不会体,就不会产生两个生两个刚体重叠或者相交的情况,所以大家不要感到我体重叠或者相交的情况,所以大家不要感到我说的唯一的唯一很奇怪。很奇怪。Box2D鼠标与刚体交互之拖拽刚体由于Box2D是不直接与鼠标交互的,而是通过鼠标关节b2MouseJoint交互的。交互的过程由四个步骤完成:第一步:获取鼠标单击处的刚体。第二步:创建鼠标关节。第三步:控制鼠标关节。第四步:销毁鼠标关节。获取刚体:publicfunctiongetBodyAtMouse(world:b2World,stage:Stage,includeStatic:Boolean=true):b2Bodyvarmouseb

12、2Vec:b2Vec2=newb2Vec2(stage.mouseX/30,stage.mouseY/30);varaabb:b2AABB=newb2AABB();aabb.lowerBound.Set(mouseb2Vec.x-0.001,mouseb2Vec.y-0.001);aabb.upperBound.Set(mouseb2Vec.x+0.001,mouseb2Vec.y+0.001);varmaxCount:int=10;varshapesArray:Array=newArray();varcount:int=world.Query(aabb,shapesArray,maxCoun

13、t);varbody:b2Body;for(vari:int=0;icount;i+)if(!shapesArrayi.m_body.IsStatic()|includeStatic)vartShape:b2Shape=shapesArrayiasb2Shape;varinside:Boolean=tShape.TestPoint(tShape.m_body.GetXForm(),mouseb2Vec);if(inside)body=tShape.m_body;break;returnbody;创建关节:varlbf_tempBody:b2Body=getBodyAtMouse(lbf_wor

14、ld,stage);if(lbf_tempBody)/设置关节varlbf_mouseJointDef:b2MouseJointDef=newb2MouseJointDef();/设置body1为无碰撞检测形状的静态刚体lbf_mouseJointDef.body1=lbf_world.GetGroundBody();/设置body2为当前被检测到被点击的刚体lbf_mouseJointDef.body2=lbf_tempBody;/设置鼠标关节的目标位置lbf_mouseJointDef.target.Set(mouseX/30,mouseY/30);/设置鼠标关节的力度lbf_mouseJ

15、ointDef.maxForce=10000;/设置鼠标关节的时间步lbf_mouseJointDef.timeStep=lbf_timeStep;/在世界中创建这个b2MouseJoint对象lbf_mouseJoint=lbf_world.CreateJoint(lbf_mouseJointDef)asb2MouseJointlbf_mouseJointDef=null;lbf_tempBody=null;控制关节:/控制鼠标关节很简单,就是在帧循环时间中不断更新鼠标关节的目标位置。if(lbf_mouseJoint)lbf_mouseJoint.SetTarget(newb2Vec2(m

16、ouseX/30,mouseY/30);销毁关节:if(lbf_mouseJoint)lbf_world.DestroyJoint(lbf_mouseJoint);lbf_mouseJoint=null;具体细节请详看:Box2D 鼠鼠标与与刚体交互之拖拽体交互之拖拽刚体体Box2D键盘事件在Box2D中,刚体不仅会受到重力、碰撞等影响,而且也可以施加一个力对它造成影响。可以通过至少以下这几个方法去移动一个刚体:publicfunctionApplyForce(force:b2Vec2,point:b2Vec2):void向目标(世界位置)施加一个力,如果这个力不是施加在刚体的质心,它将产生一

17、个扭矩并影响其角速度,在此之前,它将自动唤醒刚体。力的单位为N。(1N=1kg*m/s2)publicfunctionApplyImpulse(impulse:b2Vec2,point:b2Vec2):void向目标(世界位置)施加一个冲量,它将立刻改变刚体的速度,如果这个力不是施加在刚体的质心,它将影响其角速度,在此之前,它将自动唤醒刚体。冲量的单位为kg*m/s或N*s。publicfunctionSetLinearVelocity(v:b2Vec2):void直接设置质心线速度,需要注意的是它是不会自动唤醒刚体的,所以你必须事先唤醒施加对象再设置质心线速度,免得以为方法不执行。遇到问题应如何具体操作:左右移动时:direction.Set(-2,0);/direction.Set(2,0);player.WakeUp();player.ApplyForce(direction,player.GetWorldCenter();跳跃时:direction.Set(0,-5);player.WakeUp();player.ApplyImpulse(direction,player.GetWorldCenter();详细细节请参考:Box2D 键盘事件事件

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 研究生课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号