Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Basic 2 button with 1 listener — Gideros Forum

Basic 2 button with 1 listener

twisttaptwisttap Member
edited July 2012 in General questions
Hello,
I was porting some AS code today and I encountered a problem:
function scene:addControls(x,y)
local texture = Texture.new("ptex.png")
 
local leftButtonRegion = TextureRegion.new(texture,0,0,100,100)
local rightButtonRegion = TextureRegion.new(texture,0,100,100,100)
 
local leftButton = Bitmap.new(leftButtonRegion)
local rightButton = Bitmap.new(rightButtonRegion)
leftButton.name = "leftButton"
rightButton.name = "rightButton"
 
leftButton:setPosition(x,y)
rightButton:setPosition(x+120, y)
 
self:addChild(leftButton)
self:addChild(rightButton)
 
 
rightButton:addEventListener(Event.MOUSE_DOWN, onMouseDown, scene.rightButton)
rightButton:addEventListener(Event.MOUSE_UP, onMouseUp, scene.rightButton)
 
leftButton:addEventListener(Event.MOUSE_DOWN, onMouseDown, scene.leftButton)
leftButton:addEventListener(Event.MOUSE_UP, onMouseUp, scene.leftButton)
 
end
 
 
function onMouseDown(event)
local target = event:getTarget()
 
 
print(target.name)
if target.name == "leftButton" then
print("Left Press")
end
 
if target.name == "rightButton" then
print("Right Press")
end
 
end
that was a working and easy to use approach in as3 that you can use only 1 event listener for various buttons etc.
(it may not be the best practice but it is good to use for sketch up something quick) however I couldn't make it work
in Gid.

Likes: kamcknig

+1 -1 (+1 / -0 )Share on Facebook

