Zurück   Flashforum > Flash > ActionScript > ActionScript 3

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 05-01-2010, 12:08   #1 (permalink)
klein und fein:)
 
Registriert seit: Nov 2009
Ort: Köln
Beiträge: 24
[AS3] Problem mir eigenen Event für Klasse

Hallo,

ich habe folgendes Problem:

Ich habe in meiner .fla Datei ein einziges Schlüsselbild, wo mein AS3 Code drin steht. Ich habe mehrere eigene Klassen, in seperaten Dateien die ich da importiere. Dies funktioniert auch soweit.

Nur habe ich ein Problem mit eigenen Events die Klassenfunktionen aufrufen sollen. Die eigenen Events habe ich in einer eigenen Klasse Events definiert (nach dieser Anleitung: AS3 – Eigene Events verwenden // Thomas Aull // Grafik und Webdesign // Grafikdesign, Webdesign, Screendesign, Flash, ActionScript, (X)HTML, CSS)

Mein EventListener wird im Konstruktor der Klasse Test dem Objekt hinzugefügt:
this.addEventListener(Events.START, startByEvent);

Event.START habe ich in der Klasse Events definiert
startByEvent ist eine Methode dieser Klasse, die aufgerufen werden soll, wenn das Event eintrifft. (Funktionskopf: public function startByEvent(e:Events))

wenn ich jetzt in dem Schlüsselbild meiner .fla Datei ein Objekt der Klasse Test mit dem namen myTest instanziiere und danach dispatchEvent(new Events(Events.START, null)); aufrufe, macht er nichts.

Schreibe ich addEventListener(Events.START, myTest.startByEvent); direkt hinter die Instanziierung, dann funktioniert es bedingt.

Was mach ich falsch?

Geändert von julianeS.85 (05-01-2010 um 12:09 Uhr)
julianeS.85 ist offline   Mit Zitat antworten
Alt 05-01-2010, 12:55   #2 (permalink)
Neuer User
 
Registriert seit: Oct 2007
Beiträge: 434
Hi!

Wenn in der Klasse this.addEventListener steht, muss auch diese Klasse das Event Dispatchen. Sprich in deinem fall myTest.dispatchEvent(bla blub).

Allerdings scheint mir die ganze Konstruktion etwas widersinnig, da du ja in deinem Konstrukt auch einfach die startByEvent Funktion direkt aufrufen kannst.

Wenn Parent objekte beim Child was auslösen sollen macht man das in der Regel über public functions. Events benutzt man hingegen um als Child funktionen in der Parentklasse auszulösen.

Hoffe das ist so verständlich.
Lukas78 ist offline   Mit Zitat antworten
Alt 05-01-2010, 13:00   #3 (permalink)
klein und fein:)
 
Registriert seit: Nov 2009
Ort: Köln
Beiträge: 24
Zitat:
Zitat von Lukas78 Beitrag anzeigen
Hi!

Wenn in der Klasse this.addEventListener steht, muss auch diese Klasse das Event Dispatchen. Sprich in deinem fall myTest.dispatchEvent(bla blub).

Allerdings scheint mir die ganze Konstruktion etwas widersinnig, da du ja in deinem Konstrukt auch einfach die startByEvent Funktion direkt aufrufen kannst.

Wenn Parent objekte beim Child was auslösen sollen macht man das in der Regel über public functions. Events benutzt man hingegen um als Child funktionen in der Parentklasse auszulösen.

Hoffe das ist so verständlich.
Ok, ich hatte nur ein Thema dazu gefunden, wo beides als Möglichkeit angeboten wurde. Ich hatte mich für die Eventlösung entschieden.

Muss ich da der Funktion die Referenz des Objektes mitgeben? Könntest du kurz ein allgemeines Beispiel posten? Wäre super nett Danke
julianeS.85 ist offline   Mit Zitat antworten
Alt 05-01-2010, 13:27   #4 (permalink)
Neuer User
 
Registriert seit: Oct 2007
Beiträge: 434
Mal ein Beispiel für beide Richtungen:

Hauptklasse:

PHP-Code:
public class MyMainClass
{

    private var 
_sub1 :MySubClass;

