html 游戏槽位,[HTML5]使用Box2dWeb模拟射箭效果并添加能量槽

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

[javascript]

var b2Joints =  Box2D.Dynamics.Joints;

var b2Contacts =  Box2D.Dynamics.Contacts;

var b2Listener =Box2D.Dynamics.b2ContactListener;

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

[javascript]

var arrowContactListener = new b2Listener;

arrowContactListener.PreSolve = arrowPreSolve;

world.SetContactListener(arrowContactListener);

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

[javascript]

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文件中添加下面的p,表示能量槽,在后面的JS代码中动态更新它的长度。

[html]

然后在JS文件中修改鼠标消息响应方法,

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);

}

}

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

效果如下图:

143269_0.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值