В AS3 может ли символ библиотеки расширять другой символ библиотеки, предполагая, что каждый из них связан с классом? - PullRequest
0 голосов
/ 10 декабря 2010

Например:

  1. Символ библиотеки "Карта" связан с классом "Карта", который расширяет "MovieClip".Символ библиотеки «Карта» содержит фоновое изображение карты.
  2. Символ библиотеки «Туз» связан с классом «Туз», который расширяет класс «Карта».Символ библиотеки "Ace" содержит TextField с большой буквой "A".

Итак, у нас есть Ace extends Card, которая расширяет MovieClip.Поэтому Ace расширяет MovieClip, но НЕ ПРЯМО расширяет MovieClip.

Когда я бросаю экземпляр Ace на сцену и компилирую клип, все, что появляется, это большая буква A. Однако я ожидал, что фоновое изображениеиз карты, которая будет включена, поскольку Ace расширяет карту, а символ карты содержит фон.

Похоже, Flash игнорирует содержимое символа, если только он не принадлежит экземпляру класса верхнего уровня, для которого создается экземпляр.Я думаю, что это LAME, что один символ не может расширить другой.IDE может легко нарисовать карту как нередактируемый фон, пока я редактирую Ace, который расширяет его, и он должен создавать экземпляр содержимого Card, а затем содержимое Ace при создании экземпляра Ace.Мысли? * * 1013

Ответы [ 4 ]

1 голос
/ 10 декабря 2010

Да, я пытался это сделать.Теоретически можно ожидать, что список отображения каждого расширенного класса будет складываться, но это не так - он работает так, как вы описали, когда вы видите только графику, связанную с самым последним классом.

Это недля вас, однако, - различные архитектурные варианты в вашем распоряжении.Например, вы можете создать класс CardBackground, который экспортируется из вашей библиотеки и имеет форму карточки и т. Д. Затем вы создаете класс Card, имеющий свойство background: CardBackground.Тогда ваш класс Ace может расширить Card и у него должен быть желаемый фон.

Технически вы должны отдавать предпочтение композиции, а не наследованию, но Flash действительно поощряет образ мышления наследования.Как только вы привыкнете выходить из этого, вы поймете, что можно создавать гораздо более мощные и надежные классы, используя композицию описанным способом.

Приветствия, и я надеюсь, что это поможет!

1 голос
/ 10 декабря 2010

Базовым классом для вашего card_mc (мувиклипа Card) может быть класс Card, но он не делает ваш класс Card синонимичным с card_mc.

Попробуйте сделать это вместо:

1) Создайте мувиклип, содержащий фоновое изображение карты, и назовите его cardSprite_mc.Дайте ему имя класса CardSprite и установите для его базового класса flash.display.Sprite.

2) Создайте фрагмент ролика, содержащий текстовое поле с буквой «A», и назовите его ace_mc.Дайте ему имя класса Ace и базовый класс com.cards.Ace.

3) Создайте класс с именем Card со следующим кодом:

package com.cards
{
    import flash.display.Sprite;

    public class Card extends Sprite
    {
        public function Card():void 
        {
            addChildAt(new CardSprite(), numChildren - 1);

        }// end function

    }// end class

}// end package

4) Создайте класс с именемAce со следующим кодом:

package com.cards
{
    import com.cards.Card;

    public class Ace extends Card
    {
        public function Ace():void 
        {

        }// end function

    }// end class

}// end package

Теперь, если вы добавите экземпляр Ace на сцену, вы также должны увидеть фоновое изображение карты.

Надеюсь, это помогло:)

0 голосов
/ 21 сентября 2012

Решение Taurayi является вдохновляющим, поскольку оно устанавливает отсутствующую явную связь между классом и символом, обеспечивая создание экземпляра содержимого символа, будь то класс верхнего уровня или просто базовый класс в цепочке наследования.Побочным эффектом этого подхода, однако, является то, что он добавляет дополнительный уровень содержания в содержимое Card, а именно контейнер CardSprite.

Мне удалось реализовать практическое универсальное решение, которое фактически сохраняет ожидаемое поведение стека всехунаследованные символы.Например, если вы отметите «numChildren» для экземпляра Symbol2 ниже, это будет в точности сумма символов Symbol1.numChildren и Symbol2.numChildren, так что это будет истинное объединение содержимого символа.

Когда ваш символнаходится в цепочке наследования, просто добавьте этот вызов «sureLinkage» в любое время после вызова метода super ().

package
{
    public class Symbol1 extends Sprite
    {
        public function Symbol1()
        {
            super();
            BugFixes.ensureLinkage( this, "Symbol1" );
        }
    }
}


package
{
    public class Symbol2 extends Symbol1
    {
        public function Symbol2()
        {
            super();
            BugFixes.ensureLinkage( this, "Symbol2" );
        }
    }
}

