Need help with making surface of image clickable.

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.
fragileslime
Prole
Posts: 5
Joined: Wed Dec 02, 2020 9:23 am

Need help with making surface of image clickable.

Post by fragileslime » Wed Dec 02, 2020 9:31 am

Hi everyone, new to love2D and lua.
I'm trying to create a game menu but am having trouble with making the surface of a image clickable.

What is expected to happen:
Mouse clicks on image, function runs.

What is happening:
Mouse clicks anywhere, and function does not run but returns error.

Code: Select all

Error: main.lua:23: attempt to index local menubuttonimg' (a boolean value)
What am I doing wrong?

Source Code:

Code: Select all

-- Call Backs --
function love.load()
	x = 500
   	y = 400
	menuscreenimg = love.graphics.newImage("placeholdermenu.png")
	menubuttonimg = love.graphics.newImage("menubutton.png")
	--testimg = love.graphics.newImage("logomario.png")
	--love.graphics.setNewFont(12)
	--love.graphics.setColor(0,0,0)
	--love.graphics.setBackgroundColor(255,255,255)
	-- testing for image collision 
end
-- End of Call Backs -- 

-- Window Resolution --
success = love.window.setMode(1280, 720)
love.window.setTitle("Beta")

-- Mouse input for Menu Selection
function love.mousepressed(mx, my, button, menubuttonimg)
   if button == 1
   and mx >= x and mx < x + menubuttonimg:getWidth()
   and my >= y and my < y + menubuttonimg:getHeight()
   then print("IT WORKED!")
   end
end

-- Menu Screen --
function love.draw()
  love.graphics.draw(menuscreenimg) --1280, 720)
  love.graphics.print("BETA",600, 300)
  love.graphics.draw(menubuttonimg, 500, 400)
  love.graphics.print("Start!", 600, 425)
end

-- For finding mouse position --
--[[
function love.draw()
	mousey = love.mouse.getY()
	mousex = love.mouse.getX()
	love.graphics.print(mousex, mousey, 100, 100)
end
]]

User avatar
zorg
Party member
Posts: 3058
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Need help with making surface of image clickable.

Post by zorg » Wed Dec 02, 2020 10:10 am

Hi and welcome to the forums.

The code is mostly fine, but there's one issue that's glaring;
As by the wiki page, the mousepressed callback has this synopsis:

Code: Select all

love.mousepressed( x, y, button, istouch, presses )
You are shadowing your "menubuttonimg" variable by writing that as the 4th parameter in there, which is going to be false since you're not dealing with touch events, hence the error.

Leave that out of the function's parameter list, and it will work.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

fragileslime
Prole
Posts: 5
Joined: Wed Dec 02, 2020 9:23 am

Re: Need help with making surface of image clickable.

Post by fragileslime » Wed Dec 02, 2020 10:19 am

zorg wrote:
Wed Dec 02, 2020 10:10 am
Leave that out of the function's parameter list, and it will work.
Hi, thank you for the warm welcome and reply.
After removing the 4th parameter there is no error but when trying to click on the images surface it seems that the print function does nothing. I changed it from printing through the console and instead printing to the screen although it did not seem to make a difference.

User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Need help with making surface of image clickable.

Post by Nixola » Wed Dec 02, 2020 10:20 am

Printing to the screen during love.mousepressed will not do anything meaningful; the screen is cleared right before love.draw is called and drawn right after that, so anything happening to the screen in any other moment will be discarded. You would need to change the value of a variable or something similar, and have some code in love.draw reacting to that value change.
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics

fragileslime
Prole
Posts: 5
Joined: Wed Dec 02, 2020 9:23 am

Re: Need help with making surface of image clickable.

Post by fragileslime » Wed Dec 02, 2020 10:26 am

Nixola wrote:
Wed Dec 02, 2020 10:20 am
Printing to the screen during love.mousepressed will not do anything meaningful; the screen is cleared right before love.draw is called and drawn right after that, so anything happening to the screen in any other moment will be discarded. You would need to change the value of a variable or something similar, and have some code in love.draw reacting to that value change.
Thank you,
After changing the print function to a window close function it seems that everything is working.

I do feel however, the way I'm going about this is kinda sloopy.
Specially when it comes to placing text over the images. ( it is not perfectly aligned)
What would be the preferred way to deal with this whole front end button with images situation?

RNavega
Citizen
Posts: 60
Joined: Sun Aug 16, 2020 1:28 pm

Re: Need help with making surface of image clickable.

Post by RNavega » Wed Dec 02, 2020 9:22 pm

When I want to print some debug string or number, I use the console.
For this you need to create a conf.lua file with the 'console' attribute set to true, the opposite of this: https://github.com/RNavega/2DMeshAnimat ... onf.lua#L2

Then add a...

Code: Select all

io.setvbuf('no')
...at the start of your main.lua script, so that any print() calls immediately output to the console instead of being buffered.
Then you use Lua's print() function (note, it's not love.graphics.print() from LÖVE, it's just Lua's built-in print() ) with the variables that you want to print. Very helpful.

As for aligning text with images, you can find some theory and inspiration from web design:
https://levelup.gitconnected.com/the-cs ... e9bda94455

