4

I have a custom class for menu buttons. In the main, I create objects of this button, and use them in functions. Ultimately I want to have: when I click on button 1, display text 1; click button 2, display text 2, etc...

Here are code examples for the main and the custom class that I have:

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);
    }
}
}

And this is the code from Main:

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);
}

Sorry for the raw code sample.

So what I want to do is check which button was pressed in the main, and send this info to the custom class and fire a function that will display the proper text for each button.

larsiusprime
  • 935
  • 6
  • 14
Soul Bruteflow
  • 115
  • 2
  • 8

1 Answers1

4

Solution 1:

Check the target property (not currentTarget) of the event:MouseEvent parameter -- it may very well be the specific button you want (it's either that or the button's container). If it is the button you want (just trace out what event.target is to check), then all you need to do is

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

In case that doesn't work, there's function binding.

Solution 2:

Haxe has a feature called function binding that allows you to attach specific data to a callback.

So your situation is you have these three buttons all hooked up to the same event listener response function, but if event.target isn't the button you want, then there's no way to distinguish what's actually been clicked at the time -- they all call the same function. Something was clicked, but you don't know what.

So what you want to do, is when you assign the listener, you add some information to the function call about which button this is.

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();}
}

Let me explain what's happening here -- normally you would just pass the function name itself in to addEventListener. Instead what we've done is call "bind()" on it. Every function in Haxe can have ".bind()" called on it with any number of parameters passed to it, which will return a new function with the extra parameters appended.

So look at this:

swordMenu.addEventListener(MouseEvent.CLICK, choose.bind(_,"sword"));

The _ as the first parameter means "pass whatever you would normally pass to this slot", and then we pass "sword" as a constant afterwards.

This is basically just a simpler way of typing this:

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();}
}

Which would have the same effect, but is more verbose.

larsiusprime
  • 935
  • 6
  • 14
  • Thank you for the answer. Both of this solution work perfectly. But my original question (before edit) have one more question. Can i use the same function from custom class to display different text for all three buttons? And if so how can i in custom class tell which button was pressed? – Soul Bruteflow Feb 05 '16 at 21:42
  • Not sure I understand ... you want to click on a button, and then display some specific text on that button depending on which one was pressed? – larsiusprime Feb 05 '16 at 23:16
  • I want to click on button and run a function that will display a text under that button. – Soul Bruteflow Feb 05 '16 at 23:36
  • Let me give you example to clarify things. Lets imagine that player at the start of the game needs to choose 1 out of 3 characters. We display this characters for players as icons, after player clicks on one of the character icon he will see a description text for this character. – Soul Bruteflow Feb 05 '16 at 23:45
  • And here is come my question. Can i use one function to display all three different descriptions for each icon/button player will press? If this function is inside custom class like WeaponMenu from example above. Or how i can send info of which button was pressed from main to custom class. – Soul Bruteflow Feb 05 '16 at 23:50
  • I created new topic for this question. Cause i couldn't find the answer. I you can help with it would be great. Here the link http://stackoverflow.com/questions/35285411/how-to-send-back-to-custom-class-which-object-of-that-class-was-clicked – Soul Bruteflow Feb 09 '16 at 06:54