第七章-游戏中的冲突检测

上传人:F****n 文档编号:99559171 上传时间:2019-09-19 格式:DOC 页数:6 大小:166KB
返回 下载 相关 举报
第七章-游戏中的冲突检测_第1页
第1页 / 共6页
第七章-游戏中的冲突检测_第2页
第2页 / 共6页
第七章-游戏中的冲突检测_第3页
第3页 / 共6页
第七章-游戏中的冲突检测_第4页
第4页 / 共6页
第七章-游戏中的冲突检测_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《第七章-游戏中的冲突检测》由会员分享,可在线阅读,更多相关《第七章-游戏中的冲突检测(6页珍藏版)》请在金锄头文库上搜索。

1、闽江学院教案校际选修课 课程名称Flash游戏编程 任课老师: 肖刚第七章 游戏中的冲突检测教学提要冲突检测的方法介绍基于位图的冲突检测实例“战场生存记”中的冲突检测重点与难点冲突检测的边际条件冲突检测技术与延迟循环的综合应用教学内容:冲突检测是指检测两个对象是否有重叠的部分或者某个对象是否覆盖了某个点。许多游戏必须使用到冲突检测,例如:格斗游戏,两个对战角色是否相碰是出招是否有效的前提。再比如台球游戏,如果台球在运动的过程中相碰,那么它应该有动量传递。正确地进行冲突检测,是这些游戏设计成败的关键点。一、 冲突检测的方法介绍ActionScript给我们提供了三种冲突检测的方法。列表如下:名称

2、描述提供者hitTestObject(目标显示对象)检测两个对象是否有重叠的部分DisplayObjecthitTestPoint(x,y,形状标记)检测本对象是否覆盖了某个点DisplayObjecthitTest(参数列表)检测两个BitmapData是否有重叠的部分BitmapData现分别介绍如下:1、检测两个显示对象是否有重叠的部分使用显示对象的hitTestObject方法可以检测两个显示对象是否有重叠的部分。其语法如下:源显示对象.hitTestObject(目标显示对象);它的返回值true表示有重叠,false表示没有重叠。但需要注意的是,这个函数以显示对象的外接矩形框作为评

3、判是否重叠的依据。两个显示对象图像部分重叠当然好理解,但是如下图中的两个影片剪辑(矩形框是外接矩形区域示意图),在视觉上虽然没有重叠,但是由于它们的矩形框区域有交叉的部分,所以hitTestObject的返回值为true。外接矩形框示意图还有一个细节需要注意,如果影片剪辑在编辑过程中,或者是运行过程中有旋转,那么此时的情况会如何呢?例如上图中的五角星,如果旋转了一个某个角度,如下图所示:旋转后的外接矩形框示意图那么,进行冲突检测的时候,采用剪辑原有的方框(实线),还是大虚线方框,抑或是小虚线方框?实验结果表明,Flash采用的是大虚线方框作为冲突检测的矩形区域。2、检测显示对象与某一点是否重叠

4、使用显示对象的hitTestPoint方法可以检测显示对象与某个坐标点是否重叠。形状标记为false(默认)时,使用显示对象的外接矩形框作为判断的依据,为true时,使用显示对象的实体像素作为判断的依据与坐标点进行检测。其语法如下:显示对象.hitTestPoint(x,y,形状标记);可选参数默认值是false,它表示使用边框作为判断的依据。参数x和参数y指出了场景中的一个坐标,当形状标记值为true的时候,则判断显示对象的实际形状与指定的作标点是否冲突,当形状标记为false的时候,则判断显示对象的矩形形状区域与指定的作标点是否冲突。如下图所示,显示对象的点冲突检测五角星剪辑和三个坐标点A

5、、B、C在形状标记不同取值下hitTestPoint的返回值如下表:形状标记truefalseAfalsetrueBtruetrueCfalsefalse提示:大多数游戏中,将尺寸较小的剪辑简化为点,用hitTestPoint检测它与某个对象是否冲突。例如战斗机游戏中,所有的子弹都被简化成质点。这显著提高了游戏的性能,也使爆炸点更贴近战斗机的轮廓。例如“战场生存记”游戏中就采用点探测的方式实现冲突检测。3、对位图数据进行像素级别的冲突检测使用BitmapData的hitTest方法可以检测BitmapData与另一个Point、Rectangle、Bitmap或者BitmapData是否有重叠

6、。它以透明度域值作为有效像素的根据,低于域值的是无效像素,等于或者高于域值的是有效像素,如果两个对象比较的区域内有重叠的有效像素,则返回true,否则返回false。这给我们提供了一个实现两个可视对象实体冲突检测的思路。即将游戏中需要进行严格的实体冲突检测的对象制作成带透明通道的位图,导入Flash中使用,或者是通过BitmapData的draw方法从现有的影片剪辑中获取位图快照,然后再使用hitTest方法进行冲突检测。这样做的好处是可以实现真正的与视觉完全一致的冲突检测结果。使用draw方法还有一个好处,就是可以获取动画的位图快照,从而在两个动画之间进行基于位图的冲突检测,大大提高了冲突检

7、测的真实性。hitTest有5个参数,按顺序为:1) firstPoint (Point):设定源BitmapData左上角在比较空间中的位置。 2) firstAlphaThreshold (uint):设定源BitmapData对象被视为不透明的最小 Alpha 通道值,取值0255。Alpha值小于这个值的像素不参与重叠计算。3) secondObject (Object):目标对象,目标对象可以是Rectangle、Point、Bitmap或BitmapData对象。4) secondBitmapDataPoint (Point):可选参数,当目标对象为BitmapData 对象时才使

