[HTML5]使用Box2dWeb模拟射箭效果并添加能量槽

原创 2013年03月26日 08:03:27

上次已实现箭矢的飞行效果,但是箭在碰到墙壁时直接反弹回来,像钢棍而不是箭。在Box2d中,可以利用关节(Joint)将箭和靶子连接起来,组成一个整体,实现射击效果。使用关节要在文件开头添加新的变量,方便后面使用:

var b2Joints =  Box2D.Dynamics.Joints;
var b2Contacts =  Box2D.Dynamics.Contacts;
var b2Listener =Box2D.Dynamics.b2ContactListener;

箭与靶子的起始位置并不相同,要检测箭是否射中靶子就要实时进行碰撞检测,幸好Box2d可以自动进行这部分工作,不过检测到碰撞时如何处理需要自己定义。所以有下面的声明,声明一个b2Listener,两个物体碰撞时会调用Listener指定的方法。

var arrowContactListener = new b2Listener;
arrowContactListener.PreSolve = arrowPreSolve;
world.SetContactListener(arrowContactListener);

arrowPreSolve就是检测到碰撞时要执行的方法,具体实现如下:

function arrowPreSolve(contact,oldManifold){
   var contactPoint = new b2Vec2;
   var weldJointDef = new b2Joints.b2WeldJointDef;
 
   if(contact.IsTouching()){
       var bodyA =contact.GetFixtureA().GetBody();
       var bodyB = contact.GetFixtureB().GetBody();
       var objA = bodyA.GetUserData();
       var objB = bodyB.GetUserData();
       if (objA.name=="arrow" &&objB.name=="arrow") {
           for (var j = bodyA.GetJointList(); j; j=j.next) {
               bodyA.GetWorld().DestroyJoint(j.joint);
           }
           for (j=bodyB.GetJointList(); j; j=j.next) {
               bodyB.GetWorld().DestroyJoint(j.joint);
           }
       }
 
       if (objA.name=="arrow" &&objB.name=="target") {
           if (objA.isflying) {
                weldJointDef = newb2Joints.b2WeldJointDef;
               weldJointDef.Initialize(bodyB,bodyA,bodyA.GetWorldCenter());
                bodyB.GetWorld().CreateJoint(weldJointDef);
           }
           console.log("Hit Target!");
       }
 
       if (objB.name=="wall"&&objA.name=="arrow") {
           if (objA.isflying) {
                weldJointDef = newb2Joints.b2WeldJointDef;
                weldJointDef.Initialize(bodyA,bodyB,bodyB.GetWorldCenter());
               bodyA.GetWorld().CreateJoint(weldJointDef);
           }
 
       }
 
       if (objB.name=="arrow") {
           objB.isflying=false;
       }
       if (objA.name=="arrow") {
           objA.isflying=false;
       }
    }
}

几个条件语句分别处理箭与箭碰撞,箭与靶子碰撞和箭与墙壁碰撞这三种情况,最后更新箭的飞行状态。设置箭飞行状态的主要目的就是保证当前世界中只有一支活动的箭。

平时一些小游戏在射箭或者发生炮弹的时候都会有一个能量槽来表示力度的大小,接下来就向这个小游戏中添加一个能量槽,按鼠标时间越长,射箭的力度越大。

首先向arrow.html文件中添加下面的div,表示能量槽,在后面的JS代码中动态更新它的长度。

<divid="power_bar"></div>

然后在JS文件中修改鼠标消息响应方法,并添加一个定时修改能量槽长度的方法calculateStrength:

functiononMouseDown(e){
    if(arrowGame.state == arrowGame.STATE_PLAY){
        if(allowCreateArrow()) {
            arrowGame.chargeTaskID =setInterval(calculateStrength, 25);
        }
    }
}
 
functiononMouseUp(e) {
    if(arrowGame.state == arrowGame.STATE_PLAY){
        // Only one arrow in gaming.
        if(allowCreateArrow()) {
           createArrow(e.clientX-canvasPosition.x,e.clientY-canvasPosition.y,arrowGame.power);
           clearInterval(arrowGame.chargeTaskID);
            arrowGame.power = 0;
        }
    }
}
 
functioncalculateStrength() {      
    arrowGame.power++;
    arrowGame.powerBar.style.width =arrowGame.power*10 + "px";
 
    if(arrowGame.powerBar.style.width =="300px"){
        clearInterval(arrowGame.chargeTaskID);
    }
}

在鼠标按下时,开启定时器,增加能量槽的长度,当鼠标弹起时,根据当前的鼠标位置和能量槽长度创建一支箭。

效果如下图:


为方便后面编程,对整个JS文件的结构进行了修改,使用一个全局结构存储游戏状态,并修改整个流程,细节部分可以参照源代码。

源代码下载地址

[HTML5]使用Box2dWeb模拟飞行箭矢

Box2d是一个2D游戏物理引擎,由Erin Catto开发,于2007年发布。很多2D游戏都用过Box2d,其中最有名的自然是愤怒的小鸟。Box2d本身是C++编写,但在不同平台都有它的衍生版本,像...

HTML5游戏开发-Box2dWeb应用(一)-创建各种各样的刚体

本篇开始,会介绍lufylegend-1.4.0的新功能,怎样结合box2dweb创建一个物理世界以及这个物理世界里的各种刚体准备工作首先你需要下载html5开源库件lufylegend-1.4.0h...

HTML5游戏开发-Box2dWeb应用(二)-碰撞以及各种连接

上次介绍了用box2dweb创建各种刚体,这次来介绍如何用鼠标拖拽刚体,刚体之间的碰撞,以及刚体之间的各种连接。HTML5游戏开发-Box2dWeb应用(一)-创建各种各样的刚体http://blog...

【HTML5】使用Box2d模拟飞行箭矢

  • 2013年03月17日 18:04
  • 44KB
  • 下载

使用Box2dWeb模拟飞行箭矢

[HTML5]使用Box2dWeb模拟飞行箭矢 标签: HTML5Box2d游戏 2013-03-18 09:14 3287人阅读 评论(0) 收藏 举报  分类:   ...
  • cdnight
  • cdnight
  • 2016年02月15日 16:57
  • 743

基于HTML5的WebGL结合Box2DJS物理引擎应用

Box2D最早是Erin Catto在GDC大会上的一个展示例子,后来不断完善成C++的开源物理引擎库,这些年了衍生出Java、ActionScript以及JS等版本,被广泛应用在游戏领域。说其丰富的...

COCOS-HTML5-3.9版本学习(三)box2d物理引擎的测试

我也是刚学习这两种引擎的JS写法,具体我先给大家说下box2dLayer的结构把: var box2dLayer = cc.Layer.extend({ world: null, allowSl...

使用HTML5和jQuery插件Reel实现一个超酷的星际争霸2兵种动画360度预览效果

今天继续给大家介绍HTML5和jQuery插件结合使用生成的图形特效,这里我继续使用星际争霸2的图片元素给大家介绍一个360度全景预览兵种的特效实现,希望大家喜欢!请大家多多留言! 在线演示  ...
  • jjfat
  • jjfat
  • 2011年11月07日 20:22
  • 1183
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[HTML5]使用Box2dWeb模拟射箭效果并添加能量槽
举报原因:
原因补充:

(最多只允许输入30个字)