ActionScript3.0碰撞检测技术分析

时间:2022-08-17 03:48:56

ActionScript3.0碰撞检测技术分析

摘要:本文介绍了ActionScript3.0语言关于碰撞检测的各种方法和手段,结合FLASH开发工具实现了各种碰撞常用算法,分析常用方法的缺点和优点,并根据不同的碰撞要求总结合理的碰撞解决方案。

关键词:Flash;ActionScript3.0;碰撞检测

中图分类号:TP311.52 文献标识码:A文章编号:1007-9599(2012)05-0000-02

在开发基于ActionScript3的FLASH游戏和RIA应用程序的过程中,经常会用到碰撞检测技术,选用适当的碰撞检测方法是优化Flash游戏和RIA应用程序中至关重要的环节。当前,网页游戏十分盛行,小巧的游戏容量,精美的游戏画面,吸引着众多的玩家。随着游戏的规模越来越大,游戏玩家对游戏的精细程度要求越来越高,在满足用户对游戏效果要求的同时难免会降低网页游戏的运行速度,尽管ADOBE公司的FLASH已经支持了硬件加速等技术来优化游戏和视频的运行,但是速度仍然是FLASH网页游戏的一个瓶颈,而影响游戏速度的一个重要因素就是碰撞检测的复杂度。

AS3开发游戏及RIA应用程序常用的碰撞检测方法包括:地图网格检测、矩形检测、圆形检测、像素级位图检测四种方法。

一、地图网格检测

地图网格检测是比较粗糙的矩形检测,将固定尺寸的矩形作为一个整体单元进行处理,将整张地图划分为若干行列有序的矩形区域,在地图上移动的对象必须满足尺寸是矩形网格的整数倍,每次移动至少是矩形网格的整数倍,这样通过检测2个对象的网格坐标是否相邻就可以判断是否发生碰撞,实现这种碰撞需要对地图中出现的对象内存储自身的网格坐标,例如某对象内部存储了自身的网格坐标为(3,2)代表第3行第2个格子,该对象和其它对象发生碰撞仅需要检测另一个对象的坐标是不是(3,1)、(3,3)、(2,2)、(4,2)即可。这种方式常运用在移动对象尺寸较固定的简单游戏中,例如俄罗斯方块、推箱子等。

二、矩形检测

矩形检测是最常用的检测碰撞,实现矩形检测可以通过DisplayObject对象内的Rectangle对象的位置进行判断,也可以直接调用hitTestObject ()方法来实现。

(一)使用DisplayObject的Rectangle对象来判断碰撞就是要检测两个矩形是否重叠。假设对象A的Rectangle左上角的坐标是(x1,y1),宽度是w1,高度是h1;对象B的Rectangle左上角的坐标是(x2,y2),宽度是w2,高度是h2。只需要比较2个Rectangle矩形中心点在X,Y方向的分量距离,满足

x方向:| (x1 + w1 / 2) (x2 + w2/2) | < |(w1 + w2) / 2|

y方向:| (y1 + h1 / 2) (y2 + h2/2) | < |(h1 + h2) / 2|

则Rectangle矩形发生了重叠即碰撞。

(二)使用hitTestObject()方法仅需要将带入另一个DisplayObject对象参数即可判断矩形是否碰撞。例如displayobject1.hitTextObject(displayobject2),其中displayobject1和displayobject2为DisplayObject子类对象

三、圆形检测

如果我们将近似矩形的对象都认为是矩形对象,使用矩形检测碰撞,则我们将近似圆的对象使用圆形碰撞检测。圆形碰撞的基本思路是计算两个圆心之间的距离是否小于两个圆的半径和。假设圆形A的左上角坐标是(x1,y1),半径是r1,圆形B的左上角的坐标是(x2,y2),半径是r2,判断2个圆形对象实现碰撞公式为:

(x1 x2)2 + (y1 y2) 2 < (r1 + r2) 2

四、基于像素级碰撞检测

