前进的MouseEvent透明位图到底层影片剪辑位图、底层、影片剪辑、透明

2023-09-08 15:24:02 作者:你望穿秋水,我忘穿秋裤

所以我Bitmaping一些沉重的东西,试图搞垮[pre-渲染]和[渲染]根据FlashBuilder的剖析,它是相当高的。我的认为的这种进展顺利,直到我意识到,只要你改变一个影片剪辑到一个位图,你失去了鼠标移动事件(在,出,移动...)的基于像素的精度,所有你留下的是整个边框的位图的,东西是不太理想的。我有一个游戏,许多位图资源将是对彼此顶部的一个场景,在舞台上,安排在不同的方式,需要具备之间的像素精度移动的每一个,已用尽我的努力就如何实现相同的鼠标移动的结果与位图家伙是正常的。

So I'm Bitmaping some heavy stuff to try bring down the [pre-render] and [render] which is quite high according to FlashBuilder's profiling. I thought this was going well until I realised that as soon as you change a MovieClip to a Bitmap, you lose the pixel based accuracy of the mouse move events (Over, Out, Move...), all your left with is the entire bounding box of the Bitmap, something which is less than desirable. I've got a game where many Bitmapped assets would be on top of each other in a scene, on the stage, arranged in various ways and need to have that pixel accuracy moving between each one and have exhausted my efforts as to how to achieve the same mouse move results with the Bitmapped guys as normal.

这, http://seadersforums.appspot.com/static/bitmaps.fla,是一个FLA这说明这个操作,你可以看到它是如何工作在这里,的http:// sea​​dersforums.appspot.com/static/bitmaps.html 。当它加载了,在舞台上两个项目都绘制的形状,封装在影片剪辑,无论是得到焕发,如果你对他们悬停。如果单击阶段可言,紫色的家伙被变成了一个位图,现在,他的重灾区,当谈到MouseEvents是他的整个边界框,你只能得到通过对背绿项目在边缘条子

This, http://seadersforums.appspot.com/static/bitmaps.fla , is a FLA which shows this operation, and you can see how it works here, http://seadersforums.appspot.com/static/bitmaps.html . When it loads up, both items on stage are drawn Shapes, encapsulated in MovieClips, both that get a glow, if you hover over them. If you click the stage at all, the purple guy gets turned into a Bitmap and now, his 'hit area', when it comes to MouseEvents is his whole bounding box and you can only get through to the back green item at the edge slivers.

我也在追查这鼠标是在像素,所以我可以明确地告诉当鼠标悬停在透明区域,它是0,但我怎么能告诉事件转发本身就下来链的绿色影片剪辑?

I'm also tracing the pixel which the mouse is over, so I can clearly tell when the mouse is over a transparent area, it's 0, but how can I tell the event to forward itself on down the chain to the green MovieClip?

下面是它是如何的,现在pretty的多为我工作,

Below is how it's now pretty much working for me,

        var bitmap:Bitmap = this['bitmap'];
        var shouldMouseOver:Boolean = bitmap.bitmapData.getPixel(event.localX - bitmap.x, event.localY - bitmap.y);
        if(shouldMouseOver)
        {
            this.mouseOver();
        }
        else {
            this.mouseEnabled = false;
            var point:Point = new Point(event.stageX, event.stageY);
            for each(var other:DisplayObject in _topContainer.getObjectsUnderPoint(_topContainer.globalToLocal(point)))
            {
                if(other.mouseEnabled)
                {
                    point = other.globalToLocal(point);
                    other.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_MOVE, false, false, point.x, point.y));
                    break;
                }
            }
            this.mouseEnabled = true;
        }

我关闭将mouseEnabled为我的项目,当我知道这是错的,那么我搜索了正确符合该法案的另一个项目,如果有,发送一个事件到并打破。如果一个人的也是错误的,它会再次做同样的,但每次取自己跳出循环。

I shut off mouseEnabled for my item, when I know it's wrong, then I search for another item that properly fits the bill and if there is one, send an Event to that and break. If that one's also wrong, it'll do the same again, but each time taking themselves out of the loop.

这确实工作正是我想要的,但我一直preFER让事情像globalToLocal和循环,并从阵列读不经常更新的类似听众MOUSE_MOVE方法。有没有更有效的方法来做到这一点?

This does work exactly how I want it to, but I'd always prefer to keep things like globalToLocal and looping, and reading from arrays for not frequently updated methods like listeners to MOUSE_MOVE. Is there a more efficient way to do this?

推荐答案

