欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

html5游戏开发-愤怒的小鸟--碰撞产生的冲力

程序员文章站 2022-06-03 08:38:34
其实在box2d中,只要我们设定了物体的密度,摩擦,以及弹力等属性之后,他们之间会模拟真实的世界进行碰撞,如果想要根据这些碰撞来做一些特殊的处理的话,就需要取得它们之间碰撞的冲力,从而根据冲力的大小...

其实在box2d中,只要我们设定了物体的密度,摩擦,以及弹力等属性之后,他们之间会模拟真实的世界进行碰撞,如果想要根据这些碰撞来做一些特殊的处理的话,就需要取得它们之间碰撞的冲力,从而根据冲力的大小来做自己想要做的事情,在lufylegend库件中使用下面一行代码来检测碰撞。

[javascript] 
lglobal.box2d.setevent(levent.post_solve,postsolve); 
碰撞函数如下,接受两个参数
[javascript] view plaincopy
function postsolve(contact, impulse){ 

然后用impulse.normalimpulses[0]来取得碰撞产生的冲力大小。
下面,我们来根据碰撞的冲力来控制猪头的状态,首先准备下面两张图

 html5游戏开发-愤怒的小鸟--碰撞产生的冲力html5游戏开发-愤怒的小鸟--碰撞产生的冲力

然后,建立pig类如下

[javascript]
function pig(){ 
    base(this,lsprite,[]); 
    var self = this; 
    self.hp = 200; 
    self.name = "pig"; 
    self.list = ["pig01","pig02"]; 
    self.bitmap = new lbitmap(new lbitmapdata(imglist[self.list[0]])); 
    self.addchild(self.bitmap); 
    self.addbodycircle(24,self.bitmap.getheight()*0.5,self.bitmap.getwidth()*0.5,1,5,.4,.13); 

pig.prototype.hit = function(value){ 
    var self = this; 
    if(value < 10)return; 
    if(self.hp == 200)self.bitmap.bitmapdata = new lbitmapdata(imglist[self.list[1]]); 
    self.hp -= value; 

上面代码,在构造器里首先给猪头设置了一张健康的状态图片,然后在hit函数里,将猪头的图片变成了一张受伤的图片。
有了上面的pig类,只要在猪头和其他物体之间发生碰撞的时候,将碰撞的冲力传入hit函数,就能控制猪头的状态和hp的值,当然你也可以为猪头准备多种状态的图片,比如轻伤,重伤等,然后在hit函数中根据它的hp值的大小,来给他设定不同的显示图片。
另外,在愤怒的小鸟这个游戏中,每个物体也都是有它的不同的状态的,比如下面的两张图,表示木条的两个状态

 html5游戏开发-愤怒的小鸟--碰撞产生的冲力html5游戏开发-愤怒的小鸟--碰撞产生的冲力

为了便于操作这些物体,我们和上面的猪头一样,建立一个stage类,如下

[javascript] 
function stage(list,rotate,m,ctrl){ 
    base(this,lsprite,[]); 
    var self = this; 
    self.name = "stage"; 
    self.ctrl = ctrl; 
    self.list = list; 
    self.bitmap = new lbitmap(new lbitmapdata(imglist[self.list[0]])); 
    self.hp = 200; 
    self.addchild(self.bitmap); 
    self.addbodypolygon(self.bitmap.getwidth(),self.bitmap.getheight(),1,m,.4,.2); 
    if(rotate != 0)self.setrotate(rotate*math.pi/180); 

stage.prototype.hit = function(value){ 
    var self = this; 
    if(!self.ctrl)return; 
    if(value < 1)return; 
    if(self.hp == 200)self.bitmap.bitmapdata = new lbitmapdata(imglist[self.list[1]]); 
    self.hp -= value; 

原理和pig类相同,就不多做解释了。
然后,在主函数中加入一些物体,如下
[javascript]  
setstage(["desk"],800,430,0,10,false); 
setstage(["desk"],970,430,0,10,false); 
setstage(["st11","st12"],935,410,0,1,true); 
setstage(["st01","st02"],905,370,90,1,true); 
setstage(["st01","st02"],965,370,90,1,true); 
setstage(["st11","st12"],935,310,0,1,true); 
setstage(["st31","st32"],817,370,90,1,true); 
setstage(["st31","st32"],970,370,90,1,true); 
setstage(["st31","st32"],895,250,0,1,true); 
setstage(["st21","st22"],955,230,0,1,true); 
setstage(["st31","st32"],858,150,90,1,true); 
setstage(["st31","st32"],925,150,90,1,true); 
setstage(["st11","st12"],935,50,0,1,true); 
setstage(["st21","st22"],950,30,90,1,true); 
setstage(["st21","st22"],800,430,90,1,true); 
setstage(["st21","st22"],1100,430,90,1,true); 
var pig = new pig(); 
pig.x = 950; 
pig.y = 173; 
backlayer.addchild(pig); 
setstage函数如下,是为了实例化一个物体
[javascript] view plaincopy
function setstage(list,x,y,rotate,m,ctrl){ 
    var stagelayer = new stage(list,rotate,m,ctrl); 
    stagelayer.x = x; 
    stagelayer.y = y; 
    backlayer.addchild(stagelayer); 
    return stagelayer; 

上面的代码生成的画面如下
html5游戏开发-愤怒的小鸟--碰撞产生的冲力

如果你玩过愤怒的小鸟这个游戏的话,对上面的画面应该不陌生吧,它就是愤怒的小鸟第一关的画面。

接下来,修改碰撞检测函数,因为我在lufylegend库件中将body的userdata设置成了lsprite对象本身,所以这里通过getuserdata来得到lsprite对象

[javascript] 
function postsolve(contact, impulse){ 
    if(contact.getfixturea().getbody().getuserdata().hit)contact.getfixturea().getbody().getuserdata().hit(impulse.normalimpulses[0]); 
    if(contact.getfixtureb().getbody().getuserdata().hit)contact.getfixtureb().getbody().getuserdata().hit(impulse.normalimpulses[0]); 

有了上面的碰撞,现在运行游戏的话,可以得到下面的效果
html5游戏开发-愤怒的小鸟--碰撞产生的冲力

可以看到,画面中的猪头和一些木条的状态都已经发生了变化了,这样我们就完成了根据碰撞来改变物体的状态了,下面当猪头的hp变为0的时候,将它移除游戏画面。
一般猪头在消失的时候,会有一个类似爆炸的效果,如下图

 html5游戏开发-愤怒的小鸟--碰撞产生的冲力

下面建立一个removeobject类来实现这一效果

[javascript]
function removeobject(){ 
    base(this,lsprite,[]); 
    var self = this; 
    self.name = "remove"; 
    self.index = 0; 
    self.bitmap = new lbitmap(new lbitmapdata(imglist["remove"])); 
    self.addchild(self.bitmap); 

removeobject.prototype.run = function(){ 
    var self = this; 
    if(self.index++ > 20){ 
        self.parent.removechild(self); 
    }    

上面的run函数中,之所以要在运行20次循环之后才将其移除,是为了让上面的爆炸状态稍微持续一小段时间,然后才消失。
剩下最后一个处理,就是在循环函数中,监视这些物体的状态,来控制它们什么时候消失

[javascript] 
function onframe(){ 
    if(bird){ 
        backlayer.x = lglobal.width*0.5 - (bird.x + bird.getwidth()*0.5);    
        if(backlayer.x > 0){ 
            backlayer.x=0; 
        }else if(backlayer.x < lglobal.width - 1600){ 
            backlayer.x = lglobal.width - 1600; 
        } 
        lglobal.box2d.synchronous(); 
    } 
    var child; 
    for(var key in backlayer.childlist){ 
        child = backlayer.childlist[key]; 
        if(child.name == null)continue; 
        if(child.x < -child.getwidth() || child.x > backlayer.getwidth()){ 
            backlayer.removechild(child); 
            if(child.name == "bird01"){ 
                bird = null; 
                backlayer.addeventlistener(lmouseevent.mouse_down,movestart); 
                backlayer.addeventlistener(lmouseevent.mouse_move,moverun); 
                backlayer.addeventlistener(lmouseevent.mouse_up,moveend); 
            } 
        }else if((child.name == "stage" || child.name == "pig") && child.hp <= 0){ 
            if(child.name == "pig"){ 
                var removeobj = new removeobject(); 
                removeobj.x = child.x; 
                removeobj.y = child.y; 
                backlayer.addchild(removeobj); 
            } 
            backlayer.removechild(child); 
        }else if(child.name == "remove"){ 
            child.run(); 
        } 
    } 

上面代码都很简单,就不解释了,其中小鸟消失之后,我加入了三个事件,用来移动屏幕,最后会给出完整代码,大家可以看一下
[javascript] 
backlayer.addeventlistener(lmouseevent.mouse_down,movestart); 
backlayer.addeventlistener(lmouseevent.mouse_move,moverun); 
backlayer.addeventlistener(lmouseevent.mouse_up,moveend); 

好了,下面是效果图和测试连接,试试看吧

 html5游戏开发-愤怒的小鸟--碰撞产生的冲力
 

 

大家可以看到,上面的小鸟已经把猪头给撞爆了!

 作者:lufy_legend