Love2D游戏开发:如何实现同一时间仅拖拽一个方块?
问题解决:拖拽单个方块避免同时拖动多个
问题描述
按下“A”键在鼠标位置生成方块,左键拖动方块时,若鼠标悬停到另一个方块上,两个方块会同时被拖动,视觉上其中一个像消失了。
问题根源
- 回调函数嵌套错误:将
love.keypressed嵌套在squares.update中,导致每次update都会重新定义该函数,引发不可预期的行为。 - 无拖拽状态跟踪:循环检测所有方块,只要鼠标在方块上且左键按下就移动,导致多个方块同时响应拖拽。
解决方案
- 移出嵌套的回调函数,正确使用Love2D的事件回调。
- 添加
currentDrag变量跟踪当前被拖拽的方块,仅处理该方块的移动逻辑。 - 在鼠标按下时选中目标方块,释放时取消拖拽并对齐网格。
修改后的主代码
fs = require("fs") squares = {} currentDrag = nil -- 跟踪当前被拖拽的方块 -- 移出嵌套的keypressed回调 function love.keypressed(key) if key == "a" then local mousex = love.mouse.getX() local mousey = love.mouse.getY() local object = { defaultposx = fs.roundednumber(mousex), defaultposy = fs.roundednumber(mousey), width = 20, height = 20 } table.insert(squares, object) end end -- 鼠标按下时选中要拖拽的方块 function love.mousepressed(x, y, button) if button == 1 then -- 从后往前遍历,确保选中最上层的方块 for i = #squares, 1, -1 do local obj = squares[i] if fs.hoveringOver(obj.defaultposx, obj.defaultposy, obj.width, obj.height) then currentDrag = obj -- 记录鼠标相对于方块的偏移,避免瞬移 currentDrag.offsetX = x - obj.defaultposx currentDrag.offsetY = y - obj.defaultposy break -- 找到第一个(最上层)的方块后停止遍历 end end end end -- 鼠标释放时取消拖拽并对齐网格 function love.mousereleased(x, y, button) if button == 1 and currentDrag then -- 对齐到20倍数的网格 currentDrag.defaultposx = fs.roundednumber(currentDrag.defaultposx) currentDrag.defaultposy = fs.roundednumber(currentDrag.defaultposy) currentDrag = nil end end function squares.update(dt) local mousex = love.mouse.getX() local mousey = love.mouse.getY() -- 仅处理当前被拖拽的方块 if currentDrag then currentDrag.defaultposx = mousex - currentDrag.offsetX currentDrag.defaultposy = mousey - currentDrag.offsetY end end function squares.draw() -- 绘制所有方块 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
fs.lua代码(无需修改)
local fs = {} -- 向下取整到最近的20的倍数 function fs.roundednumber(a) local b = math.floor(a / 20) * 20 return b end -- 检测鼠标是否悬停在方块上 function fs.hoveringOver(x, y, w, h) local mx = love.mouse.getX() local my = love.mouse.getY() return mx > x and mx < x + w and my > y and my < y + h end return fs
关键改进点
- 回调函数正确放置:将
love.keypressed、love.mousepressed、love.mousereleased作为独立回调,符合Love2D的运行机制。 - 精准拖拽跟踪:用
currentDrag锁定单个拖拽目标,从后往前遍历确保选中最上层方块。 - 偏移量记录:记录鼠标点击时相对于方块的偏移,避免拖拽时方块瞬移到鼠标位置,提升交互体验。
内容的提问来源于stack exchange,提问作者Krzysztof5
相关产品推荐
相关产品推荐

