Форум 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=148963)

DZHETIGAPA 16.01.2011 00:48

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

Поэтому, уважаемые форумчане, скиньте пожалуйста полный код какого-нить своего простого пользовательского события, чтобы я его разжувал и наконец таки все понял. А то по примерам, которые у меня есть, мне мало что понятно. Или же объясните простым языком, что да как.

Заранее благодарен.

Dukobpa3 16.01.2011 01:00

А может для начала вы скажете что именно не получается, и свой код скинете, а мы уж коллективным разумом ошибки поищем?;)

Здается мне, так эффективнее получится)

JackFromChaos 16.01.2011 01:03

Само событие, расширяющее стандартный event 2 параметрами - x и y(по типу как mouse event);

Код AS3:

package
{
        import flash.events.Event;
        /**
        * ...
        * @author Denis `Jack` Vinogradsky
        */

        public class EventChangePos extends Event
        {
                public static const CHANGE_POS : String = "changePos";
                private var _x:Number;
                private var _y:Number;
                public function EventChangePos(type:String,x:Number,y:Number)
                {
                        super(type);
                        _x = x;
                        _y = y;
                }
 
                public function get x():Number
                {
                        return _x;
                }
 
                public function set x(value:Number):void
                {
                        _x = value;
                }
 
                public function get y():Number
                {
                        return _y;
                }
 
                public function set y(value:Number):void
                {
                        _y = value;
                }
 
        }
 
}

Класс, который генерит событие по изменению свойств X и Y:
Код AS3:

package
{
        import flash.events.EventDispatcher;
        /**
        * ...
        * @author Denis `Jack` Vinogradsky
        */

        public class TestObject extends EventDispatcher
        {
                private var _x:Number;
                private var _y:Number;
                public function TestObject()
                {
 
                }
 
                public function get x():Number
                {
                        return _x;
                }
 
                public function set x(value:Number):void
                {
                        _x = value;
                        dispatchEvent(new EventChangePos(EventChangePos.CHANGE_POS, _x, _y);
                }
 
                public function get y():Number
                {
                        return _y;
                }
 
                public function set y(value:Number):void
                {
                        _y = value;
                        dispatchEvent(new EventChangePos(EventChangePos.CHANGE_POS, _x, _y);
                }
 
        }
 
}

Пример использования:
Код AS3:

                        var test:TestObject = new TestObject();
                        test.addEventListener(EventChangePos.CHANGE_POS, onChangePos);


mayakwd 16.01.2011 06:38

эм... а зачем у вас в событии сеттеры?

JackFromChaos 16.01.2011 07:00

Цитата:

Сообщение от mayakwd (Сообщение 965001)
эм... а зачем у вас в событии сеттеры?

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

Добавлено через 3 минуты
Там в примере еще атрибутов по хорошему не хватает, вроде такого:
Код AS3:

[Event(name="activate", type="flash.events.Event")]

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

mayakwd 16.01.2011 07:14

Цитата:

Сообщение от JackFromChaos (Сообщение 965002)
Ну, как бы правила хорошего тона, в ООП...

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

Использовать сеттеры в событиях это мягко скажем моветон.

Ваше же объяснение совсем не по теме вышло.

cleptoman 16.01.2011 11:13

в чем моветон то?
ну сеттер и сеттер... хочешь 1 раз при создании передать в него что-то - передай всего 1 раз. благо if никто не отменял)

Добавлено через 8 минут
п.с. я, просто, вообще не сторонник "много параметров в конструктор". в отношении Ивентов - больше одного кастомного параметра для ивента - моветон (ИМХО). в данном случае х,у легко заменяется одним поинтом.

goodguy 16.01.2011 11:39

Ну вот событие, которое у меня посылается при взлете вертолета в игре:
Код AS3:

package  
{
        import flash.events.Event;
 
        public class UpEvent extends Event
        {
                public static const INAIR:String = "inair";
 
                public function UpEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
                {
                        super(type, bubbles, cancelable);
 
                }
 
                public override function clone():Event
                {
                        return new UpEvent(type, bubbles, cancelable);
                }
 
                public override function toString():String
                {
                        return formatToString("UpEvent", "type", "bubbles", "cancelable", "eventPhase");
                }
 
        }
 
}


JackFromChaos 16.01.2011 13:48

Цитата:

Сообщение от mayakwd (Сообщение 965004)
Вы немножко заблуждаетесь. Правило хорошего тона — не использовать сеттеры в эвентах, так как события выполняют функцию оповещения (тавтология мой конек), и отдают данные.

Использовать сеттеры в событиях это мягко скажем моветон.

Ваше же объяснение совсем не по теме вышло.

До меня дошло, о чем вы... :) Вы спросили, для чего тут "СЕТТЕРЫ". я для себя прочел/подумал, для чего тут свойства :) Да, вы правы, данном случае сеттер, в общем то не нужен.

