PDA

Просмотр полной версии : Взаимодействие экземпляров класса


vvk80
10.08.2007, 11:33
Уважаемые форумчане!

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

Итак, у меня есть несколько экземпляров класса MyClass (наследованный от Sprite), добавленные на сцену var myVar:MyClass = new MyClass (... param).

Соответственно в классе есть ивенты и т.д... Мне нужно чтобы при клике на один экземпляр класса, все другие тоже выполняли какое-либо действие (простейший пример - задвигались назад и уменьшались в размерах). Причем event.target выполнял бы другое действие.

Тут в пред. темах речь шла о классах контейнерах, но я, честно признаюсь, не въехал, как это сделать...

Пожалуйста, растолкуйте чайнику, как сделать описанную мною схему правильно и с максимальным быстройдействием. Если можно то максимально подробно и по шагам (на пальцах ;). Хотя бы схему дайте, которой надо следовать... А то совсем зашел в тупик...:o

Заранее большое спасибо за любую помощь...

silin
10.08.2007, 12:51
вариант (http://flasher.ru/forum/showpost.php?p=667983&postcount=28) без контейнера
на пальцах: создаем статический диспатчер, подписываем на него обработчики всех экземпляров, по клику заставляем его диспатчить событие: все экземпляры его получают..

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

etc
10.08.2007, 13:03
Как раз в соседней теме и рассказывается об этом. Даже примерный код классов в наличии.

vvk80
10.08.2007, 13:07
Спасибо, код видел... осталось только его прикрутить к моми целям... что не так просто (для меня)

etc
10.08.2007, 13:13
Ну я могу лишь посоветовать понять и разобраться в нем.
Ничего сложного там нет. В случае контейнера, контейнер подписывается на всплывающее событие от кнопок и сам в конструкторе подписывает обработчики кнопок на свои события.

vvk80
10.08.2007, 13:36
Прошу прощения за наглость...
но у меня вопрос

немного модифицировал, предоставленный ув. silin код след. образом

package {
import flash.display.MovieClip;
import flash.events.*;

public class MenuButton extends MovieClip
{

static private var dispatcher:ButDispatcher=new ButDispatcher();

public function MenuButton()
{
dispatcher.addEventListener(ButDispatcher.BTN_STATUS, onStatus);
addEventListener("click",onClick);
addEventListener("rollOver",onOver);
addEventListener("rollOut",onOut);
}

private function onClick(evt:Event):void
{
dispatcher.broadcast("click");
}

private function onOver(evt:Event):void
{
dispatcher.broadcast("over");
this.addEventListener(Event.ENTER_FRAME,increase);
this.removeEventListener(Event.ENTER_FRAME,diminish);
}
private function onOut(evt:Event):void
{
dispatcher.broadcast("out");
this.addEventListener(Event.ENTER_FRAME,diminish);
this.removeEventListener(Event.ENTER_FRAME,increase);

}

public function onStatus(evt:ButEvent):void
{
trace(name+":"+evt.status);
}
private function increase(evt:Event):void
{
if (this.scaleX<2)
{
this.scaleX+=.1;
this.scaleY+=.1;
}
else
{
this.removeEventListener(Event.ENTER_FRAME,increase);
}
}
private function diminish(evt:Event):void
{
if (this.scaleX>.5)
{
this.scaleX-=.1;
this.scaleY-=.1;
}
else
{
this.removeEventListener(Event.ENTER_FRAME,diminish);
}
}
}
}


Если делаю не праивльно, просьба пнуть и указать, как правильно ;)
В итоге сейчас мне нужно следующее:
чтобы по клику на один экземпляр, тот на кого кликнули (event.target) выезжал вперед, другие двигались назад... (попробовал решить в лоб, через event.target, но к другим экземплярам (кот. не являются event target) не понял как обратиться...

Заранее спасибо за помощь!
P.S.
признаюсь, еще пока не совсем разобрался как код работает, всякие там диспатчеры, но я разберусь:confused:

silin
10.08.2007, 14:28
т.е, тебе просто надо знать какой из экземпляров инициировал событие..
ну и передавай его диспатчеру , а тот добавит его в событие..
тогда в обработчиках события экземпляров будем знать по нему кликнули или по соседу..
package {
import flash.display.MovieClip;
import flash.events.*;

public class MenuButton extends MovieClip {

static private var dispatcher:ButDispatcher=new ButDispatcher();

public function MenuButton(){
dispatcher.addEventListener(ButDispatcher.BTN_STATUS, onStatus);
addEventListener("click",onClick);
}

private function onClick(evt:Event):void{
dispatcher.broadcast(this);
}

public function onStatus(evt:ButEvent):void {
var self:Boolean=evt.sender==this;
addEventListener(Event.ENTER_FRAME,self ? increase : diminish);
removeEventListener(Event.ENTER_FRAME,self ? diminish : increase);
}

private function increase(evt:Event):void{
if (this.scaleX<2) {
this.scaleX+=.1;
this.scaleY+=.1;
}
else{
this.removeEventListener(Event.ENTER_FRAME,increase);
}
}

private function diminish(evt:Event):void{
if (this.scaleX>.5) {
this.scaleX-=.1;
this.scaleY-=.1;
}
else{
this.removeEventListener(Event.ENTER_FRAME,diminish);
}
}
}
}
package {
import flash.events.*;
class ButDispatcher extends EventDispatcher {
public static var BTN_STATUS:String = "btnStatus";

public function broadcast(sender:Object):void {
dispatchEvent(new ButEvent(sender));
}
}
}
package {
import flash.events.Event;
public class ButEvent extends Event{
public var sender;

public function ButEvent(sender:Object=null){
super(ButDispatcher.BTN_STATUS);
this.sender=sender;
}
}
}

vvk80
10.08.2007, 15:35
silin, спасибо...
наверное я неправильно объяснил, что я хочу... прошу прощения...:rolleyes:

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

package {
import flash.display.MovieClip;
import flash.events.*;

public class MenuButton extends MovieClip
{
private var self:Boolean;
private var sender;
static private var dispatcher:ButDispatcher=new ButDispatcher();

public function MenuButton()
{
dispatcher.addEventListener(ButDispatcher.BTN_STATUS, onStatus);
addEventListener("click",onClick);
addEventListener("rollOver",onOver);
addEventListener("rollOut",onOut);
}

private function onClick(evt:Event):void
{
dispatcher.broadcast("click",this);
if(sender==this)
{
trace(self);
this.x-=20;
}
else
{
this.x+=120; //НЕ РАБОТАЕТ ТАК КАК Я ХОЧУ ПО ИДЕЕ ЕСЛИ ЭТО СОБЫТИЕ ТРАНСЛИРУЕТСЯ НА ВСЕ ЭКЗЕМПЛЯРЫ ТО ОНИ ДОЛЖНЫ СДВИГАТЬСЯ НА УКАЗАННУЮ ВЕЛИЧИНУ...
//У МЕНЯ ЖЕ ДВИГАЕТСЯ ТОЛЬКО ИНИЦИАТОР СОБЫТИЯ. бЛИН КАК ПОЧИНИТЬ...
trace(this.x);
}
}

private function onOver(evt:Event):void
{
dispatcher.broadcast("over", this);
this.addEventListener(Event.ENTER_FRAME,increase);
this.removeEventListener(Event.ENTER_FRAME,diminish);
}
private function onOut(evt:Event):void
{
dispatcher.broadcast("out",this);
this.addEventListener(Event.ENTER_FRAME,diminish);
this.removeEventListener(Event.ENTER_FRAME,increase);

}

public function onStatus(evt:ButEvent):void
{
self=evt.sender==this;
sender=evt.sender;
trace(name+":"+evt.status);

}
private function increase(evt:Event):void
{
if (this.scaleX<2)
{
this.scaleX+=.1;
this.scaleY+=.1;
}
else
{
this.removeEventListener(Event.ENTER_FRAME,increase);
}
}
private function diminish(evt:Event):void
{
if (this.scaleX>1)
{
this.scaleX-=.1;
this.scaleY-=.1;
}
else
{
this.removeEventListener(Event.ENTER_FRAME,diminish);
}
}
}
}


package {
import flash.events.*;
class ButDispatcher extends EventDispatcher
{
public static var BTN_STATUS:String = "btnStatus";

public function broadcast(status:String,sender:Object):void
{
dispatchEvent(new ButEvent(ButDispatcher.BTN_STATUS,status,sender));
}
}
}

package {
import flash.events.Event;
public class ButEvent extends Event
{
public var status:String;
public var sender;

public function ButEvent(type:String,status:String=null,sender:Object=null)
{
super(type);
this.status=status;
this.sender = sender;
}
}
}

Заранее спасибо за помощь!

silin
10.08.2007, 15:56
onClick вызывается при нажатии на конкретный экземпляр, в нем вызывается dispatcher.broadcast, который в свою очередь вызовет onStatus у всех экземпляров..
какой логикой ты руководствуешься, ожидая вызова onClick у всех экземпляров - загадка..

vvk80
10.08.2007, 16:34
onClick вызывается при нажатии на конкретный экземпляр, в нем вызывается dispatcher.broadcast, который в свою очередь вызовет onStatus у всех экземпляров..
какой логикой ты руководствуешься, ожидая вызова onClick у всех экземпляров - загадка..

silin, спасибо, сейчас вроде разобрался..:rolleyes: в итоге я повесил на onStatus проверку, какое событие в данный момент обрабатывается, чтобы сделать разные варианты движения на rollOver и на onClick

public function onStatus(evt:ButEvent):void
{
self=evt.sender==this;
trace(name+":"+evt.status);
if (evt.status == "click")
{
trace("CLICK");

addEventListener(Event.ENTER_FRAME,self ? increase : diminishMore );
}
else
{
trace("OTHER");
}

vvk80
15.08.2007, 11:18
package {
import flash.events.*;
class ButDispatcher extends EventDispatcher {
public static var BTN_STATUS:String = "btnStatus";

public function broadcast(sender:Object):void {
dispatchEvent(new ButEvent(sender));
}
}
}


Ув. Silin, возник тут вопрос, а в строке объявления класса ButDispatcher намеренно опущено определние области видимости класса? Ничего не будет страшного, если сделать его public??? А то я раскидал все по package и у меня перестало работать...

Заранее спасибо!

silin
15.08.2007, 12:09
дада, он и должен быть public..