我的头,你可以使用getObjectsUnderPoint方法的顶部。任何显示对象类型类有这个方法。该方法采用类型为点,在那里你可以通过鼠标的坐标参数。相信该方法将返回点下方的对象,所包含您呼吁getObjectsUnderPoint方法是DisplayObject内的阵列。例如,如果被嵌套在父剪辑称为集装箱内你们这些影片剪辑,那么你可以做这样的事情:

Off the top of my head you could use the getObjectsUnderPoint method. Any display object typed class has this method. The method takes an argument of type Point, where you can pass the mouse coordinates. I believe the method returns an array of objects beneath that point, that are contained within the DisplayObject that you called the getObjectsUnderPoint method on. For example if these movieclips of yours are nested within a parent clip called Container, then you could do something like this:

var pt:Point = new Point(10, 20);
var objects:Array = container.getObjectsUnderPoint(pt);

然后针对具体的情况我会通过深度返回的对象进行排序,以获得下一个列表中(一之下,或任何一个我想要的)。

Then for your specific scenario I'd sort the returned objects by depth to get the next one in the list (the one beneath, or whatever one I want).

var i:int = 0;
var topContainer:DisplayObject;
var lastIndex:int = 0;
for(i; i < objects.length; ++i){
   if(topContainer:DisplayObject){
       if(container.getChildIndex(DisplayObject(objects[i])) < lastIndex){
            lastIndex = container.getChildIndex(DisplayObject(objects[i]));
       }
   }else{
       topContainer = DisplayObject(objects[i]);
       lastIndex = container.getChildIndex(DisplayObject(objects[i]));
   }   
}

所以基本上我在做什么这里是排序通过所有的结果,并挑选具有最低的子索引来获得理想的下一个孩子最接近的表面。它已经有一段时间,因为我已经到闪存,所以我不是100%肯定,如果显示列表作品的方式在儿童指数方面,也就是说,如果近处的物体具有较低的指数值以上。换言之,这是极可能的是,子带索引,如果0可能是孩子在列表的底部。你必须给它一个尝试,只是调整上述code。如果是这样的话。无论如何,一旦该功能运行(这是未经测试的方式,所以可能是O型的这种性质的事物,但这个概念应该工作),那么你将有你真的想访问由topContainer引用的剪辑。从这里你可以派遣MouseEvent来的容器。

So basically what I'm doing here is sorting through all the results and picking the one with the lowest child index to ideally get the next child closest to the surface. It's been a while since I've been into flash so I'm not 100% sure if the display list works that way in terms of child index, that is, if closer objects have a lower index value or higher. In other words, it is highly possible that a child with an index if 0 could be the child at the bottom of the list. You'll have to give it a try and just adjust the above code if that is the case. Anyway once that function runs (it's un-tested by the way, so might be type-o's and things of this nature but the concept should work) then you will have the clip you really want to access referenced by topContainer. From here you can dispatch a mouseEvent to that container.

topContainer.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN, false, false, MOUSE_POSITION_X, MOUSE_POSITION_Y));

现在,这是你会做什么,如果你有一个听众的topContainer等待接收它自己的鼠标事件的内部。也就是说,有直接连接到topContainer对象作为这样一个事件监听器:

Now this is what you would do if you have a listener inside of the topContainer waiting to receive it's own mouse event. That is, there is an event listener directly attached to the topContainer object as so:

topContainer.addEventListener(MouseEvent.MOUSE_DOWN, onMouse);

或者,在topContainer类中:

or, inside the topContainer class:

this.addEventListener(MouseEvent.MOUSE_DOWN, onMouse);

原因是,我们直接调度的事件,没有事件目标的topContainer参考,并与事件冒泡关闭。

The reason being that we are dispatching the event directly to the topContainer reference with no event target, and with event bubbling turned off.

如果在另一方面你的模型涉及单个的MouseEvent处理器在舞台上一级或其他级别的,和你的onMouse处理器有一个开关语句来完成这取决于事件的目标是使某些操作:

If on the other hand your model involves a single MouseEvent handler at the stage level or some other level, and your onMouse handler has a switch statement to do certain actions depending on the event target as so:

function onMouse(e:MouseEvent):void
{
   switch(e.currentTarget){
      case MyMovieClip1:
          //Do Something
      break;

      case MyMovieClip2:
          //Do Something
      break;
   }
}

然后你将需要分派该事件略有不同的庄园。你需要包括一个参考topContainer对象以及启用事件冒泡:

Then you're going to need to dispatch that event in a slightly different manor. You'll need to include a reference to the topContainer object as well as enable event bubbling:

someRelativeClip.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, MOUSE_POSITION_X, MOUSE_POSITION_Y, topContainer));

希望这有助于让我知道如果你需要任何澄清。

Hope this helps let me know if you need any clarification.