Aedis.Ju

2007年2月7日星期三

HitTestPoint处理透明png和透明swf

上次已经介绍过一次Doug McCune ,如果你正在处理图片等问题方面的话,也许他真得是一个很不错的专家级人物.

这次他又一次给我们解决了一个我们认为的BUG:
我们一般用DisplayObject.hitTestPoint(x, y, obj):Boolean来判断x,y的位置是否存在在这个display object上,如果在上面的话,返回来是true.当object是透明的话,我们认为,这个方法返回的应该是false,就是说不在display object上面.
这次提到的是png图片和swf中透明的问题.大家经过验证得出来的结论就是:只要是png图片,flex认为它整个是一个实体,包括透明和不透明的,所以它一直返回的是true,但swf就不一样了,只要swf透明的地方,它返回的是false,不透明的地方返回的是true.

结论得出来了,问题是我们都一直认为透明不是'东西' ,既然不是'东西'返回的就应该是false.那怎么样让透明png图片的透明部分返回的是false呢?就象swf一样?
第一种:重新判断x,y下面的透明度,如果是0,返回的是false;
第二种:采用Doug的方法:写了一个realHitTest(obj,point).首先判断是不是BitmapData,如果是的话直接采用BitmapData自带的hitTest(firstPoint, firstAlphaThreshold, secondObject, secondBitmapDataPoint, secondAlphaThreshold):Boolean,当然,png和swf它们都不是BitmapData. 当png图片和swf不透明的时候,hitTestPoint(x, y, obj)返回来是true,这时候,就要进行处理了,让png透明的地方返回来是false,他把将要检测的display obje 转成一个BitmapData,然后用BitmapData的HitTest来进行检测.

代码片段:

if(object is BitmapData)
{
return (object as BitmapData).hitTest(new Point(0,0), 0, object.globalToLocal(point));
} else {
/* First we chack if the hitTestPoint method returns false. If it does, that * means that we definitely do not have a hit, so we return false. But if this * returns true, we still don't know 100% that we have a hit because it might * be a transparent part of the image. */
if(!object.hitTestPoint(point.x, point.y, true)) {
return false;
} else {
/* So now we make a new BitmapData object and draw the pixels of our object * in there. Then we use the hitTest method of that BitmapData object to * really find out of we have a hit or not. */
var bmapData:BitmapData = new BitmapData(object.width, object.height, true, 0x00000000);
bmapData.draw(object, new Matrix());
var returnVal:Boolean = bmapData.hitTest(new Point(0,0), 0, object.globalToLocal(point));
bmapData.dispose(); return returnVal;
}
}


Demo
View the source

Link:Using hitTestPoint or hitTest on Transparent PNG images by Doug McCune

knowledge:
DisplayObject --> EventDispatcher --> Object
hitTestPoint(x:Number, y:Number, shapeFlag:Boolean = false):Boolean
Evaluates the display object to see if it overlaps or intersects with the point specified by the x and y parameters.

BitmapData --> Object

hitTest(firstPoint:Point, firstAlphaThreshold:uint, secondObject:Object, secondBitmapDataPoint:Point = null, secondAlphaThreshold:uint = 1):Boolean
Performs pixel-level hit detection between one bitmap image and a point, rectangle, or other bitmap image.

1 条评论:

匿名 说...

学习了!
HooPower