当使用相同的回调函数或事件监听器时,如何检查按下了哪个按钮?

4
我有一个自定义的菜单按钮类。在主函数中,我创建了此按钮的对象,并在函数中使用它们。最终我想要实现:当我点击按钮1时,显示文本1;点击按钮2,显示文本2,以此类推...
以下是我的主函数和自定义类的代码示例:
class WeaponMenu extends Sprite{

var wpnMenuImagePath:String;
var _wpnMenuImagePath:String;

var wpnMenuName:String;
var _wpnMenuName:String;

var swordMenuBtmp:Bitmap = new Bitmap ();
var swordMenuSprt:Sprite = new Sprite();

var bowMenuBtmp:Bitmap = new Bitmap ();
var bowMenuSprt:Sprite = new Sprite();

public function new(wpnMenuImagePath, wpnMenuName) {

    super();

    _wpnMenuImagePath = wpnMenuImagePath;
    _wpnMenuName = wpnMenuName;

    createWpnMenu ();
}
public function createWpnMenu () :Void {

    if (_wpnMenuName == "Sword") {

        swordMenuSprt.x = -500;
        swordMenuSprt.y = ((Lib.current.stage.stageHeight - swordMenuBtmp.height) / 2) -150;

        swordMenuBtmp = new Bitmap (Assets.getBitmapData (_wpnMenuImagePath));
        swordMenuSprt.addChild(swordMenuBtmp);

        var swordMenuSprtX:Float = ((Lib.current.stage.stageWidth - swordMenuBtmp.width) / 2) -200;
        var swordMenuSprtY:Float = ((Lib.current.stage.stageHeight - swordMenuBtmp.height) / 2) -150;

        Actuate.tween(swordMenuSprt, 2, { x:swordMenuSprtX, y:swordMenuSprtY } ) .delay( -1.1) .ease (Back.easeIn);

        addChild(swordMenuSprt);
    }
    if (_wpnMenuName == "Bow") {

        bowMenuSprt.x = (Lib.current.stage.stageWidth - bowMenuBtmp.width) / 2;
        bowMenuSprt.y = Lib.current.stage.stageHeight + 500;

        bowMenuBtmp = new Bitmap (Assets.getBitmapData (_wpnMenuImagePath));
        bowMenuSprt.addChild(bowMenuBtmp);

        var bowMenuSprtX:Float = (Lib.current.stage.stageWidth - bowMenuBtmp.width) / 2;
        var bowMenuSprtY:Float = ((Lib.current.stage.stageHeight - bowMenuBtmp.height) / 2) -150;

        Actuate.tween(bowMenuSprt, 2, { x:bowMenuSprtX, y:bowMenuSprtY } ) .delay( -1.1) .ease (Back.easeIn);

        addChild(bowMenuSprt);
    }
    if (_wpnMenuName == "Staff") {

        staffMenuSprt.x = Lib.current.stage.stageWidth + 500;
        staffMenuSprt.y = ((Lib.current.stage.stageHeight - staffMenuBtmp.height) / 2) -150;

        staffMenuBtmp = new Bitmap (Assets.getBitmapData (_wpnMenuImagePath));
        staffMenuSprt.addChild(staffMenuBtmp);

        var staffMenuSprtX:Float = ((Lib.current.stage.stageWidth - staffMenuBtmp.width) / 2) +200;
        var staffMenuSprtY:Float = ((Lib.current.stage.stageHeight - staffMenuBtmp.height) / 2) -150;

        Actuate.tween(staffMenuSprt, 2, { x:staffMenuSprtX, y:staffMenuSprtY } ) .delay( -1.1) .ease (Back.easeIn);

        addChild(staffMenuSprt);
    }
}
}

以下是来自主函数的代码:

