全局鼠标事件应该怎么加?

  • 本站文章除注明转载外,均为本站原创或者翻译。
  • 本站文章欢迎各种形式的转载,但请18岁以上的转载者注明文章出处,尊重我的劳动,也尊重你的智商;
  • 本站部分原创和翻译文章提供markdown格式源码,欢迎使用文章源码进行转载;
  • 本博客采用 WPCMD 维护;
  • 本文标题:全局鼠标事件应该怎么加?
  • 本文链接:http://zengrong.net/post/1327.htm

一般情况下,我只需要一个全局鼠标事件就可以判断所有可视对象的点击事件了。但是这个全局鼠标事件应该加在哪里呢?

至少有3个(类)对象可以侦听这个事件:

  1. Stage对象;
  2. root对象,就是你的swf的根显示对象;
  3. 自己绘制一个与舞台等大Sprite对象。

那么,加在什么地方合适呢?

Stage是首先被我排除的对象

Stage上的点击事件总是会被侦测到,我不能控制某些“被遮盖”的对象。举个例子:

假设我制作的这个SWF是游戏地图,另外还有一个UI.swf是游戏的UI界面。UI处于地图的上层。在UI窗体上操作的时候,地图是不应该收到单击事件的。因为这种单击事件,会造成地图中玩家的某些行动。但我总是能收到鼠标的事件,且不容易判断当前的点击是否处于窗体上方。

root对象的有趣之处

每个显示对象都有一个root属性。在将其加入到显示列表的时候,root就指向根显示对象。这个根显示对象,对于纯AS项目来说是主Class;对于Flash项目来说,就是文档类或者MainTimeline(取决于你是否定义了文档类)。

如果root中没有任何的内容,那么即使对root进行了侦听,也是没办法得到鼠标事件的。这很容易理解,因为root是空的,它的里面必须有内容,才可以收到单击。

可是,我在root的graphics对象中绘制了图形,依然是没办法收到鼠标事件。

同样的,即使在root中添加的其他的非InteractiveObject(例如Bitmap、Shape等等)显示对象,也无法收到鼠标事件。

还是用一个Sprite来侦听吧

一个普通的Sprite,只需要在其graphics属性中绘制图形,就可以接收到鼠标事件了。如果想禁用鼠标事件,只需要将该sprite的mouseEnabled设置为false就行了。稍稍麻烦一点的就是,在舞台大小变化的时候,需要重绘一下这个Sprite让它适合舞台而已。

让人奇怪的是,既然root也是Sprite(AS项目的主Class是继承Sprite的),为啥就不行呢?

下面是测试用的代码:

package
{

import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.Shape;
/**
 * 侦测鼠标事件
 */
public class Main extends Sprite
{
    public function Main()
    {
        this.mouseEnabled = true;
        this.mouseChildren = true;
        var __sprite:Sprite = new Sprite();
        __sprite.graphics.beginFill(0xFF0000);
        __sprite.graphics.drawRect(0,0,this.stage.stageWidth, this.stage.stageHeight);
        __sprite.graphics.endFill();
        //__sprite.mouseEnabled = false;
        this.addChild(__sprite);

        var __shape:Shape = new Shape();
        __shape.graphics.beginFill(0x000FF0);
        __shape.graphics.drawRect(0,0,100, 100);
        __shape.graphics.endFill();
        this.addChild(__shape);
        this.addEventListener(MouseEvent.CLICK, handler_click);

    }

    private function draw():void
    {
        this.graphics.beginFill(0);
        this.graphics.drawRect(0,0,this.stage.stageWidth, this.stage.stageHeight);
        this.graphics.endFill();
    }

    private function handler_click($evt:MouseEvent):void
    {
        trace(this.mouseX, this.mouseY);
    }
}
}