2017-03-24 3 views
0

J'ai une scène avec plusieurs objets enfants de différents types. J'ai un auditeur d'événement sur la scène. Je voudrais obtenir l'objet enfant cible sur un clic de souris afin que je puisse gérer les clics sur différents types d'objets.Obtention de cibles enfants pour un événement de clic de souris dans OpenFL

Quelque chose le long des lignes de:

stage.addEventListener(MouseEvent.CLICK, onClick); 

function onClick(e:Event):Void 
{ 
    var target = e.target 
    // if target type is Foo 
    //  target.aFooMethod(); 
    // else if target type is Bar 
    //  target.aBarMethod(); 

} 

Quelle est la bonne façon de le faire? Le suivi e.target semble imprimer le type d'objet correct, mais je suis incapable d'appeler les méthodes d'objets.

Je me souviens vaguement dans ActionScript 3 de pouvoir utiliser target.name mais retourner la valeur null dans ce cas.

Répondre

1

Il semble que votre question concerne principalement l'identification de type à l'exécution (RTTI) et la conversion de type. Haxe fournit un certain nombre d'utilitaires dans les classes Type et Reflect pour traiter cela.

Pour votre code, il semble que vous voulez précisément:

if (Std.is(target, Foo)) 
    (target:Foo).aFooMethod(); 
else if (Std.is(target, Bar)) 
    (target:Foo).aBarMethod(); 

Ou peut-être:

if (Std.is(target, Foo)) { 
    var targetAsFoo:Foo = cast target; 
    targetAsFoo.aFooMethod(); 
} else if (Std.is(target, Bar)) { 
    var targetAsBar:Bar = cast target; 
    targetAsBar.aBarMethod(); 
} 

Voici un exemple qui démontre un certain nombre d'utilitaires qui pourraient vous aider, y compris Std.is, interfaces , Type.getClass, type coulée, etc: http://try.haxe.org/#3C192

Le code est le suivant:

class Test { 
    static function main() { 

     function identify(tgt:Dynamic) 
     { 
      trace("1: "+tgt); 
      trace("2: "+Type.typeof(tgt)); 
      trace("3: "+Type.getClassName(tgt)); 
      trace("4: "+Type.getClass(Type.getClassName(tgt))); 
      trace("5: "+Std.is(tgt, Something)); 

      if (Std.is(tgt, Something)) { 
      // Can cast explicitly 
       var casted:Something = cast tgt; 
       trace("Got a Something named: "+casted.name); 
      } 

      if (Std.is(tgt, Something)) { 
      // Can cast implicitly 
       var casted:Something = untyped tgt; 
       trace("Got a Something named: "+casted.name); 
      } 

      if (Std.is(tgt, Something)) { 
      // Can cast in an inline style, (obj:Type) 
       trace("Got a Something named: "+(tgt:Something).name); 
      } 

      if (Std.is(tgt, IHasAName)) { 
      // Can cast to an interface, if you prefer 
       var i_casted:IHasAName = (tgt:IHasAName); 
       trace("Got a IHasAName named: "+i_casted.name); 
      } 

      // Can reflect to see if the name field exists: 
      if (Reflect.hasField(tgt, "name")) { 
       trace("tgt has a name: "+Reflect.field(tgt, "name")); 
      } 
      if (Reflect.hasField(tgt, "length")) { 
       trace("tgt has a length: "+Reflect.field(tgt, "length")); 
      } 
     } 

     trace("----------------------------------"); 
     trace("Calling identify with a Something:"); 
     trace("----------------------------------"); 
     var a = new Something("foo", 3); 
     identify(a); 

     trace("----------------------------------"); 
     trace("Calling identify with a String:"); 
     trace("----------------------------------"); 
     var b = "a string"; 
     identify(b); 

     trace("----------------------------------"); 
     trace("Calling identify with anonymous:"); 
     trace("----------------------------------"); 
     var c = { "name" : "anonymous" }; 
     identify(c); 

    } 
} 

class Something implements IHasAName 
{ 
    public var name:String; 
    public var length:Int; 
    public function new(name:String, length:Int) 
    { 
     this.name = name; 
     this.length = length; 
    } 
} 

interface IHasAName { 
    public var name:String; 
} 

La sortie est:

14:41:24:664 ---------------------------------- 
14:41:24:664 Calling identify with a Something: 
14:41:24:664 ---------------------------------- 
14:41:24:664 1: { name : foo, length : 3 } 
14:41:24:665 2: TClass({ __name__ : [Something] }) 
14:41:24:665 3: null 
14:41:24:665 4: null 
14:41:24:665 5: true 
14:41:24:665 Got a Something named: foo 
14:41:24:665 Got a Something named: foo 
14:41:24:665 Got a Something named: foo 
14:41:24:665 Got a IHasAName named: foo 
14:41:24:665 tgt has a name: foo 
14:41:24:665 tgt has a length: 3 
14:41:24:666 ---------------------------------- 
14:41:24:666 Calling identify with a String: 
14:41:24:666 ---------------------------------- 
14:41:24:666 1: a string 
14:41:24:666 2: TClass({ __name__ : [String] }) 
14:41:24:666 3: null 
14:41:24:666 4: null 
14:41:24:666 5: false 
14:41:24:666 tgt has a length: 8 
14:41:24:667 ---------------------------------- 
14:41:24:667 Calling identify with anonymous: 
14:41:24:667 ---------------------------------- 
14:41:24:667 1: { name : anonymous } 
14:41:24:667 2: TObject 
14:41:24:667 3: null 
14:41:24:668 4: null 
14:41:24:668 5: false 
14:41:24:668 tgt has a name: anonymous 

Je me souviens vaguement en actionscript 3 pouvoir utiliser target.name mais NULL dans ce cas.

En AS3, event.target est de type DisplayObject, et tout DisplayObjects have a .name property, ce qui est la raison pour laquelle vous pourriez faire en AS3.

Le Event.target d'OpenFL est un IEventDispatcher, qui n'est pas spécifiquement associé aux classes d'affichage.

0

Etes-vous sûr que votre scène a une valeur "nom"? De mes tests, l'utilisation de event.target.name devrait fonctionner.

Pour confirmer, essayez d'utiliser event.target.id car l'infrastructure définit une valeur par défaut même si elle n'est pas spécifiée manuellement.

Goodluck.