锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

【技术讨论】从弹弹堂说起,如何用2D物理引擎编写一个游戏<一>2011-11-05 10:36...

时间:2023-12-05 10:07:03 气缸tox传感器

转自:http://www.cnblogs.com/zcsor/archive/2010/09/09/1822466.html

呃,小儿科拿出来讨论一下。

注意:不要让大家写插件!纯粹是技术讨论。

先写一部分,用于测试。GDI 写的很简单,整体只是雏形,抛砖引玉。

【一、物理引擎】

所谓物理引擎,是通过赋予刚体真实的物理属性来计算其运动、旋转、碰撞等的结果。也许你已经编写了台球游戏,使用了很多数学方法来解决问题,如碰撞检测、线路交叉和折返,但这不是对现实世界的物理模拟。虽然它可以使你的游戏看起来更真实,但当游戏需要更复杂的物体碰撞、滚动、滑动或弹跳(如赛车游戏或保龄球游戏)时,很难编程。物理引擎使用动量、扭矩和其他高等数学手段来模拟真实的物体,这将获得更真实的效果,使我们的编码更容易。当然,好的物理发动机允许复杂的机械装置,如球形关节、轮子、气缸或铰链。有些还支持非刚性体的物理属性,如流体。

著名的物理引擎有:

Lagoa Multiphysics

Physx

Bullet

Havok

等等,他们多提供3D特性,用于在三维空间内来模拟物理运动——就像星际2、暗黑3使用的就是Havok。当然,这些物理引擎可以应用于2D在游戏中,它们的计算量将超过2D引擎。许多物理引擎提供图形界面功能,AI很多游戏元素,比如功能,都很优秀!但我们这里还是比较简单的BOX2D简单地说,它只负责计算物理运动(当然,它也非常强大,除了不支持流体等),然后只提供一些接口,这有利于我们专注于物理引擎的使用。

出处:http://www.cnblogs.com/zcsor/

【二、BOX2D】

Box2D 是游戏用的 2D 刚体仿真库。程序员可以在他们的游戏中使用它,使物体的运动更可信,使世界看起来更互动。从游戏的角度来看,物理引擎是程序性动画(proceduralanimation)而不是动画师移动你的物体。牛顿可以当导演。Box2D 可移植 C 来写成的。引擎中定义的大多数类型都有 b2 前缀,希望能消除与游戏引擎的名称冲突。这就是BOX2D的概况。在学习如何使用它们时,我们首先了解几个必要的概念及其存在的意义:

A、我觉得质量、力、扭矩、冲量大家都很清楚。呃,如果不清楚,可以去百科弥补。……

B、刚体:即物体在碰撞、挤压等力作用后不会变形。你应该注意我的描述。(当然,如果你愿意,你可以告诉我BOX2D改变其任何属性)

C、形状:这决定了物体的外观以及碰撞等发生的位置,当然,还有摩擦的大小等

D、自由:这个概念可能更深奥,但在这里,我们只需要知道,2D物理引擎只模拟物体在平面上的运动——也就是说,你的游戏将是一个平面游戏,即使你空分开,你的游戏也将是一个平面游戏。。。事实上,没有必要在意。很少有游戏使用这种伎俩,我相信XNA向VB.NET微笑时,那些手段会被赶出你的头。

E、世界:我们应该将所有物体限制在一个范围内——当物体运行时,引擎会抛出错误,停止计算物体,所以我们的世界通常足够大……

F、其他:当然,它指的是关节、齿轮等,这与我们的介绍无关。即使在我的代码中,我也使用了一些卑劣的方法来避免使用回调来处理对象的接触——这将使代码更介绍,足以处理如此简单的情况

【三、创造一个世界】

首先,确保引用BOX2D引擎。如果不能在其网站下载:http://www.box2d.org/

接下来,我们将创造一个使用它的世界BOX2D发动机第一步:

世界外边框
Dim Wordaabb As Box2DX.Collision.AABB
Wordaabb.LowerBound.Set(-10000.0F, -10000.0F)
Wordaabb.UpperBound.Set(10000.0F, 10000.0F)
第二个参数是重力,第三个是否允许引擎休眠
world = New Box2DX.Dynamics.World(Wordaabb, g, False)

这样,创建就完成了,很简单!

4.创建一个对象

在BOX2D中,物体是这样创建的:

1.首先,创建了一个物体所以这么叫,是因为是因为它应该只是一个抽象的物体,直到你添加形状并计算质量),但他没有形式

2.指定物体的一些信息:位置、空气阻尼等

3.创建一个形式,并设置由形式关闭的信息:体积、密度、摩擦系数等

出处:http://www.cnblogs.com/zcsor/

4.为物体添加形式,让发动机计算其质量

