Help with making a button

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
Midhun
Prole
Posts: 5
Joined: Sun Oct 06, 2024 1:33 pm

Help with making a button

Post by Midhun »

I have made a button using a image. I am not sure how to make it trigger an event when clicked on it. Pls help me.
User avatar
darkfrei
Party member
Posts: 1204
Joined: Sat Feb 08, 2020 11:09 pm

Re: Help with making a button

Post by darkfrei »

Simple version:
The button has top left corner in x, y and width, height w, h.
On the click check if the mouse position mx, my is inside the rectangle of button.

Code: Select all

if (mx > x) and (mx < x + w) and (my > y) and (my < y + h) then -- point is inside the box
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
Midhun
Prole
Posts: 5
Joined: Sun Oct 06, 2024 1:33 pm

Re: Help with making a button

Post by Midhun »

Do u mean that x and y is the position in top left of the button or the position of the button(midpoint of the button)???
Also how do we find the x and y of the top left corner of the button if yes to the first question.
By the way thank you so much for telling me how to do this.
User avatar
dusoft
Party member
Posts: 654
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: Help with making a button

Post by dusoft »

Midhun wrote: Sun Dec 01, 2024 12:58 pm Do u mean that x and y is the position in top left of the button or the position of the button(midpoint of the button)???
Also how do we find the x and y of the top left corner of the button if yes to the first question.
By the way thank you so much for telling me how to do this.
X and Y are known as you placed the button in question before, right?
Post your code.
RNavega
Party member
Posts: 385
Joined: Sun Aug 16, 2020 1:28 pm

Re: Help with making a button

Post by RNavega »

To add to what's being said,
Try the example at the bottom of this wiki page:
https://love2d.org/wiki/love.mousepressed

If you can later combine that with darkfrei's example (which shows how to test if the mouse coordinates are within a rectangular region on screen), then you can make a virtual button from that.
The rectangular region is described by the X and Y coordinates of its top-left corner, as well its width and height. Those (as well as the mouse coordinates) are all numbers, so you can compare them with each other to test if, say "the mouse X is bigger than this, but less than that", to know if the mouse is within a certain region on screen.
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: Help with making a button

Post by pgimeno »

darkfrei wrote: Fri Nov 29, 2024 11:21 am Simple version:
The button has top left corner in x, y and width, height w, h.
On the click check if the mouse position mx, my is inside the rectangle of button.

Code: Select all

if (mx > x) and (mx < x + w) and (my > y) and (my < y + h) then -- point is inside the box
This will be off by one pixel, though. Clicking exactly on the left or top border of the rectangle won't register the click; you need to be 1 pixel inside the left or top border for this to work.
User avatar
darkfrei
Party member
Posts: 1204
Joined: Sat Feb 08, 2020 11:09 pm

Re: Help with making a button

Post by darkfrei »

pgimeno wrote: Tue Dec 03, 2024 11:39 am This will be off by one pixel, though. Clicking exactly on the left or top border of the rectangle won't register the click; you need to be 1 pixel inside the left or top border for this to work.
Yes, the better solution needs more logic: array of buttons, highlight the hovered button, select not all hovered, but the top of them, dynamically adding/removing buttons, the texture, text, rounded corners etc.

But for the testing it will be enough, just remember that corner of button is not a button.
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: Help with making a button

Post by pgimeno »

I was just pointing in the direction that the check for the left and top corners should use >= instead of > to avoid that problem.
Midhun
Prole
Posts: 5
Joined: Sun Oct 06, 2024 1:33 pm

Re: Help with making a button

Post by Midhun »

pauseMenu = {}
pauseMenu.isVisible = false
MenuP = {}
require("music")
MenuP.PauseM = love.graphics.newImage('Sprites/ButtonsPaused/PauseMenu.png')
MenuP.PauseQ = love.graphics.newImage('Sprites/ButtonsPaused/PauseQuit.png')
MenuP.PauseR = love.graphics.newImage('Sprites/ButtonsPaused/PauseResume.png')
MenuP.PauseB = love.graphics.newImage('Sprites/ButtonsPaused/Pause.png')
WidthofR = MenuP.PauseR:getWidth()

function love.keypressed(key)
if key == "r" then
pauseMenu.isVisible = false
update()
end
if key == "escape" then
if pauseMenu.isVisible == false then
pauseMenu.isVisible = true
update2()
else
love.event.quit()
end
end
end

function myDraw()
if pauseMenu.isVisible == true then
love.graphics.translate(0, 0)
love.graphics.draw(MenuP.PauseM, love.graphics.getWidth()/2 - MenuP.PauseM:getWidth()/2*4, love.graphics.getHeight()/2 - MenuP.PauseM:getHeight()/2*4, nil, 4)
love.graphics.draw(MenuP.PauseQ, love.graphics.getWidth()/2 - MenuP.PauseQ:getWidth()/2*1.5, 700, nil, 1.5)
love.graphics.draw(MenuP.PauseR, love.graphics.getWidth()/2 - WidthofR/2*1.5, 400, nil, 1.5)
end
end

