You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Love2D游戏开发:如何实现同一时间仅拖拽一个方块?

问题解决:拖拽单个方块避免同时拖动多个

问题描述

按下“A”键在鼠标位置生成方块,左键拖动方块时,若鼠标悬停到另一个方块上,两个方块会同时被拖动,视觉上其中一个像消失了。

问题根源

  1. 回调函数嵌套错误:将love.keypressed嵌套在squares.update中,导致每次update都会重新定义该函数,引发不可预期的行为。
  2. 无拖拽状态跟踪:循环检测所有方块,只要鼠标在方块上且左键按下就移动,导致多个方块同时响应拖拽。

解决方案

  • 移出嵌套的回调函数,正确使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 14:35:21