Search code examples
lua2d-gameslove2d

How can I make it so that only one of the draggable objects in my game can be moved at a time?


So I'm trying to make it so that when I press "a" a square gets created on the cursor's position, and I can drag these squares around with left mouse button. The problem is that when I'm dragging a square and hover over a different one, they are both being dragged making it look like one square disappears.

here's how that looks: the game

Here's the code:

fs = require ("fs")
squares = {}

function squares.update (dt)

  mousex = love.mouse.getX()
  mousey = love.mouse.getY()
  --add a square on the tile where the cursor is when pressing "a"
  function love.keypressed(key)
    if key == "a" then
      local object = {
        defaultposx = fs.roundednumber(mousex),
        defaultposy = fs.roundednumber(mousey),
        width = 20,
        height = 20,
        drag = 0
      }
      table.insert(squares, object)
    end
  end
  
  --if hoverig over a square and pressing lmb make the square follow the cursor until lmb released 
  for i = #squares, 1, -1 do

    local object = squares[i]

    if (fs.hoveringOver(object.defaultposx, object.defaultposy, object.width, object.height)
    and love.mouse.isDown(1)) then
      --follow cursor
      object.width = 20
      object.height = 20
      object.defaultposx = mousex - 8
      object.defaultposy = mousey - 8
    elseif not love.mouse.isDown(1) then
      --snap to grid    
      object.defaultposx = fs.roundednumber(object.defaultposx + 10)
      object.defaultposy = fs.roundednumber(object.defaultposy + 10)
      object.width = 20
      object.height = 20
    end 

  end
end



function squares.draw () 
  -- draw the squares
  for i = #squares, 1, -1 do
    local object = squares[i]
      
    love.graphics.setColor(1, 0, 0, 1)
    love.graphics.rectangle("line", object.defaultposx , object.defaultposy , object.width, object.height)
    love.graphics.setColor(1, 1, 1, 1)
    love.graphics.rectangle("fill", object.defaultposx , object.defaultposy , object.width, object.height)    
  end
     
end


The fs.lua file which is used here looks like this:


local fs = {}

--function that just rounds a number down to the nearest multiple of 20
function fs.roundednumber(a)
    b = math.floor(a / 20) * 20
    return(b)
end
--[[
function that checks if the mouse cursor is in a square defined by the position and dimensions of an object
--]]
function fs.hoveringOver(x, y, w, h)
    if (love.mouse.getX()  > x
    and love.mouse.getX() < x + w
    and love.mouse.getY()  > y
    and love.mouse.getY() < y + h) then
      return true
    else
      return false
    end  
end



return fs

I've tried making a function that assigns either 0 or 1 to the drag attribute of an object depending on if is' being dragged and using it as an argument to the if statement that makes a square follow the cursor. Did not work at all.

I've been trying different things and i could not get it to work. The squares either couldn't be dragged at all, or they were all dragged at once whenever i tried to drag one of them.

I've now gone bald from scratching my head over this for like four days.


Solution

  • Instead of looping thru all objects in update, use mousepressed to find the object which was pressed and store its index, then in mousemoved move the object based on its index to new mouse position and finally use mousereleased to snap object to grid, place it and reset stored index, so no square is moved.

    The reason why your implementation is not working is that while mouse is pressed, you move all objects under mouse, not only the one you are hovering.