在 OpenFL 中获取鼠标单击事件的子目标
Getting child targets for mouse click event in OpenFL
我的舞台有多个不同类型的子对象。我在舞台上有一个事件监听器。我想通过单击鼠标获得目标子对象,这样我就可以处理对不同对象类型的点击。
大致如下:
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();
}
正确的做法是什么?跟踪 e.target
似乎打印出正确的对象类型,但我无法调用任何对象方法。
我依稀记得在 actionscript 3 中可以使用 target.name
但在这种情况下 return null。
听起来您的问题主要是关于运行时类型识别 (RTTI) 和类型转换。 Haxe 在 Type
and Reflect
类 中提供了一些实用程序来处理这个问题。
对于你的代码,看起来你特别想要:
if (Std.is(target, Foo)) (cast target:Foo).aFooMethod();
else if (Std.is(target, Bar)) (cast target:Bar).aBarMethod();
或者也许:
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();
}
这里是一个示例,演示了一些可以帮助您的实用程序,包括 Std.is
、接口、Type.getClass
、类型转换等:http://try.haxe.org/#3C192
代码如下:
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;
}
输出为:
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
I vaguely remember in actionscript 3 being able to use target.name but return null in this case.
在 AS3 中,event.target
是 DisplayObject
类型,并且都是 DisplayObjects have a .name
property,这就是您可以在 AS3 中这样做的原因。
OpenFL 的 Event.target
is an IEventDispatcher
,它与显示没有特别关联 类。
您确定您的舞台有 "name" 值吗?
根据我的测试,使用 event.target.name
应该可以。
要确认,请尝试使用 event.target.id
,因为框架会设置一个默认值,即使它不是手动指定的。
祝你好运。
我的舞台有多个不同类型的子对象。我在舞台上有一个事件监听器。我想通过单击鼠标获得目标子对象,这样我就可以处理对不同对象类型的点击。
大致如下:
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();
}
正确的做法是什么?跟踪 e.target
似乎打印出正确的对象类型,但我无法调用任何对象方法。
我依稀记得在 actionscript 3 中可以使用 target.name
但在这种情况下 return null。
听起来您的问题主要是关于运行时类型识别 (RTTI) 和类型转换。 Haxe 在 Type
and Reflect
类 中提供了一些实用程序来处理这个问题。
对于你的代码,看起来你特别想要:
if (Std.is(target, Foo)) (cast target:Foo).aFooMethod();
else if (Std.is(target, Bar)) (cast target:Bar).aBarMethod();
或者也许:
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();
}
这里是一个示例,演示了一些可以帮助您的实用程序,包括 Std.is
、接口、Type.getClass
、类型转换等:http://try.haxe.org/#3C192
代码如下:
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;
}
输出为:
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
I vaguely remember in actionscript 3 being able to use target.name but return null in this case.
在 AS3 中,event.target
是 DisplayObject
类型,并且都是 DisplayObjects have a .name
property,这就是您可以在 AS3 中这样做的原因。
OpenFL 的 Event.target
is an IEventDispatcher
,它与显示没有特别关联 类。
您确定您的舞台有 "name" 值吗?
根据我的测试,使用 event.target.name
应该可以。
要确认,请尝试使用 event.target.id
,因为框架会设置一个默认值,即使它不是手动指定的。
祝你好运。