Flash中碰撞检测技术的研究与应用

2011-02-17 15:48明昀
中国科技信息 2011年16期
关键词:碰撞检测敌机子弹

明昀

Flash中碰撞检测技术的研究与应用

明昀

Flash是现今十分热门的技术,通过Flash可以实现动画、游戏和交互多媒体等应用,功能强大。

本文重点讨论采用Flash技术中使用actionscript进行碰撞检测,并举例说明其不同的使用方式,最后通过对一款平面飞行射击游戏中碰撞检测的设计,来说明其具体应用方法。

Flash; 碰撞检测

在Flash actionscript 2.0中我们可以使用MovieClip 类的 hitTest() 方法来检测 SWF 文件中的冲突。它检查某个对象是否与影片剪辑有冲突,然后返回一个布尔值(true 或 false)。我们可能想了解是否发生了冲突,以测试用户是否已到达舞台上的某个特定静态区域,或确定一个影片剪辑何时到达另一个影片剪辑。利用hitTest() 方法,可以判定这些结果。可以使用 hitTest() 的参数来指定舞台上某个点击区域的 x 和 y 坐标,或者使用另一个影片剪辑的目标路径作为点击区域。在指定 x 和 y 时,如果由 (x, y) 标志的点是非透明点,则 hitTest() 返回 true。当目标传递给 hitTest() 时,会对两个影片剪辑的边框进行比较。如果二者相交,则 hitTest() 返回 true。如果两个边框没有相交,则 hitTest() 返回 false。hitTest具体用法为:

用法 1:根据 shapeFlag 设置,将 x和 y 坐标与指定实例的形状或边框进行比较。如果 shapeFlag 设置为 true,则只计算在舞台上的实例实际占据的区域,并且如果 x 和 y 在任意一点重叠,则返回true 值。此评估对于确定影片剪辑是否处于指定的点击区域或热点区域中很有用。参数x为舞台上点击区域的 x 坐标,y为舞台上点击区域的 y 坐标,x 和 y 坐标都在全局坐标空间中定义,shapeFlag为一个布尔值,指定是计算指定实例的整个形状(true) 还是仅计算边框 (false);只有当用x 和 y 坐标参数标志点击区域时,才可以指定该参数。例如,鼠标控制影片剪辑移动。鼠标在(坐标_xmouse, _ymouse)影片剪辑test_mc上(与test_mc重叠或交叉)时,test_mc向右移动10个像素。此时可以在场景第1帧上使用test_mc执行onEnterFrame事件处理函数,并在函数中使用hitTest进行判断,即“if (this.hitTest (_xmouse, _ymouse, false))”,如果鼠标坐标与test_mc交叉或重叠(鼠标在test_mc上),则test_mc横坐标增加10个像素“this. _x += 10”,test_mc横坐标大于或者等于500个像素时“if (this._x>=500)”,重新设置test_mc横坐标为0。

用法 2:计算target 和指定实例的边框,如果它们在任意一点上重叠或交叉,则返回 true。Target为可能与影片剪辑相交或重叠的点击区域的目标路径。target 参数通常表示一个按钮或一个文本输入字段。例如,要把圆等6个图形拖到上面对应的文字上。6个图形分别是tx1_mc~tx6_mc,6个对应的文字都是动态文本,名称分别是wz1~wz6,每个mc拖动的位置如果出错了能够自动回到原来的位置,当6个mc都能正确拖到对应位置上时,主时间轴从第1帧跳到第2帧,并给予文字说明。显然,此时我们只要在一个mc上的脚本写对了,其他5个mc就可以很方便的写出来;在主时间轴第1帧上写的脚本“stop()”,设置用于记数的变量“i=0”,在圆(tx1_mc)上的脚本使用“on (press)”判断鼠标按下时进行,并在on语句中把本mc的坐标赋给本mc下的变量x、y,并拖动这个mc,即“startDrag(this, true)”;使用“on (release)”判断松开鼠标时动作,在做松开动作时停止拖动这个mc,并使用“if (this.hitTest(_root. wz1))”来判断这个mc和动态文本wz1重叠或相交;相交时,判断这时如果这个mc上的变量k不为1则主时间轴上的变量i加1,并在这个mc上设置变量k=1(使一个mc拖动正确时,主时间轴上的记数变量i只加1次);如相交时,主时间轴上的记数变量i等于6(图形都正确拖动完毕),主时间轴跳到下1帧停下;但如果这个mc和动态文本wz1不重叠或相交,那么把这个mc的坐标设置为前面得到的这个mc的坐标的数值;我们可以先检测一个mc代码的正确性,然后再把这代码复制在其他5个mc上,只消把其中的wz1改为相应的wz2~wz6即可。

