目前,我们的一个团队遇到了一个非常奇怪的现象:在操纵z
的{{1}}属性并改变舞台质量之后,一些嵌套MovieClip
的事件监听器似乎消失了(或者至少不再对适当的事件做出反应。)
同时执行 时出现问题,更改舞台质量和操纵MovieClips
属性。
这是一个简单的课程,展示了这个问题:
z
任何人都可以给我一个指针在这里发生了什么?为什么package {
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.StageQuality;
import flash.events.MouseEvent;
public class StageQualityTestDemo extends MovieClip {
private static const OVER_COLOR:uint = 0x13ff37;
private static const OUT_COLOR:uint = 0x000000;
private static const BACK_COLOR:uint = 0xdeadc0de;
private var _qualitySetting:int = 0;
private var _zoom:Number = 0.0;
private var _mainsprite:MovieClip = new MovieClip();
private var _button:MovieClip = new MovieClip();
public function StageQualityTestDemo() {
initDemo();
}
private function initDemo():void {
this.addChild(_mainsprite);
_mainsprite.addChild(_button);
this.stage.addEventListener(MouseEvent.MOUSE_WHEEL, handleMouseWheel);
stage.quality = StageQuality.LOW;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
drawButtonCircle(OUT_COLOR);
drawMainBackground(BACK_COLOR);
_button.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOver);
_button.addEventListener(MouseEvent.MOUSE_OUT, handleMouseOut);
}
private function handleMouseOver(event:MouseEvent):void {
drawButtonCircle(OVER_COLOR);
}
private function handleMouseOut(event:MouseEvent):void {
drawButtonCircle(OUT_COLOR);
}
private function drawMainBackground(color:uint):void {
var g:Graphics = _mainsprite.graphics;
g.clear();
g.beginFill(color);
g.drawRect(0, 0, 500, 500);
g.endFill();
}
private function drawButtonCircle(color:uint):void {
var g:Graphics = _button.graphics;
g.clear();
g.beginFill(color);
g.drawCircle(250, 250, 50);
g.endFill();
}
private function handleMouseWheel(event:MouseEvent):void {
var motion:Number = event.delta * 5;
_zoom += motion;
_mainsprite.z = _zoom;
if (_zoom < 0 && _qualitySetting != 0 ) {
_qualitySetting = 0;
trace("setting LOW");
stage.quality = StageQuality.LOW;
}
if (_zoom > 100 && _qualitySetting == 0 ) {
_qualitySetting = 1;
trace("setting HIGH");
stage.quality = StageQuality.HIGH;
}
}
}
}
上的事件监视器在缩小时停止工作,舞台质量为_button
,但在放大并且舞台质量为HIGH
时再次工作?救命?任何人吗?
[更新]
基于@Amy Blankenship的建议,我添加了一些LOW
语句。结果是trace
和willTrigger()
都报告为true,但处理函数仍未被调用。
代码更改:
hasEventListener()
跟踪输出:
[...]
private var _counter:int;
[...]
private function initDemo():void {
this.addChild(_mainsprite);
_mainsprite.addChild(_button);
this.stage.addEventListener(MouseEvent.MOUSE_WHEEL, handleMouseWheel);
this.stage.addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove);
stage.quality = StageQuality.LOW;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
drawButtonCircle(OUT_COLOR);
drawMainBackground(BACK_COLOR);
_button.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOver);
_button.addEventListener(MouseEvent.MOUSE_OUT, handleMouseOut);
}
private function handleMouseMove(event:MouseEvent):void {
if (_counter++ % 50 == 0) {
trace("_button.willTrigger(MouseEvent.MOUSE_OVER): " + _button.willTrigger(MouseEvent.MOUSE_OVER));
trace("_button.willTrigger(MouseEvent.MOUSE_OUT): " + _button.willTrigger(MouseEvent.MOUSE_OVER));
trace("_button.hasEventListener(MouseEvent.MOUSE_OVER): " + _button.hasEventListener(MouseEvent.MOUSE_OVER));
trace("_button.hasEventListener(MouseEvent.MOUSE_OUT): " + _button.hasEventListener(MouseEvent.MOUSE_OUT));
}
}
private function handleMouseOver(event:MouseEvent):void {
trace("handleMouseOver");
drawButtonCircle(OVER_COLOR);
}
private function handleMouseOut(event:MouseEvent):void {
trace("handleMouseOut");
drawButtonCircle(OUT_COLOR);
}
[...]
[/更新]
答案 0 :(得分:3)
我发现使用stage.quality = StageQuality.MEDIUM;而不是HIGH工作。 我知道flash z转换实际上是通过将剪辑转换为位图来实现的。而且这些位图不是InteractiveObjects。我想你找到了一个flash播放器的bug。 但是,希望使用中等质量的放大项目将为您提供“足够好”的质量来完成您的项目。
答案 1 :(得分:2)
我也不知道为什么正在发生这种行为,但我找到了一种解决方法。
重建显示列表可让您再次获取鼠标事件。我不知道这对你的情况有多实际;你提到这是你问题的简化版本。无论如何,这是我正在运行的代码。我仍然可以在处理鼠标事件的同时放大并改变舞台的质量:
package
{
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.getTimer;
public class AS3Playground extends MovieClip
{
private static const OVER_COLOR:uint = 0x13ff37;
private static const OUT_COLOR:uint = 0x000000;
private static const BACK_COLOR:uint = 0xdeadc0de;
private var _qualitySetting:int = 0;
private var _zoom:Number = 0.0;
private var _mainsprite:MovieClip;
private var _button:MovieClip;
private var _lastKnownStageQuality:String;
private var _counter:int;
public function AS3Playground()
{
trace("AS3Playground() @"+getTimer());
initDemo();
}
private function maintainDisplayOrder():void
{
addChild(_mainsprite);
_mainsprite.addChild(_button);
}
private function initDemo():void
{
trace("initDemo() @"+getTimer());
_mainsprite = new MovieClip();
_mainsprite.graphics.clear();
_mainsprite.graphics.beginFill(BACK_COLOR);
_mainsprite.graphics.drawRect(0, 0, 500, 500);
_mainsprite.graphics.endFill();
_button = new MovieClip();
_button.graphics.clear();
_button.graphics.beginFill(OUT_COLOR);
_button.graphics.drawCircle(250, 250, 50);
_button.graphics.endFill();
maintainDisplayOrder();
stage.quality = StageQuality.LOW;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
_lastKnownStageQuality = stage.quality;
stage.addEventListener(MouseEvent.MOUSE_WHEEL, handleMouseWheel);
_button.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOver);
_button.addEventListener(MouseEvent.MOUSE_OUT, handleMouseOut);
addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
}
private function onEnterFrame(event:Event):void
{
if (_counter++ % 50 == 0)
{
trace("onEnterFrame(event) @"+getTimer());
trace("_button.willTrigger(MouseEvent.MOUSE_OVER): " + _button.willTrigger(MouseEvent.MOUSE_OVER));
trace("_button.willTrigger(MouseEvent.MOUSE_OUT): " + _button.willTrigger(MouseEvent.MOUSE_OVER));
trace("_button.hasEventListener(MouseEvent.MOUSE_OVER): " + _button.hasEventListener(MouseEvent.MOUSE_OVER));
trace("_button.hasEventListener(MouseEvent.MOUSE_OUT): " + _button.hasEventListener(MouseEvent.MOUSE_OUT));
trace("mouse: @("+mouseX+", "+mouseY+")");
var buttonStageRect:Rectangle = new Rectangle();
var buttonStageCoordinate:Point = _button.localToGlobal(new Point(0, 0));
buttonStageRect.x = buttonStageCoordinate.x;
buttonStageRect.y = buttonStageCoordinate.y;
trace("_button stage area: @("+buttonStageRect.x+", "+buttonStageRect.y+") "+_button.width+"x"+_button.height);
trace("hitTest? "+_button.hitTestPoint(mouseX, mouseY));
}
if (_lastKnownStageQuality != stage.quality)
{
trace("stage quality changed!");
maintainDisplayOrder();
_lastKnownStageQuality = stage.quality;
}
}
private function handleMouseOver(event:MouseEvent):void
{
trace("handleMouseOver(event) @"+getTimer());
drawButtonCircle(OVER_COLOR);
}
private function handleMouseOut(event:MouseEvent):void
{
trace("handleMouseOut(event) @"+getTimer());
drawButtonCircle(OUT_COLOR);
}
private function drawButtonCircle(color:uint):void
{
_button.graphics.clear();
_button.graphics.beginFill(color);
_button.graphics.drawCircle(250, 250, 50);
_button.graphics.endFill();
}
private function handleMouseWheel(event:MouseEvent):void
{
trace("handleMouseWheel(event) @"+getTimer());
var motion:Number = event.delta * 5;
_zoom += motion;
_mainsprite.z = _zoom;
if (_zoom < 0 && _qualitySetting != 0 )
{
_qualitySetting = 0;
trace("setting LOW");
stage.quality = StageQuality.LOW;
}
if (_zoom > 100 && _qualitySetting == 0 )
{
_qualitySetting = 1;
trace("setting HIGH");
stage.quality = StageQuality.HIGH;
}
maintainDisplayOrder();
}
}
}
答案 2 :(得分:1)
我相信这可能是你的问题。 Flash不支持MOUSE_WHEEL事件。
使用javascript代码和ExternalInterface有一种解决方法。 本质上,javascript拦截鼠标滚轮事件并将其传递给光标下的flash对象。
以下是解决此问题的源代码(包括评论: http://code.google.com/p/contentdisplay/source/browse/trunk/source/com/earthbrowser/ebutils/MacMouseWheelHandler.as?r=20
答案 3 :(得分:1)
在最初发生错误的团队进行了更多测试和调查后,问题自行解决了。我在我的问题中提到,所显示的代码只是该问题的简化演示。
原始产品是Flex 4.1应用程序并使用矢量图形。在地图上进行缩放或平移时,我们将stage.quality
切换为LOW,因为差异几乎不明显,但质量较低,整体速度明显加快。
这个bug给团队造成了很多麻烦,因为它碰巧弹出窗口中的一些按钮没有响应,这基本上破坏了游戏的一些核心功能。然而,这个问题显然与这些弹出窗口的一些淡入效应有关。团队取消了淡入淡出,现在一切正常...... o_O
“Flash Player,你没有像普通软件一样工作吗?”
我reported the issue to Adobe并且确认它是一个错误。我已经要求我们的其他团队详细报告该bug出现在附加到跟踪的bug上的情况,所以有些人会在下周获得有关该问题的更多信息。
谢谢大家的意见和建议。 :)