I thought I had solved my mouseEvent problem for Sprites containing a Bitmap with an alpha channel but I've encountered a new issue shown in the image below: the bounding box of the "Eurasia" map Sprite is triggering a `MouseEvent.Roll_Out" for the "Africa" Sprite.
我以为我已经解决了包含带有alpha通道的Bitmap的Sprites的mouseEvent问题,但我遇到了下图中显示的新问题:“Eurasia”地图的边界框Sprite正在触发`MouseEvent.Roll_Out“ “非洲”雪碧。
My setup: Each map piece is a Sprite with a child Bitmap (PNG with alpha) and a "hitArea" Sprite derived from the Bitmap. The relevant code is below. This works great – except in the case where there are bounding box overlaps. The eventListeners
I attach to each Sprite use MouseEvent.ROLL_OVER
and MouseEvent.ROLL_OUT
but I have also tried MouseEvent.MOUSE_OVER
and MouseEvent.MOUSE_OUT
.
我的设置:每个地图块都是一个带有子位图的Sprite(带有alpha的PNG)和一个从Bitmap派生的“hitArea”Sprite。相关代码如下。这很有效 - 除了有边界框重叠的情况。我附加到每个Sprite的eventListeners使用MouseEvent.ROLL_OVER和MouseEvent.ROLL_OUT,但我也尝试过MouseEvent.MOUSE_OVER和MouseEvent.MOUSE_OUT。
I've tried attaching eventlisteners to the "hitArea" Sprite and various other things but I can't get the bounding box to be ignored. Are there any settings I may have missed – or a workaround?
我已经尝试将eventlisteners附加到“hitArea”Sprite和其他各种东西,但我不能让边界框被忽略。有没有我可能错过的设置 - 或解决方法?
Code:
buttonImage = new Bitmap(upImageData);
buttonImage.smoothing = true;
this.addChild(buttonImage);
hitSprite = createHitArea(upImageData, 4);
this.addChild(hitSprite);
hitSprite.visible = false;
hitSprite.mouseEnabled = false;
this.hitArea = hitSprite;
public function createHitArea(bitmapData:BitmapData, grainSize:uint=1):Sprite
{
var _hitarea:Sprite = new Sprite();
_hitarea.graphics.beginFill(0x000000, 1.0);
for(var x:uint=0;x<bitmapData.width;x+=grainSize) {
for(var y:uint=grainSize;y<bitmapData.height;y+=grainSize) {
if(x<=bitmapData.width && y<=bitmapData.height && bitmapData.getPixel(x,y)!=0) {
_hitarea.graphics.drawRect(x,y,grainSize,grainSize);
}
}
}
_hitarea.graphics.endFill();
_hitarea.cacheAsBitmap = true;
return _hitarea;
}
1 个解决方案
#1
1
If using a vector mask is not a viable option (it should work if you changed your hitSpite
into a Shape
and then made it the mask of the map piece sprite - also you'd have to add it as a sibling of the map piece and not a child), then the way most people do this is checking if the pixel under the mouse is transparent or not.
如果使用矢量蒙版不是一个可行的选项(如果你将你的hitSpite更改为一个Shape然后使它成为地图片段精灵的面具,那么它应该有效 - 你也必须将它添加为地图片段的兄弟和不是孩子),那么大多数人这样做的方式是检查鼠标下的像素是否透明。
Here is an example:
这是一个例子:
Let's say all your map pieces are the sole children of a Sprite referenced in a var called container
. Let's also make the assumption for the example, that your map pieces are all Sprites that have the png Bitmap as the bottom most child.
假设你所有的地图片段都是一个名为容器的var中引用的Sprite的唯一子元素。让我们假设这个例子,你的地图片段都是将png Bitmap作为最底层孩子的Sprite。
You need to add the click listener to the container (instead of each individual map piece):
您需要将click侦听器添加到容器(而不是每个单独的map片段):
container.addEventListener(MouseEvent.CLICK,click);
function click(e:MouseEvent):void {
var child:Sprite; //a helper var to store the current iterations child below in the while loop
var target:Sprite; //the item that we determined was clicked
//iterate through all children of container (backwards, so we process the top most layer first)
var i:int = container.numChildren;
while(i--){
child = container.getChildAt(i) as Sprite; //populate the child var
//now we check if the mouse is over this child by a simple hit test point
//we also then check if the pixel under the mouse is transparent (a value of 0)
if(child.hitTestPoint(e.stageX, e.stageY) && Bitmap(child.getChildAt(0)).bitmapData.getPixel32(child.x + e.localX,child.y + e.localY)){
target = child;
break; //break out of the loop since we found a child that meets the criteria
}
}
trace(target);
//now do something with target
}
#1
1
If using a vector mask is not a viable option (it should work if you changed your hitSpite
into a Shape
and then made it the mask of the map piece sprite - also you'd have to add it as a sibling of the map piece and not a child), then the way most people do this is checking if the pixel under the mouse is transparent or not.
如果使用矢量蒙版不是一个可行的选项(如果你将你的hitSpite更改为一个Shape然后使它成为地图片段精灵的面具,那么它应该有效 - 你也必须将它添加为地图片段的兄弟和不是孩子),那么大多数人这样做的方式是检查鼠标下的像素是否透明。
Here is an example:
这是一个例子:
Let's say all your map pieces are the sole children of a Sprite referenced in a var called container
. Let's also make the assumption for the example, that your map pieces are all Sprites that have the png Bitmap as the bottom most child.
假设你所有的地图片段都是一个名为容器的var中引用的Sprite的唯一子元素。让我们假设这个例子,你的地图片段都是将png Bitmap作为最底层孩子的Sprite。
You need to add the click listener to the container (instead of each individual map piece):
您需要将click侦听器添加到容器(而不是每个单独的map片段):
container.addEventListener(MouseEvent.CLICK,click);
function click(e:MouseEvent):void {
var child:Sprite; //a helper var to store the current iterations child below in the while loop
var target:Sprite; //the item that we determined was clicked
//iterate through all children of container (backwards, so we process the top most layer first)
var i:int = container.numChildren;
while(i--){
child = container.getChildAt(i) as Sprite; //populate the child var
//now we check if the mouse is over this child by a simple hit test point
//we also then check if the pixel under the mouse is transparent (a value of 0)
if(child.hitTestPoint(e.stageX, e.stageY) && Bitmap(child.getChildAt(0)).bitmapData.getPixel32(child.x + e.localX,child.y + e.localY)){
target = child;
break; //break out of the loop since we found a child that meets the criteria
}
}
trace(target);
//now do something with target
}