{lang: 'de'}
Flashhilfe.de - Flash Community

Brauche bitte dringend Hilfe für dynamische Bezeichner [Flash 11]

 


AntwortenRegistrieren Seite1 2  

Sharky25#1
Benutzerbild von Sharky25
Beiträge: 37
Registriert: Mar 2012

26.03.2012, 06:54

Hallo zusammen,
ich benötige dringend Eure Hilfe bei folgendem Problem:

Für eine Desktop App in AIR lege ich mir einige hundert Movies in der Bibliothek an, aus denen der Anwender dann etwas konstruieren können soll.

In AS 2 funktionierte das problemlos über attachMovie

In AS 3 verwende ich nun addChild. Mein Problem:
Wie kann ich einem Movie, den ich per Button-Funktion aus der Library auf die Bühne hole einen dynamischen Bezeichner mit geben - und wie kann ich ihn aus einer anderen Funktion unter Verwendung seines eindeutigen Namens wieder ansprechen, um ihn zu löschen oder eine seiner Eigenschaften zu ändern?

Aktuell vergebe ich den Movies wie folgt Namen, nachdem sie eingefügt wurden:

ActionScript:
1MeinNeuerMC.name = "MC_"+String(Counter)


Wenn ich jedoch aus einer anderen Funktion z.B.:

ActionScript:
1this["MC_"+String(Counter)].x = 100


aufrufe oder

