By
被删
2017-02-17
更新日期:2018-12-18
本节我们主要讲述创建一个物理世界,以及初始化的过程。
创建世界并初始化
创建世界 前面我们在介绍世界的时候,也有简单说明如何创建一个物理世界:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var canvas = document .getElementById ('game' );var ctx = canvas.getContext ('2d' );var canvasWidth = parseInt (canvas.width );var canvasHeight = parseInt (canvas.height );function createWorld ( ) { var worldAABB = new b2AABB (); worldAABB.minVertex .Set (-4000 , -4000 ); worldAABB.maxVertex .Set (4000 , 4000 ); var gravity = new b2Vec2 (0 , 300 ); var doSleep = false ; var world = new b2World (worldAABB, gravity, doSleep); return world; }
绘制世界 我们可以添加一个绘制世界的功能,讲里面的刚体、关节等都进行绘制:
1 2 3 4 5 6 7 8 9 10 11 12 13 function drawWorld (world, context ) { for (var j = world.m_jointList ; j; j = j.m_next ) { } for (var b = world.m_bodyList ; b; b = b.m_next ) { for (var s = b.GetShapeList (); s != null ; s = s.GetNext ()) { } } }
刷新世界 现在我们可以开始模拟循环了,在游戏中模拟循环应该并入游戏循环。每次循环你都应该调用world.Step(timeStep, iterations)
,通常调用一次就够了,这取决于帧频以及物理时间步。
Box2D中有一些数学代码构成的积分器(integrator),积分器在离散的时间点上模拟物理方程,它将与游戏动画循环一同运行。 所以我们需要为Box2D选取一个时间步,通常来说游戏物理引擎需要至少60Hz的速度,也就是1/60的时间步。你可以使用更大的时间步,但是你必须更加小心地为你的世界调整定义。
除了积分器之外,Box2D中还有约束求解器(constraint solver)。约束求解器用于解决模拟中的所有约束,一次一个。 单个的约束会被完美的求解,然而当我们求解一个约束的时候,我们就会稍微耽误另一个。要得到良好的解,我们需要迭代所有约束多次。
建议的Box2D迭代次数是10次。你可以按自己的喜好去调整这个数,但要记得它是速度与质量之间的平衡。更少的迭代会增加性能并降低精度,同样地,更多的迭代会减少性能但提高模拟质量。
1 2 3 4 5 6 7 8 9 10 11 12 function step ( ) { world.Step (1.0 / 60 , 1 ); ctx.clearRect (0 , 0 , canvasWidth, canvasHeight); drawWorld (world, ctx); setTimeout (step, 10 ); }
完整代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 var canvas = document .getElementById ('canvas' );var ctx = canvas.getContext ('2d' );var canvasWidth = parseInt (canvas.width );var canvasHeight = parseInt (canvas.height );var world;function createWorld ( ) { var worldAABB = new b2AABB (); worldAABB.minVertex .Set (-4000 , -4000 ); worldAABB.maxVertex .Set (4000 , 4000 ); var gravity = new b2Vec2 (0 , 300 ); var doSleep = false ; var world = new b2World (worldAABB, gravity, doSleep); return world; } function drawWorld (world, context ) { for (var j = world.m_jointList ; j; j = j.m_next ) { } for (var b = world.m_bodyList ; b; b = b.m_next ) { for (var s = b.GetShapeList (); s != null ; s = s.GetNext ()) { } } } function step ( ) { world.Step (1.0 / 60 , 1 ); ctx.clearRect (0 , 0 , canvasWidth, canvasHeight); drawWorld (world, ctx); setTimeout (step, 10 ); console .log ('step...' ); } world = createWorld (); step ();
此处查看项目代码(仅包含src部分) 此处查看页面效果
查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场 边撸猫边学前端噢
如果你想要关注日常生活中的我,欢迎关注“牧羊的猪”公众号噢