Но это вовсе не значит, что в событиях не нужны сеттеры, просто они не нужны конкретно здесь...
К примеру взгляните на тот же MouseEvent, и вы найдете там сеттеры, и не случайно;)

Впрочем когда я писал код примера, я как то об этом не задумывался, нужны там сеттеры или нет...:) На вопрос, как сделать пользовательские события, такие тонкости, как наличие сеттеров... врятли имеет какое то значение....

Wolsh 16.01.2011 15:10

goodguyабсолютно не понял, в чем "кастомность" Вашего события, в каком месте оно "расширяет" обычное Событие и, в частности, чем отличается метод clone в Вашем событии от исходного, что его пришлось оверрайдить. Не логичнее было бы создать класс ВертолётИвэнт, а в нем уже разные ТИПЫ этого события - ап, даун, дестрой и т.п.? Даже в этом ключе в нем нет особой необходимости - можно создать класс-список констант типа HELICOPTER_UP, HELICOPTER_DOWN, HELICOPTER_DESTROYED и диспатчить обычные экземпляры Event с нужным Типом из этого списка. Нет смысла множить сущности.
Кастомные классы событий нужны, когда Вы хотите передавать в событиях дополнительные параметры.
По поводу количества параметров - можно иногда отказаться от передачи типа в конструктор кастомного события, если тип в реальности один. Например
Код AS3:

package  
{
        import flash.events.Event;
 
/* * * * * * * * * *
*                  *
*  @author wolsh  *
*                  *
\* * * * * * * * * */

        public class SizeEvent extends Event
        {
                public static const CHANGED:String = "sizeChanged";
                public var width:Number;
                public var height:Number;
 
                public function SizeEvent(width:Number, height:Number, bubbles:Boolean=false, cancelable:Boolean=false)
                {
                        super(CHANGED, bubbles, cancelable);
                        this.width = width;
                        this.height = height;
                }
 
                public override function clone():Event
                {
                        return new SizeEvent(width, height, bubbles, cancelable);
                }
 
                public override function toString():String
                {
                        return formatToString("SizeEvent", CHANGED, "width", "height", "bubbles", "cancelable", "eventPhase");
                }
        }
}

Код AS3:

addEventListener(SizeEvent.CHANGED, onSizeEvent);
dispatchEvent(new SizeEvent(stage.stageWidth, stage.stageHeight));
private function onSizeEvent(event:SizeEvent):void
{
        trace(event.type);
        trace(event.width, event.height);
}

Но есть неприятная непрозрачность конечно с типом, указываемым в листенере и не указываемым при создании события)))

DZHETIGAPA 16.01.2011 15:21

Благодарю всех за ответы и комменты. Начало доходить. Будут еще вопросы - буду сюда обращаться.

У меня есть вопрос:где можно найти открытый код всех классов AS3?

Wolsh 16.01.2011 15:37

DZHETIGAPA, одна тема - один вопрос. Относитесь к Теме не как к посиделкам за чаем, а как к разделу в Справочнике. Удачи.

DZHETIGAPA 19.01.2011 23:07

Вот в конкретном примере возникли проблемы с событием.

Есть два класса. В первом классе Menu3D располагается скроллер, менюшки, контент. А второй класс ScrollerClass и есть СКРОЛЛЕР. Мне нужно, чтобы при нажатии на контент(в классе Menu3D) в классе ScrollClass вызвалось это событие. Вот мои действия.
Код AS3:

//класс Menu3D
 
public static const SCROLL:String = "scroll";
 
//другой код
 
private function clickContent(e:MouseEvent):void
                {
                        timeline.reverse();
                        dispatchEvent(new Event(Menu3D.SCROLL));
 
                }

Код AS3:

//Класс ScrollerClass
private function onAddedToStage(e:Event):void
                {
                        //какой-то код
 
                    var menu:Menu3D = new Menu3D();
                    menu.addEventListener(Menu3D.SCROLL, onScroll);
 
                }               
 
                private function onScroll(e:Event):void
                {
                        trace("STAS")
                }

Почему-то событие не работает. Где-то моя ошибка. Укажите пожалуйста, где тут ошибка. Просто со своими событиями опыт у меня малый.

