我有一个Flash项目,必须显示大量不规则形状的位图(大约10000),我想知道鼠标当前的位图。如果鼠标位于位图的透明部分上,则不应将其视为鼠标悬停。
执行此操作的一种方法是计算命中区域,然后使用包含位图的Sprite
替换每个位图,使用计算的命中区域替换另一个Sprite
,然后设置hitArea
属性。但这种效率非常低,结果完全无法使用。
最有效的方法是什么?
答案 0 :(得分:6)
在容器上试试这个:
var hits:Array = getObjectsUnderPoint(new Point(mouseX, mouseY));
if(hits.length > 0)
{
var bitmap:Bitmap = hits[0] as Bitmap;
var color:uint = bitmap.bitmapData.getPixel32(bitmap.mouseX, bitmap.mouseY);
if(color >>> 24 > 0)
{
trace('hit: '+bitmap);
}
}
如果位图重叠,则迭代hits
。您还可以设置透明度的阈值。
答案 1 :(得分:2)
答案 2 :(得分:2)
我建议使用像spatial hashing这样的东西。假设每个位图的大小相似,那么我们可以将您的舞台划分为一个巨大的网格,其中每个单元格将比任何给定的位图都大。
网格中的每个存储桶都会保存对位图的引用(请注意,位图一次可能位于多个单元格中)。单击舞台时,您可以检索鼠标坐标以用作查找此网格。然后,您可以遍历单元格以查找其包含的位图,并检查x,y坐标是否位于位图的边界框中。如果是,则可以检查位图的像素以检查它是否是透明像素。
假设找到了位图,那么您可以在点击位图时返回它。
答案 3 :(得分:1)
我的头顶没有代码,但你可以做的是每个位图都有一个图层,你用一个平面颜色填充图像,每个图像都有不同的颜色。然后在鼠标单击时,执行平面颜色图层的屏幕截图,并检查鼠标下像素的颜色。
附加:刚刚看到你的评论表明位图没有移动。这意味着您无需在鼠标点击时截取屏幕截图;只需在首次加载位图时截取屏幕截图。
答案 4 :(得分:0)
如果位图是显示对象,请使用DisplayObjectContainer方法:getObjectsUnderPoint()。这可以正确处理不规则的矢量对象,但我还没有尝试使用位图对象。
答案 5 :(得分:0)
最大的问题是大量的图像循环低谷并检查透明度。 如果位图和它们的位置没有太大变化(相对于彼此),那么有一个非常干净的解决方案:
Make an array of bitmaps(references to bitmaps actually so not consuming a
gigamount of memory) the size of your screen (or even bigger when you want
to be able to pan around in a bigger area like in a platform game for example).
Loop over all images in z order (beginning with the image furthest away)
[Calculate a mask for each image (making a black and white bitmap, white is transparent, black is everything else)]
Loop over the pixels in the image [mask] and update the array (mind the offset) to the current bitmap if not transparent
现在,每当你想要获得鼠标结束的图像时,你可以使用这个数组进行查找。
每次布局更改时,您都必须重新计算。
这为您提供了一些广泛的指导原则,可能有许多可能的优化。