通过上面研究了解了hitTest的基本用法后,下面就以一款平面飞行游戏中碰撞检测为例,进一步说明其实际应用:

1、首先确定需要相互碰撞的对象。游戏中主角飞机与所有敌机机身会发生碰撞,被撞后双方同归于尽;主角子弹和其他友机子弹会与所有敌机机身发生碰撞,被撞后敌机生命将根据子弹威力扣减,为零则敌机被击毁;敌机子弹与主角飞机发生碰撞,被撞后主角生命将根据子弹威力扣减,为零则主角被击毁。

2、设置碰撞范围。在Flash库中双击子弹元件,进入元件编辑,更改主角子弹图形为“影片剪辑”,“实例名称”为“body”,这就是子弹进行碰撞判断的范围;同样,重复此步骤,对其他元件也设置好碰撞范围,对于飞机元件除了设置好碰撞范围外,还可以加多一帧,把实例属性“颜色”为“亮度100%”,这表示是飞机被击中时进行一次反白显示。

3、子弹碰撞检测。在库中双击“敌机子弹(enemy_bullet)”元件,进入元件编辑,新建一图层,起名为“action”,在该层第1帧按进入动作编辑,输入代码“stop ()”,在所有层第20帧处按插入帧,在“action”层第2帧按插入空白关键帧,更改“帧标签”为“end”,在第20帧按插入空白关键帧,更改“帧标签”为“remove”,在第20帧按进入动作编辑,输入代码“stop()”和“this. removeMovieClip()”,“remove”标签表示此帧进行子弹消失的处理;选择子弹实例,按进入动作编辑,先定义子弹属性“bullet_power=1”和“bullet_speed=20”,分别表示该子弹的威力和速度;其次需定义子弹飞出画面时消失,使用“if(元件坐标超过规定xy范围){ _parent.gotoAndPlay (‘remove’) }”语句设置;最后使用hitTest来判断是否击中主角飞机,即使用“if (_parent.body.hitTest(_root.player.body))”语句来判断当前子弹实例是否进入主角飞机“player”中实例名为“body”的碰撞范围,如是则根据子弹威力扣主角飞机生命数值,如“_root.player_life-=bullet_power”;按+测试,发现凡是敌机子弹击中主角飞机,主角飞机都会反白一下,这表示碰撞检测成功。其他“主角飞机子弹”和“友机子弹”的做法也基本相同,但需要调整相关子弹属性,同时需要注意与敌机子弹的飞行方向不同。

4、飞机碰撞检测。在库中双击“敌机(enemy)”元件,进入元件编辑,先在最后一帧设置“帧标签”为“remove”,加入代码“stop()”和“this.removeMovieClip()”,表示飞机消失处理;其次选择飞机实例,按进入动作编辑,同样先设置好飞机属性,如:“enemy_life=2”和“score=5”,分别表示敌机生命和击毁该机得分;接着同样使用if语句设置好判断是否飞出边界,超出则删除;判断是否与主角飞机相撞,使用“if(_parent.body.hitTest(_root. player.body))”语句来判断当前敌机实例是否进入主角飞机“player”中实例名为“body”的碰撞范围,如进入则两机同归于尽,如代码“_root.player_life-=_root. player_life”;判断是否被主角或主角友机子弹击中,这里由于子弹不只一发,因此需要使用“for (i=1; i<=子弹最大数量; i++)”语句进行循环,使用“if(_parent. body.hitTest (_root["player_bullet"+i]. body))”语句来判断是否与子弹相撞,如相撞则子弹消失,并根据子弹威力扣减自己生命数值;最后判断自身生命数值是否为0,是则播放爆炸消失效果。

10.3969/j.issn.1001-8972.2011.16.138

猜你喜欢
碰撞检测敌机子弹
基于动力学补偿的机器人电机力矩误差碰撞检测
冲着敌机,开炮!——M1939式37毫米高射炮
全新预测碰撞检测系统
基于BIM的铁路信号室外设备布置与碰撞检测方法
三颗子弹
子弹VS防弹
Karma:让子弹飞一会儿
子弹
新中国建国后击落入侵敌机大盘点
BIM技术下的某办公楼项目管线碰撞检测