Can't detect when mouse hovers over an object?

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
JacobFM
Prole
Posts: 5
Joined: Mon Jul 05, 2021 8:57 am

Can't detect when mouse hovers over an object?

Post by JacobFM »

Beginner question alert.
I can't seem to detect when the mouse hovers over a pawn.
I have a similar class called button that works the same way, and functions just fine.

The problematic code:

Code: Select all

Pawn = Class{}

pawns = {}
function pawns:init(x1, y1, x2, y2, x3, y3, type, controller, name, inplay)
    local newPawn = {
    x1 = x1,
    y1 = y1,
    x2 = x2,
    y2 = y2,
    x3 = x3,
    y3 = y3,
    controller = controller,
    type = type,
    inplay = inplay,
    place = "none",
    hot = false
    }
    table.insert(pawns, newPawn)
end

function pawns:update(dt)
    local mx, my = love.mouse.getPosition()
    for i,v in ipairs(pawns) do
        if mx > pawns[i].x1 and mx < pawns[i].x2 then
            if my > pawns[i].y1 and my < pawns[i].y3 then
                pawns[i].hot = true
                currentlyFocused = self
                print("a pawn is hot")
            else
                pawns[i].hot = false
            end
        else
            pawns[i].hot = false
        end
    end
end


function pawns:render()
    pawns:flash()

    for i,v in ipairs(pawns) do
        -- defining a table with the coordinates
        local vertices = {pawns[i].x1, pawns[i].y1, 
        pawns[i].x2, pawns[i].y2, pawns[i].x3, pawns[i].y3}

        if pawns[i].inplay == true then
            -- passing the table to the function as a second argument
            love.graphics.polygon('fill', vertices)
        end
    end
end

-- flash if hot function
function pawns:flash()
    for i,v in ipairs(pawns) do
        if pawns[i].hot == true then
            love.graphics.setColor(0.5, 1, 0.5, 1)
        else
            love.graphics.setColor(0, 0, 0, 1)
        end
    end
end
The working code:

Code: Select all

Button = Class{}

function Button:init(x, y, width, height, name, red, green, blue, action)
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.name = name
    self.red = red
    self.green = green
    self.blue = blue
    self.action = action
    self.hot = false
end

function Button:update(dt)
    local mx, my = love.mouse.getPosition()
    if mx > self.x and mx < self.x + self.width then
        if my > self.y and my < self.y + self.height then
            self.hot = true
            currentlyFocused = self
            print("a ui button is hot")
        else
            self.hot = false
        end
    else
        self.hot = false
    end
end

function Button:click()
    if self.hot == true then
        self.action()
    end
end

function Button:render()
    -- set rect color and print
    -- if hot then flash
    self:flash()
    love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)

    -- set text color and print
    love.graphics.setColor(1, 1, 1, 1)
    love.graphics.setFont(mainFont)
    love.graphics.printf(tostring(self.name), self.x, self.y, self.width, "center")
end

-- next turn function
function nextTurn()
    if pTurn == playerNum then
        pTurn = 1
    else
        pTurn = pTurn + 1
    end
end

-- flash if hot function
function Button:flash()
    if self.hot == true then
        love.graphics.setColor(self.red, 1, self.blue, 1)
    else
        love.graphics.setColor(self.red, self.green, self.blue, 1)
    end
end
User avatar
Gunroar:Cannon()
Party member
Posts: 1101
Joined: Thu Dec 10, 2020 1:57 am

Re: Can't detect when mouse hovers over an object?

Post by Gunroar:Cannon() »

y3? Should that be y2? Or is x2 maybe supposed to be x3?
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
User avatar
idbrii
Prole
Posts: 34
Joined: Sat Jun 12, 2021 5:07 am

Re: Can't detect when mouse hovers over an object?

Post by idbrii »

You could try refactoring your working code into a Hoverable class that you can use in both cases:

Code: Select all

Hoverable = Class{}

function Hoverable:init(x, y, width, height)
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.hot = false
end

function Hoverable:update(dt)
    local mx, my = love.mouse.getPosition()
    if mx > self.x and mx < self.x + self.width then
        if my > self.y and my < self.y + self.height then
            self.hot = true
            -- Instead of this single global, you could pass each hoverable a group
            -- key they can use to set themselves (currentlyFocused[self.group] = self).
            -- Then your buttons and pawns can be different groups where each
            -- can only have one hovered but both a button and pawn could be
            -- hovered.
            currentlyFocused = self
            print("a ui button is hot")
        else
            self.hot = false
        end
    else
        self.hot = false
    end
end


Button = Class{}

function Button:init(x, y, width, height, name, red, green, blue, action)
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.hover = Hoverable.new(x,y,width,height)
    self.name = name
    self.red = red
    self.green = green
    self.blue = blue
    self.action = action
end

function Button:click()
    if self.hover.hot == true then
        self.action()
    end
end

function Button:update(dt)
    self.hover:update(dt)
end

function Button:render()
    -- set rect color and print
    -- if hot then flash
    self:flash()
    love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)

    -- set text color and print
    love.graphics.setColor(1, 1, 1, 1)
    love.graphics.setFont(mainFont)
    love.graphics.printf(tostring(self.name), self.x, self.y, self.width, "center")
end

-- next turn function
function nextTurn()
    if pTurn == playerNum then
        pTurn = 1
    else
        pTurn = pTurn + 1
    end
end

-- flash if hot function
function Button:flash()
    if self.hover.hot == true then
        love.graphics.setColor(self.red, 1, self.blue, 1)
    else
        love.graphics.setColor(self.red, self.green, self.blue, 1)
    end
end
(Entirely untested.)

Then your Pawn can have one of those hoverables too.
JacobFM
Prole
Posts: 5
Joined: Mon Jul 05, 2021 8:57 am

Re: Can't detect when mouse hovers over an object?

Post by JacobFM »

Gunroar:Cannon() wrote: Tue Jul 06, 2021 9:17 pm y3? Should that be y2? Or is x2 maybe supposed to be x3?
No, I think that's correct as it is. An example of one of the pawns initialized:

Code: Select all

pawns:init(1000, 70, 1030, 70, 1015, 35, don, "player" .. tostring(pTurn), "don", true)
Although I did realize that my y1 and y3 were out of order, but fixing that did not fix the issue.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Can't detect when mouse hovers over an object?

Post by ReFreezed »

One issue is the relation between pawns:render() and pawns:flash(). The flash function goes through all pawns and updates the current color with love.graphics.setColor() for every pawn, but the outcome of the function is that the current color will depend on the last pawn. So after the render function has called flash() the current color will depend on whether the *last* pawn was "hot" or not, and then you draw all polygons (which will have the same color). You'll need to call setColor() right before drawing each separate polygon.

Edit: Also, about the coordinates. You may want to remove the assumption that x1/x2/x3 are in a certain order.

Code: Select all

-- Maybe change this
if mx > pawns[i].x1
-- into this
if mx > math.min(pawns[i].x1, pawns[i].x2, pawns[i].x3)
-- etc.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
JacobFM
Prole
Posts: 5
Joined: Mon Jul 05, 2021 8:57 am

Re: Can't detect when mouse hovers over an object?

Post by JacobFM »

I'm a moron, I just wasn't calling the function. Thanks everyone for your help anyway!
User avatar
Gunroar:Cannon()
Party member
Posts: 1101
Joined: Thu Dec 10, 2020 1:57 am

Re: Can't detect when mouse hovers over an object?

Post by Gunroar:Cannon() »

:o :o :o :o :| :rofl: :ultrahappy:
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 1 guest