如何在Love2d中拖放特定对象?

时间:2016-07-25 04:22:33

标签: lua drag-and-drop love2d

我是Lua的新手和一般编码所以我决定写一个国际象棋程序来学习。我已经设置了一个类并从中创建了对象来表示它们。现在我想用鼠标开始移动碎片。我查看了一个教程,但它只处理了一个矩形。我的第一个是使用" for#34;在love.mousePressed()函数中循环遍历每个对象,直到找到具有匹配的x,y坐标的对象。这显然不像我做的那样有效。相反,它只在每次按下鼠标时进入下一个对象,或者至少在按钮被释放后程序没有立即崩溃的情况下。所以我的问题是,正确的方法是什么?

local blackPawn = love.graphics.newImage("Textures/Blackpawn.png")
local blackRook = love.graphics.newImage("Textures/Blackrook.png")
local blackKnight = love.graphics.newImage("Textures/Blackknight.png")
local blackBishop = love.graphics.newImage("Textures/Blackbishop.png")
local blackQueen = love.graphics.newImage("Textures/Blackqueen.png")
local blackKing = love.graphics.newImage("Textures/BlackKing.png")
local whitePawn = love.graphics.newImage("Textures/Whitepawn.png")
local whiteRook = love.graphics.newImage("Textures/Whiterook.png")
local whiteKnight = love.graphics.newImage("Textures/Whiteknight.png")
local whiteBishop = love.graphics.newImage("Textures/Whitebishop.png")
local whiteQueen = love.graphics.newImage("Textures/Whitequeen.png")
local whiteKing = love.graphics.newImage("Textures/WhiteKing.png")
local chessboard = love.graphics.newImage("Textures/ChessBoard.png")

local register = {}

local id = 0

piece = {
    xSquare = 0, ySquare = 0,
    x = 0, y = 0,
    height = 64, width = 64,

    pawn = false,
    Rook = false,
    Knight = false,
    Bishop = false,
    Queen = false,
    King = false,
    color = "",
    texture = whitePawn,

    dragging = {active = false, diffx = 0, diffy = 0}
}

function piece.new()
    newPiece = {}
    for k, v in pairs(piece) do
        newPiece[k] = v
    end
    return newPiece
end

function piece:draw()

end

function getMouse()
    local x, y = love.mouse.getPosition()
    local isDown = love.mouse.isDown(1,2)
        return x, y, isDown
end

function createBoard(id)
    for x = 1, 8 do
        for y = 1, 8 do
            if y ~= 3 and y ~= 4 and y ~=5 and y ~= 6 then
                id = id + 1
                    register[id] = piece.new()
                    register[id].x = x * 64 - 48
                    register[id].y = (y - 1) * 64
                if y == 2 then
                    register[id].pawn = true
                    register[id].color = "white"
                    register[id].texture = whitePawn
                    print("item " .. id .. " is here x = " .. register[id].x  ..  " y = " .. register[id].y .. " Is pawn = " .. tostring(register[id].pawn) ..
                    " Color is " .. register[id].color)
                elseif y == 7 then
                    register[id].pawn = true
                    register[id].color = "black"
                    register[id].texture = blackPawn 
                    print("item " .. id .. " is here x = " .. register[id].x  ..  " y = " .. register[id].y .. " Is pawn = " .. tostring(register[id].pawn) ..
                    " Color is " .. register[id].color) 
                elseif y == 1 then 
                    register[id].color = "white"
                    if x == 1 or x == 8 then 
                        register[id].Rook = true
                        register[id].texture = whiteRook
                    elseif x == 2 or x == 7 then 
                        register[id].Knight = true
                        register[id].texture = whiteKnight
                        print("knight is here")
                    elseif x == 3 or x == 6 then
                        register[id].Bishop = true
                        register[id].texture = whiteBishop
                    elseif x == 5 then
                        register[id].King = true
                        register[id].texture = whiteKing
                    elseif x == 4 then
                        register[id].Queen = true
                        register[id].texture = whiteQueen
                    end
                elseif y == 8 then 
                    register[id].color = "black"
                    if x == 1 or x == 8 then 
                        register[id].Rook = true
                        register[id].texture = blackRook
                    elseif x == 2 or x == 7 then 
                        register[id].Knight = true
                        register[id].texture = blackKnight
                    elseif x == 3 or x == 6 then
                        register[id].Bishop = true
                        register[id].texture = blackBishop
                    elseif x == 5 then
                        register[id].King = true
                        register[id].texture = blackKing
                    elseif x == 4 then
                        register[id].Queen = true
                        register[id].texture = blackQueen
                    end
                end
            end
        end
    end
