Кажется, что это работает:
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, метод получения возвращаетобычный объект Transform.Есть что-то странное в том, как объекты преобразования работают во Flash (например, это верно и для SoundTransform).Существует некоторый механизм кэширования, реализованный довольно неэффективно, который заставляет вас переназначить экземпляр, если вы хотите зафиксировать свои изменения.
Я имею в виду этот шаблон:
var t:Transform = mc.transform;
// do something with t
mc.transform = t;
Так что я думаю, это связано с тем, почему ваш код не работает должным образом.
Чтобы обойти это, я 'Проверка как в установщике, так и в получателе, если переданный объект trasnform имеет тип MyTransform.Если это так, я использую это как есть.Если это не так, я создаю объект 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);
}
}