吐槽CSGO物理引擎格斗游戏太复杂,这是游戏还是物理模拟

超逼真的物理模拟!看达人打造的游戏引擎演示
当前位置:超逼真的物理模拟!看达人打造的游戏引擎演示
超逼真的物理模拟!看达人打造的游戏引擎演示
发表: 17:50:44来源:99游戏编辑:
国外达人工作室BeamNG近来正在开发一款次世代级的柔体物理引擎,下面就是外媒给我们带来的该引擎之技术演示,从中我们可以发现该引擎的物理模拟真的是非同一般的赞,敬请欣赏!
热门游戏开服表
最近freestyle这个梗在网上非常火,相关的表情包也层出不穷,不知道吴亦凡看到这样的景象会做何感想。今天99单机为大家带来了一批最新的搞笑内涵图,让我们一起来轻松一乐吧!
  高考结束了,各大高校也都陆续放假,只剩下小编这样的上班族还要继续工作。自从离开了学校就再也没有寒假和暑假了,想到这里泣不成声。不过今天是周末,还是能稍微轻松一下。在这里为大家分享一组搞笑内涵图片,让大家能拥有一个好的心情。也希望大家都能和小编一样,打起十二分的精神努力赚钱,认真工作。
铁拳7PC中文破解版是为玩家集成了铁拳7未加密补丁和汉化补丁的免费游戏资源,将这款铁拳7破解版下载后玩家便可以体验由虚幻4引擎打造的最新的铁拳系列游戏内容。游戏中全文中文语言,并解锁游戏所有内容。
猎天使魔女PC破解版是一款集成了猎天使魔女破解补丁和3dm汉化补丁的免费游戏下载资源,大家将这款猎天使魔女免安装中文破解版下载解压后便可直接进入游戏体验畅爽的战斗内容。
逃生2Outlast2简体中文版是官方汉化的版本,由于游戏一发布就热销,官方也立刻开启了汉化工作,这个版本中添加了简体中文字幕和译文,想要获得更原汁原味的游戏体验,那就赶紧下载吧!
《上古卷轴5:天际重制版》与原版最大的区别在于画面。包括水体效果、叶片效果、天气效果以及贴图画质都得到了相当大的提升。除此之外,主机板玩家还可以获得MOD支持。
异星探险家是以太空探索玩法为主要内容的一款沙盒游戏,是由System Era Softworks开发制作完成。游戏中玩家将驾驶飞船深入太空探索冒险。《csgo爆囧集锦 2》物理引擎最真实的手雷游戏_期-游戏-高清正版视频–爱奇艺
更多频道内容在这里查看
爱奇艺用户将能永久保存播放记录
过滤短视频
暂无长视频(电视剧、纪录片、动漫、综艺、电影)播放记录,
按住视频可进行拖动
&正在加载...
请选择打赏金额:
请选择打赏金额:
{{ each data as item index}}
{{ each data as item index}}
{{if item.isLast}}
&正在加载...
{{ each data as item index}}
{{item.playcount}}
&正在加载...
把视频贴到Blog或BBS
当前浏览器仅支持手动复制代码
视频地址:
flash地址:
html代码:
通用代码:
通用代码可同时支持电脑和移动设备的分享播放
收藏成功,可进入查看所有收藏列表
方式1:用手机看
用爱奇艺APP或微信扫一扫,在手机上继续观看:
方式2:一键下载至手机
限爱奇艺安卓6.0以上版本
使用微信扫一扫,扫描左侧二维码,下载爱奇艺移动APP
其他安装方式:手机浏览器输入短链接http://71.am/udn
下载安装包到本机:&&
设备搜寻中...
请确保您要连接的设备(仅限安卓)登录了同一爱奇艺账号 且安装并开启不低于V6.0以上版本的爱奇艺客户端
连接失败!
请确保您要连接的设备(仅限安卓)登录了同一爱奇艺账号 且安装并开启不低于V6.0以上版本的爱奇艺客户端
部安卓(Android)设备,请点击进行选择
请您在手机端下载爱奇艺移动APP(仅支持安卓客户端)
使用微信扫一扫,下载爱奇艺移动APP
其他安装方式:手机浏览器输入短链接http://71.am/udn
下载安装包到本机:&&
爱奇艺云推送
请您在手机端登录爱奇艺移动APP(仅支持安卓客户端)
使用微信扫一扫,下载爱奇艺移动APP
180秒后更新
打开爱奇艺移动APP,点击“我的-扫一扫”,扫描左侧二维码进行登录
没有安装爱奇艺视频最新客户端?
爸爸去哪儿2游戏 立即参与
30秒后自动关闭
:物理引擎最真实的手雷游戏
播放量数据:快去看看谁在和你一起看视频吧~
{{each data}}
抱歉,没有“{{feature}}”的其他视频了.
&正在加载...
&正在加载...
&正在加载...
&正在加载...
&正在加载...
&正在加载...
{{ each data as item index}}
{{ each data as item index}}
Copyright (C) 2017
All Rights Reserved
您使用浏览器不支持直接复制的功能,建议您使用Ctrl+C或右键全选进行地址复制
安装爱奇艺视频客户端,
马上开始为您下载本片
5秒后自动消失
&li data-elem="tabtitle" data-seq="{{seq}}"&
&a href="javascript:void(0);"&
&span>{{start}}-{{end}}&/span&
&li data-downloadSelect-elem="item" data-downloadSelect-selected="false" data-downloadSelect-tvid="{{tvid}}"&
&a href="javascript:void(0);"&{{pd}}&/a&
选择您要下载的《》剧集:
您使用浏览器不支持直接复制的功能,建议您使用Ctrl+C或右键全选进行地址复制呃,小儿科拿出来讨论一下。
巨注意:不是让大家去写外挂哦!纯属技术讨论。
先写一部分,测试是用GDI+写的,非常的简陋,而且整体只是一个雏形,抛砖引玉。
【一、物理引擎】
&&&&& 所谓物理引擎,是通过为刚体赋予真实的物理属性的方式来计算它们的运动、旋转、碰撞等等的结果。也许你曾经编写过台球游戏,使用了大量的类似于碰撞检测,线相交和折返等等数学方法来解决问题,但那不是对真实世界的物理模拟,虽然可以使你的游戏看起来比较真实,但当游戏需要比较复杂的物体碰撞、滚动、滑动或者弹跳的时候(比如赛车类游戏或者保龄球游戏),通过编程的方法就比较困难了。而物理引擎则使用动量、扭矩等用高等数学手段来模拟真实物体,这将得到更真实的效果且使我们的编码更加容易。当然好的物理引擎允许有复杂的机械装置,像球形关节、轮子、气缸或者铰链。有些也支持非刚性体的物理属性,比如流体。
著名的物理引擎有:
Lagoa Multiphysics
等等,它们多提供3D特性,用于在三维空间内来模拟物理运动——就像星际2、暗黑3使用的就是Havok。这些物理引擎当然可以应用到2D游戏当中,但它们的运算量将会大于2D引擎。很多物理引擎提供了图形界面功能,AI功能等诸多游戏要素,而且非常出色!但我们这里还是从比较简单的BOX2D入手,说它简单是它只负责计算物理运动(当然它也非常强大——除了不支持流体等)进而只提供了很少的一些接口,这有利于我们专注于物理引擎的使用。
【二、BOX2D】
Box2D 是一个用于游戏的 2D 刚体仿真库。程序员可以在他们的游戏里使用它,它可以使物体的运动更加可信,让世界看起来更具交互性。从游戏的视角来看,物理引擎就是一个程序性动画(proceduralanimation)的系统,而不是由动画师去移动你的物体。你可以让牛顿来做导演。Box2D 是用可移植的 C++ 来写成的。引擎中定义的大部分类型都有 b2 前缀,希望这能消除它和游戏引擎之间的名字冲突。这就是BOX2D的概况。在学习如何使用时,我们先认识几个必要概念和它们存在的意义:
A、我想,质量,力,扭矩和冲量大家都非常清楚了,呃,如果不清楚那可以去百科恶补一下……
B、刚体:即说这个物体会在碰撞、挤压等力的作用后不变形。你应该注意我这个描述。(当然如果你愿意,可以告诉BOX2D改变它的任何属性)
C、形状:这决定了物体的外观以及碰撞等发生的位置,当然,还有摩擦的大小等
D、自由度:这个概念也许比较深奥,但在这里,我们只需要知道,2D物理引擎只模拟物体在一个平面上的运动——即你的游戏将是一个平面游戏,即使你用一些手段将地面和墙壁以及天空分开。。。其实不必在意,这种伎俩已经很少有游戏在用了,而且我相信当XNA向VB.NET微笑时,那些手段会被赶出你的脑袋。
E、世界:我们应该把所有物体限定在一个范围内——当物体跑出去了,引擎会抛出一个错误并停止对该物体进行演算,所以,我们的世界通常有足够大……
F、其他:当然指关节,齿轮等,这些与我们入门毫无关系。甚至在我的代码里也采用了一些卑劣的手段避开使用回调方式来处理物体的接触——这将使代码更“入门”,而且也足够应付这么简单的情况
【三、创建一个世界】
首先,确保你引用了BOX2D引擎。如果没有可以在其网站下载:
接下来我们创建一个世界,这是使用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)
这样,就创建完成了,非常简单吧!
【四、创建一个物体】
在BOX2D中,物体是这样创建的:
1、首先有一个“物体”(之所以这样叫,是因为到你附加形状并计算质量之前,它应该只是一个“抽象”的处于意识中的物体)被创建,但是他没有形态
2、指定物体的一些信息:位置,空气阻尼等
3、创建一个形态并设置由形态先关的信息:体积、密度、摩擦系数等
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()&& '根据形状计算质量至此,我们创建了一个动态物体。
【五、物体的运动】
好,我们先考虑一下,影响我们的“炮弹”运动轨迹的因素都有哪些:
2、发射角度
3、发射力度
4、空气阻尼
6、发射点(这在创建动态物体时已经被指定了,当然你可以告诉引擎来修改它的属性来使它停下并“瞬移”到你想要的位置重新开始运动。但我没有这样做——出于编码的原因当它无用时,我销毁它,下次计算时创建一个新物体,这样做效率并不很低)所以我们不关心它。
好,我们一个一个解决这些问题:
1、重力——这个属性是属于世界的,一般我们定义重力是向下的一个向量(BOX2D提供了用于内置计算的向量对象)
Dim g As mon.Vec2(0.0F, 17.27F)&&&&&&&&&&&&&& '重力
2、3、发射角度和力度——这将是瞬间完成的,不要指望去模拟一个在炮筒中的爆炸,那是得不偿失的——我们直接用一个向量作用于物体质心即可:
Body.ApplyImpulse(mon.Vec2( Math.Cos(Angle) * Power , -Math.Sin(Angle) * Power), Body.GetPosition)
这个语句可能稍微复杂一些,实际上有两个参数,第一个就是冲量,第二个是物体当前位置。
第一个参数只是用了三角形的基本知识,将发射角度和力度进行换算,得到X,Y两个方向上的力——即得到一个向量^ ^。
4、空气阻尼——一个属于物体的性质:这也灰常的简单,只需要告诉BOX2D一个数值,它就会在迭代器模拟物理运动的计算过程中应用它。
bodyDef.LinearDamping = Damping
5、风力——这是一个BOX2D所没有提供的性质,换句话说,BOX2D的世界里没有风……果然是灰常的风和日丽……那怎么办呢?呃……
思考中……
思考中……
其实物理引擎无非是在一定的时刻(后面将提到步长)近似的求得物体的位置及速度(线速度和角速度),那么我们可以在每次计算时,都作用一个风力给物体。这是我的解决方案,当然,你也可以改变重力的大小和方向来达到目的(将风力和重力的合力作为重力),也许你还有更好的办法……
好了,这个风力代码我是这样写的:
&'添加位置到返回数组
&&&&&&& Dim ret(MaxStep) mon.Vec2&&&&&&& For i As Integer = 0 To MaxStep&&&&&&&&&&& Body.ApplyForce(f, Body.GetPosition)&&& '应用风力&&&&&&&&&&& world.Step(timeStep, MaxStep, 1)&&&&&&&& '步进计算,第一个参数是步长(多久计算一次),第二个参数是计算的最多步数,第三个,呃是迭代数(每次计算时用迭代器的次数)&&&&&&&&&&& ret(i) = mon.Vec2(Body.GetPosition.X, Body.GetPosition.Y)&&&&&&&&&&&&&& '当前步位置&&&&&&&&&&& '检测进入&&&&&&&&&&& 'Dim s(0) As Box2DX.Collision.Shape
‘出处:&&&&&&&&&&& '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)
而检测代码已经在上面的代码中了——还记得吗,我把他们注释掉了。
上面讲到的类,代码如下:
Public&Class&Box2DEngine&&&&Dim&world&As&Box2DX.Dynamics.World&&&&Dim&g&As&New&mon.Vec2(<span style="color: #.0F,&<span style="color: #.27F)&&&&&&&&&&&&&&&'重力&&&&Dim&Damping&As&Single&=&<span style="color: #.1F&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'空气阻尼&&&&Dim&WapOffset&As&PointF&=&New&PointF(<span style="color: #.5F,&-<span style="color: #.5F)&&&&&&&&&&&'相对于人物中心的武器的偏移量&&&&Dim&RevisePower&As&Single&=&<span style="color: #.0F&&&&&&&&&&&&&&&&&&&&&&&&&&&&'力度&&&&Dim&ReviseWind&As&Single&=&<span style="color: #.474F&&&&&&&&&&&&&&&&&&&&&&&&&&&'风速&&&&Dim&Density&As&Single&=&<span style="color: #.3746&&&&&&&&&&&&&&&&&&'密度&&&&Dim&timeStep&As&Single&=&<span style="color: #&/&<span style="color: #&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'时间步数&#8212;&#8212;游戏每帧时间&&&&Dim&mAABB&As&New&Box2DX.Collision.AABB&&&&&&&&&&&&&&&&&&&&&&'范围检测,这里用的不是冲突而是范围内是否有物体&&&&Public&Event&InAABB(ByVal&power&As&Single,&ByVal&x&As&Single,&ByVal&y&As&Single,&ByVal&vs()&As&mon.Vec2)&&&&Public&Event&NotInAABB(ByVal&power&As&Single,&ByVal&x&As&Single,&ByVal&y&As&Single,&ByVal&vs()&As&mon.Vec2)&&&&Public&Enum&ForRight&As&Integer&&&&&&&&Yes&=&<span style="color: #&&&&&&&&No&=&-<span style="color: #&&&&End&Enum&&&&Sub&New()&&&&&&&&'世界外边框&&&&&&&&Dim&Wordaabb&As&Box2DX.Collision.AABB&&&&&&&&Wordaabb.LowerBound.Set(-<span style="color: #000.0F,&-<span style="color: #000.0F)&&&&&&&&Wordaabb.UpperBound.Set(<span style="color: #000.0F,&<span style="color: #000.0F)
&#8217;出处:&&&&&&&&'允许引擎休眠&&&&&&&&Dim&dosleep&As&Boolean&=&False&'&True&&&&&&&&'创建世界&&&&&&&&world&=&New&Box2DX.Dynamics.World(Wordaabb,&g,&dosleep)&&&&End&Sub&&&&Sub&SetAABB(ByVal&p&As&PointF,&ByVal&mSize&As&SizeF)&&&&&&&&mAABB.LowerBound.Set(p.X&/&<span style="color: #&-&mSize.Width,&p.Y&/&<span style="color: #&-&mSize.Height)&&&&&&&&mAABB.UpperBound.Set(p.X&/&<span style="color: #&+&mSize.Width,&p.Y&/&<span style="color: #&+&mSize.Height)&&&&End&Sub&&&&'''&&summary&&&&&'''&获取指定状态下的关键点&&&&'''&&/summary&&&&&'''&&param&name="PlayerPoint"&玩家位置(玩家中心位置的屏幕坐标)&/param&&&&&'''&&param&name="ForRight"&玩家是否朝向右面&/param&&&&&'''&&param&name="Power"&射击力度&/param&&&&&'''&&param&name="Angle"&射击角度(无左右方向,有上下方向)&/param&&&&&'''&&param&name="Wind"&风力及方向,向右为正,向左为负&/param&&&&&'''&&param&name="MaxStep"&最大计算步数,每一秒计算25次&/param&&&&&'''&&returns&从当前位置开始模拟运动时,每一步的坐标&/returns&&&&&'''&&remarks&&/remarks&&&&&Public&Function&GetPath(ByVal&PlayerPoint&As&PointF,&ByVal&ForRight&As&ForRight,&ByVal&Power&As&Single,&ByVal&Angle&As&Double,&ByVal&Wind&As&Single,&ByVal&MaxStep&As&Single)&As&mon.Vec2()&&&&&&&&Dim&RsEvnt&As&Boolean&&&&&&&&Dim&RsX,&RsY&As&Single&&&&&&&&Dim&ret(MaxStep)&As&mon.Vec2&&&&&&&&'创建一个动态物体&&&&&&&&Dim&Body&As&Box2DX.Dynamics.Body&=&CreateBody(PlayerPoint,&ForRight,&<span style="color: #.5F,&False,&Angle)&&&&&&&&'发射&#8212;&#8212;对其质心应用一个冲力&&&&&&&&Body.ApplyImpulse(New&mon.Vec2(CInt(ForRight)&*&Math.Cos(Angle)&*&Power&*&RevisePower,&-Math.Sin(Angle)&*&Power&*&RevisePower),&Body.GetPosition)&&&&&&&&'一个持久作用力&#8212;&#8212;风力&&&&&&&&Dim&f&As&mon.Vec2&=&New&mon.Vec2(Wind&*&ReviseWind,&<span style="color: #)&&&&&&&&'添加位置到返回数组&&&&&&&&For&i&As&Integer&=&<span style="color: #&To&MaxStep&&&&&&&&&&&&Body.ApplyForce(f,&Body.GetPosition)&&&&'应用风力&&&&&&&&&&&&world.Step(timeStep,&MaxStep,&<span style="color: #)&&&&&&&&'步进计算&&&&&&&&&&&&ret(i)&=&New&mon.Vec2(Body.GetPosition.X,&Body.GetPosition.Y)&&&&&&&&&&&&&&&'当前步位置&&&&&&&&&&&&'检测进入&&&&&&&&&&&&Dim&s(<span style="color: #)&As&Box2DX.Collision.Shape&&&&&&&&&&&&If&RsEvnt&=&False&AndAlso&world.Query(mAABB,&s,&<span style="color: #)&=&<span style="color: #&Then&&&&&&&&&&&&&&&&RsX&=&Body.GetPosition.X&*&<span style="color: #&&&&&&&&&&&&&&&&RsY&=&Body.GetPosition.Y&*&<span style="color: #&&&&&&&&&&&&&&&&RsEvnt&=&True&&&&&&&&&&&&End&If&&&&&&&&Next&&&&&&&&'销毁这次用的BODY,下次将重新创建&&&&&&&&world.DestroyBody(Body)&&&&&&&&Body.Dispose()&&&&&&&&Body&=&Nothing&&&&&&&&If&RsEvnt&Then&&&&&&&&&&&&RaiseEvent&InAABB(Power,&RsX,&RsY,&ret)&&&&&&&&Else&&&&&&&&&&&&RaiseEvent&NotInAABB(Power,&RsX,&RsY,&ret)&&&&&&&&End&If&&&&&&&&Return&ret&&&&End&Function&&&&Private&Function&RotateV2(ByVal&p&As&PointF,&ByVal&a&As&Double)&As&PointF&&&&&&&&Dim&ret&As&New&PointF&&&&&&&&Dim&b&As&Double&=&-a&&&&&&&&ret.X&=&p.X&*&Math.Cos(b)&-&p.Y&*&Math.Sin(b)&&&&&&&&ret.Y&=&p.X&*&Math.Sin(b)&+&p.Y&*&Math.Cos(b)&&&&&&&&Debug.Print(b)&&&&&&&&Debug.Print(ret.ToString)&&&&&&&&Return&ret&&&&End&Function&&&&'''&&summary&&&&&'''&根据玩家位置和是否向右,来创建一个炮弹,这个炮弹的具体位置和发射者位置及角度相关。&&&&'''&&/summary&&&&&'''&&param&name="PlayerPoint"&玩家位置&/param&&&&&'''&&param&name="ForRight"&是否向右&/param&&&&&'''&&param&name="R"&半径&/param&&&&&'''&&param&name="IsSensor"&是否是感应器&/param&&&&&'''&&param&name="Angle"&发射角度&/param&&&&&'''&&returns&&/returns&&&&&'''&&remarks&&/remarks&&&&&Private&Function&CreateBody(ByVal&PlayerPoint&As&PointF,&ByVal&ForRight&As&ForRight,&ByVal&R&As&Single,&ByVal&IsSensor&As&Boolean,&ByVal&Angle&As&Double)&As&Box2DX.Dynamics.Body&&&&&&&&'Debug.Print(CInt(ForRight))&&&&&&&&'创建动态物体,它的质量一定要大于0&&&&&&&&Dim&bodyDef&As&New&Box2DX.Dynamics.BodyDef&&&&&&&&WapOffset&=&RotateV2(New&PointF(<span style="color: #.5,&<span style="color: #),&Angle)&&&&&&&&bodyDef.Position.Set((PlayerPoint.X&/&<span style="color: #&+&CInt(ForRight)&*&WapOffset.X),&(PlayerPoint.Y&/&<span style="color: #&+&WapOffset.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()&&&'根据形状计算质量&&&&&&&&Return&Body&&&&End&Function&&&&Protected&Overrides&Sub&Finalize()&&&&&&&&world.Dispose()&&&&&&&&MyBase.Finalize()&&&&End&SubEnd&Class
而我所用的测试代码如下:
Public&Class&Form1&&&&Dim&gr&As&Graphics&&&&&&'窗体的画布&&&&Dim&CompassRect&As&Rectangle&&&&'罗盘&&&&Dim&po&As&Point&&&&&'罗盘中心&&&&Dim&p1&As&Point&&&&&'指针终点&&&&Dim&powerRect&As&Rectangle&&'力度框&&&&Dim&mb&As&Point&'目标位置&&&&Dim&wind&As&Single&&'风力&&&&Dim&ang&As&Integer&&'角度&&&&Dim&Userpower&As&Single&'力度*5&&&&Dim&mFont&As&Font&&&'字体&&&&Dim&WithEvents&eg&As&New&Box2DEngine&&&&'封装引擎&&&&Dim&v2s()&As&mon.Vec2&&&&&'路径点&&&&Dim&img&As&Bitmap&&&&&&&'背景图&&&&Dim&grp&As&Graphics&&&&&'背景图或最终图的画布&&&&Dim&pnt&As&Bitmap&&&&&&&'最终图&&&&Private&Sub&Form1_KeyPress(ByVal&sender&As&Object,&ByVal&e&As&System.Windows.Forms.KeyPressEventArgs)&Handles&Me.KeyPress&&&&&&&&Select&Case&e.KeyChar&&&&&&&&&&&&Case&"&"&&&&&&&&&&&&&&&&If&puter.Keyboard.ShiftKeyDown&Then&&&&&&&&&&&&&&&&&&&&If&Userpower&&&<span style="color: #&Then&Userpower&-=&<span style="color: #.5&&&&&&&&&&&&&&&&Else&&&&&&&&&&&&&&&&&&&&If&Userpower&&&<span style="color: #0&Then&Userpower&+=&<span style="color: #.5&&&&&&&&&&&&&&&&End&If&&&&&&&&&&&&Case&"w",&"W"&&&&&&&&&&&&&&&&If&ang&&&-<span style="color: #&Then&ang&-=&<span style="color: #&&&&&&&&&&&&Case&"s",&"S"&&&&&&&&&&&&&&&&If&ang&&&<span style="color: #&Then&ang&+=&<span style="color: #&&&&&&&&&&&&Case&"r",&"R"&&&&&&&&&&&&&&&&Randomize()&&&&&&&&&&&&&&&&wind&=&CInt(Int((<span style="color: #0&*&Rnd())))&/&<span style="color: #&-&<span style="color: #&&&&&&&&&&&&&&&&mb&=&New&Point(<span style="color: #0&*&Rnd()&+&<span style="color: #0,&<span style="color: #0&*&Rnd())&&&&&&&&&&&&&&&&eg.SetAABB(New&PointF(mb.X,&mb.Y),&New&Size(<span style="color: #,&<span style="color: #))&&&&&&&&&&&&&&&&Userpower&=&<span style="color: #&&&&&&&&End&Select&&&&&&&&Form1_Paint(Me,&New&PaintEventArgs(gr,&Me.ClientRectangle))&&&&End&Sub&&&&Private&Sub&Form1_KeyUp(ByVal&sender&As&Object,&ByVal&e&As&System.Windows.Forms.KeyEventArgs)&Handles&Me.KeyUp&&&&&&&&Select&Case&e.KeyData&&&&&&&&&&&&Case&Keys.Space,&Keys.Shift&Or&Keys.Space,&Keys.ShiftKey&Or&Keys.Space,&Keys.W,&Keys.S&&&&&&&&&&&&&&&&v2s&=&eg.GetPath(New&PointF(po.X,&po.Y),&Box2DEngine.ForRight.Yes,&Userpower&/&<span style="color: #,&-ang&*&Math.PI&/&<span style="color: #0,&wind,&<span style="color: #0)&&&&&&&&End&Select&&&&End&Sub&&&&Private&Sub&Form1_Load(ByVal&sender&As&System.Object,&ByVal&e&As&System.EventArgs)&Handles&MyBase.Load&&&&&&&&img&=&New&Bitmap(<span style="color: #00,&<span style="color: #0)&&&&&&&&grp&=&Graphics.FromImage(img)&&&&&&&&Dim&alppen&As&Pen&=&New&Pen(Color.FromArgb(&H40FFFFFF))&&&&&&&&grp.DrawString("按W增加角度"&&&vbCrLf&&&"按S减少角度"&&&vbCrLf&&&"按空格增加力度"&&&vbCrLf&&&"按SHIFT+空格减少力度"&&&vbCrLf&&&"按R重置",&New&Font("宋体",&<span style="color: #),&Brushes.DarkCyan,&<span style="color: #,&<span style="color: #)&&&&&&&&For&x&As&Integer&=&<span style="color: #&To&<span style="color: #00&Step&<span style="color: #0&&&&&&&&&&&&grp.DrawLine(Pens.White,&x,&<span style="color: #5,&x,&<span style="color: #0)&&&&&&&&&&&&grp.DrawLine(alppen,&x,&<span style="color: #,&x,&<span style="color: #5)&&&&&&&&&&&&grp.DrawString(x&/&<span style="color: #0,&Font,&Brushes.White,&x,&<span style="color: #0)&&&&&&&&Next&&&&&&&&For&y&As&Integer&=&<span style="color: #&To&<span style="color: #0&Step&<span style="color: #&&&&&&&&&&&&grp.DrawLine(alppen,&<span style="color: #,&y,&<span style="color: #00,&y)&&&&&&&&Next&&&&&&&&pnt&=&New&Bitmap(<span style="color: #00,&<span style="color: #0)&&&&&&&&grp.Dispose()&&&&&&&&grp&=&Graphics.FromImage(pnt)&&&&&&&&gr&=&Me.CreateGraphics&&&&&&&&CompassRect&=&New&Rectangle(<span style="color: #,&<span style="color: #0,&<span style="color: #0,&<span style="color: #0)&&&&&&&&po&=&New&Point(CompassRect.X&+&CompassRect.Width&/&<span style="color: #,&CompassRect.Y&+&CompassRect.Height&/&<span style="color: #)&&&&&&&&p1&=&New&Point(CompassRect.X&+&CompassRect.Width&/&<span style="color: #&+&<span style="color: #,&CompassRect.Y&+&CompassRect.Height&/&<span style="color: #)&&&&&&&&powerRect&=&New&Rectangle(<span style="color: #0,&<span style="color: #0,&<span style="color: #2,&<span style="color: #)&&&&&&&&mFont&=&New&Font("宋体",&<span style="color: #,&FontStyle.Bold)&&&&End&Sub&&&&Private&Sub&Form1_Paint(ByVal&sender&As&Object,&ByVal&e&As&System.Windows.Forms.PaintEventArgs)&Handles&Me.Paint&&&&&&&&grp.Clear(Color.DarkGreen)&&&&&&&&grp.DrawImage(img,&PointF.Empty)&&&&&&&&Dim&offset&As&Point&=&RotateV2(p1&-&po,&-ang)&+&po&&&&&&&&grp.DrawLine(Pens.Blue,&po,&offset)&&&&&&&&grp.DrawString(-ang,&mFont,&Brushes.Blue,&po.X&-&<span style="color: #,&po.Y&+&<span style="color: #)&&&&&&&&grp.FillPie(Brushes.White,&New&Rectangle(po.X&-&<span style="color: #,&po.Y&-&<span style="color: #,&<span style="color: #,&<span style="color: #),&<span style="color: #,&<span style="color: #0)&&&&&&&&grp.DrawRectangle(Pens.White,&powerRect)&&&&&&&&grp.FillRectangle(Brushes.Wheat,&New&Rectangle(powerRect.X&+&<span style="color: #,&powerRect.Y&+&<span style="color: #,&Userpower,&<span style="color: #))&&&&&&&&grp.DrawString(Userpower&/&<span style="color: #,&mFont,&Brushes.Blue,&powerRect.X,&powerRect.Y&-&<span style="color: #)&&&&&&&&grp.DrawString(Math.Abs(wind),&mFont,&Brushes.Blue,&<span style="color: #0,&<span style="color: #)&&&&&&&&grp.DrawString(IIf(wind&&&<span style="color: #,&"&#8592;",&"&#8594;"),&mFont,&Brushes.Blue,&<span style="color: #0,&<span style="color: #)&&&&&&&&If&mb.X&&&<span style="color: #&AndAlso&mb.Y&&&<span style="color: #&Then&grp.FillPie(Brushes.Black,&New&Rectangle(mb.X&-&<span style="color: #,&mb.Y&-&<span style="color: #,&<span style="color: #,&<span style="color: #),&<span style="color: #,&<span style="color: #0)&&&&&&&&If&v2s&IsNot&Nothing&Then&&&&&&&&&&&&For&Each&v2&As&mon.Vec2&In&v2s&&&&&&&&&&&&&&&&grp.DrawArc(Pens.White,&CSng(v2.X&*&<span style="color: #.0F&-&<span style="color: #.5),&CSng(v2.Y&*&<span style="color: #&-&<span style="color: #.5),&<span style="color: #.0F,&<span style="color: #.0F,&<span style="color: #.0F,&<span style="color: #0.0F)&&&&&&&&&&&&Next&&&&&&&&End&If&&&&&&&&v2s&=&Nothing&&&&&&&&gr.DrawImage(pnt,&PointF.Empty)&&&&End&Sub&&&&Private&Function&RotateV2(ByVal&p&As&Point,&ByVal&a&As&Integer)&As&Point&&&&&&&&Dim&ret&As&New&Point&&&&&&&&Dim&b&As&Double&=&-a&*&Math.PI&/&<span style="color: #0&&&&&&&&ret.X&=&p.X&*&Math.Cos(b)&-&p.Y&*&Math.Sin(b)&&&&&&&&ret.Y&=&p.X&*&Math.Sin(b)&+&p.Y&*&Math.Cos(b)&&&&&&&&Return&ret&&&&End&Function&&&&Private&Sub&eg_InAABB(ByVal&power&As&Single,&ByVal&x&As&Single,&ByVal&y&As&Single,&ByVal&vs()&As&mon.Vec2)&Handles&eg.InAABB&&&&&&&&v2s&=&vs&&&&&&&&Form1_Paint(Me,&New&PaintEventArgs(gr,&Me.ClientRectangle))&&&&End&Sub&&&&Private&Sub&eg_NotInAABB(ByVal&power&As&Single,&ByVal&x&As&Single,&ByVal&y&As&Single,&ByVal&vs()&As&mon.Vec2)&Handles&eg.NotInAABB&&&&&&&&v2s&=&vs&&&&&&&&Form1_Paint(Me,&New&PaintEventArgs(gr,&Me.ClientRectangle))&&&&End&SubEnd&Class
好了,只是抛砖引玉,希望大家能够开发出自己的游戏,毕竟别人的游戏只是一种借鉴,学会思考才是最重要的。
PS:代码中使用了坐标缩放,这是因为物理引擎模拟运动时,只在一定范围内(例如十米以内)有较高的准确度,超出这个范围将会降低准确度。
PS:BOX2D是使用单精度浮点数来进行计算的&#8212;&#8212;这不会对准确度影响较大。因为它使用了一些通用的公差。
贴了这么多出处我也没办法。因为有些同学脸皮太薄了&#8212;&#8212;将将比城墙厚一点点!
Views(...) Comments()

我要回帖

更多关于 物理引擎好的游戏 的文章

 

随机推荐