How do I use a functions as parameter

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
OdnsRvns
Prole
Posts: 16
Joined: Sun Sep 14, 2014 6:43 pm

How do I use a functions as parameter

Post by OdnsRvns »

I'm trying to make a simple gui system for my game. And wanted to use something like this to draw an image in love.draw and call the function when clicked.

Code: Select all

function thm_imgbtn(x, y, sx, sy, img, hmg, func)
	
	-- Local Vars
	local mouseover
	local imgw = img:getWidth() * sx -- Button Image
	local hmgw = hmg:getWidth() * sx
	local imgh = img:getHeight() * sy --Hover Image
	local hmgh = hmg.getHeight() * sy
	
	-- Checks if Mouse is over button
	if sys.mx > x and sys.mx < (x + imgw) and sys.my > y and sys.my < (y + imgh) then 
		mouseover = true
	else 
		mouseover = false
	end
	
	-- Draw Button
	if mouseover == false then  
		LGR.setColor(255,255,255)
		LGR.draw(img, x, y, 0, sx, sy)
	else 
		LGR.setColor(255,255,1)
		LGR.draw(hmg, x, y, 0, sx, sy)
	end
	
	-- When mouse 1 is released call func
	--???
end
I can put the function in the parameter but it just runs over and over each draw call. How can I declare it at the start and only call it when the mouse is released or clicked.
KayleMaster
Party member
Posts: 234
Joined: Mon Aug 29, 2016 8:51 am

Re: How do I use a functions as parameter

Post by KayleMaster »

You should structure you code differently so you can use love.mousereleased callback, but a hacky solution for this is:

Code: Select all

if love.mouse.isDown(1) then
	func()
end
To do it somewhat properly you would have love.mousereleased somewhere calling this:

Code: Select all

function love.draw()
   --at the end of love.draw()
   mouse_has_been_released = false
end
 
function love.mousereleased(x, y, button)
   if button == 1 then
      mouse_has_been_released = true
   end
end

function thm_imgbtn(x, y, sx, sy, img, hmg, func)
	
	-- Local Vars
	local mouseover
	local imgw = img:getWidth() * sx -- Button Image
	local hmgw = hmg:getWidth() * sx
	local imgh = img:getHeight() * sy --Hover Image
	local hmgh = hmg.getHeight() * sy
	
	-- Checks if Mouse is over button
	if sys.mx > x and sys.mx < (x + imgw) and sys.my > y and sys.my < (y + imgh) then 
		mouseover = true
	else 
		mouseover = false
	end
	
	-- Draw Button
	if mouseover == false then  
		LGR.setColor(255,255,255)
		LGR.draw(img, x, y, 0, sx, sy)
	else 
		LGR.setColor(255,255,1)
		LGR.draw(hmg, x, y, 0, sx, sy)
	end
	
        if mouse_has_been_released and mouseover then func() end
end
But ideally you should use x,y in mousereleased to identify on which button it has been pressed.
This basically sets a global flag for this step and removes it at the end of the step (or at least, it should).

EDIT: make sure you're passing the function, and not it's result

Code: Select all

thm_imgbtn(x, y, sx, sy, img, hmg, func)
instead of

Code: Select all

thm_imgbtn(x, y, sx, sy, img, hmg, func())
User avatar
OdnsRvns
Prole
Posts: 16
Joined: Sun Sep 14, 2014 6:43 pm

Re: How do I use a functions as parameter

Post by OdnsRvns »

Yep as soon as you said the () i knew where I messed up. Should have caught that. That said for those of you wanting to know how I got this super simple image button hack method to work. Here is how I have my code laid out as of right now. Hope it helps someone out.

Step 1: A function to check to see if Mouse1 has been pressed and released.

Code: Select all

function love.mousereleased(x, y, button)
	if button == 1 then
		print("mb1 released")
		sys.mb1 = 1
	end
end


Step 2: A function to create image buttons that can run a function when clicked.

Code: Select all

function thm_imgbtn(x, y, sx, sy, img, hmg, func)
	
	-- Local Vars
	local mouseover
	local imgw = img:getWidth( ) * sx -- Button Image (make sure they are the same size image)
	local hmgw = hmg:getWidth( ) * sx -- Hover Image (make sure they are the same size image)
	local imgh = img:getHeight( ) * sy 
	local hmgh = hmg:getHeight( ) * sy 
	local btnstate
	
	-- Checks if Mouse is over button sys.mx and sys.my are my global mouse x and y variables
	if sys.mx > x and sys.mx < (x + imgw) and sys.my > y and sys.my < (y + imgh) then 
		mouseover = true
	else 
		mouseover = false
	end
	
	-- Draw Button
	if mouseover == false then  
		LGR.setColor(255,255,255)
		LGR.draw(img, x, y, 0, sx, sy)
	else 
		LGR.setColor(255,255,0)
		LGR.draw(hmg, x, y, 0, sx, sy)
		if sys.mb1 == 1 then 
			func()
			btnstate = 1
		end
	end
	
	--resets the mouse button released variable 
	if sys.mb1 == 1 and btnstate == 1 then sys.mb1 = 0 end

end
Step 3:A simple test function to check that its working

Code: Select all

function thm_btnclicked()
	 print("Clicked the button!")
end
Step 4: Resetting the Mouse1 button variable back to nil for use in the next click. Place this at the end of the love.draw().

Code: Select all

function sys_cleanup()
	sys.mb1 = nil -- resets Mouse Button 1 to Nil after being pressed. 
end
Step 5: Whenever I need to Draw a button using the function from above. Super Simple Buttons that run a function when clicked.

Code: Select all

thm_imgbtn(10, 10, 1, 1, buttonimg, hoverimage, thm_btnclicked)

Any thoughts on my code or improvements I'd love to hear. Still quite a novice in Lua/Love2d.
KayleMaster
Party member
Posts: 234
Joined: Mon Aug 29, 2016 8:51 am

Re: How do I use a functions as parameter

Post by KayleMaster »

It could be shortened to this, but it's less readable now.

Code: Select all

function thm_imgbtn(x, y, sx, sy, img, hmg, func)
	
	-- Local Vars
	local imgw = img:getWidth( ) * sx -- Button Image (make sure they are the same size image)
	local hmgw = hmg:getWidth( ) * sx -- Hover Image (make sure they are the same size image)
	local imgh = img:getHeight( ) * sy 
	local hmgh = hmg:getHeight( ) * sy 
	
	-- Checks if Mouse is over button sys.mx and sys.my are my global mouse x and y variables
	if sys.mx > x and sys.mx < (x + imgw) and sys.my > y and sys.my < (y + imgh) then 
		LGR.setColor(255,255,0)
		LGR.draw(hmg, x, y, 0, sx, sy)
		if sys.mb1 == 1 then 
			func()
			sys.mb1 = 0
		end
	else 
		LGR.setColor(255,255,255)
		LGR.draw(img, x, y, 0, sx, sy)
	end
	
end
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 85 guests