Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Action script 2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=49)
-   -   ASBroadcaster. Генрация классом своих событий. (http://www.flasher.ru/forum/showthread.php?t=63974)

Manowar1 20.10.2004 12:34

ASBroadcaster. Генрация классом своих событий.
 
Не могу понять некоторые вещи связанные с объектом ASBroadcaster. Во первых, почему когда делаешь
trace(ASBroadcaster) выводится undefined? Ну каким бы скрытым и не документированным этот объект не был, но он же должен себя хоть как - то проявлять.
И второй вопрос, у меня есть мувиклип и связаный с ним с помощью Linkage класс. Мне нужно, чтобы этот класс генерил события, как это сделать? Пробывал в конструкторе писать
ASBroadcaster.initialize(this); но это понятно не катит по скольку объекта ASBroadcaster он просто не видит, передавал в класс этот объект как параметр, но не понятно тогда, что должно вызывать broadcastMessage, если this.broadcastMessage, то опять же будет ругаться, чтот такого метода нету, короче бред какой-то. Кстати пробывал трейсить передоваемый объект ASBroadcaster - выдаётся undefined, ну блин - это хитрая особенность или этот бродкастер нужно как то хитро подключать.
Ах да, у меня Flash MX 2004, может в нём они вообще убрали этот бродкастер?

silin 20.10.2004 19:29

trace(AsBroadcaster), ну и далее в том же духе..

Manowar1 21.10.2004 11:07

Круто, надож было так купиться на ASBroadcaster. Блин а почему, на flash-rapper и в уроке здесь на сайте пишется именно ASBroadcaster?
Вообщем спасибо.

Proman 22.10.2004 18:09

Используй класс EventDispatcher
допустим твой класс:
Код:

import mx.events.EventDispatcher;
class Babble {
       
        function Babble() {
                mx.events.EventDispatcher.initialize(this);
               
        }
        function say(phrase:String) {
                trace(phrase);
                var eventObject:Object = {target:this, type:'said'};
                eventObject.phrase = phrase;
                dispatchEvent(eventObject);
        }
        function dispatchEvent() {
        }
        function addEventListener() {
        }
        function removeEventListener() {
        }
       
}

в кадре пишеш:
Код:

var chat:Babble = new Babble();
var listener:Object = new Object;
listener.said = function(event) {
        trace("Фраза сказана!");
        trace("Свойство type: "+ event.type);
        trace("Свойство target: "+ event.target);
        trace("Свойство phrase: "+ event.phrase);
}
chat.addEventListener("said",listener);


chat.say("Hello World!");

мы создали свое собственное событие
Ты это имел ввиду?

Manowar1 25.10.2004 11:13

Цитата:

Оригинал написал(а) Proman
Используй класс EventDispatcher
допустим твой класс:
Код:

import mx.events.EventDispatcher;
class Babble {
       
        function Babble() {
                mx.events.EventDispatcher.initialize(this);
               
        }
        function say(phrase:String) {
                trace(phrase);
                var eventObject:Object = {target:this, type:'said'};
                eventObject.phrase = phrase;
                dispatchEvent(eventObject);
        }
        function dispatchEvent() {
        }
        function addEventListener() {
        }
        function removeEventListener() {
        }
       
}

в кадре пишеш:
Код:

var chat:Babble = new Babble();
var listener:Object = new Object;
listener.said = function(event) {
        trace("Фраза сказана!");
        trace("Свойство type: "+ event.type);
        trace("Свойство target: "+ event.target);
        trace("Свойство phrase: "+ event.phrase);
}
chat.addEventListener("said",listener);


chat.say("Hello World!");

мы создали свое собственное событие
Ты это имел ввиду?

Ну вообщем чувствую, что то, но вот до конца понять не получается :). Если не сложно может объяснишь?
mx.events.EventDispatcher.initialize(this); это я так понимаю объявляется текущий класс генератором событий.
dispatchEvent(eventObject); - это генерация события? или тут какой то другой принцип изпользуется?
Не подскажешь, где можно прочитать про этот класс?

Proman 25.10.2004 13:59

EventDispatcher.initialize(this); -- методы класса EventDispatcher копируються в твой класс.
var dispatchEvent:Function;
var addEventListener:Function;
var removeEventListener:Function;

собственно методы которые копируються
dispatchEvent -- посылает обьект события всем зарегистрированным с твоим классом listener-ам.
Где почитать не знаю, в хэлпе есть и собственно сам \Flash MX 2004\en\First Run\Classes\mx\events\EventDispatcher.as я его читал :)

