这似乎有效:
public class MyClass extends Sprite
{
public function MyClass()
{
super();
transform = new MyTransform(this,super.transform);
// i'm drawing a rect just to see the results of scaling
graphics.beginFill(0xff0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
}
override public function get transform():Transform {
var tmp:Transform;
if(super.transform is MyTransform) {
tmp = super.transform;
} else {
tmp = new MyTransform(this,super.transform);
}
return tmp;
}
override public function set transform(value:Transform):void {
var tmp:Transform;
if(value is MyTransform) {
tmp = value;
} else {
tmp = new MyTransform(this,value);
}
super.transform = tmp;
}
}
public class MyTransform extends Transform
{
public function MyTransform(dp:DisplayObject,transf:Transform = null)
{
super(dp);
if(transf) {
for(var prop:String in transf) {
this[prop] = transf[prop];
}
}
}
override public function set matrix(value:Matrix):void
{
super.matrix = value;
// customcode();
}
}
用途:
var sp:MyClass = new MyClass();
var mat:Matrix = sp.transform.matrix;
mat.scale(3,3);
trace(sp.transform);
sp.transform.matrix = mat;
addChild(sp);
问题在于,即使您创建并指定您的转换为 MyTransform 类型,getter 也会返回一个常规的转换对象。变换对象在 Flash 中的工作方式有些奇怪(例如,SoundTransform 也是如此)。有某种缓存机制以相当蹩脚的方式实现,如果您想提交更改,它会强制您重新分配实例。
我的意思是这种模式:
var t:Transform = mc.transform;
// do something with t
mc.transform = t;
所以我认为这与您的代码无法按预期工作的原因有关。
为了解决这个问题,如果传递的 trasnform 对象是 MyTransform 类型,我会同时检查 setter 和 getter。如果是,我按原样使用它。如果不是,我创建一个 MyTransform 对象并从原始 Transform 中复制所有属性。如果 Transform 类有一个 clone 方法就好了,但它没有,所以我实现了这个简单的复制机制。不确定这是否不会与 Transform 中的某些内部状态混淆(可能是这种情况)。除了应用规模之外,我还没有测试过一次。您可能想要这样做,因为我没有考虑其他副作用。此外,这可能不是最高效的。但我想不出另一种方法来调用你的矩阵设置器。
编辑
使用静态/全局调度程序不是一个好主意,除非您确实需要它是全局的。实现IEventDispatcher,因为你不能直接扩展EventDispatcher,是你想要的。
为此所需的代码有点冗长,但无论如何它是不费吹灰之力的。您所需要的只是拥有一个事件调度程序的内部实例并实现接口的方法。在上述方法中,您将参数转发给实际的调度程序。
public class MyTransform extends Transform implements IEventDispatcher
{
private var _dispatcher:EventDispatcher;
public function MyTransform(dp:DisplayObject,transf:Transform = null)
{
super(dp);
_dispatcher = new EventDispatcher(this);
if(transf) {
for(var prop:String in transf) {
this[prop] = transf[prop];
}
}
}
override public function set matrix(value:Matrix):void
{
super.matrix = value;
// customcode();
}
public function dispatchEvent(event:Event):Boolean {
return _dispatcher.dispatchEvent(event);
}
public function addEventListener(type:String,listener:Function,useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void {
_dispatcher.addEventListener(type,listener,useCapture,priority,useWeakReference);
}
public function removeEventListener(type:String,listener:Function,useCapture:Boolean = false):void {
_dispatcher.removeEventListener(type,listener,useCapture);
}
public function hasEventListener(type:String):Boolean {
return _dispatcher.hasEventListener(type);
}
public function willTrigger(type:String):Boolean {
return _dispatcher.willTrigger(type);
}
}