RussKh
RussKh

Reputation: 1

Love2d / LUA grid locked movement NO DIAGONAL

I thought this would be a common problem but after days of research I can't find a solution. Very new to programming in general and LUA specifically. I'm building a SUPAPLEX clone as a CS50 personal project: the character moves along the grid based map and there's a code that everyone seems to suggest (attached). On release of arrow buttons the movement is continued until the end of a tile, smoothly. But if 2 movement buttons are pushed, it causes brief diagonal movement and that's the problem I'm unsuccessfully trying to solve.

Basically I'm trying to either ignore any input until the movement of the sprite is finished at the end of the grid tile or prevent updating until movement in one direction is complete. Seems like a simple thing but I'm about to give up this whole thing. Frustrating. Any input is hiiiighly appreciated and I'm sure this would be a lot of help for very many people...

function love.load()

    love.keyboard.setKeyRepeat(true)

    player = {
        grid_x = 256,
        grid_y = 256,
        act_x = 256,
        act_y = 256,
        speed = 5,
    }

    map = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
        { 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
        { 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1 },
        { 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
    }

    
    function testMap(x, y)
        if map[(player.grid_y / 32) + y][(player.grid_x / 32) + x] == 1 then
            return false
        end
        return true
    end


    function love.keypressed(key)
        if key == "up" then
            player.grid_y = player.grid_y - 32
        elseif key == "down" then
            player.grid_y = player.grid_y + 32
        elseif key == "left" then
            player.grid_x = player.grid_x - 32
        elseif key == "right" then
            player.grid_x = player.grid_x + 32
        end
    end

end
 
function love.update(dt)
    player.act_y = player.act_y - ((player.act_y - player.grid_y) * player.speed * dt)
    player.act_x = player.act_x - ((player.act_x - player.grid_x) * player.speed * dt)
end
 
function love.draw()
    love.graphics.rectangle("fill", player.act_x, player.act_y, 32, 32)
    for y=1, #map do
        for x=1, #map[y] do
            if map[y][x] == 1 then
                love.graphics.rectangle("line", x * 32, y * 32, 32, 32)
            end
        end
    end
end

Upvotes: 0

Views: 422

Answers (1)

Doyousketch2
Doyousketch2

Reputation: 2145

you're trying to get it to only walk along grid-lines?

take out love.keyboard.setKeyRepeat(true)
and don't use love.keypressed(key)

that's for one-at-a-time keypresses, and it would be hard to use that
with love.keyreleased() to see if all the other keys are released.

use isDown instead, and if one of them isDown, then none of the other dir keys allow input. (along with the couple player.act lines you already have in your update)

player = {
    grid_x = 256,
    grid_y = 256,
    act_x = 256,
    act_y = 256,
    speed = 5,
    dir = ''
}


function love.update(dt)
    if love.keyboard.isDown("up", "down", "left", "right") then
        if love.keyboard.isDown("up") and ( player.dir == 'up' or player.dir == '' ) then
            player.dir = 'up'  --  only go up if currently held, or no other dir key being pressed
            player.grid_y = player.grid_y - 32
        elseif love.keyboard.isDown("down") and ( player.dir == 'down' or player.dir == '' ) then
            player.dir = 'down'  --  only go down if currently held...
            player.grid_y = player.grid_y + 32
        elseif key == "left" and ( player.dir == 'left' or player.dir == '' ) then
            player.dir = 'left'
            player.grid_x = player.grid_x - 32
        elseif key == "right" and ( player.dir == 'right' or player.dir == '' ) then
            player.dir = 'right'
            player.grid_x = player.grid_x + 32
        end
    else  --  none of those keys are being pressed, so player is idle
        player.dir = ''
    end  --  isDown()

    player.act_y = player.act_y - ((player.act_y - player.grid_y) * player.speed * dt)
    player.act_x = player.act_x - ((player.act_x - player.grid_x) * player.speed * dt)
end  --  update()

Upvotes: 0

Related Questions