Page 1 of 1

Help with making a button

Posted: Fri Nov 29, 2024 9:49 am
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.

Re: Help with making a button

Posted: Fri Nov 29, 2024 11:21 am
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

Re: Help with making a button

Posted: Sun Dec 01, 2024 12:58 pm
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.

Re: Help with making a button

Posted: Sun Dec 01, 2024 1:23 pm
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.

Re: Help with making a button

Posted: Mon Dec 02, 2024 10:33 pm
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.

Re: Help with making a button

Posted: Tue Dec 03, 2024 11:39 am
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.

Re: Help with making a button

Posted: Tue Dec 03, 2024 3:40 pm
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.

Re: Help with making a button

Posted: Tue Dec 03, 2024 5:43 pm
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.

Re: Help with making a button

Posted: Sun Dec 08, 2024 9:38 am
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

Re: Help with making a button

Posted: Mon Dec 09, 2024 11:34 am
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