也许这不是我们习惯的,但你真的应该这样做:先设置形式,然后设置密度,因为不仅是质量决定了物体的运动状态,而且形式将发挥决定性的作用!
创建动态物体的质量必须大于0
Dim bodyDef As New Box2DX.Dynamics.BodyDef

物体的位置
bodyDef.Position.Set(X,Y)

空气阻尼
bodyDef.LinearDamping = Damping

'实际物体
Dim Body As Box2DX.Dynamics.Body

在世界上创造物体
Body = world.CreateBody(bodyDef)
附加一个多边形的物体
Dim shapeDef As New Box2DX.Collision.CircleDef
shapeDef.IsSensor = IsSensor '可否“休眠”即物体不动时引擎是否可以不计算它。(可能听起来有点别扭)
shapeDef.Radius = R 将体积设置为1,使质量计算结果为1
shapeDef.Density = Density '密度
'shapeDef.Friction = 1 '摩擦系数
Dim shape = Body.CreateShape(shapeDef) 附加物体
Body.SetMassFromShapes() 按形状计算质量
到目前为止,我们已经创建了一个动态物体。

【五、物体运动】

好吧,让我们先考虑一下影响我们炮弹运动轨迹的因素:

1、重力

2、发射角度

3、发射力度

4、空气阻尼

5、风力

6.发射点(这是在创建动态物体时指定的。当然,你可以告诉引擎修改它的属性,让它停下来,瞬移到你想要的位置,重新开始运动。但是我没有这样做——因为编码的原因,当它无用的时候,我毁了它,下次计算的时候创建一个新物体,效率不是很低),所以我们不在乎。

好吧,让我们逐一解决这些问题:

1.重力-这个属性属于世界。一般来说,我们将重力定义为向下的向量(BOX2D为内置计算提供向量对象)

Dim g As New Box2DX.Common.Vec2(0.0F, 17.27F) '重力

2.3.发射角度和强度-这将在瞬间完成。不要指望模拟炮筒中的爆炸。得不偿失——我们可以直接用向量作用于物体的纹理:

Body.ApplyImpulse(New Box2DX.Common.Vec2( Math.Cos(Angle) * Power , -Math.Sin(Angle) * Power), Body.GetPosition)

这个句子可能有点复杂实际上有两个参数,一个是冲量,另一个是物体的当前位置。

第一个参数只使用三角形的基本知识来转换发射角度和强度X,Y两个方向的力-获得一个向量^ ^。

4.空气阻尼-属于物体的性质:灰色通常很简单,只需要告诉BOX2D它将应用于迭代器模拟物理运动的计算过程中。

bodyDef.LinearDamping = Damping

5.风-这是一个BOX2D换句话说,没有提供的性质,BOX2D世界上没有风……果然是灰常风和日丽……那怎么办?……

思考中……

思考中……

事实上,物理引擎只不过是在某个时刻(后面将提到步长)获得对象的位置和速度(线速度和角速度),所以我们可以在每次计算中使用一个风。这是我的解决方案,当然,你也可以改变重力的大小和方向来实现目标(风和重力作为重力),也许你有更好的方法……

嗯,我是这样写这个风力代码的:

添加位置到返回数组

Dim ret(MaxStep) As Box2DX.Common.Vec2
For i As Integer = 0 To MaxStep
Body.ApplyForce(f, Body.GetPosition) '应用风力
world.Step(timeStep, MaxStep, 1) 步进计算,第一个参数是步长(多久计算一次),第二个参数是计算最多步数,第三个是迭代数(每次计算时使用迭代器的次数)
ret(i) = New Box2DX.Common.Vec2(Body.GetPosition.X, Body.GetPosition.Y) 当前步位置
'检测进入
'Dim s(0) As Box2DX.Collision.Shape

‘出处:http://www.cnblogs.com/zcsor/
'If RsEvnt = False AndAlso world.Query(mAABB, s, 1) = 1 Then
' RsX = Body.GetPosition.X * 10
' RsY = Body.GetPosition.Y * 10
' RsEvnt = True
'End If
Next

为了看起来更清晰,我仅保留了记录当前位置和应用风力的代码——注释掉的是检测是否击中目标的代码。

至此,我们已经可以得到一个物体的运动轨迹,也许——你应该在GDI+上绘制一下他们了。

 

【六、冲突检测】

BOX2D提供了AABB检测和其他的冲突检测方式。我们这里简要的提一下AABB,如果你感兴趣,完全可以使用“接触监听器”或者“传感器”来完成你的代码。

创建一个AABB检测和使用它将非常简单:只需要设置AABB的两个坐标点——像创建世界外边框那样,指定左上角和右下角。
mAABB.LowerBound.Set(X1, Y1)
mAABB.UpperBound.Set(X2, Y2)

而检测代码已经在上面的代码中了——还记得吗,我把他们注释掉了。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章