    public function 
MyMainClass()
    {
        
_sub1 = new MySubClass();
        
        
//register Listener for MyEvent.DO_IT
        
_sub1.addEventListenerMyEvent.DO_ITeventHandler);

        
// call public function of sub class
        
_sub1.myPublicFunction();
    }

    private function 
eventHandlere:MyEvent):void
    
{
        
_sub1.removeEventListenerMyEvent.DO_ITeventHandler);
        
//mach irgendwas
    
}  

PHP-Code:
public class MySubClass
{

    public function 
MySubClass()
    {

    }

    public function 
myPublicFunction():void
    
{
        
//mach irgendwas
    
}

    private function 
dispatcher():void
    
{
        
this.dispatchEvent( new MyEventMyEvent.DO_IT));
    }

Macht jetzt so erstmal nichts, soll nur die Wege verdeutlichen.

Du hast eine Instanz deiner SubKlasse in deiner Hauptklasse, auf die SubKlasse und all Ihre public functions und vars kannst du direkt zugreifen, und Events abfangen. Die Subklasse kann nicht auf die Hauptklasse zugreifen, sondern nur Events dispatchen.

Ein klassisches Beispiel wäre eine Loader Klasse. Man erstellt eine Instanz, registriert einen EventListener und ruft dann die z.B. die funktion load bei der Instanz auf. In der Loader Klasse wird nun geladen und wenn das Laden fertig ist, wird ein Event dispatch. Somit weiß dann die Hauptklasse, der Loader ist fertig ich kann jetzt auf die Daten zugreifen.

Hoffe das war jetzt verständlicher.

Grüße
Lukas78 ist offline   Mit Zitat antworten
Alt 05-01-2010, 16:23   #5 (permalink)
klein und fein:)
 
Registriert seit: Nov 2009
Ort: Köln
Beiträge: 24
Dank! das bringt schonmal Licht ins dunkle ...

Was mach ich aber, wenn die Objekte nicht innerhalb der Funktionen der Elternobjekte instanziiert werden?

Bsp.:
PHP-Code:
var meineKlasse1:Klasse1= new Klasse1();
var 
meineKlasse2:Klasse2= new Klasse2(); 
nun möchte ich in einer Funktion der Klasse2 eine Funktionder Klasse1 aufrufen/auslösen.

Bsp.:
PHP-Code:
public function Klasse2()
{
   
Klasse1.bewegeDich();

mit bewegeDich möchte ich eben genau das Objekt ansprechen, was auf selber Ebene mal instanziiert wurde. Deshalb habe ich das mit Events versucht, geht es auch anders? mit Referenzen auf das Objekt? Oder war das so mit Referenzen schon richtig? Ich instanziier ja nicht immer die Objekte in Funktionen von anderen Klassen. Verstehst du mich?

Sorry wenn die Frage dumm ist, hab erst mit Flash angefangen


Geändert von julianeS.85 (05-01-2010 um 17:04 Uhr)
julianeS.85 ist offline   Mit Zitat antworten
Alt 05-01-2010, 17:26   #6 (permalink)
Neuer User
 
Registriert seit: Oct 2007
Beiträge: 434
Einfach in deiner Hauptklasse einen EventListener auf Klasse zwei (wo die überprüfung stattfindet). Dann aus der Hauptklasse die Beweg dich funktion von Klasse eins aufrufen.

PHP-Code:
checkClass.addEventListnerMyEvent.START_MOVEmove);
checkClass.check();

private function 
movee:MyEvent):void
{
    
moveClass.startMove();

So in etwa als Schema. Natürlich muss irdgendwo in CheckClass das Event MyEvent.START_MOVE dispatched werden. Wenn du keine variablen in deinem Event benötigst, kannst du auch mit dem Flash Standard Event arbeiten.

Frage ist halt, müssen beide Klassen auf einer Ebene sein, oder kann die eine vielleicht eine in der anderen Instanziert werden. Kommt immer drauf an, gutes Klassendesign ist wichtig aber auch nicht einfach.

Geändert von Lukas78 (05-01-2010 um 17:30 Uhr)
Lukas78 ist offline   Mit Zitat antworten
Alt 05-01-2010, 19:53   #7 (permalink)
klein und fein:)
 