Comments

  • Btw, this is a basic example to grasp the things. In as3 I was able to iterate over 100 boxes and just use the same eventListener with all of them for different functions.
  • @twisttap: It is entirely possible to use a single eventListener for multiple buttons. I think your problem lies in the implementation. I'm not at my machine at the moment but will look at it when I am. I use the same function for several buttons all the time and use hitTestPoint(event.x, event.y) to differentiate between them.

  • OK @twistap, here is code that works in my current project. As you can see it is doing exactly what you want it to do so
    local menuOptions = { PLAY=1, TUTORIAL=2, CREDITS=3, HELP=4, OPTIONS=5, EXIT=6 }
    local sMenu = { "PLAY", "TUTORIAL", "CREDITS", "HELP", "OPTIONS", "EXIT" }
     
    local function popupClosed() bCanClick = true theOverlay = nil end
     
    -- the actual event listener 
    local function onClick(but)
    	if bCanClick and not theOverlay then	-- avoid multiple clicks on the popup boxes
    		if but.opt == menuOptions.PLAY then
    			bStopAll = true
    			sceneManager:changeScene("gameScreen", 1, SceneManager.flipWithFade, easing.outBack,false)
    		elseif but.opt == menuOptions.TUTORIAL then
    			bStopAll = true
    			sceneManager:changeScene("gameScreen", 1, SceneManager.flipWithFade, easing.outBack,true)
    		elseif but.opt == menuOptions.CREDITS then
    			bCanClick = false
    			theOverlay = Credits.new(theScreen, theTexture, popupClosed)
    			theScreen:addChild(theOverlay)
    		elseif but.opt == menuOptions.HELP then
    			bCanClick = false
    			theOverlay = Help.new(theScreen, theTexture, popupClosed)
    			theScreen:addChild(theOverlay)
    		elseif but.opt == menuOptions.OPTIONS then
    			bCanClick = false
    			theOverlay = Options.new(theScreen, theTexture, popupClosed)
    			theScreen:addChild(theOverlay)
    		elseif but.opt == menuOptions.EXIT then
    			-- Confirm Quit ??
    			application:exit()
    		end
    	end
    end
     
    function menuScreen:init()
     
    	-- add a Tilemap background 
    	theScreen = mapLoader.new(layout, theTexture) theScreen:setPosition(0,0) self:addChild(theScreen)
     
    	menuSprite = Sprite.new() 	-- container (or group) to hold all of the buttons so I can tween it if necessary
    	theScreen:addChild(menuSprite)	-- add it to the background
     
    	local menuItems = #sMenu	-- number of items in the menu
    	-- remove the exit option if we're not on an android device
    	if devInfo ~= "Android" then menuItems=menuItems-1 end
     
    	local c
    	for c=1, menuItems do
    		txt = BMTextField.new(theFont, sMenu[c])
    		txt:setRotation(22.5)
    		-- textButton is just a wrapper around the Button class to allow me to use a single sprite and it's coordinates
    		txtBut = textButton(txt, 0, (75*(c-1))) 
    		-- add the button to my container
    		menuSprite:addChild(txtBut)
    		save for later in case I want to change some text
    		menuTexts[1] = txtBut
    		-- quicker to do a numeric comparison than a string (I think) so let's add our button index so we know what has been pressed
    		txtBut.opt = c
    		-- add the eventlistener to each textButton
    		txtBut:addEventListener("click", onClick, txtBut)
    	end
    end
  • @twisttap Well first off you didn't include your whole example, so you code won't run directly to test it, but anyway AS3 does things a little different then Gideros Studio, instead of finding the target you pass the actual target to the onMouseDown function as a copy of self. And then since Gideros Studio uses a global onClick event, you need to use hitTestPointto find out if that click happened on your button image or not.

    @Scouser your example is perfect for what to do, but you didn't include the textButton function which is going to become pretty confusing really quick for some people on the forum :) otherwise @twisttap be sure to take a look at his code, it's more complex but does some nice things as well--like save them for later to update, etc

    Change your onMouseDown function to the following and you should see the results you want--of course this is assuming that you have this code in a scene class of some kind:
    function onMouseDown(self, event)
    	if(self:hitTestPoint(event.x, event.y)) then
    		print(self.name)
    		if self.name == "leftButton" then
    			print("Left Press")
    		end
     
    		if self.name == "rightButton" then
    			print("Right Press")
    		end
    	end
    end
    On the off chance that this example is the actual code in use and you can't get it to run I have included a copy with this message that will run by itself--you will still need the ptext.png file of course:
     
    function addControls(x,y)
    local texture = Texture.new("ptex.png")
     
    local leftButtonRegion = TextureRegion.new(texture,0,0,100,100)
    local rightButtonRegion = TextureRegion.new(texture,0,100,100,100)
     
    local leftButton = Bitmap.new(leftButtonRegion)
    local rightButton = Bitmap.new(rightButtonRegion)
    leftButton.name = "leftButton"
    rightButton.name = "rightButton"
     
    leftButton:setPosition(x,y)
    rightButton:setPosition(x+120, y)
     
    stage:addChild(leftButton)
    stage:addChild(rightButton)
     
     
    rightButton:addEventListener(Event.MOUSE_DOWN, onMouseDown, rightButton)
    --rightButton:addEventListener(Event.MOUSE_UP, onMouseUp, rightButton)
     
    leftButton:addEventListener(Event.MOUSE_DOWN, onMouseDown, leftButton)
    --leftButton:addEventListener(Event.MOUSE_UP, onMouseUp, leftButton)
     
    end
     
     
    function onMouseDown(self, event)
    	if(self:hitTestPoint(event.x, event.y)) then
    		print(self.name)
    		if self.name == "leftButton" then
    			print("Left Press")
    		end
     
    		if self.name == "rightButton" then
    			print("Right Press")
    		end
    	end
    end
     
    addControls(0, 0)
    Now if I haven't managed to write a book yet, might I suggest you don't re-invent the wheel and use Gideros Studios create little button class. :)

    The example comes with Gideros Studio on how to use it and can be accessed by clicking on the Buttons option int he Examples box. It does what I changed your example to do and more as it supports up and down states automatically and you don't have to do the hitTestPointas it does it internally as well.

    Happy coding! :)

    Eli
    ThumbHurt Games / FB: ThumbHurt Games / FB: Eli/Teranth | Skype: teranth37
  • Good point @Teranth here it is:-
    textButton = function(txt, xp, yp)
    	-- txt is a textarea (ot any sprite really)
    	local newButton = Button.new(txt, txt)
    	newButton:setPosition(xp, yp)
    	return newButton
    end
  • Thanks for the codes guys, I looked at Gideros Button Class, I may use it in the future when I need the up/down states of buttons visually etc, but it still does not do what I expected. In this case scourers and your version of modified my code works fine, thanks for help :)
  • @twisttap not a problem, glad we could help :)
    ThumbHurt Games / FB: ThumbHurt Games / FB: Eli/Teranth | Skype: teranth37
Sign In or Register to comment.