Manowar1 25.10.2004 18:15

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

Щас опишу ситуацию. У меня есть класс, котоорый привязан к мувиклипу по средствам Linkage и наследуется от класса MovieClip. На главную сцену я его переношу посредством attachMovie. При этоом по идее создаётся объект этого класса автоматически. Но эвенты совсем не хотят работать.

Вот пример класса (всё не относящееся к делу выкинуто)
Код:

import mx.events.EventDispatcher;
class loader extends MovieClip{
        var x:Number;
        var y:Number;
        var barWidth:Number;
                var target:MovieClip;

        function loader(){
                ...........................
                mx.events.EventDispatcher.initialize(this);
                onEnterFrame = run;
                ................................
        }
        function run() {
                ...............................
                setFinishHandler();
                ...............................
        }
        function setFinishHandler(){

        var eventObject:Object = {target:this, type:'eventMovieLoaded'};
                dispatchEvent(eventObject);
               
        }
        function dispatchEvent() {
        }
        function addEventListener() {
        }
        function removeEventListener() {
        }
}

в вызове делаю так
Код:

var obj:Object = new Object();
obj.target = _root;
obj.x = 100;
obj.y = 100;
obj.barWidth = 300;

var aObj:Object = new Object();
aObj.eventMovieLoaded = function(eventObj){
        trace('loaded');
}
_root.attachMovie('loader', 'loader1', 2, obj);


_root.loader1.addEventListener(aObj);
trace(_root.loader1.x);

Вопрос всё тотже, где ошибка и как её исправить?

Manowar1 26.10.2004 11:37

Блин всё работает, не знаю почему, но всё заработало.
Простот поменял имя у эвента и всё...

Proman 26.10.2004 15:08

Код:

_root.loader1.addEventListener(aObj);
Сдаеться мне проблема здесь. Метод addEventListener должен получать два параметра (имя события и ссылку на обьект Listener или функцию)

Manowar1 27.10.2004 10:54

Да это верно, без этого параметра оно тооже не работает, это я просто добавил код, после определённых колдовских манипуляция с целью обеспечения его работы :). А в начале я с параметром передовал, но увы.. Сейчас всё работает, мне кажется что я толи букву неправильную где-то записал, тооли ещё что-то в этом роде.

Кстати может подскажешь, пытался в этоом классе dispatcherEvent раставлять trace, но они нифига не работали, получается, что флеш откудато скомпиленный вариант класса берёт, не знаешь как его можно пересобрать?

Proman 27.10.2004 12:53

Ты видимо не с "тем" классом работаеш.
Флэш при запуске создает копию директории Classes в
Код:

C:\Documents and Settings\Your_profile\Local Settings\
Application Data\Macromedia\Flash MX 2004\en\Configuration\Classes

поэтому если ты изменяеш классы которые находяться в директории в которой установлен флэш, то изменения ты увидиш только после его перезапуска, вот и причина почему код не работает, не работает а после перезапуска флэша начинает работать. :)

Manowar1 27.10.2004 13:12

вот блин!!

Век живи век учись, спасибо тебе большое!

Nirth 29.10.2004 18:17

если не трудно то объясните пожалуйста, по подробнее как добавить событие к классу, скажем есть класс XMC к нему нужно добавить событие onDoubleClick , как этого можно добиться?
спасибо заранее

Manowar1 29.10.2004 19:37

могу предложить тебе такой вариант
Класс для отслеживания двойного нажатия testEvent.as

Код:

class testEvent{
        static var numClicks:Number = 0;
        private var curNumTakts:Number = 0;
        function testEvent(){
        }
        function onMouseDown(){
                numClicks ++;

                if (numClicks == 2){
                        numClicks = 0;
                        trace('Double Click');
                }
        }
        function unsetInterval(){
                numClicks = 0;
        }
}

а это создание объекта и его инициализация для работы
Код:

te = new testEvent();
setInterval(te.unsetInterval, 300);
Mouse.addListener(te);


Но это в том случае если тебе нужно просто отследить двойное нажатие, если же тебе нужно чтоб класс генерил своё событие по двойному щелчку, то trace нужно заменить на вышесказанное Proman' ом по поводу eventDispatcher

Nirth 29.10.2004 19:58

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

silin 29.10.2004 20:22

вариант:
Код:

import mx.events.EventDispatcher
class XMC {
        var md:Number
        var dt:Number
       
