Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как проводить замену спрайтов? (http://www.flasher.ru/forum/showthread.php?t=208110)

Лохматый 04.06.2014 08:21

Как проводить замену спрайтов?
 
Всем доброго времени суток. Я недавно приступил к изучению as3, начал с книги К.Мука. К своему сожалению обнаружил, что данная книга написана сложноватым для меня языком и часть материала я так и не понял. В итоге решил просто начать делать что-либо на as3, и сейчас столкнулся с проблемой которую не знаю как решить: как провести замену одного спрайта на другой?

На данный момент мне нужно создать объект, который будет выполнять функцию кнопки. У кнопки должно быть только 2 отображаемых состояния: вкл\выкл. Нажал на кнопку - отображается изображение, соответствующее "вкл", ещё раз на неё нажал - отображается изображение, соответствующее состоянию "выкл". Решил для этого дела создать собственный класс. Но не могу понять, как реализовать замену одного изображения на другое. Вот код, который есть на данный момент и который исправно работает:

Код AS3:

package
{
        import flash.display.Sprite;
        import flash.display.DisplayObject;
        import flash.events.MouseEvent;
 
        public class toggleButton extends Sprite
        {
 
                public function toggleButton(up,down) //  получаем из массива изображений спрайты
                {
 
                        this.addChild(up)// создаём спрайт, соответствующий положению кнопки "выкл"
 
                        addEventListener(MouseEvent.CLICK, swap) 
                }
 
                private function swap(event:MouseEvent):void
                {
                        trace("Клик")// здесь должен быть код переключающий состояние кнопки
                }
 
        }
 
}

Как мне кажется, по этому принципу можно создать программную анимацию. Т.е. создать класс, в котором при выполнении условий события, будет запускаться цикл замены одного спрайта следующим с задержкой по времени, устанавливаемой таймером. Но как проводить эту замену - ума не приложу. И будут ли объекты, созданные на базе такого класса эффективны в плане ресурсоёмкости?

Очень бы хотелось понять, как реализуется спрайтовая программная анимация в as3. Если кто может объяснить - буду премного благодарен. И если возможно, поделитесь примером кода кнопки.

dimarik 04.06.2014 10:54

Набросал заготовку. И тут меня понесло. В оригинале ToggleButton наследуется от Button, у которого четыре состояния: up, down, over и disabled. Три первых состояния соответствуют поведению курсора или "пальца" для соответствующей среды исполнения — десктопе или мобилке. Четвертое зависит от флага компонента enabled, показывающий на то, что может ли компонент сейчас быть интерактивным. ToggleButton привносит еще четыре состояния с добавлением "andSelected": "upAndSelected", "downAndSelected", "overAndSelected", "disabledAndSelected".
ToggleButton диспатчит два вида собственных событий: Event.SELECTED, если переключение произошло из-за взаимодействия с пользователем, точнее, из-за события MouseEvent.CLICK с проверкой результата диспатча. Если диспатч был неудачным, т.е. какой-то из слушателей сделал event.preventDefault(), то переключение состояния не происходит. Т.о. мы привносим гибкость, и управление состоянием передается во внешний мир. Второе событие Event.VALUE_COMMIT посылается всегда при успешном переключении состояния selected / not selected. Оно необходимо в случае программного переключения, без участия пользователя. Итого, в случае с инициативой пользователя посылается два события: Event.SELECTED и Event.VALUE_COMMIT. В случае внешнего программного переключения только одно Event.VALUE_COMMIT.
По сути, визуальная составляющая состояния любого компонента описывается термином "скин". Button и ToggleButton относятся к категории таких компонентов. Компонент содержит логику изменения состояния, а система скинирования переключает соответствующий этому состоянию скин. Само переключение может быть не мгновенным, а иметь т.н. transition, переход из предыдущего состояния в новое. Например, какие-нибудь эффекты анимации, поддерживаемые Tween-движками.
Но это все решается на уровне суперкласса, визуализирующего состояние и лежащего в иерархии наследования выше Button. Очень удобно для описания возможных состояний компонента использовать метаданные.

Код AS3:

package components
{
 
/**
 *
 * @author                                        Dimarik
 * @version                                        1.0
 * @langversion                                3.0
 * @playerversion                        Flash 10
 * @playerversion                        AIR 1.5
 *
 * @keyword                                        button, togglebutton
 */

public class ToggleButton extends Sprite
{
 
        //-------------------------------------------------------------------------
        //
        //  Constructor
        //
        //-------------------------------------------------------------------------
 
        /**
        * Constructor
        */

        public function ToggleButton() {
                super();
                super.addEventListener(MouseEvent.CLICK, this.handler_click);
                // Скины не должны быть источником событий. Только сам компонент.
                super.mouseChildren = false;
        }
 
        //-------------------------------------------------------------------------
        //
        //  Properties
        //
        //-------------------------------------------------------------------------
 
        //---------------------------------
        //  selected
        //---------------------------------
 
        /**
        *  @private
        *  Storage for the selected property
        */

        private var _selected:                Boolean;
 
        /**
        *  Contains <code>true</code> if the button is in the down state,
        *  and <code>false</code> if it is in the up state.
        *
        *
        *  @langversion 3.0
        *  @playerversion Flash 10
        *  @playerversion AIR 1.5
        */

        public function get selected():Boolean {
                return this._selected;
        }
 
        /**
        *  @private
        */

        public function set selected(value:Boolean):void {
                if (this._selected === value)
                        return;
 
                this._selected = value;
                this.validateState();
        }
 
        //---------------------------------
        //  upSkin
        //---------------------------------
        /**
        *  @private
        *  upSkin reference
        */

        private var _upSkin:        DisplayObject;
 
        public function set upSkin(value:DisplayObject):void {
                if (this._upSkin === value)
                        return;
                if (this._upSkin && this._upSkin.parent)
                        super.removeChild(this._upSkin);
                this._upSkun = value;
                this.validateState();
        }
 
        public function get upSkin():DisplayObject {
                return this._upSkin;
        }
 
        //---------------------------------
        //  upAndSelectedSkin
        //---------------------------------
        /**
        *  @private
        *  upAndSelectedSkin reference
        */

        private var _upAndSelectedSkin:        DisplayObject;
 
        public function set upAndSelectedSkin(value:DisplayObject):void {
                if (this._upAndSelectedSkin === value)
                        return;
                if (this._upAndSelectedSkin && this._upAndSelectedSkin.parent)
                        super.removeChild(this._upAndSelectedSkin);
                this._upSkun = value;
                this.validateState();
        }
 
        public function get upAndSelectedSkin():DisplayObject {
                return this._upSkin;
        }
 
        //-------------------------------------------------------------------------
        //
        //  Private methods
        //
        //-------------------------------------------------------------------------
 
        private function validateState():void {
                if (this._selected) {
                        if (this._upSkin && this._upSkin.parent) {
                                super.removeChild(this._upSkin);
                        }
                        if (this._upAndSelectedSkin)
                                super.addChild(this._upAndSelectedSkin);
                } else {
                        if (this._upAndSelectedSkin && this._upAndSelectedSkin.parent) {
                                super.removeChild(this._upAndSelectedSkin);
                        }
                        if (this._upSkin)
                                super.addChild(this._upSkin);
                }
        }
 
        //-------------------------------------------------------------------------
        //
        //  Event handlers
        //
        //-------------------------------------------------------------------------
 
        protected function handler_click(event:MouseEvent):void {
                this.selected = !this.selected;
        }
 
 
}
}


Bletraut 04.06.2014 12:39

Чисто на глаз.
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.display.DisplayObject;
        import flash.events.MouseEvent;
 
        public class toggleButton extends Sprite
        {
                private upImg:Sprite;
                private downImg:Sprite;
 
                public function toggleButton(up:Sprite, down:Sprite) //  получаем из массива изображений спрайты
                {
                        upImg = up;
                        downImg = down;
                        downImg.visible = false;
 
                        this.addChild(downImg)
                        this.addChild(upImg)// создаём спрайт, соответствующий положению кнопки "выкл"
 
                        addEventListener(MouseEvent.CLICK, swap) 
                }
 
                private function swap(event:MouseEvent):void
                {
                        trace("Клик")// здесь должен быть код переключающий состояние кнопки
 
                        downImg.visible = !downImg.visible;
                        upImg.visible = !downImg.visible;
                }
 
        }
 
}

dimarik, а куда в коде импорты делись?

Лохматый 04.06.2014 20:40

Большое спасибо за ответы! Очень пригодились оба варианта для понимания as3. Пока не представляю, как должен выглядеть адекватный супер-класс для кода dimarik, но попробую его реализовать. Очень интересно!

Bletraut, если я не ошибаюсь, ToggleButton здесь унаследует импорты от супер-класса, например, от TargetButtonSkin, который в данном примере опущен.

caseyryan 04.06.2014 22:37

Цитата:

Bletraut, если я не ошибаюсь, ToggleButton здесь унаследует импорты от супер-класса, например, от TargetButtonSkin, который в данном примере опущен.
импорты не наследуются


Часовой пояс GMT +4, время: 21:52.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.