Registriert seit: Nov 2009
Ort: Köln
Beiträge: 24
Also ich hab es soweit:

Klasse1
PHP-Code:
public class Klasse1
{
    ...
        public function 
Klasse1()
        {
             ...
             
this.addEventListener(Events.MOVEmoveByEvent);
        }
        public function 
moveByEvent(e:Events)
       ....

wenn ich jetzt in meinem Hauptschlüsselbild:
myKlasse1.dispatchEvent(new Events(Events.MOVE, null));

funktioniert das ganze!

schreib ich es aber direkt in die Funktion der Klasse2 passiert nix:
PHP-Code:
public class Klasse2
{
    ...
        public function 
Klasse2()
        {
             ...
        }
        public function 
starte()
        {
             
dispatchEvent(new Events(Events.MOVEnull));
        }

julianeS.85 ist offline   Mit Zitat antworten
Alt 05-01-2010, 20:08   #8 (permalink)
Perverted Hermit
 
Benutzerbild von Omega Psi
 
Registriert seit: Mar 2004
Ort: Delmenhorst
Beiträge: 12.139
Deine Klassen erben nicht von EventDispatcher. Der Code kann nicht funktionieren.
Omega Psi ist offline   Mit Zitat antworten
Alt 05-01-2010, 20:46   #9 (permalink)
klein und fein:)
 
Registriert seit: Nov 2009
Ort: Köln
Beiträge: 24
sorry, aber ich komm nicht hin
ich habe jetzt bei beiden Klassen extends EventDispatcher gemacht ... aber is will nicht, ich heul gleich
julianeS.85 ist offline   Mit Zitat antworten
Alt 06-01-2010, 09:38   #10 (permalink)
Neuer User
 
Registriert seit: Oct 2007
Beiträge: 434
Wird der Listener geaddet bevor das Event dispatched wird?
Lukas78 ist offline   Mit Zitat antworten
Alt 06-01-2010, 10:21   #11 (permalink)
klein und fein:)
 
Registriert seit: Nov 2009
Ort: Köln
Beiträge: 24
Guten morgen! mit neuen Elan in den neuen Tag nachdem der letzte so deprimierend endete ...

Sooo, ich hab mal eine Projekt angelegt, welches das Problem entsprechend runter bricht!

