专栏首页HT基于HTML5的WebGL结合Box2DJS物理应用

基于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 = 0
function 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 < -150 || g3d.isSelected(node)){
                dm.remove(node);
                world.DestroyBody(list);
            }else{
                node.p3(position.x, position.y, 0);
                node.setRotationZ(list.GetAngle());                            
            }                                              
        }                    
        list = list.GetNext();
    }                    
    requestAnimationFrame(render);
}

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • W3C对外公布了标准HTML5的草案

    周二,W3C机构正式对外公布了互联网网页代码新标准HTML5的草案.预计正式版的标准将会在两年以后形成. HTML可以说是互联网信息组织的一个基石.据悉,这是自...

    练小习
  • HTML5设备定向小实践

    简介 HTML5的Device API中提供了几个DOM事件,可以获得设备的物理方向及运动的信息,API提供的数据不是来源于原始的传感器信息,而是来源于设备上的...

    IMWeb前端团队
  • 九大网页编程入门网站

    许多职业需要几年的时间来学习和训练, 而对于许多刚刚踏入网页开站发的人来说, 最令人高兴的事莫过于可以很轻松的入门。 ? 但你真的找到了适合自己的学习平台吗? ...

    企鹅号小编
  • 微信小程序的编程模式

    在进行「轻芒小程序+」和其他小程序应用开发的过程中,本文作者与其团队对当前正火热的小程序开发有了更为深度的理解与认识,进而有了本文。文章从从编程模式入手,看在小...

    云加社区专栏
  • HTML5设计原理(上)

    今天我想跟大家谈一谈HTML5的设计。主要分两个方面:一方面,当然了,就是HTML5。我可以站在这儿只讲HTML5,但我并不打算这样做,因为如果你想了解HTML...

    RP道貌不岸然
  • HTML5设计原理(中)

    避免不必要的复杂性 下面我就给大家介绍一些这份文档中记载的设计原理。第一个,非常简单:避免不必要的复杂性。好像很简单吧。我用一个例子来说明。 假设我使用HTML...

    RP道貌不岸然
  • WEB 文件传输技术全讲解

    近些年以来,技术突飞猛进,唯独文件上传这一块却貌似依然停留在IE6的年代。对于用户来说,最不能忍受的事情,大概就是上传到99%的时候突然卡住不动然后被告知要从头...

    潘兴颂
  • Android开发必知--WebView加载html5实现炫酷引导页面

      大多数人都知道,一个APP的引导页面还是挺重要的,不过要想通过原生的Android代码做出一个非常炫酷的引导页相对还是比较复杂的,正巧html5在制作炫酷动...

    codingblock
  • HTML5设计原理(下)

    平稳退化 下一条原理大家应该都很熟悉了,那就是平稳退化。毕竟,我们已经遵守这条规则好多年了。渐进增强的另一面就是平稳退化。 有关HTML5遵循这条原理的例子,就...

    RP道貌不岸然
  • html5 article & section

    html5 article & section 关于 article & section 关于 article 和 section 的区别也是老生常谈的事了 但...

    IMWeb前端团队

扫码关注云+社区

领取腾讯云代金券