Treating your button image as a rectangle, how should the text be aligned to it? (You usually want it centered when it's a UI element.)
The formula for getting the coordinates for centered text on a rectangle can be:
textX = imageX + imageWidth/2 - textWidth/2 = imageX + (imageWidth - textWidth) / 2
(And the same for the Y axis, replacing X by Y and width by height).
You can find out the size of printable text using a love.graphics.Font object, it's the :getWidth() method (check the wiki).

fragileslime
Prole
Posts: 5
Joined: Wed Dec 02, 2020 9:23 am

Re: Need help with making surface of image clickable.

Post by fragileslime » Tue Dec 08, 2020 9:41 am

RNavega wrote:
Wed Dec 02, 2020 9:22 pm
Thank you so much!

Have run into a new issue with my code.
The player image does not seem to get drawn/show up.

main.lua

Code: Select all

-- Imports --
require "player"
require "map"
require "conf"

-- Call Backs --
function love.load()
function Player.load()
-- debug --
io.setvbuf('no')
--Player Movement --
function love.update(dt)
	if love.keyboard.isDown('d') then
		Player.x = Player.x + (Player.speed * dt)
			elseif love.keyboard.isDown('a') then
				Player.x = Player.x - (Player.speed * dt)
		    end
		end
	end
end
-- End of Call Backs -- 

-- Window Resolution --
success = love.window.setMode(1280, 720) -- 720p Resolution
love.window.setTitle("Beta") -- Window Title 

-- Menu Screen --
function love.draw()
	menu_screen_img = love.graphics.newImage("/resources/menu/menu.png")
	button_newgame = love.graphics.newImage("/resources/buttons/menubutton.png")
	love.graphics.draw(menu_screen_img) --1280, 720)
	love.graphics.print("BETA",600, 300)
  	love.graphics.draw(button_newgame, 500, 400)
	love.graphics.print("New Game", 600, 425)
end

-- Mouse input for Menu Selection --
x = 500 -- Width for Button "New Game"
y = 400 -- Heigth for Button "New Game"
function love.mousepressed(mx, my, button)
	if button == 1
	and mx >= x and mx < x + button_newgame:getWidth()
	and my >= y and my < y + button_newgame:getHeight()
	then NewGame()  
	end
end

-- New Game Function ==
function NewGame()
	Map1()
	player()
end
map.lua

Code: Select all

-- Map 1 --
function Map1()
	function love.draw()
		love.graphics.clear( )
		map1 = love.graphics.newImage("/resources/maps/map1/Map1.png")
		love.graphics.draw(map1)
	end
end
player.lua

Code: Select all

Player = {}
function player()
	function Player.load()
	function love.load()
		Player.x = 50
		Player.y = 50
		Player.speed = 200
		Player = love.graphics.newImage("/resources/player/spritetemp.png")
			function love.draw()
				love.graphics.draw(Player)
				love.graphics.scale(2, 2) -- Scale Player Sprite
			end
		end
	end
end

RNavega
Citizen
Posts: 60
Joined: Sun Aug 16, 2020 1:28 pm

Re: Need help with making surface of image clickable.

Post by RNavega » Tue Dec 08, 2020 9:50 am

For every 'function' definition there needs to be an 'end' to close it. So when you do something like this:

Code: Select all

-- Call Backs --
function love.load()
function Player.load()
-- debug --
io.setvbuf('no')
--Player Movement --
function love.update(dt)
	if love.keyboard.isDown('d') then
		Player.x = Player.x + (Player.speed * dt)
			elseif love.keyboard.isDown('a') then
				Player.x = Player.x - (Player.speed * dt)
		    end
		end
	end
end
The LuaJIT parser is going to think that love.load() is the top-level function, inside it there's a Player.load() function, and inside that there's a love.update(dt) function, so it interprets things like this:

Code: Select all

-- Call Backs --
function love.load()
    function Player.load()
        -- debug --
        io.setvbuf('no')
        --Player Movement --
        function love.update(dt)
            if love.keyboard.isDown('d') then
                Player.x = Player.x + (Player.speed * dt)
            elseif love.keyboard.isDown('a') then
                Player.x = Player.x - (Player.speed * dt)
            end
        end
    end
end
...which completely messes up with your intended flow. The LÖVE framework will only be able to 'see' your custom .load() callback, and not the .update() callback as it's inside the Player.load() function.

Where did you write this code? You should think of using Notepad++ or Notepad2, they add an indentation level when you hit Enter to go to the next line, so you can tell when you're starting a new block scope. I didn't manually go in and add the blank spaces to align everything in that second example, the code editor did that for me.
Last edited by RNavega on Tue Dec 08, 2020 9:56 am, edited 3 times in total.

RNavega
Citizen
Posts: 60
Joined: Sun Aug 16, 2020 1:28 pm

Re: Need help with making surface of image clickable.

Post by RNavega » Tue Dec 08, 2020 9:54 am

You can see the same mistake in your other files.
How about any time you write a "function somethingsomething()", go ahead and already add the "end" that will close it, just so you don't forget that anything between the name and the end will belong to the body of that function. Then start adding code to the body.

fragileslime
Prole
Posts: 5
Joined: Wed Dec 02, 2020 9:23 am

Re: Need help with making surface of image clickable.

Post by fragileslime » Tue Dec 08, 2020 11:00 am

Thank you for the info.
I've been using sublime for the IDE.

Post Reply

Who is online

Users browsing this forum: No registered users and 45 guests