end

function drawBoard(id, register)
    love.graphics.draw(chessboard, 0, 0)
    for id = 1, 32 do
        love.graphics.draw(register[id].texture, register[id].x, register[id].y)
    end
end

function love.load()
    createBoard(id)
end

function love.update(dt)
    for id = 1, 32 do 
        if register[id].dragging.active == true then
            register[id].x = love.mouse.getX() - register[id].dragging.diffx
            register[id].y = love.mouse.getY() - register[id].dragging.diffy
        end
    end
end

function love.draw()
    drawBoard(id, register)
end

function love.mousepressed(x, y, button)
    for id = 1, 32 do
        if (button  == 1 or button == 2)
        and x > register[id].x and x < register[id].x + register[id].width
        and y > register[id].y and y < register[id].y + register[id].height 
        then
            register[id].dragging.active = true
            register[id].dragging.diffx = x - register[id].x
            register[id].dragging.diffy = y - register[id].y
        end
    end
end

function love.mousereleased(x, y, button)
    for id = 1, 32 do 
        if button == 1 or button == 2 then register[id].dragging.active = false end
    end
end

function love.keypressed(key, unicode)
end

function love.keyreleased(key)

end

function love.focus(bool)

end

function love.quit()
end

更新: 我修复了崩溃,但我仍然有一个奇怪的错误,它将拖动的部分更改为另一个部分

更新2:经过多一点调试后,我发现主要问题是它由于某种原因没能正确检查拖动是否处于活动状态。由于代码现在我需要else dragging.active = false之后才能正确设置它,但现在它已正确设置它不会拖动任何东西,尽管正确的对象已将拖动设置为活动(除非我尝试并拖动值为32的对象,一次拖动所有内容)。对于什么是错误我很困惑。为什么Lua不能像这样检查价值?

1 个答案:

答案 0 :(得分:0)

首先,我创建一个全局布尔值,用于是否已选择一个片段,然后是一个变量来保存所选片段

local selected = false
local selectedPiece = {}

然后创建一个游戏板并将其拆分成网格,每个方块的大小相等。像这样的东西

board = {
    size = { 8, 8 }, -- 8x8 grid
    squareSize = 40, -- 40 pixels long sides
    pieces = {
        {   -- First row contains which pieces?
            Piece:Rook(),
            Piece:Bishop(),
            ...
        },

        {   -- Second row
            Piece:Pawn(),
            ...
        },

        {   -- etc.
            Piece:Empty(),
            ...
        }
    }
}

由于带有nil索引的表的奇怪行为,我建议不要在表中使用nil作为空方块。

love.mousepressed()方法中,您可以检查点击位于其位置的位置(假设主板占据了整个窗口)

function love.mousepressed(x, y, btn)
    -- If a piece hasn't been clicked on.
    if (not selected) then
        -- This line is assuming that since all board squares are equal size, then the mouse click has to be in at least one square.
        -- Therefore, if we take the floor of the position/board.squareSize, we will always get a value from 0 - 7 (8 values) on the board.
        local piece = board.pieces[math.floor(x/board.squareSize)][math.floor(y/board.squareSize)]

        -- If there is a piece here.
        if (piece:isNotAnEmpty()) then
            selectedPiece = piece -- Select the piece.
            selected = not selected -- Notify program that a piece is selected to handle such things accordingly in other methods.
        end
    else
        -- Assuming you wrote a method that determines if a piece can be moved to a certain spot on the board.
        if (board:CanMovePieceHere(selectedPiece, x/board.size, y/board.size)) then
            -- Do your stuff here.
            ...

            -- Eventually, reset your variables.
            selected = not selected
            selectedPiece = {}
        end
    end
end

这就是我接近它的方法,但你的问题很容易解释。