function love.mousepressed(x, y, button, istouch, presses)
if pauseMenu.isVisible == true then
if button == 1 then
if (x > love.graphics.getWidth()/2 - WidthofR/2) and (x < love.graphics.getWidth()/2 - WidthofR/2 + WidthofR) and (y > 400) and (y > 400 + MenuP.PauseR:getHeight()) then
pauseMenu.isVisible = false
end
end
end
end

function myDraw2()
if pauseMenu.isVisible == false then
love.graphics.draw(MenuP.PauseB, 1800, 50, nil, 1.1)
end
end

return myDraw, pauseMenu, myDraw2
RNavega
Party member
Posts: 385
Joined: Sun Aug 16, 2020 1:28 pm

Re: Help with making a button

Post by RNavega »

Hi. That's some good progress.
By the way, when posting code here in the forums, put all the code between the {code} {/code} tags (replace { } with [ ]) to preserve the indentation, it helps others when reading it.

If someone asked me to work on your code, I'd try making it more generic and use small functions to define what happens after each button gets clicked. I think this would be the button event that you were talking about in your first post.
Something like this:

Code: Select all

require("music")


local pauseMenu = {isVisible=true, header=nil, pauseButton=nil,
                   buttons=nil, startDrawY = 400}


function onPause()
    pauseMenu.isVisible = true
end


function onPauseResume()
    -- The code in here runs when the Pause->Resume menu is selected.
    pauseMenu.isVisible = false
end


function onPauseQuit()
    -- The code in here runs when the Pause->Quit menu is selected.
    love.event.quit()
end


function makeButton(filename, onClickFunc)
    local newButton = {image=nil, onClick=onClickFunc}
    newButton.image = love.graphics.newImage(filename)
    newButton.halfWidth  = menu.image:getWidth() / 2.0
    newButton.halfHeight = menu.image.getHeight() / 2.0
    return newButton
end


function getButtonY(index)
    return pauseMenu.startDrawY + (index - 1) * 300
end


function makeAllMenus()
    pauseMenu.header = love.graphics.newImage('Sprites/ButtonsPaused/PauseMenu.png')
    pauseMenu.pauseButton = makeButton('Sprites/ButtonsPaused/Pause.png', onPause)
    pauseMenu.buttons = {
        -- Resume.
        makeButton('Sprites/ButtonsPaused/PauseResume.png', onPauseResume),
        -- Other buttons.
        --makeButton('Sprites/ButtonsPaused/PauseSettings.png', onPauseSettings),
        -- Quit.
        makeButton('Sprites/ButtonsPaused/PauseQuit.png', onPauseQuit),
    }
end


function love.keypressed(key)
    if key == "r" then
        onPauseResume()
        update()
    end
    if key == "escape" then
        if pauseMenu.isVisible then
            love.event.quit()
        else
            onPause()
            update2()
        end
    end
end


function myDraw()
    if pauseMenu.isVisible == true then
        local hgw = love.graphics.getWidth() / 2.0
        local hgh = love.graphics.getHeight() / 2.0
        love.graphics.draw(pauseMenu.header,
                           hgw - pauseMenu.halfWidth * 4.0,
                           hgh - pauseMenu.halfHeight * 4,
                           nil, 4)
        for index = 1, #pauseMenu.buttons do
            local button = pauseMenu.buttons[index]
            love.graphics.draw(button.image,
                               -- X position.
                               hgw - button.halfWidth * 1.5,
                               -- Y position, changes by the button index.
                               getButtonY(index),
                               -- No rotation, and 1.5 horizontal scale.
                               nil, 1.5)
        end
    end
end


function love.mousepressed(x, y, button, istouch, presses)
    if pauseMenu.isVisible == true then
        if button == 1 then
            local hgw = love.graphics.getWidth() / 2.0
            local hgh = love.graphics.getHeight() / 2.0
            for index = 1, #pauseMenu.buttons do
                local button = pauseMenu.buttons[index]
                local leftX   = hgw - button.halfWidth * 1.5
                local topY    = getButtonY(index)
                local rightX  = leftX + button.halfWidth + button.halfWidth
                local bottomY = topY + button.halfHeight + button.halfHeight
                if x >= leftX and x < rightX and y >= topY and y < bottomY then
                    button.onClick()
                end
            end
        end
    end
end


function myDraw2()
    if pauseMenu.isVisible == false then
        love.graphics.draw(pauseMenu.pauseButton.image, 1800, 50, nil, 1.1)
    end
end


return myDraw, pauseMenu, myDraw2
Edit: if you're interested in learning more, read about "callback" functions:
- https://www.baeldung.com/cs/callbacks
- https://medium.com/@cortneythomas/what- ... 34a08605cb
Post Reply

Who is online

Users browsing this forum: Amazon [Bot], Google [Bot] and 11 guests