class Main extends Sprite {

public var swordMenu:WeaponMenu;
public var bowMenu:WeaponMenu;
public var staffMenu:WeaponMenu;

public function new () {

    super ();
    swordMenu = new WeaponMenu ("ui/swordBtn.png", "Sword");
    bowMenu = new WeaponMenu ("ui/bowBtn.png", "Bow");
    staffMenu = new WeaponMenu ("ui/staffBtn.png", "Staff");
    weaponChoose ();
}
    public function weaponChoose ():Void {

    swordMenu.buttonMode = true;
    swordMenu.useHandCursor = true;
    bowMenu.buttonMode = true;
    bowMenu.useHandCursor = true;
    staffMenu.buttonMode = true;
    staffMenu.useHandCursor = true;

    swordMenu.createWpnMenu();
    bowMenu.createWpnMenu();
    staffMenu.createWpnMenu();
    addChild(swordMenu);
    addChild(bowMenu);
    addChild(staffMenu);
    swordMenu.addEventListener(MouseEvent.CLICK, choose);
    bowMenu.addEventListener(MouseEvent.CLICK, choose);
    staffMenu.addEventListener(MouseEvent.CLICK, choose);
}

public function choose (event:MouseEvent):Void {

    if (event.currentTarget == swordMenu) {
    trace ("good"); 
    }

    swordMenu.removeEventListener(MouseEvent.CLICK, choose);
    bowMenu.removeEventListener(MouseEvent.CLICK, choose);
    staffMenu.removeEventListener(MouseEvent.CLICK, choose);

    removeChild(swordMenu);
    removeChild(bowMenu);
    removeChild(staffMenu);
}

很抱歉这是原始的代码示例。

我想要做的是检查在主程序中按下了哪个按钮,并将此信息发送到自定义类中并触发一个函数,以显示每个按钮的适当文本。

1个回答

4

解决方案1:

检查event:MouseEvent参数的target属性(而不是currentTarget)--它很可能是你想要的特定按钮(要检查一下event.target是不是你想要的按钮)。如果它是你想要的按钮(只需跟踪一下event.target),那么你所需要做的就是:

if (event.target == button1) { doSomething();} else if (event.target == button2) { doSomethingElse();}

如果这种方法不起作用,可以使用函数绑定。

解决方案2:

Haxe有一个名为函数绑定的功能,允许你向回调附加特定数据。

因此,你的情况是你有这三个按钮都连接到同一个事件监听器响应函数,但如果event.target不是你想要的按钮,则无法区分实际上被点击的是什么 -- 它们都调用相同的函数。确实有东西被点击了,但你不知道是什么。

因此,在分配监听器时,你需要添加一些关于这个按钮的信息到函数调用中。

swordMenu.addEventListener(MouseEvent.CLICK, choose.bind(_,"sword"));
bowMenu.addEventListener(MouseEvent.CLICK, choose.bind(_,"bow"));
staffMenu.addEventListener(MouseEvent.CLICK, choose.bind(_,"staff"));

public function choose (event:MouseEvent,id:String):Void {
   if(id == "sword") { onSword();}
   if(id == "bow") { onBow();}
   if(id == "staff") { onStaff();}
}

让我解释一下这里发生了什么 - 通常你只需要将函数名称传递给addEventListener即可。相反,我们对其调用了"bind()"。在Haxe中,每个函数都可以调用".bind()",并传递任意数量的参数给它,这将返回一个新函数,其中包含附加的参数。

因此看看这个:

swordMenu.addEventListener(MouseEvent.CLICK, choose.bind(_,"sword"));
_作为第一个参数,表示“传递您通常要传递到此插槽的任何内容”,然后我们在其后传递“sword”作为常量。这基本上只是一种更简单的方式来输入以下内容:
swordMenu.addEventListener(MouseEvent.CLICK, 
    function(e:MouseEvent):Void
    {
        choose(e,"sword");
    }
);
bowMenu.addEventListener(MouseEvent.CLICK, 
    function(e:MouseEvent):Void
    {
        choose(e,"bow");
    }
);
staffMenu.addEventListener(MouseEvent.CLICK, 
    function(e:MouseEvent):Void
    {
        choose(e,"staff");
    }
);

public function choose (event:MouseEvent,id:String):Void {
   if(id == "sword") { onSword();}
   if(id == "bow") { onBow();}
   if(id == "staff") { onStaff();}
}

这样做的效果是一样的,但是更加冗长。


谢谢您的回答。这两个解决方案都完美地解决了我的问题。但是,在我编辑之前,我的原始问题还有一个问题。我能否使用自定义类中的相同函数来显示所有三个按钮的不同文本?如果可以,那么在自定义类中如何告诉哪个按钮被按下了呢? - Soul Bruteflow
我不确定我理解了...你想点击一个按钮,然后根据按下的是哪个按钮,在该按钮上显示一些特定的文本? - larsiusprime
我想点击按钮并运行一个函数,在该按钮下方显示一段文本。 - Soul Bruteflow
让我举个例子来澄清一下。假设在游戏开始时,玩家需要从三个角色中选择一个。我们将这些角色显示为图标供玩家选择,当玩家点击其中一个角色图标后,他将看到该角色的描述文本。 - Soul Bruteflow
这里是我的问题。我能否使用一个函数来显示玩家按下的每个图标/按钮的三种不同描述?如果此函数位于自定义类中,例如上面的WeaponMenu。或者我如何将哪个按钮被按下的信息从主类发送到自定义类中。 - Soul Bruteflow
我为这个问题创建了一个新主题,因为我找不到答案。如果您能帮忙解决,那就太好了。这是链接:http://stackoverflow.com/questions/35285411/how-to-send-back-to-custom-class-which-object-of-that-class-was-clicked - Soul Bruteflow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接