8、用。表示目标对象左上角在比较空间中的位置。 5) secondAlphaThreshold (uint):可选参数,设定目标BitmapData 对象被视为不透明的最小 Alpha 通道值。注意:hitTest不支持对缩放、旋转等变换操作之后的位图进行冲突检测,它将忽略这些变换。如果游戏需要这种变换(例如让蝴蝶任意地飞翔),那么应该将这种缩放、旋转动画在剪辑内部实现,而不宜在获取位图快照的剪辑上进行变换操作。二、 基于位图的冲突检测实例演示程序:小心触电你扮演一个小人物,要穿过到处都是高压电的区域,你不能碰到任何带电的东西,到达目的地即可获胜。程序分析:很明显,这个游戏的关键技术就是如何精确判

9、断小人与众多各种剪辑对象之间是否有重叠的部分,如果有,则表示触电失败,如果碰到游戏结束所在位置的显示对象,表示游戏胜利。我们单独抽出冲突检测部分进行讲解。我们要完成的工作是用鼠标引导小人运动,用一个影片剪辑模拟带电物体,如果带电物体碰到小人,就输出一条信息。设计步骤:1) 新建Flash文档(ActionScript 3.0),设置文档的大小为:550*200,帧频率为40。2) 设计两个影片剪辑,一个是小人,一个是有三条天线的带电体,是个会旋转的动画,如下图所示:注意两个剪辑的中心位置都必须定义在左上角,并且要在剪辑内添加一个透明的方块,用来覆盖动画中可能接触到的区域。如天线剪辑内就有一个这

10、样的方块。这样做的目的是为了在任意时刻用draw方法获得剪辑的快照时不会丢失部分动画内容。3) 将这两个剪辑都布置在舞台上,设置小人的实例名称为boy。4) 进入boy剪辑内部,在其第一帧输入如下代码:startDrag(true);Mouse.hide();这样运行中这个小人将会跟随鼠标移动,并且鼠标指针被隐藏了。5) 进入天线剪辑,在其第一帧输入以下代码:var enemy:MovieClip=MovieClip(root).boy;addEventListener(Event.ENTER_FRAME,bHitTest);function bHitTest(target:Event) va

11、r bd1:BitmapData=new BitmapData(width,height,true,0x);var bd2:BitmapData=new BitmapData(enemy.width,enemy.height,true,0x);var pt1:Point=new Point(x,y);var pt2:Point=new Point(enemy.x,enemy.y);bd1.draw(this);var rec:Rectangle=new Rectangle(-50,-10,100,200);bd2.draw(enemy);if (bd1.hitTest(pt1,1,bd2,pt

12、2,1) trace(碰到啦!);这样天线剪辑就会每过ENTER_FRAME时间就会检查一下是否与boy有基于位图的冲突,如果有,就输出信息“碰到啦!”。冲突检测的代码也可以放在boy剪辑中,但是因为可能实际游戏中有很多个这样的带电体,所以将代码放在带电体内部,可以简化代码。例如这个例子里,把天线剪辑复制多份在舞台上,那么每个天线剪辑实例都能够正确地与boy进行冲突检测。6) 保存文件,然后测试效果。7) 用同样的方法进行更多地带电体的设计,以及对boy剪辑进行适当的改造,就可以实现这个游戏。下图为这个游戏示例的运行截图:三、 “战场生存记”中的冲突检测“战场生存记”中的冲突检测只有一个,就是

13、检测炮弹与小兵是否有碰到。只要有一个炮打碰到小兵,小兵就应该死去,游戏结束。很显然,这个冲突检测应该设计在炮弹角色里面。因为这里炮弹非常小,我们简化设计,将炮弹当作一个质点,使用点冲突检测来设计,使得检测的边界条件较为接近小兵的身体。设计步骤:在实验四的基础上修改炮弹角色,使得炮弹角色具有冲突检测功能即可。打开实验四时制作的fla文档,在库中找到炮弹剪辑,双击进入剪辑内部。在第一帧的代码部分做如下修改:1) 将repeat函数修改为:function repeat(Event) moveBall();/炮弹的运动var deadHero = checkBomb();/检查是否碰到敌人if (d

14、eadHero != null) /碰到敌人了gotoAndPlay(bomb);/自身爆炸deadHero.dead();/指示敌人死去这样炮弹在repeat时不仅运动,还将检测它是否碰到敌人。如果碰到,就指示这个敌人死去。这里引用了deadHero的dead方法,也就是前面设计的小兵角色的dead方法。这是直接调用另一个角色的方法的示例。但是事实上如果是构建一个复杂的应用系统,则不应该直接调用其它对象的方法,否则相当于炮弹的任何敌人必须有dead方法,提高了模块之间的耦合度。改用自定义事件则可以解决这个问题。代码如下:function repeat(e:Event) moveBall();

15、/炮弹的运动var deadHero = checkBomb();/检查是否碰到敌人if (deadHero != null) /碰到敌人了gotoAndPlay(bomb);/自身爆炸var e:Event=new Event(bomb);this.dispatchEvent(e);这样只要它碰到敌人就会发出bomb事件,至于如何响应这个事件,就交给使用角色的代码来完成了,这大大提高了模块的独立性。2) 编写checkBomb函数以便完成碰撞检测。function checkBomb():MovieClip /检查是否与敌人列表中的一个敌人相碰撞for (var i = 0; ienemy.length; i+) if (enemyi=null) continue;if (enemyi.hitTestPoint(this.x, this.y, true) & enemyi.status != dead) /

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 教学/培训

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号