Hoerer.as
PHP-Code:
package classes
{
    
import flash.events.Event;
    
import flash.events.EventDispatcher;
    
import flash.display.*;
    public class 
Hoerer extends MovieClip
    
{
        public function 
Hoerer()
        {
            
//Ich will das mein Objekt Hoerer "hoert" wenn der Dispatcher losgegeben wird und dann die funktion starteByEvent ausführt
            
this.addEventListener(Events.STARTEstartByEvent);
        }
        function 
startByEvent(e:Events)
        {
            
trace("ueber Dispatcher ausgeloest");
        }
    }

Ausloeser.as
PHP-Code:
package classes
{
    
//Imports
    
import flash.events.*;
    
import flash.events.EventDispatcher;
    
    public class 
Ausloeser extends EventDispatcher
    
{
        public function 
Ausloeser()
        {
            
//Hier soll der Dispatcher für Hoerer abgegeben werden
            
this.dispatchEvent(new Events(Events.STARTEnull));
        }
    }        

Event.as
PHP-Code:
package classes
{
    
// Import der Flash Eventklasse
    
import flash.events.*;

    public class 
Events extends Event
    
{
        
// Eventarten, bekanntes Beispiel: MouseEvent.CLICK
        
public static const STARTE:String "STARTE";
 
        
// Variable in denen wir zusätzliche Eventdaten speichern können
        
public var data;
 
        
// Der Konstruktor
        
public function Events(type:Stringdata
        {
            
super(type);
            
this.data data;
            
trace("Konstruktor von Events");
        }
    }

main.fla
PHP-Code:
import classes.Hoerer;
import classes.Ausloeser;
import flash.events.*;
import flash.events.EventDispatcher;

var 
meinHoerer:Hoerer = new Hoerer();
var 
meinAusloeser:Ausloeser = new Ausloeser(); 
Wie gesagt, es ist reduziert, eine Lösung mit übergabe der Objektreferenz sollte nicht erfolgen.

Die Ausloeserklasse erbt von EventDispatcher, wie Omega Psi eingeworfen hat.

Der EventListener muss ja dem Element angehangen werden, welches das Ereignis auslöst, richtig? (Sagt mein Buch) Genau da scheint ja mein Problem zu liegen, dass Hoerer einfach nicht hoert, bzw. meint es ist nicht fuer Ihn was Ausloeser ausloest, oder?

Wichtig ist noch, dass die beiden Objekte in keine Beziehung stehen, sprich kein Kind- oder Elternklasse

Geändert von julianeS.85 (06-01-2010 um 10:25 Uhr)
julianeS.85 ist offline   Mit Zitat antworten
Alt 06-01-2010, 10:47   #12 (permalink)
Neuer User
 
Registriert seit: Oct 2007
Beiträge: 434
Wenn man sich nicht kennt hört man nicht aufeinander, ist wie im richtigen Leben

Von daher musst du schon eine Referenz übergeben entweder im Konstruktor oder in einer separaten Funktion. Letzeres ist flexibler, da kannst du dann mehrere Objekte den Event auslösen lassen.

PHP-Code:
package classes
{
    
import flash.events.Event;
    
import flash.events.EventDispatcher;
    
import flash.display.*;
    public class 
Hoerer extends MovieClip
    
{
        public function 
Hoerer()
        {
            
        }

        public function 
addDispatcherdisp:EventDispatcher):void
        
{
            
disp.addEventListener(Events.STARTEstartByEvent);
        }
     
        private function 
startByEvent(e:Events):void
        
{
            
trace("startByEvent - Dispatcher: " e.currentTarget);
        }
    }

PHP-Code:
import classes.Hoerer;
import classes.Ausloeser;
import flash.events.*;
import flash.events.EventDispatcher;

var 
meinHoerer:Hoerer = new Hoerer();

var 
meinAusloeser:Ausloeser = new Ausloeser();
meinHoerer.addDispatchermeinAusloeser); 

//Beispiel für zweiten Ausloeser
var meinZweiterAuslöser:Ausloeser = new Ausloeser();
meinHoerer.addDispatchermeinZweiterAusloeser); 
Die Klasse Ausloeser darf allerdings das Event nicht im Konstruktor dispatchen, da es sonst dispatcht wird bevor man dem Objekt einen Listener geben kann.
Lukas78 ist offline   Mit Zitat antworten
Alt 06-01-2010, 12:35   #13 (permalink)
klein und fein:)
 
Registriert seit: Nov 2009
Ort: Köln
Beiträge: 24
HAB 1000 DANK! es funktioniert

Falls alle die mal das gleiche Problem haben mit eigenen Events und Kommunikation mit anderen Objekten. So schauts jetzt bei mir fertig aus!

hoerer.as
PHP-Code:
package classes
{
    
import flash.events.Event;
    
import flash.events.EventDispatcher;
    
import flash.display.*;
    public class 
Hoerer extends MovieClip
    
{
        public function 
Hoerer()
        {

        }
        public function 
addDispatcherdisp:EventDispatcher):void
        
{
            
disp.addEventListener(Events.STARTEstartByEvent);
        }
        function 
startByEvent(e:Events)
        {
             
trace("startByEvent - Dispatcher: " e.currentTarget);
        }
    }

ausloeser.as
PHP-Code:
package classes
{
    
//Imports
    
import flash.events.*;
    
import flash.events.EventDispatcher;
    
    public class 
Ausloeser extends EventDispatcher
    
{
        public function 
Ausloeser()
        {
            
//Hier soll der Dispatcher für Hoerer abgegeben werden
        
}
        public function 
ausloesen()
        {
            
this.dispatchEvent(new Events(Events.STARTEnull));
        }
    }        

events.as
PHP-Code:
//subclass semster
package classes
{
    
// Import der Flash Eventklasse
    
import flash.events.*;

    public class 
Events extends Event
    
{
        
// Eventarten, bekanntes Beispiel: MouseEvent.CLICK
        
public static const POWERON:String "POWERON";
 
        
// Variable in denen wir zusätzliche Eventdaten speichern können
        
public var data;
 
        
// Der Konstruktor
        
public function Events(type:Stringdata
        {
            
super(type);
            
this.data data;
            
trace("Konstruktor von Events");
        }
    }

main.fla
PHP-Code:
import classes.Hoerer;
import classes.Ausloeser;
import flash.events.*;
import flash.events.EventDispatcher;

var 
meinHoerer:Hoerer = new Hoerer();
var 
meinAusloeser:Ausloeser = new Ausloeser();

meinHoerer.addDispatchermeinAusloeser); 
meinAusloeser.ausloesen(); 
Nochmal vielen Dank besonders an Lukas78!
julianeS.85 ist offline   Mit Zitat antworten
Alt 06-01-2010, 14:02   #14 (permalink)
klein und fein:)
 
Registriert seit: Nov 2009
Ort: Köln
Beiträge: 24
Ah eine Frage noch, wie mach ich es, wenn ich das Ausloeser-Objekt in einer Funktion einer Klasse erstellt habe?!

In der Praxis siehts bei mir so aus

Klasse A
-- in einer funktioner der Klasse A wird Klasse B instanziirt
-- Klasse B
---- in einer Funktion von Klasse B wird Klasse C instanziirt
---- Klasse C soll mein Ausloeser sein
Klasse E = Hoerer

Klasse A und E bedinden sich in der main.fla

Geändert von julianeS.85 (06-01-2010 um 14:09 Uhr)
julianeS.85 ist offline   Mit Zitat antworten
Alt 06-01-2010, 14:59   #15 (permalink)
Neuer User
 
Registriert seit: Oct 2007
Beiträge: 434
Wenn deine Klassen DisplayObjecte sind, kannst du beim dispatchen bubbles auf true setzten, dann geht das Event durch die ganze DisplayListe.

Oder du reichst den Event durch, sprich Klasse B erhält einen Listener auf Klasse C, mit der Listener Funktion dispatchEvent und gleiches für A und B

Klasse A
PHP-Code:
var myB = new B();
myB.addEventListenerMyEvent.DO_ITthis.dispatchEvent); 
und in Klasse B
PHP-Code:
var myC = new C();
myC.addEventListenerMyEvent.DO_ITthis.dispatchEvent); 
da beim weiter dispatchen das Event geclont wird muss die Funktion bei deinem Event überschrieben werden, sonst gehen die Daten verloren und es wird nur noch ein Typ Event und nicht mehr MyEvent dispatched
PHP-Code:
public class MyEvent extends Event
    
