检测精灵位置的变化

时间:2009-10-22 13:19:59

标签: flash actionscript-3

检测精灵相对于舞台的位置(x,y)何时发生变化的好策略是什么?换句话说,如何检测精灵全局位置的变化?

当精灵是其他DisplayObjectContainer对象的子节点时,这变得很困难。

7 个答案:

答案 0 :(得分:1)

UIComponent还是Sprite?如果它只是一个Sprite,我不知道怎么做,但如果它是UIComponent它可行,但可能会变得混乱。

您必须收听组件的move事件。当您获得该事件时,您可以使用localToGlobal()方法获取其位置并将其转换为全局坐标。

不幸的是,我认为您还必须为其所有父组件监听move事件,因为如果父组件移动,我认为组件不会引发move事件

可能有一种更简洁的方法可以做到这一点,但如果没有,这应该有效。

答案 1 :(得分:1)

您可以创建Sprite的子类并覆盖public function set x(value:Number):voidpublic function set y(value:Number):void

简单的例子:

public class Exemple extends Sprite{

    override public function set x(value:Number):void{
         super.x=value;
         dispatchEvent(new Event("move"));
    }
    override public function set y(value:Number):void{
         super.y=value;
         dispatchEvent(new Event("move"));
    }

}

另外,请查看Event.RENDER事件......

答案 2 :(得分:1)

如果你真的想要它,并且你想要它准确,那就制作一个onEnterFrame并在其中嵌套这样的东西:

var vals:Object = new Object;
function checkPositionChanged(obj:DisplayObject):Boolean
{
var bool:Boolean = false;

var pt:Point = new Point(obj.x,obj.y);
pt = pt.localToGlobal(obj);
if( vals.x != pt.x || vals.y != pt.y ){
   bool = true;
}
vals.x = pt.x;
vals.y = pt.y;
return bool;
}

答案 3 :(得分:1)

我能想到的唯一方法是在EnterFrame事件上调用一个函数,并检查针对存储属性测试的lacalToGloabal坐标。问题是,如果你有很多精灵,这可能会变得相当耗费资源。您可以根据外部条件以某种方式缓解问题,启用和禁用事件处理程序。否则,我会考虑反过来讨论这个问题,并专注于可能移动精灵的情况,即触发因素,而不是影响,如果可能的话。

答案 4 :(得分:1)

遇到同样的问题。

我编写了一个监听所有祖先移动事件的管理器,并在添加到/删除阶段时更新侦听器。它使用相关组件的阶段x / y坐标调度GlobalMoveEvent。

它目前仅适用于UIComponents,但设计为可以扩展到Sprite等。

如果您有兴趣,请告诉我。

答案 5 :(得分:0)

另一个解决方案是使用Timer创建一个“线程”,每隔100毫秒使用localToGlobal()来检查位置。在移动发生和你得到事件之间会有延迟,但是这样你就不必查看整个显示列表来判断精灵或其任何父母是否发生了变化。你只需要检查精灵的全局位置,如果它被改变了你就会调用一些东西。

你甚至可以创建一个可以检查多个精灵的辅助类。然后你只需用它来注册sprite,每次运行它都会检查所有它们并为它检测到的每个sprite引发一个move事件。可能不会太难创建它。

同样,这不是完美的,因为你不会在搬家后立即得到事件,但如果你不需要马上知道它可能就足够了。

答案 6 :(得分:0)

您可以根据对OXMO456建议的修改来完成此操作。由于您担心基于它在舞台中的位置的通知,而不是它的父级,它可以简单地缓存和比较“全局”坐标,并在发生变化时触发。

了解有用的方法:

localToGlobal

globalToLocal

public class Example extends Sprite{
    private var stagePoint:Point = new Point(0,0);
    override public function set x(value:Number):void{
        super.x=value;
        if(stage != null){
            var globalPoint:Point = this.parent.localToGlobal(new Point(x,y));
            if(globalPoint.x != stagePoint.x){
                stagePoint = globalPoint;
                dispatchEvent(new Event("move"));
            }
        }
    }
    override public function set y(value:Number):void{
         super.y=value;
         if(stage != null){
            var globalPoint:Point = this.parent.localToGlobal(new Point(x,y));
            if(globalPoint.y != stagePoint.y){
                stagePoint = globalPoint;
                dispatchEvent(new Event("move"));
            }
        }
    }

}
编辑:哦等等,我想我错误地解释了你在问什么,呃!我会留下它,以防它以其他方式有用。

您是否可以通过此方式提供有关您尝试解决的问题的更多详细信息?这可能有助于我们找到一个能够在没有突破性开销的情况下工作的解决方案(比如大量已注册的事件监听器或其他类似的)

相关问题