Selecting and moving a singular object contained in a list

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
interested_party
Prole
Posts: 3
Joined: Sun Mar 30, 2025 5:00 am

Selecting and moving a singular object contained in a list

Post by interested_party »

I'm a very new love2d/lua user. I have been tinkering around with it the past day, trying to figure out some basics. I've watched a couple tutorials as well, but I learn best by doing and really understanding exactly what is happening in my code. I've been tinkering with simple card game mechanics (deal cards from a deck, selecting and moving a card with the mouse). I've run into an issue with moving specific cards when multiple cards have been dealt. Here is my code for the Cards and the main.lua code.
local

Code: Select all

love = require("love")

function Card()
    return {
        length = 100,
        width = 60,
        x = 200,
        y = 880,
        title = "",
        selected = false,

        move = function(self, player_x, player_y, ismouse_down)

            if self.x <= player_x and player_x <= self.x + 60 and self.y <= player_y and player_y <= self.y + 100 then
                if ismouse_down then
                    self.selected = true
                end
            end
            if not ismouse_down then
                self.selected = false
            end 
            if self.selected then
                self.x = player_x - 30
                self.y = player_y - 50
            end
        end,

        draw = function (self)
            love.graphics.setColor(1, 1, 1)

            love.graphics.rectangle("fill", self.x, self.y, self.width, self.length)

            love.graphics.setColor(1,1,1)
        end
    }
end

return Card

Code: Select all

_G.love = require("love")
local card = require("Card")

local game = {
    state = {
        menu = false,
        paused = false,
        running = true,
        ended = false,
    }
}

local player = {
    x = 30,
    y = 30
}
local cards = {}

local dealButton = {
    length = 70,
    width = 120,
    x = 1740,
    y = 500,

    draw = function (self)
        love.graphics.setColor(1, 1, 1)
        love.graphics.rectangle("fill", self.x, self.y, self.width, self.length)
        love.graphics.setColor(1, 1, 1)
    end
}

function love.mousepressed(x, y)
    if dealButton.x <= x and x <= dealButton.x + 120 and dealButton.y <= y and y <= dealButton.y + 70 then
        table.insert(cards, #cards + 1, card())
        for i = 2, #cards do
            cards[i].x = i * 80
        end
    end
end

function love.load()
    love.graphics.setBackgroundColor(0.5,0.5,0.3)
    love.mouse.setVisible(true)

end

function love.update(dt)
    player.x, player.y = love.mouse.getPosition()
    local mouseDown = love.mouse.isDown(1)

    for i = 1, #cards do
        cards[i]:move(player.x, player.y, mouseDown)
    end
end

function love.draw()
    love.graphics.printf("FPS: " .. love.timer.getFPS(), love.graphics.newFont(12), 10, 20, love.graphics.getWidth())
    love.graphics.printf("Number of Cards: ".. #cards, love.graphics.newFont(12), 10, 50, love.graphics.getWidth())
    if game.state["running"] then
        dealButton:draw()
        for i = 1, #cards do
            cards[i]:draw()
        end
    end
    

end
What is happening is that when multiple cards have been dealt on to the board, I can select one and move it, but the others disappear only to reappear when the deal card button is pressed. The other cards reappear in positions that are definitely related to the move() function, but in a manner that is making it difficult for me to discern the reason. My thought process was that because I am passing the (self) into the move() function, it should only move the card that the mouse is positioned on. Obviously I am inexperienced and this is the most simple issue ever, but I feel like if I can understand why this is happening it will help me understand things in a much broader way.

Thanks for any help in advance and apologies for such a simple issue.
kordaff
Prole
Posts: 1
Joined: Mon Mar 10, 2025 8:46 pm

Re: Selecting and moving a singular object contained in a list

Post by kordaff »

Everytime the mouse moves over a card with the mouse button down, it picks it up and moves it. If you run over all the cards, all of them move. When you click the deal button, the x positions all (or all but [1]) get reset, displaying them again. You may need a flag to be set when it detects the first card to be moved and only unset the flag when the mouse button is no longer down.
Ross
Party member
Posts: 102
Joined: Tue Mar 13, 2018 12:12 pm
Contact:

Re: Selecting and moving a singular object contained in a list

Post by Ross »

You are calling move() on every card, every frame. Inside that move function, you're checking for mouse collision with the current card and moving it to the mouse cursor if the mouse button is down while the cursor is over the card. You don't have anything in your code to ensure that only one card is dragged at once. :) So you can click and hold anywhere on the screen and drag over any number of cards to collect them all at the mouse cursor position.

When you add a new card, you set the X positions of all cards (except the first for some reason) to be spaced out, so they generally become visible again instead of being all stacked in the same place.
interested_party
Prole
Posts: 3
Joined: Sun Mar 30, 2025 5:00 am

Re: Selecting and moving a singular object contained in a list

Post by interested_party »

Thanks so much! I added a boolean for if the mouse was over a card and a seperate for if the mouse button is down. and only changed positions if both were true. I have to fix the dealing position issues still but I understand the issues there! Here's the new move() code:

Code: Select all

function Card()
    return {
        length = 100,
        width = 60,
        x = 200,
        y = 880,
        title = "",
        selected = false,
        hovered = false,

        move = function(self, player_x, player_y, ismouse_down)

            if self.x <= player_x and player_x <= self.x + 60 and self.y <= player_y and player_y <= self.y + 100 then
                self.hovered = true
            else
                self.hovered = false
            end
            if ismouse_down then
                self.selected = true
            else
                self.selected = false
            end 
            if self.selected and self.hovered then
                self.x = player_x - 30
                self.y = player_y - 50
            end
        end,
        
This helped a ton!
interested_party
Prole
Posts: 3
Joined: Sun Mar 30, 2025 5:00 am

Re: Selecting and moving a singular object contained in a list

Post by interested_party »

Update: had an issue where if you moved too fast the mouse would escape the card boundaries and the card would stop following the mouse. Changed it to where love.mousepressed() and love.mousereleased() are call in the main.lua file and change a boolean in the according card. this means that once a card is selected it stays with your mouse until you release. Would not have figured any of this out without you guys' help. Here's the new code.

Code: Select all

function love.mousepressed(x, y)
    if dealButton.x <= x and x <= dealButton.x + 120 and dealButton.y <= y and y <= dealButton.y + 70 then
        table.insert(cards, #cards + 1, card())
        for i = 2, #cards do
            cards[i].x = cards[i-1].x + 80
        end
    end
    for i = 1, #cards do
        if cards[i].x <= x and x <= cards[i].x + 60 and cards[i].y <= y and y <= cards[i].y + 100 then
            cards[i].selected = true
        end
    end
end

function love.mousereleased(x, y)
    for i = 1, #cards do
        cards[i].selected = false
    end
end

Code: Select all

function Card()
    return {
        length = 100,
        width = 60,
        x = 200,
        y = 880,
        title = "",
        selected = false,

        move = function(self, player_x, player_y)
            if self.selected then
                self.x = player_x - 30
                self.y = player_y - 50
            end
        end
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 7 guests