基于html5的webgl结合box2djs物理引擎应用上篇我们基于ht for web呈现了a* search algorithm的3d寻路效果,这篇我们将采用ht for web 3d来呈现box2djs物理引擎的碰撞效果,同上篇其实box2djs只是二维的平面碰撞物理引擎,但同样通过3d的呈现能让人更直观的体验到碰撞效果,最终例子效果:
http://hightopo.com/demo/box2djs/ht-box2d-demo.html
box2d最早是erin catto在gdc大会上的一个展示例子,后来不断完善成c++的开源物理引擎库,这些年了衍生出java、actionscript以及js等版本,被广泛应用在游戏领域。说其丰富的确很丰富,说乱也够乱的,找个box2d的js版就有n多选择,而且不同版本api还有差异,可参考这里的对比http://stackoverflow.com/questions/7628078/which-box2d-javascript-library-should-i-use
虽然版本较多有点乱,但各个版本的基本原理和api都类似,以下为我基于box2djs融合ht for web写的例子代码。box2d有很多参数功能点,这里例子我们仅呈现最基础简单的要素,主要让大家理解box2djs引擎的基本使用,以及呈现上如何与ht for web结合。
以下代码在createnode中即构建的ht for web的node对象,同时构建了box2d的body对象,并通过userdata属性关联在一起,在requestanimationframe的渲染过程,先通过world.step(1 / 60, 10, 10);更新物理引擎的内部运算,然后遍历所有body元素将运算结果,也就是body的位置和旋转角度等信息同步到ht for web的node对象,从而达到了ht for web和box2djs的强强结合各施其才。
function init() { dm = new ht.datamodel(); g3d = new ht.graph3d.graph3dview(dm); g3d.setgridvisible(true); g3d.addtodom(); g3d.seteye(100, 50, 150); // define the world var gravity = new b2vec2(0, -100); var dosleep = false; world = new b2world(gravity, dosleep); createnode([0, -3, 0], [100, 6, 100], false, 0); createnode([-100, -50, 0], [400, 6, 100], false, -math.pi/8); createnode([100, -50, 0], [50, 6, 100], false, math.pi/6); createnode([1, 50, 0], [10, 10, 10], true); createnode([-1, 90, 0], [10, 10, 10], true); render();}function createnode(p3, s3, dynamic, angle) { var node = new ht.node(); node.p3(p3); node.s3(s3); node.setrotationz(angle == null ? math.pi * math.random() : angle); dm.add(node); var fixdef = new b2fixturedef(); if (dynamic) { fixdef.density = 0.5; fixdef.friction = 0.5; fixdef.restitution = 0.5; node.s({ 'all.color': 'red', 'batch': 'dynamic' }); } else { fixdef.density = 0.0; } var shape = new b2polygonshape(); shape.setasbox(s3[0] / 2, s3[1] / 2); fixdef.shape = shape; var bodydef = new b2bodydef(); bodydef.type = dynamic ? b2body.b2_dynamicbody : b2body.b2_staticbody; bodydef.position.set(p3[0], p3[1]); bodydef.angle = node.getrotationz(); bodydef.userdata = node; world.createbody(bodydef).createfixture(fixdef);}count = 0function render() { count++; if(count % 10 === 0){ createnode([-1, 50, 0], [10, 10, 10], true); } world.step(1 / 60, 10, 10); var list = world.getbodylist(); while (list) { var node = list.m_userdata; if(node){ var position = list.getposition(); if(position.y http://hightopo.com/demo/box2djs/ht-box2d-demo.html
例子中物体掉落到-150以下我就删除了box2djs以及ht的datamodel中对应的数据元素,同时选中图元也会自动删除图元,count % 10 === 0 这个用来没十次刷新产生一个新的立方体。box2d还可以玩出很多花样,如果数据量大也可以考虑参考《3d拓扑自动布局之web workers篇》,将box2djs的密集运算在webwork中执行,我没评估过性能的提升幅度,数据量大时webwork和gui线程的数据序列化传递也会有负担需注意,最终的例子3d效果玩起来还是挺有趣的:http://v.youku.com/v_show/id_xodm0otq0nzey.html
http://www.bkjia.com/phpjc/1078320.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/1078320.htmltecharticle基于html5的webgl结合box2djs物理引擎应用 上篇我们基于ht for web呈现了a* search algorithm的3d寻路效果,这篇我们将采用ht for web 3d来呈现box2djs物理...