Это похоже на работу:
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);
Проблема заключается в том, что, даже если вы создаете и назначаете tranform быть типа 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);
}
}
Да, это похоже на работу с несколькими преобразованиями! Только одно, я думал об увольнении события, как только это произойдет (так что я могу запустить функцию в своем основном классе), но класс Transform не имеет EventDispatcher. Есть идеи? – Obto
Ничего, наконец, понял. Для всех, кого интересует метод, используемый в следующей ссылке, в основном, что я сделал. http://www.gskinner.com/blog/archives/2007/07/building_a_stat_1.html – Obto
Рад, что это сработало. Я не думаю, что использование глобального/статического диспетчера - хорошая идея.Вам лучше реализовать IEventDispatcher и сделать ваши объекты MyTransform доступными для отправки событий. Проверьте мое редактирование. –