        function XMC(t:Number){
                mx.events.EventDispatcher.initialize(this)
                md=getTimer()
                dt=t
                var r=this
                Mouse.addListener(r)
                r.onMouseDown=function(){
                        if(getTimer()-md<dt){
                                var eventObject:Object = {target:r, type:'onDoubleClick'};
                                dispatchEvent(eventObject);
                        }
                        else md=getTimer()
                }
        }
        function dispatchEvent() {
        }
        function addEventListener() {
        }
        function removeEventListener() {
        }
}

в кадре:
Код:

var cd:XMC = new XMC(300);
var listener:Object = new Object;
listener.onDoubleClick = function(event) {
        trace("double click");
}
cd.addEventListener("onDoubleClick",listener);


llllllllll 29.10.2004 21:17

Извращенцы, нафиг вам EventDispatchet? Я понимаю еще сложнейший проект, и то люди переписывают этот класс потому что у ММ там лажа полная, AsBroadcaster или mx.transitions.BroadcasterMX - по уши хватит :)

silin 29.10.2004 23:25

полностью согласен с забором, в этом раскладе класс на двойной клик выглядит
Код:

class DblClick extends MovieClip{
        static var bc:Object
        static var dt:Number=300
        private var md:Number
       
        function DblClick(){
                AsBroadcaster.initialize(bc={})
                bc.addListener(this)
                Mouse.addListener(bc)
                bc.onMouseDown=function(){
                        if(getTimer()-md<dt)this.broadcastMessage("onDoubleClick")
                        else md=getTimer()
                }
        }
}

а использование
mc.onDoubleClick=function(){trace("dbl")}//mc связан с классом с помощью Linkage

зы:однако ж раз диспатчер существует надо и его пробывать, хотя б для того что бы разобраться и сравнить

llllllllll 30.10.2004 04:32

Что касается диспатчера - это просто расширенная событийная модель, вот и все ...

Код:


        import mx.events.EventDispatcher;

        // ************************************************
       
        function onEvent():Void
        {
                trace("onEvent");
        }

        var listener:Object = new Object();
       
        listener.event = function():Void
        {
                trace("listener.event");
        }
       
        listener.handleEvent = function(event:Object):Void
        {
                switch(event.type)
                {
                        case("event"):
                                trace("listener.handleEvent");
                                break;
                }
        }

        var dispatcher:Object = new Object();
               
        EventDispatcher.initialize(dispatcher);

        dispatcher.addEventListener("event", onEvent);
        dispatcher.addEventListener("event", listener);
       
        dispatcher.eventHandler = function():Void
        {
                trace("Dispatcher.eventHandler");
        }
       
        // ************************************************
       
        dispatcher.dispatchEvent({type:"event"});

Где-то она полезна, где-то излишни ...

Что касается MovieClip.onDblClick - опять же зачем городить?
Ну ни кто ведь не отменял прототипы, и та же ММ их использует в своих классах ... во всяком случае, в, примерно, таком виде ...

Код:

class mx.Extensions.MovieClipExtensions
{
        static function addDrawingAPI():Void
        {
                MovieClip.prototype.drawCircle = function (x:Number, y:Number, radius:Number):Void
                {
                        // ...
                }
        }       
}

// и далее когда необходимо подключаем это ...

import mx.Extensions.MovieClipExtensions;
MovieClipExtensions.addDrawingAPI();


Да есть момент, что MovieClip - это dynamic class, но не важно, кто мешает для того же String, залезть в String.as и добавить либо ключевое слово dynamic, или зарезервировать местечко для своего метода, типа:

function hello():Void;

И далее в подключаемом StringExtension уже его определить ...
Кстати если поставить себе Central SDK - то можно увидеть как обновится тот же String.as (function replace( re:String, repl:String ):String; // Central API)

Вобщем будте проще :)

llllllllll 30.10.2004 04:37

про дабл клик
 
Про onDoubleClick - это я к тому, что Ноксовский вариант ничуть не устарел ;)

Что onDoubleClick должен быть у Mouse, а не у какой-то там class SDAA345klklk35lbjj ... :)

Proman 30.10.2004 15:17

Цитата:

Что касается диспатчера - это просто расширенная событийная модель
И да и нет. Класс EventDispatcher реализует событийную модель компонентов второй версии.
Например, если необходимо связать какой-то обьект с компонентом без постоянных вызовов execute, то очень даже помогает. :)
А так я согласен, AsBroadcaster-а в большенстве случаев достаточно.