Dukobpa3 19.01.2011 23:35

clickContent - сюда трейс вставь и погляди, а то судя по коду должно работать.

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

DZHETIGAPA 19.01.2011 23:43

Событие клика работает как надо. Еще один нюанс, про который не сказал. ScrollClass изначально помещен в класс-библиотеку Lib. Там ему задается статическая публичная переменная. Через эту переменную я и переношу скролл в класс Menu3D.
Код AS3:

//класс Lib
public static function scrollBar(n:int):void
                {
 
                        scroll = new FullScreenScrollBar(massivCon[n], massivContent[n], 0x000fff, 0xff4400, 0xffffff, 15, 15, 4, true);
 
                }
 
                public static function destroyScroll():void
                {
                        scroll = null;
                }

Код AS3:

//Где-то в классе Menu3D
Lib.scrollBar(n);

Может из-за того, что я использую статическую переменную и не происходит вызова события?

Добавлено через 6 минут
Заменил статические переменные просто публичными - ничего не изменилось. Событие клика работает, но мое событие нет.

Psycho Tiger 20.01.2011 00:34

А мне вот странно, почему не придрались к этой строке:
Код AS3:

public function EventChangePos(type:String,x:Number,y:Number)

Ни бабблов, ни канселябл.

@Wolsh:
Цитата:

и, в частности, чем отличается метод clone в Вашем событии от исходного, что его пришлось оверрайдить.
Стандартный шаблон из FD.

Цитата:

Не логичнее было бы создать класс ВертолётИвэнт, а в нем уже разные ТИПЫ этого события - ап, даун, дестрой и т.п.? Даже в этом ключе в нем нет особой необходимости - можно создать класс-список констант типа HELICOPTER_UP, HELICOPTER_DOWN, HELICOPTER_DESTROYED и диспатчить обычные экземпляры Event с нужным Типом из этого списка. Нет смысла множить сущности.
Я скажу что не логичнее. Вертолёт он парень такой... сегодня ничего не шлёт, а завтра прицепляет к себе какой-нибудь параметр. И когда в коде получается такая каша, что половина обработчиков с Event, половина с HelicopterEvent — хочется плюнуть и переписать всё под единый стиль. Под HelicopterEvent.
Поэтому я ратую "за" при создании подобных эвентов. Даже те, которые в данный момент ничего не переносят.


Но конкретно в этом случае я вообще ратую за использование Event со стандартными константами Event. Абстракция, друзья мои. Типа
Код AS3:

super.dispatchEvent(new Event(Event.COMPLETE));


Wolsh 20.01.2011 03:50

Цитата:

Не логичнее было бы создать класс ВертолётИвэнт...
Цитата:

Я скажу что не логичнее... ...хочется плюнуть и переписать всё под единый стиль. Под HelicopterEvent.
Тигр, иногда ты просто ставишь меня в тупик...
Цитата:

Поэтому я ратую "за" при создании подобных эвентов.
Ага. MouseClickEvent, MouseRollOverEvent, MouseRollOutEvent, MouseMouseMoveEvent, MouseMouseDownEvent... не, я не участвую в этом празднике.

Добавлено через 10 часов 42 минуты
Сам язык подсказывает, что "логично" а что нет.
MouseEventRollOut.ROLL_OUT выглядит совершенно нелогично.
Любое событие с единственным типом содержит в себе какое-то несовершенство. Хотя конечно возможны исключения.
Язык подсказывает - есть объект-источник событий. Есть событие, источником которого является объект. Иногда объект генерит разные типы событий. Но Лётчик генерит СобытиеЛётчика, а не СобытиеОфициантки. Любое событие "от лётчика" - это СобытиеЛётчика. Оно может быть разных типов - СобытиеЛётчика.Я_УСНУЛ, СобытиеЛётчика.Я_НАЖРАЛСЯ. Но это событие - Лётчика, вы можете передавать в нем показания приборов или температуру тела на момент события. Официантка тоже может уснуть, но в ее событии, подозреваю, будут совсем другие параметры.
Подход, о котором вы говорите - создавать КЛАСС на каждый ТИП события, т.е. СобытиеЛетчикНажрался.ЛЁТЧИК_НАЖРАЛСЯ, СобытиеЛётчикУснул.ЛЁТЧИК_УСНУЛ.
По-моему, эти "синтаксисы" говорят сами за себя.
Нет такого объекта "летчик нажрался", который является источником события "ЛЁТЧИК_НАЖРАЛСЯ".
Это УЖЕ и есть событие. Событие, источником которого является Летчик.


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

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