Примечание. Не забудьте убедиться, что ваш символ верхнего уровня также явно определяет класс с указанным выше шаблоном.

Когда Symbol2 и Symbol1 связаны с соответствующими символами вбиблиотека, их содержимое теперь будет складываться.Просто поместите экземпляр Symbol2 на сцену и протестируйте фильм.Вы увидите, что содержимое Symbol1 отображается под содержимым Symbol2.(Примечание: не отображается в конструкторе, поскольку это исправление во время выполнения).

РеализацияureLinkage выглядит следующим образом:

package
{
    import flash.utils.getQualifiedClassName;
    import flash.utils.getDefinitionByName;
    import flash.events.Event;

    public class BugFixes
    {

        public static var linkageMonitor:Object = new Object();
        private static var linkageMonitorAuthority:Array = new Array();

        public function BugFixes()
        {
        }

        public static function ensureLinkage( instance:*, className:String )
        {
            if (getQualifiedClassName( instance ) != className) //detect non-top-level construction
            {
                //prevent inevitable factorial-recursive construction
                var stack:Array = linkageMonitor[instance] as Array;
                if (stack == null)
                {
                    stack = new Array();
                    stack["numChildren"] = instance.numChildren;
                    linkageMonitor[instance] = stack;
                }

                var barredByAuthority:Boolean = false;
                if (linkageMonitorAuthority.length > 0)
                    barredByAuthority = (linkageMonitorAuthority[linkageMonitorAuthority.length - 1] as Array).indexOf( className ) > -1;
                if (stack.indexOf( className ) == -1 && !barredByAuthority)
                {
                    stack.push( className ); //remember construction
                    trace( "ensuring Linkage of inherited class " + className );

                    //perform top-level construction to trigger symbol linkage and child object instantiation
                    linkageMonitorAuthority.push( stack );
                    var temp:* = new (getDefinitionByName( className ) as Class)();
                    linkageMonitorAuthority.pop();

                    //Merge children
                    while (temp.numChildren > 0)
                        instance.addChild( temp.getChildAt( 0 ) );

                    //Merge properties
                    for (var prop:String in temp)
                        instance[prop] = temp[prop];
                }
                else
                {
                    trace( "skipping redundant construction of: " + className );
                }
            }
            else
            {
                var stack:Array = linkageMonitor[instance] as Array;
                if (stack != null)
                {
                    var nc:int = int(stack["numChildren"]);
                    trace("construction completing for " + getQualifiedClassName( instance ) );
                    for (var i:int = 0; i < nc; i++)
                        instance.setChildIndex( instance.getChildAt( 0 ), instance.numChildren - 1 );
                }
                delete linkageMonitor[instance]; //top-level constructor is completing, all relevant sub-objects have been constructed
            }
        }
    }
}

По сути, он определяет, собираются ли символынеобходимо создать вручную, увидев, соответствует ли полное имя класса экземпляра ожидаемому имени класса, переданному в вызов от самого класса.Поскольку он вызывается после «super», вызовы начинаются с самого глубокого класса и гарантируют, что дочерние элементы его библиотечного экземпляра создаются путем создания временного экземпляра верхнего уровня и утверждения его дочерних элементов как своих собственных.Самый первый вызов экземпляра также захватывает исходное число присутствующих дочерних элементов, поскольку клип верхнего уровня в стеке уже будет создавать экземпляры своих дочерних элементов до того, как какой-либо код конструктора будет выполнен вообще.Сохраняя это число, последний шаг может затем подтянуть эти начальные дочерние элементы к вершине, к которой они принадлежат.Класс гарантирует отсутствие ненужной рекурсии, используя стек «полномочий», чтобы основной стек всегда был виден дочерним конструкторам.

Одна проблема заключается в том, что статические штрихи не сохраняются, но это только потому, что AS3не предоставляет API для доступа к штрихам (т. е. как только вы рисуете линию в конструкторе или с graphics.lineTo, нет никакого способа программно получить доступ к этому штриху для нумерации или изменения, кроме как для очистки всех штрихов сразу).Так что это не ограничение этого подхода, а скорее API Flash.

Возможно, Adobe просто не смогла придумать эту реализацию: P

Обратите внимание, что если ваши символы выполняют какую-либо работу, связанную сВ экземпляре символа для другого кода может возникнуть проблема, поскольку этот класс требует владения дочерними элементами из временного экземпляра.Он также запрашивает значения ссылок на переменные из временного экземпляра, используя цикл for, но это лучшее, что он может сделать в общей реализации, такой как эта.

0 голосов
/ 10 декабря 2010

Вы не можете сделать это программным способом.

Вместо этого вы должны использовать среду Flash Authoring.Расширьте символы, создав символ, включающий в себя базовый символ.

И, да, я согласен, это довольно LAME.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...