Zurück   Flashforum > Flash > ActionScript > Softwarearchitektur und Entwurfsmuster

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 02-02-2006, 19:13   #1 (permalink)
Padawan
 
Benutzerbild von Seebold
 
Registriert seit: Dec 2005
Ort: Hannover
Beiträge: 75
onLoad Event bei Buttons

Hallo an alle,

ich habe eine tolle Problemlösung und Flash spielt nicht mit :-(

Ich möchte 400 Schaltflächen färben. Bei Rollover sollen in einem Fähnchen weitere Informationen erscheinen. Die Infos werden mir via XML angeliefert.

Derzeit wird das ganze von oben herab verwaltet. Das finde ich sehr unschön, zumal in der XML-Datei manchmal Datensätze fehlen; leider fehlt mir dann auch die Information zum Ansprechen der Schaltflächeninstanzen (weil Name enthalten).

Meine Lösung war: Man gebe jeder Buttoninstanz beim ersten Laden die Informationen als Eigenschaften.
PHP-Code:
sgn150056.ort
sgn150056
.flaeche 
Desweiteren soll jede Buttoninstanz für sich selbst nachschauen, ob die Farbangabe ändert und sich dann selbst umfärben.

Zum erstmaligen Laden benötige ich aber ein Button.onLoad-Event: Gibts aber nicht. Für die Färbung benötige ich das Button.onEnterFrame -- oder besser noch einen selbstdefinierten Handler, der laut "jetzt" brüllt und die Schaltflächen führen Ihre Methode aus.

Bei Lingo ( Macromedia Director) gibt man einer Instanz eine Methode

PHP-Code:
on MeinHandler me
   put 
"Hallo"
end 
und kann von überall aus aufrufen
PHP-Code:
sendAllSprites(#MeinHandler) 
Gibt es etwas ähnliches in AS? Hat der EventListener damit zu tun, und wenn, kann mir irgendwer erklären, wie dieser eingesetzt wird. Ich finde darüber nur sehr wenig und das, was ich finde ist krassestes Programmierer-Latein.

Über Hilfe würde ich mich freuen
Danke
Seebold
Seebold ist offline   Mit Zitat antworten
Alt 02-02-2006, 23:09   #2 (permalink)
Neuer User
 
Registriert seit: Feb 2006
Ort: undefined
Beiträge: 70
Generell würde ich das mit MovieClips statt mit Buttons machen. Buttons verwende ich persönlich so gut wie nie. Und wenn du sie unbedingt brauchst
erstelle halt Container-Mc´s, in die die Buttons geladen werden.

Das onLoad kannst du regeln indem du einen Callback definierst, der klassisch
via Mc.getBytesLoaded() und Mc.getBytesTotal() angesteuert wird, oder
du benutzt die ab Flash7 interne MovieClipLoader-Klasse.
In deinem Fall würde ich eine Manager-Klasse schreiben, die das Parsen des Xml, Laden und Initialisieren der "Buttons" übernimmt sowie auch die Callbacks implementiert. Wobei das XML-Parsen würde ich eine separate Klasse auslagern.
Wenn die 400 Elemente auf einen Rutsch reinkommen sollen, kannst du diese ja in eine gemeinsame Timeline laden, deren Ladestatus du dann überwachst.
Sparst du dir halt die entsprechende Anzahl von Prozessen. Oder du schreibst eine weitere Klasse, die das Laden ( gemeinsames Preloading ) übernimmt.

In diesem Fall ist onLoad ein Custom-Event, der von der Manager-Klasse
generiert wird. Die Klasse implementiert die EventDispatcher Funktionalität indem die statische Methode initialize() der Klasse EventDispatcher aufgerufen wird, wobei du als Argument eine Referenz auf die Manager-KLassen-INstanz übergibst. Andere Objekte, die die Methode onLoad bereitstellen, können sich dann bei der Manager Instanz anmelden und führen ihre onLoad() aus, wenn der Event aus der Manger-Instanz generiert wird.
Das sähe ungefähr so aus:

Code:
import mx.events.EventDispatcher;

class ButtonManager
{

        private var dispatchEvent:Function;         // Dispatcher API Blaupause
	public var removeEventListener:Function;
	public var addEventListener:Function;
   
       private var parsedXml:Object;

       function ButtonManager()
       {
                EventDispatcher.initialize(this);
       }

       public function load(parsedXml:Object, targetTl:MovieClip):Void
       {
           this.parsedXml = parsedXml;
           var i:String;
           var dep:Number = 0;
           for(i in parsedXml)
           {
                var trgt:MovieClip = targetTl.createEmptyMovieClip(parsedXml[i].buttonName, dep++);
                trgt.loadMovie(parsedXml[i].pathToLoad);
                 
           }
           
           var ref:ButtonManager = this;   // besser über Delegate

           targetTl.onEnterFrame = function()
           {
                  var i:String;
                  if(this.getBytesLoaded() == this.getBytesTotal())
                  {
                        for(i in ref.parsedXml){           // init vars aus xml in mc schreiben
                             this[i] = ref.parsedXml[i];
                        }
                        ref.dispatchEvent({type:"onLoad", target:this});
                  }
           }
       }


      public function updateObjects(parsedXml:Object):Void
      {
              this.dispatchEvent({type:"onUpdate", target:this});
      }


}

class ButtonXMLManager
{
     // parse XML und gib Array von Objekten zurück: [ {pathToLoad:"url", buttonName:"name", initVars:{...} } ]

}


// Listener Objekte
// entweder Objekte oder Instanzen einer speziellen Klasse

var o:Object = new Object();
o.onLoad = function(evObj:Object):Void
{
     // ... 
}

o.onUpdate = function(evObj:Object):Void
{
     var newCol:String = evObj.color;
     var buttonTl:MovieClip = evObj.target;
     var i:String;
     for(i in buttonTl)
     {
           if(buttonTl[i] instanceof MovieClip){
                    var c:Color = new Color(buttonTl[i]);
                    c.setRGB(newCol);
           }
     }
}


var xmlUrl:String  = "./test.xml";
var x:ButtonXMLManager = new ButtonXMLManager();
var xmlObj:Object= x.getParsed(xmlUrl);
var man:ButtonManager = new ButtonManager();
man.addEventListener(o); // Object o als Listener registrieren

man.load(xmlObj);

Is jetzt nur mal so ein Vorschlag, hoffe das hilft dir ein wenig weiter.
_sevenDust ist offline   Mit Zitat antworten
Alt 03-02-2006, 10:35   #3 (permalink)
Padawan
 
Benutzerbild von Seebold
 
Registriert seit: Dec 2005
Ort: Hannover
Beiträge: 75
Das ist ja einiges

Hallo _sevenDust,

danke für die ausführliche Hilfe. Ich werde mir das anschauen und unseren Programmierer dazuholen. Es handelt sich ja um ein generelles Problem, das ich beherrschen möchte. Tatsächlich gerate ich bei Flash immer wieder an Probleme, die aus meiner Lingo-Warte nie auftreten hätten dürfen...

Naja, eine Möglichkeit wäre es tatsächlich gewesen, die Button in MovieClips zu stecken -- aber mach das mal bei 400 Stück ;-) Derzeit läuft es mit der Diktator-Methode -- die Herrschaft des Proletariats der MovieClips muss noch warten. Es geht übrigens hierum: http://www.fischhase.de/Outbox/nds-karte.html
Seebold ist offline   Mit Zitat antworten
Alt 03-02-2006, 14:34   #4 (permalink)
Neuer User
 
Registriert seit: Feb 2006
Ort: undefined
Beiträge: 70
Hallo,

mein Beispiel ist nicht ganz richtig. Das onEnter auf der Timeline, in die
auch hineingeladen wird, macht natürlich keinen Sinn, da alle Eigenschaften
bei fertigem Laden überschrieben werden. Du brauchst also eine Controller-Timeline, die das übernimmt oder halt die erwähnte Multiple Loader-Class.
Für dein Beispiel ist das aber eh hinfällig, da du scheinbar die Routine in dem Film
ausführen kannst, der die Symbole auch in seiner Bibliothek hat.
Hier hab ich mal eine passendere Variante geschrieben, die sich in mehrere KLassen auslagert. Die Klasse ButtonManager könnte sich noch splitten, wenn
die Komplexität zunehmen würde.

Klasse ButtonManager:

PHP-Code:
import MyButton;

class 
ButtonManager
{
    public var 
attDepth:Number;
    private var 
butShell:Object;
    
    function 
ButtonManager()
    {
        
butShell = new Object();
        
attDepth 0;
    }
    
    public function 
init(initObj:ObjecttargetTimeline:MovieClip):Void
    
{
        var 
i:String;
        for(
i in initObj){ 
            var 
but:MyButton = new MyButton(initObj[i], targetTimelineattDepth++);
            
            
but.addEventListener("onRelease"this);
            
but.addEventListener("onHover"this);
            
            
butShellinitObj[i].targetName ] = but;
        }
    }
    
    
    private function 
onHover()
    {
        
// impl
    
}
    
    private function 
onRelease(eObj)
    {
        
//impl
    
}
    
    
    public function 
update(dat:Object// checke auf neue farbe im Datenmodell
    
{
        var 
i:String;
        for(
i in dat){ 
            
butShell[dat[i].targetName].update(dat[i]);
        }
    }

Klasse MyButton:

PHP-Code:
import mx.events.EventDispatcher;

class 
MyButton extends MovieClip
{
    private var 
dispatchEvent:Function;         // Dispatcher API Blaupause
    
public var removeEventListener:Function;
    public var 
addEventListener:Function;
    
    private var 
_mc:MovieClip;
    
    function 
MyButton(initObj:Objecttl:MovieClipdep:Number)
    {
        
EventDispatcher.initialize(this);
        var 
but:MovieClip tl.attachMovie(initObj.lkIdinitObj.targetNamedepinitObj);
        var 
ref:MyButton this// besser via Delegate
        
but.onRollOver = function()
        {
            
ref.hover(this);
        }
        
but.onRelease = function()
        {
            
ref.release(this);
        }
        
_mc but;
        
setCol(initObj.color);
    }
    
    public function 
get mc():MovieClip
    
{
        return 
_mc;
    }
    
    private function 
hover(butRef:MovieClip):Void
    
{
        
this.dispatchEvent({type:"onHover"target:butRef});
    }
    
    private function 
release(butRef:MovieClip):Void
    
{
        
this.dispatchEvent({type:"onRelease"target:butRef});
    }
    
    public function 
setCol(col:Number)
    {
        if(
col == nullcol _mc.color;
        new 
Color(_mc).setRGB(col);
    }
    
    public function 
update(initObj:Object):Void
    
{
        var 
i:String;
        for(
i in initObj){
            
_mc[i] = initObj[i];
        }
        
setCol();
    }

und die Initialisierung auf der Timeline und Test der Update Funktionalität:
In der Lib müssen zwei MovieClip Symbole mit Export. "button1" bzw. "button2" liegen

PHP-Code:

import ButtonManager
;
import MyButton;


// TestDaten -- sollten von XML in dieses Format geparst werden
var dataHolder:Array = new Array();
dataHolder.push( {lkId:"button1"targetName:"button1"_x:100_y:200color:0xffcc00} );
dataHolder.push( {lkId:"button2"targetName:"button2"_x:200_y:100color:0x0066CC} );

this.createEmptyMovieClip("buttonTimeline"10);

var 
bm:ButtonManager = new ButtonManager();
bm.init(dataHolderbuttonTimeline);

var 
newDataHolder:Array = new Array();
newDataHolder.push( {lkId:"button1"targetName:"button1"_x:100_y:200color:0xFF3333} );
newDataHolder.push( {lkId:"button2"targetName:"button2"_x:200_y:100color:0x00FF99} );

// test update  irgendeine Taste drücken
var = {};
o.onKeyDown = function()
{
    
bm.update(newDataHolder);
}
Key.addListener(o); 




Sources: Link
_sevenDust 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



Alle Zeitangaben in WEZ +1. Es ist jetzt 06:58 Uhr.

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


Copyright ©1999 – 2014 Marc Thiele