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

至少有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的),为啥就不行呢?

下面是测试用的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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);
}
}
}

留言

2011-05-18
次访问