{
        
//Events werden nur anhand von Strings erkannt, daher eindeutige verwenden (ich zB setze immer noch die Klasse vorne dran)
        
public static const DO_IT:String "MyEvent:DoIt";
 
        
//Klassenvariablen besser als private declarieren und dann mit getter und setter funktionen arbeiten.
        
private var _data :Object;
 
        
//immer alle parameter der BasisKlasse verwenden und an super weitergeben
        
public function MyEvent(type:Stringdata:Objectbubbles:Boolean=falsecancelable:Boolean=false
        {
            
super(typebubblescancelable);
            
_data data;
        }

        
override public function clone():Event
        
{
            return new 
MyEventthis.typethis.datathis.bubblesthis.cancelable); 
        }

        public function 
get data():Object
        
{
            return 
_data;
        }
    } 

Geändert von Lukas78 (06-01-2010 um 15:01 Uhr)
Lukas78 ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Eigenen Event auslösen? silentx ActionScript 3 7 27-04-2009 10:49
onEnterFrame in einer eigenen Klasse falconry ActionScript 2 2 16-04-2008 15:45
Event einer Klasse an Child-Klasse salzblog ActionScript 3 5 12-09-2007 10:09
Kennt eine Klasse Ihren eigenen Instanznamen? andi2003 ActionScript 2 23 04-12-2006 18:03
eigenen event-handler :onRightPress: Scrawer Softwarearchitektur und Entwurfsmuster 12 23-08-2004 21:16


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:51 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele