Zachary Ryans
Zachary Ryans

Reputation: 11

Having an issue with grid-based movement in Love2D/Lua

Using the Love2D Lua framework, I am trying to program a very basic game much like Nintendo-era RPGs where the heroes' and NPCs' movement was restricted to a tiled grid. So far I've found my past any problems, until I hit this tricky error where the player movement isn't functioning correctly.

function love.load()
    love.graphics.setDefaultFilter('nearest', 'nearest', 1)
    love.keyboard.setKeyRepeat(true)
    font = love.graphics.newFont(14) -- the number denotes the font size

    win_size = 6
    love.window.setMode(160 * win_size, 144 * win_size)

    true_sfc = love.graphics.newCanvas(160,144)
    view_sfc = love.graphics.newCanvas(160 * win_size, 144 * win_size)

    player = {
        grid_x = 3,
        grid_y = 3,
        act_x = 48,
        act_y = 48,
        transit = false,
        direction = {0, 0}
    }
end

function love.update(dt)
    if player.transit == true then

        -- The idea is that if the player selects a direction, the player will walk in that direction until it stops on the grid. 
        -- When I press left or right, the movements works as intended- the player square walks until it stops on the grid.
        -- However, when I press up or down, the player only moves a single pixel, despite having the same instructions


        player.act_x = player.act_x + player.direction[1]
        player.act_y = player.act_y + player.direction[2]

        if player.act_x == player.grid_x * 16  then
            player.direction[1] = 0
            player.transit = false
        end

        if player.act_y == player.grid_y * 16  then
            player.direction[2] = 0
            player.transit = false
        end

        -- Now in this if-statement, if I have the program compare the player's y-coordinates before comparing the x coordinates,
        -- the program will move the player on the y-axis correctly, with it locking to the 16 pixel grid, while the x coordinates
        -- will starts to have the single-pixel movement issue.

    end
end

function love.draw()
    love.graphics.setCanvas(true_sfc)
        love.graphics.setColor( 0, 0, 0)
        love.graphics.rectangle("fill", 0, 0, 256, 224)
        love.graphics.setColor(255,255,255)
        love.graphics.rectangle("fill", player.act_x, player.act_y, 16, 16)
        love.graphics.print(player.direction[1], 100, 100)
        love.graphics.print(player.direction[2], 100, 120)
    love.graphics.setCanvas()

    love.graphics.draw(true_sfc, 0, 0, 0, win_size, win_size)
end

function love.keypressed(key)
    if player.transit == false then
        if key == "up" then
            player.grid_y = player.grid_y - 1
            player.direction = {0, -1}
            player.transit = true
        elseif key == "down" then
            player.grid_y = player.grid_y + 1
            -- press down, the player's map position goes down one tile
            player.direction = {0, 1}
            player.transit = true
        elseif key == "left" then
            player.grid_x = player.grid_x - 1
            player.direction = {-1, 0}
            player.transit = true
        elseif key == "right" then
            player.grid_x = player.grid_x + 1
            player.direction = {1, 0}
            player.transit = true
        end
    end
end

Admittedly I'm pretty new to Lua so I don't understand how it uses variables very well. And I realize that my code isn't very effecient, but that's something I planned on improving over time anyway.

Upvotes: 1

Views: 997

Answers (1)

Advert
Advert

Reputation: 653

The problem here is that you check if the vertical movement lines up, see that it does, and then you set self.transit to false, preventing any future checks.

You want to also check that you are moving in that direction, before checking if you're lined up:

    if player.direction[1] ~= 0 and player.act_x == player.grid_x * 16  then
        player.direction[1] = 0
        player.transit = false
    end

    if player.direction[2] ~= 0 and player.act_y == player.grid_y * 16  then
        player.direction[2] = 0
        player.transit = false
    end

Upvotes: 1

Related Questions