(一)当只需要检测某一个对象和某一个像素点坐标是否碰撞,可以使用DisplayObject对象的hitTestPoint()方法,例如:

circle.hitTestPoint(point1.x, point1.y, true),其中circle是一个绘制了一个圆的DisplayObject子类对象,point1为坐标点Point类对象,x,y为坐标point1的横纵坐标,最后一个参数设置为true是为了检查对象的实际像素,而不是检测圆的外接矩形边框区域像素。这种方法多用在检测鼠标是否位于一个特定对象之上或者是一个不规则的形状与另一个点的碰撞检测,但是无法实现2个不规则形状的碰撞检测。

(二)借助BitmapData类和Bitmap类可以实现带有透明效果的位图图像的碰撞检测。BitmapData类中包括hitTest()方法,可实现位图上像素间的碰撞检测,我们只需要将元件写入位图图像就可以通过该方法实现不规则图形的碰撞检测。实现步骤如下:

1.将元件写入位图图像。

var bmd1:BitmapData = new BitmapData(pic.width, pic.height,true,0);

//其中pic为FLASH元件对象。其构造方法参数1:构造BitmapData宽度,2:BitmapData高度,3:指定位图图像是否支持每个像素具有不同的透明度,4:填充颜色设置,表达格式为0xAARRGGBB,从透明度、红、绿、蓝分量表现带有透明度的颜色,取值为0x00000000至0xffffffff。整体功能:根据pic元件尺寸构造BitmapData实例bmd1。

bmd1.draw(pic);//调用BitmapData的draw方法将元件pic写入BitmapData对象。

varbmp1:Bitmap=new Bitmap(bmd1);//将BitmapData数据写入位图对象bmp1。

2.再使用同样方法绘制第二个位图图像。

varbmd2:BitmapData = new BitmapData(pic2.width, pic2.height,true,0);

//pic2为另一个元件

bmd2.draw(pic2);

varbmp2:Bitmap=new Bitmap(bmd2);//将BitmapData数据写入位图对象bmp2。

3.使用BitmapData对象的hitTest()方法检测2个位图的碰撞。

bmd1.hitTest(new Point(bmp1.x,bmp1.y),255,bmd2,new Point(bmp2.x,bmp2.y),255)

//参数说明:1:BitmapData 图像的左上角的位置,2:bmd1的最小的 Alpha 通道值,当低于此值的透明度像素忽略碰撞检测,3:另一个待碰撞BitmapData 对象bmd2,还可以是Rectangle、Point、Bitmap 对象,4:另一个图像左上角位置,5:bmd2对象最小Alpha通道值,低于此值则忽略碰撞检测。

由于图像对象内部的部分可能嵌套在另一个实体中,坐标体系可能不同,定义2个待碰撞对象的左上角坐标是为了正确构造各自的点,设置透明的Alpha通道是为了将具有一定透明度的点忽略碰撞检测。当Alpha值为255时仅检查可见像素的碰撞,而值为0时则透明部分也会计算入碰撞检测。

以上是FLASH碰撞检测的四种常用方法,经过运行测试在碰撞对象数量一定的情况下,网格碰撞占用系统资源较少,其次是矩形和圆形碰撞,像素级检测占用系统资源较多,在实际的项目开发中选用较合适的碰撞检测方法是优化设计的重要一步,既要优化性能又要保证效果,往往采用几种碰撞方法组合使用,例如先进行网格碰撞检测,当网格位置接近时再进行矩形、圆形或者位图的像素级检测,有些游戏采用矩形和圆形组合检测不同碰撞部分的方法。

目前没有任何一种完美的碰撞检测方法来适应所有的项目开发,任何一种检测方法都是为了满足某类项目检测的需要,选用合适的碰撞检测方法需要将上述四种检测方法灵活变通,并通过大量的压力测试来检验最后的效果。

上一篇:浅析云计算模式下的安全问题 下一篇:对软件测试的“近忧”和“远虑”的探讨