llllllllll 30.10.2004 19:11

"без постоянных вызовов execute" - каких еще вызовов? ;) о чем ты дарагой? :)

Manowar1 01.11.2004 12:47

Silin, твой пример, с использованием AsBroadcater, что-то совсем не работает, или я как - тот неправильно создаю объект, можешь более подробнее описать?

Proman 01.11.2004 14:09

llllllllll
Цитата:

о чем ты дарагой?
Допустим у нас есть текстове поле src_fld и мы хотим связать его свойство text со свойством text текстового поля dest_fld с использованием класса Binding
Код:

import mx.data.binding.*;
var src = {component:src_fld, property:"text", event:"onChanged"};
var dest = {component:dest_fld, property:"text"};
var my_bind:Binding = new Binding(src, dest);

Чтобы связь заработала, мы должны после измнения src_fld.text вызвать метод my_bind.execute()
Код:

src_fld.onChanged = function() {
        _root.my_bind.execute(false);
};

или создать событие в стиле компонентов
Код:

import mx.events.EventDispatcher;
EventDispatcher.initialize(src_fld);

src_fld.onChanged = function() {
        this.dispatchEvent({target:this, type:'onChanged'});
};

Очевидно что для такого случая достаточно метода execute, но в более сложных случаях без EventDispatcher не обойтись.
Вот это я и имел ввиду.

Proman 01.11.2004 14:19

llllllllll
Цитата:

о чем ты дарагой?
Допустим у нас есть текстове поле src_fld и мы хотим связать его свойство text со свойством text текстового поля dest_fld с использованием класса Binding
Код:

import mx.data.binding.*;
var src = {component:src_fld, property:"text", event:"onChanged"};
var dest = {component:dest_fld, property:"text"};
var my_bind:Binding = new Binding(src, dest);

Чтобы связь заработала, мы должны после измнения src_fld.text вызвать метод my_bind.execute()
Код:

src_fld.onChanged = function() {
        _root.my_bind.execute(false);
};

или создать событие в стиле компонентов
Код:

import mx.events.EventDispatcher;
EventDispatcher.initialize(src_fld);

src_fld.onChanged = function() {
        this.dispatchEvent({target:this, type:'onChanged'});
};

Очевидно что для такого случая достаточно метода execute, но в более сложных случаях без EventDispatcher не обойтись.
Вот это я и имел ввиду.

Nirth 02.11.2004 16:50

честно говоря не знаю с какого боку начинать.
вот пример.
есть тултипа. должна появляться когда мышка наводить какие либо кнопки(не все)
тоесть нужно событие тултипы которое реагирует на навод мышки к кнопке(все эти кнопки принадлежат классу SubButton)
вот сижу уже полчаса и думаю как бы лучше это дело огранизовать.
ЗЫ тултип это объект в котором будет 1 мувик и 2-3 текстовых полей.ну и тоже принадлежит к своему собственному классу

silin 04.11.2004 18:50

Вложений: 1
Цитата:

Оригинал написал(а) Manowar1
Silin, твой пример, с использованием AsBroadcater, что-то совсем не работает, или я как - тот неправильно создаю объект, можешь более подробнее описать?
см. аттач

2Nirth : непонятно в чем трабл - что тебе мешает в твоем SubButton определить onRollOver() ?

Nirth 07.11.2004 02:38

ну дело не в том что мешает а в том что хочеться освоить данную фичу=) пусть даже пока на не нужных вещах.

столкнулся я тут с проблемкой с твои исходником.
если я убираю с рута эту строчку
Код:

mc.onDoubleClick=function(){trace("dd")}
и вешаю ее уже на мувик

Код:

this.onDoubleClick=function(){trace("dd")}
и делаю скажем четыре экземпляра класса, то получаеться не совсем то что нужно а точнее

dd
dd
dd
dd

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

silin 07.11.2004 11:54

а как же - это же мышиное событие,
можно, например, HitTest приделать, тогда будет срабатывать только на мувике как onPress
Код:

class DblClick extends MovieClip{
        static var bc:Object
        static var dt:Number=300
        private var md:Number
       
        function DblClick(){
                AsBroadcaster.initialize(bc={})
                bc.addListener(this)
                Mouse.addListener(bc)
                var mc=this
                bc.onMouseDown=function(){
                        if(getTimer()-md<dt && mc.hitTest(mc._parent._xmouse,mc._parent._ymouse,true))this.broadcastMessage("onDoubleClick")
                        else md=getTimer()
                }
        }
}


Nirth 07.11.2004 13:57

2 Sliin да спасибо, я уже понял что такое листенеры=) я сделал примерно такоеже но с помощью еще онРоллОвер, РолАут

спасибо=)
*ушел мучаться дальше*

Nirth 08.11.2004 23:55

туплю не по детски
 
думал разобрался но нет =(

по моему скомному мнению это дело должно добавить событие onSecond(вызываеться раз в секунду);

Код:

function second():Void {
  AsBroadcaster.initialize(this);
  this.broadcastMessage("onSecond");
}
//::
function everySecond() {
  this.interval = setInterval(this, "second", 1000);
}

но это дело говорит мне что я ошибся.

There is no method with the name 'broadcastMessage'.

интересно то что если делать вот так
Код:

function second():Void {
  AsBroadcaster.initialize(this);
  var mc:MovieClip = this;//тоесть не пользуемся ссылкой this
  mc.broadcastMessage("onSecond");
}
//::
function everySecond() {
  this.interval = setInterval(this, "second", 1000);
}

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

silin 09.11.2004 00:47

непонять чего ты добиваешься
Код:

AsBroadcaster.initialize(brodcaster={})//инициализируем вещательный объект
second=function(){        brodcaster.broadcastMessage("onSecond")}//вещаем
interval = setInterval(second, 1000)//запускаем интервал
brodcaster.addListener(listener={})//регистрируем листенер на вещателе
listener.onSecond=function(){trace("  :message received")}//слушаем

а вот что твой класс должен делать неясно

Nirth 09.11.2004 01:36

мой класс это часы, чтобы не вешать событие на onEnterFrame я хочу повесить на онСеконд(тоесть чтоб проверялось только раз в секунду а не 20 раз в секунду).

Nirth 09.11.2004 11:09

Silin
если не трудно мог бы объяснить почему надо каждый раз создавать листенер, тоесть это похоже на обходной путь, я создаю объект, делаю ему событие и подписываю уже мувик на получение, и почему не работает прямая привязка(this)?

silin 09.11.2004 19:31

не пойму чего ты хочешь получить - событие каждую секунду?
Цитата:

мой класс это часы...
зачем для этого класс? : пусть вещает кто угодно, а все имеющие уши( подписанные на прослушку) - услышат
Цитата:

почему надо каждый раз создавать листенер
можешь не создавать, а использовать существующий объект ,тот же мувик- он ведь тоже объект, (тока добавить его к списку листенеров вещателя по любому надо)
Цитата:

я создаю объект, делаю ему событие и подписываю уже мувик на получение
ну все правильно:
Код:

class Sec extends MovieClip{
        var bc:Object
        function Sec(){
                AsBroadcaster.initialize(bc={})
                bc.addListener(this)
                setInterval(this, "second", 1000);
        }
        function second(){
                bc.broadcastMessage("onSecond");
        }
}


silin 09.11.2004 19:34

Вложений: 1
:)

silin 09.11.2004 19:45

я тут задним числом подумал, что не нужен тебе бродкастер
(по сути ты пытаешься заставить мувик вещать самому себе)
вот так будет уместнее (проще надо быть)
Код:

class Sec extends MovieClip{
        function Sec(){
                setInterval(this, "onSecond", 1000);
        }
        function onSecond(){}
}

определив такому мувику onSecond , будешь иметь вызов ее раз в секунду ( ведь этого же надо ?)

llllllllll 11.11.2004 04:37

Цитата:

Оригинал написал(а) Proman

Допустим у нас есть текстове поле src_fld и мы хотим связать его свойство text со свойством text текстового поля dest_fld с использованием класса Binding ...

Случай клинический ;) .... допустим мы хотим узнать сумму чисел 2 и 2 с использованием класса "Class2x2" ... ;)

Proman 11.11.2004 16:41

Цитата:

Случай клинический .... допустим мы хотим узнать сумму чисел 2 и 2 с использованием класса "Class2x2" ...
Да действительно клиничиский, мы тут вообще о чем говорили-то, О генерации искуственных событий или о передачи данных между двумя текстовыми полями? Или нужно было в виде примера что-то посложней написать :D так чтоб без ящика пива и не разобрать, и достойно было применения класса Binding ? ;)

llllllllll 11.11.2004 18:56

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

А речь как раз о том, о "Классе - Два умножить на Два", ксати, ММ, продукты свои , к пример Breeze Player - делает как надо ;) с TellTarget и ты ды :)


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

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