ActionScript:
1this.removeChild(DisplayObject(["MC_"+String(Counter)])


passiert - Ihr ahnt es bereits - nichts :-(
andrelehnert#2
Benutzerbild von andrelehnert
Beiträge: 37
Registriert: Dec 2010

26.03.2012, 13:02

Manipuliere nicht die name-Eigenschaft.
Dieses Mittel aus AS2 ist in AS3 obsolet und schaft redundanten Wirrwarr
Speichere besser Deine Instanzen in einem Array/Vector um später darauf zugreifen zu können oder
nutze die instanzbezeichner themselves
ActionScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
var allMcs:Array=[]
var deinMc:MovieClip = new Symbol();
addChild(deinMc);
allMcs.push(deinMc);

//Zugriff
//entweder
deinMc.x=200;
removeChild(deinMc);
//oder
MovieClip(allMcs[0]).x = 200;
removeChild(MovieClip(allMcs[0]));


LG ANdré
Geändert von andrelehnert am 26.03.12 um 13:03 Uhr
Sharky25#3
Benutzerbild von Sharky25
Beiträge: 37
Registriert: Mar 2012

Themenautor/in

26.03.2012, 13:22

Hallo André,
Vielen Dank. Das werde ich heute Abend gleich mal testen. Ich habe hier als AS2 auf AS3 Umsteiger vermutlich einfach noch einen Knoten im Hirn.
Wie läuft es denn umgekehrt - der Anwender klickt einen zuvor gesetzten Movie an, um ihn zu löschen oder zu verändern. Woher weiß ich denn welchen er ausgewählt hat, wenn er sich nicht über seine *.name Eigenschaft identifiziert?

Meine App ist ein Modellbahnplaner, die einzelnen Teile liegen als Movies in der Library das Setzten, Löschen und Verändern (z. B. Einfärben) ist quasi die Kernfunktion und ausgerechnet die, ist in AS3 gefühlt komplett anders :-(

Würde mich freuen, wenn Du hier noch einen Tipp für mich hättest und sage schon mal 1000Dank
andrelehnert#4
Benutzerbild von andrelehnert
Beiträge: 37
Registriert: Dec 2010

26.03.2012, 13:31

Das MouseEvent enthält in der Eigenschaft target bzw currentTarget den Auslöser:

ActionScript:
1
2
3
4
5
6
deinMc1.addEventListener(MouseEvent.CLICK,deleteHandler);
deinMc2.addEventListener(MouseEvent.CLICK,deleteHandler);

function deleteHandler(e:MouseEvent):void{
     removeChild(MovieClip(e.target));
}
Geändert von andrelehnert am 26.03.12 um 13:31 Uhr
Sharky25#5
Benutzerbild von Sharky25
Beiträge: 37
Registriert: Mar 2012

Themenautor/in

26.03.2012, 13:57

Hallo André,
das wäre dann ein direktes Löschen beim Klick auf das Teil. Mein Problem ist, das ich in einem getrennten Array sämtliche Attribute dieses "Schienenteils" abgelegt habe und später wieder zuordnen muss. Es genügt also nicht eine direkte Aktion auszuführen. Ich muss das Teil identifizieren können, um z. B. anzuzeigen, um welche Art Teil es sich handelt oder bei Löschen eine Teileliste zu aktualisieren usw.

Ist das über target möglich? Bitte entschuldige, wenn ich mich hier etwas dämlich anstelle. Bisher hatten die Teile Namen à la "teil_17_strang_5" und ich konnte alle Infos aus meinem Array, Position 17;5 abrufen usw.

Entweder ist AS3 für meinen speziellen Anwendungsfall ein Rückschritt oder (wahrscheinlicher) ich kapiere das Prinzip noch nicht so ganz :-(

Nochmals vielen Dank für Deine Hilfe
andrelehnert#6
Benutzerbild von andrelehnert
Beiträge: 37
Registriert: Dec 2010

26.03.2012, 14:09

JA -ich denke letzteres ist der FAll ;)

Du solltest Das ganze in Klassen organisieren. Das macht das Ganze
dann echt easy. Stichwort OOP. Hier mal ein kurzes Beispiel.

Schiene.as
ActionScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
package{
    public class Schiene extends Sprite
    {
      public var posX:int;
      public var posY:int;
      .
      .
      .
      public function Schiene()
      {
      }
    }
};

main.as
ActionScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var schienen:Array = [];
function init():void
{
    var schiene = new Schiene();
    schiene.posX= 10;
    schiene.yPos = 30;
    addChild(schiene);
    schienen.push(schiene);
    schiene.addEventListener(MouseEvent.CLICK, deleteHandler);
 
};


function deleteHandler(e:MouseEVent):void
{
    var schiene  = Schiene(e.target);
    trace(schiene.posX+"  "+schiene.posY);
    removeChild(schiene);
}


So hast Du die Eigenschaften immer in der Klasseninstanz von Schiene greifbar.
unabhängig davon, ob schiene in der Displaylist ist oder nicht.
Außerdem hast Du so kein seperates Array sondern hältst die Eigenschaften schon dort, wo sie hingehören-

Aber vielleicht zeigst Du mal ein bisschen mehr Code, damit man genau weiß,
was Du eigentlich vorhast.

LG ANdré
Geändert von andrelehnert am 26.03.12 um 14:11 Uhr
Sharky25#7
Benutzerbild von Sharky25
Beiträge: 37
Registriert: Mar 2012

Themenautor/in

26.03.2012, 15:22

Hallo André,

Du bist schon jetzt mein Held - das sieht in der Tat so aus als könnte man Dinge wesentlich eleganter als noch unter AS2 lösen. Wenn ich das so wie in Deinem Beispiel umgesetzt bekomme, wäre das genial.
Leider gibt es noch nicht viel Code. Ich bin im Entscheidungsprozess, ob ich von AS2 auf AS3 umsteige. Um zu wissen, ob ich das Geld in die Hand nehme wollte ich "schnell" einen Prototyp entwickeln und die wichtigsten Basisfunktionalitäten implementieren.

Meine aktuelle wurde mit AS2 und Screenwaever entwickelt. Die soll jetzt in AS3 und AIR umgesetzt werden...

Vielen Dank - ich bin Dank Deiner Hilfe auf einem hoffentlich guten Weg :-)
Geändert von Sharky25 am 27.03.12 um 07:17 Uhr
andrelehnert#8
Benutzerbild von andrelehnert
Beiträge: 37
Registriert: Dec 2010

26.03.2012, 15:42

Nimm AS3 !!! Ist ja jetzt auch schon 7/8 Jahre alt.
Das zahlt sich in jedem Fall aus, ist schneller, besser und wirft effizienzfördernde Fehlermeldungen,
wenn Du dich daran hältst, alle Variablen zu typisieren.

Überigens ist Flashdevelop kostenlos zu haben und der CodeEditor ein Traum!
Jedoch hast Du keine Bühne zur verfügung.


LG ANdré
Sharky25#9
Benutzerbild von Sharky25
Beiträge: 37
Registriert: Mar 2012

Themenautor/in

26.03.2012, 20:29

Hallo André,

so - here we go ;-)
Deinen Tipp von heute Mittag habe ich wie folgt umgesetzt - und siehe da, man muss nur die richtigen Leute fragen und schon funktioniert`s ;-)

Schiene.as
ActionScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package{
     import flash.display.MovieClip;
 
      public class Schiene extends flash.display.MovieClip
      {
        public var Schiene_x:int;
        public var Schiene_y:int;
        public var Schiene_rotation:int;
        public var Schiene_type:String
        public var Schiene_length:int;
        public var Schiene_radius:int;
        public var Schiene_angle:int;
        public function Schiene()
        {
        }
      }
};


Main.as
ActionScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
btn_addPart.addEventListener(MouseEvent.CLICK,AddPart);

var Counter = 0

function AddPart(event:Event) {
     
     var NeuesTeil = new Schiene();
      NeuesTeil.Schiene_x = 10 + (34.5 * Counter);
      NeuesTeil.Schiene_y = 30;
     
     Bahn.addChild(NeuesTeil);
     NeuesTeil.x = 10 + (34.5 * Counter);
     NeuesTeil.y = 30
     
      Schienen.push(NeuesTeil);
      NeuesTeil.addEventListener(MouseEvent.CLICK, ClickHandler);
     
     Counter++
     
     checkField_stage.text = "funktioniert"   + " " + Counter + " " + NeuesTeil.name
}



function traceName(event:MouseEvent):void {
      trace(event.target.name);
     checkField_stage.text = this.Bahn["teil_"+String(Counter)].name
}


Soweit, so gut. Man könnte jetzt schon einmal die längste Bahn der Welt bauen - allerdings mit nur einer Art von Schienenteil :-(

Wie schaffe ich es der Funktion "AddPart" dynamisch über den Button btn_addPart verschiedene Arten von Teilen zu übergeben?

Beispiel: in der Bibliothek habe ich aktuell einen Movie mit dem Namen "standardgerade" und der Klasse "Schiene", ich würde jetzt noch z. B. einen Movie mit Namen "kurve" ebenfalls von der Klasse "Schiene" anlegen - Ziel soll es sein für jede Schiene einen Button zu haben, aber nach Möglichkeit nur eine Funktion "addPart" der ich dynamisch sage welche Art Schiene sie gerade anfügen soll.

Kannst Du mir hier noch weiterhelfen? Schon einmal vielen, vielen Dank - Deine bisherige Erklärung hat mir schon wesentlich mehr geholfen als jede Flash Help Datei!
andrelehnert#10
Benutzerbild von andrelehnert
Beiträge: 37
Registriert: Dec 2010

26.03.2012, 20:55

Na, das sieht doch schonmal ganz gut aus!

Erstmal vier kleine Anmerkungen zu Deinem Code:

1. Variablen und Instanzen benennt man in AS mit kleinem Anfangsbuchstaben bzw. camelCased , Klassen hingegen mit großem Anfangsbuchsteben, das erhöht die Übersicht im Code ungemein.
2. Warum brauchst Du einen MovieClip? Tut sich bei den Teilen auch noch etwas auf der Zeitleiste? Wenn nicht, dann nimm ein Sprite - das produziert dann keinen Overhead.
3. Da Schiene ja von MovieClip/Sprite erbt, kannst Du die bereits existenten public Eigenschaften der Elternklasse einfach benutzen  (x, y -wenn es normale Pixelangaben sind; und auch rotation);
4. brauchst Du die Eigenschaften in Schiene nicht noch mit einem Präfix "schiene_" zu versehen,
da sie ja sowieso immer nur in Schiene angesprochen werden. Auch das vereinfacht die Schrieberei und Übersichtlichkeit.

Zu den Fragen:
Bau Dir doch Klasse Abstraktschiene mit den Eigenschaften, die ALLE Schienen haben.
von dieser Klasse lässt Du dann Deine ganzen "Spezialschienen" erben und fügst nur noch die
speziell benötigten Eigenschaften bzw Bibliothekssymbole hinzu.

Ähnlich bei den Buttons. Bau die eine Button-Klasse. Sie könnte die Eigenschaft "relatedTile" besitzen.
Beim Initialisieren deines Programmes instanzierst Du dann die ganzen Buttons und vergibst die entsprechende Eigenschaft.

Im Klick-Handler(btn_addPart) der Buttons liest Du dann die Art des Teiles über DeineButtonClass(e.target).relatedTile aus und kannst Dann die entsprechende Schiene auf die Bühne stellen.

LG ANdré
Geändert von andrelehnert am 26.03.12 um 20:55 Uhr
Sharky25#11
Benutzerbild von Sharky25
Beiträge: 37
Registriert: Mar 2012

Themenautor/in

26.03.2012, 22:20

Hallo André,

ich traue mich schon kaum mehr zu fragen - und hoffe nicht zu sehr zu nerven - aber...

das Problem geht noch einen Schritt weiter - ich würde meine AddPart Funktion nicht nur für das Setzen von Teilen über einen Button verwenden, sondern auch nach dem Laden einer Strecke aus einer Datei.

In der Datei stünde die Reihenfolge der Teile, die dann von der AddPart Funktion auf dem Bildschirm platziert werden sollte.

Speichern und Laden ist dank AIR kein Problem, habe ich schon gelöst. Jetzt müsste ich aber in einer For-Schleife (i=1; i<=Anzahl Teile; i++) mit der AddPart Funktion die Strecke wieder aufbauen. Da wäre es wenig elegant zu sagen:

if(teileTyp[i] == "standardgerade"){
var NeuesTeil = new standardgerade();
elseif(teileTyp[i] == "drittelgerade")
var NeuesTeil = new drittelgerade();
...
usw.
}

Gibt es da nicht eine Möglichkeit einen Platzhalter für die Klasse zu verwenden à la.

var NeuesTeil = new teileTyp[i]()
Sharky25#12
Benutzerbild von Sharky25
Beiträge: 37
Registriert: Mar 2012

Themenautor/in

27.03.2012, 07:21

Hallo André,

das nicht mehr direkte ansprechen können von Movies in der mir bekannten Form ist geeignet mich komplett in den Wahnsinn zu treiben...

Meine Movies bekommen beim Setzen einen EventHandler mit. Über folgenden Code kann ich sie durch Click identifizieren

ActionScript:
1
2
3
4
function ClickHandler(e:MouseEvent):void
{
      AktuelleAuswahl = Schiene(e.target);
}


"AktuelleAuswahl" gibt mir den Bezeichner zurück, so dass ich z. B. über:

ActionScript:
1
2
3
4
5
6
btn_addRemove.addEventListener(MouseEvent.CLICK, Remove);

function Remove(event:Event):void
{
  Bahn.removeChild(AktuelleAuswahl)
}


das Teil per Button löschen kann. Versuche ich aber nach dem exakt gleichen Schema eine Eigenschaft (hier alpha-Wert) zu ändern. Funktioniert nicht nur das nicht, sondern auch das Löschen nicht mehr:

ActionScript:
1
2
3
4
5
6
btn_colorPart.addEventListener(MouseEvent.CLICK, PartColor);

function PartColor(event:Event):void
{
     Bahn.AktuelleAuswahl.alpha = 0.4
}


...was mache ich falsch?
(was war es in AS2 so schön - setProperty(Ziel, Eigenschaft, Wert) fertig...)
Geändert von Sharky25 am 27.03.12 um 07:36 Uhr
Sharky25#13
Benutzerbild von Sharky25
Beiträge: 37
Registriert: Mar 2012

Themenautor/in

27.03.2012, 07:37

okay - habe den Fehler gefunden - das "Bahn" vor "AktuelleAuswahl" war zuviel
andrelehnert#14
Benutzerbild von andrelehnert
Beiträge: 37
Registriert: Dec 2010

27.03.2012, 08:43

Ja genau - in AS3 existieren die Displayobjecte explizit und sind unabhängig von ihrer
Position/tiefe als "sie selbst" ansprechbar.

Ich glaube, Du hast noch einen Verständnisfehler, was oop betrifft:
Das Casten gibt Dir nicht den Bezeichner zurück, sondern das gesamte (in diesem Fall) Object "schiene".
Das ist ja auch das Tolle, daß DIr durch Casten des Event-target auf Deine Klasse nun alle
Eigenschaften und Methodendirekt zur Verfügung stehen.

Bei removeChild musst Du "Bahn" mit angeben, da removeChild zwei Argumente erwartet (parent und child).

Wie sieht denn Dein bisheriger Code aus?

LG ANdré
Sharky25#15
Benutzerbild von Sharky25
Beiträge: 37
Registriert: Mar 2012

Themenautor/in

27.03.2012, 09:35

Hallo André,

erneut vielen Dank für Deine Geduld mit mir - ist in der Tat nicht so ganz einfach den gedanklichen Absprung von AS2 zu schaffen, aber es wird.
Das mit den DisplayObjecten habe ich nun (hoffentlich) kapiert. Ich brauche also nicht mehr wir früher den Pfad sondern kann sie direkt ansprechen.

Frage 1:
Wenn ich Movies auf der Bühne "fest" platziere (also nicht über eine Funktion dynamisch hinzufüge) funktioniert das Pfad-Prinzip aber immer noch?

Beispiel: ich setze einen Clip, gebe ihm den Instanznamen MC_1 und in diesem befindet sich MC_2,
Dann kann ich über this.MC_1.MC_2.alpha diesen ansprechen?

Frage 2:
Wie kann ich die DisplayObject Instanzbezeichner in einem Array speichern, um sie später wieder aus einer Funktion ansprechen zu können?

In meinem aktuellen Programmbeispuel muss ich den Mivie ja erst anklicken, um über einen EventHandler seinen Bezeichner zu bekommen, ich möchte ihn aber ohne zuvorigen Klick ansprechen können.
Wenn ich mir (im Beispiel) NeuesTeil.name ausgeben lasse, wird dies zwar korrekt im Array abgelegt (instance...) wenn ich aber Bahn.removeChild(Teile_ID[...]) aufrufe passiert nichts. Ich habe auch schon versucht NeuesTeil.name in ein DisplayObject zu wandeln:

Teile_ID[Counter]=DisplayObject(NeuesTeil.name)

Oder

Bahn.removeChild(DisplayObject(Teile_ID[Countrr]))

Brachte aber auch nichts...

Sorry für die Tippfehler - schreibe hier auf meinem Smartphone
Geändert von Sharky25 am 27.03.12 um 09:39 Uhr
andrelehnert#16
Benutzerbild von andrelehnert
Beiträge: 37
Registriert: Dec 2010

27.03.2012, 10:37

Lass das mit den Namen (name-Eigenschaft) !!!

Frage1
Ja - in diesem Fall sprichst Du ihn über den Pfad an.
Ein Symbol (MovieClip, Sprite), das für AS exportiert ist (Biblio -> re Maustaste -> Eigenschaften)
ist im ja auch eine Klasse und wenn dort fest ein weiter MC liegt, ist er eine quasi eine Eigenschaft
der Klasse.

Frage2
ActionScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var instances:Array=[schiene1,schiene2]; // nicht oop
//oder oop
var instances:Array = [];
var defaults:Array=[{x:10,y:20,rotation:200,kindOf:"kurveRechts"},
                           {x:60,y:-40,rotation:0,kindOf:"gerade"},
                           {x:160,y:500,-40,rotation:2,kindOf:"kurveLinks"}];

for (var i:int=0;i<defaults.length;i++){
    var properties = defaults[i];
    var schiene:Schiene =new Schiene();
    schiene.kindOf =   properties.kindOf;
    schiene.x = properties.x;
    schiene.y = properties.y;
    addChild(schiene);
    instances.push(schiene)
}
//Ansprechen
var currentSchiene:Schiene = Schiene(instances[2]);
removeChild(schiene);


LG André
Geändert von andrelehnert am 27.03.12 um 10:40 Uhr

AntwortenRegistrieren Seite1 2  

Schnellantwort

Du musst registriert sein, um diese Funktion nutzen zu können.

 
Ähnliche Beiträge zum Thema
Partner Webseiten: art-and-law.de  Mediengestalter.info   phpwelt.de   Scubacube.de  
Haftungsausschluss   Datenschutzerklärung   Impressum
© 1999-2024 Sebastian Wichmann - Flashhilfe.de