0
votes

In my grid-based game, The player clicks on a unit then he moves his finger to determine where this unit should move. I'm using the "Jumper" library for the pathfinding. The code for getting the path works perfectly, but the code for highlighting the path, not so much.

local function onTileTouch( event )
    local phase = event.phase
    local tile = event.target


    if ( phase == "began"  ) then
        -- I could create the line here
    elseif ( phase == "moved" ) then
        createPath( tile )

        -- Getting the position of the first tile based on where the unit is
        local t = tiles[currentSelectedUnit.pos.y][currentSelectedUnit.pos.x]

        -- Create the line at the first tile's position
        line = display.newLine( t.x, t.y, t.x, t.y )
        line:setStrokeColor( 1,0,0 )
        line.strokeWidth = 8

        -- "foundPath" is a table of tiles of the correct path
        for i=1,#foundPath do
            line:append( foundPath[i].x,foundPath[i].y )
        end
    elseif ( phase == "ended" or phase == "cancelled" ) then
end

The line doesn't look right when being created in the "moved" phase. It does, however, look very accurate when being created in the "began" phase and then getting appended during the "moved" phase. But in this case, another extra line gets drawn that doesn't follow the path but gets directly from the start tile to the end tile. My second problem with the "began" phase method, is I don't know how to keep deleting the old line and create a new one with for the new correct path.

Let me know if any extra information is needed.

1
Can you provide gif or describe how exactly should look like path on the screen when player move finger?ldurniat

1 Answers

0
votes

I'm not sure what exactly you want so I have prepared my own version:

enter image description here

test.lua

local composer   = require( 'composer' )
-- Library setup
local Grid       = require ( 'jumper.grid' ) -- The grid class
local Pathfinder = require ( 'jumper.pathfinder' ) -- The pathfinder lass

local scene = composer.newScene()

-- First, set a collision map and value for walkable tiles
local board  = { 
    tiles = {}, 
    walkable = 0, 
    map = {
        {0,1,0,0,0},
        {0,1,0,1,0},
        {0,1,0,0,0},
        {0,0,0,0,0},
    } 
}

local function createPath( startx, starty, endx, endy )

    -- Creates a grid object
    local grid = Grid( board.map ) 
    -- Creates a pathfinder object using Jump Point Search
    local myFinder = Pathfinder( grid, 'JPS', board.walkable ) 
    -- Calculates the path, and its length
    local path = myFinder:getPath( startx, starty, endx, endy )

    return path

end

function scene:create( event )

    local sceneGroup = self.view
    local rowNum = #board.map
    local colNum = #board.map[1]
    local width  = 40
    local height = width
    local margin = 5

    local function touch( self, event )

        local phase = event.phase
        local endTile = event.target

        if ( phase == 'began'  ) then

            board.startTile = endTile

        elseif ( phase == 'moved' ) then

            if board.startTile ~= endTile then

                if ( board.endTile ~= endTile ) then

                    board.endTile = endTile

                    local path = createPath( board.startTile.col, board.startTile.row, board.endTile.col, board.endTile.row )

                    if path then

                        -- Remove old lines
                        display.remove( board.lines )
                        board.lines = nil           

                        -- Create new line
                        board.lines = display.newLine( sceneGroup, board.startTile.x, board.startTile.y, board.startTile.x, board.startTile.y + 1 )

                        for node, count in path:nodes() do

                            local id = colNum * ( node:getY() - 1 ) + node:getX()
                            local tile = board.tiles[id]
                            board.lines:append( tile.x, tile.y )    

                        end 

                    end 

                end 

            else

                -- Remove old lines
                display.remove( board.lines )
                board.lines = nil
                board.endTile = nil

            end 

        elseif ( phase == 'ended' or phase == 'cancelled' ) then

            -- Remove old lines
            display.remove( board.lines )
            board.lines = nil
            board.endTile = nil
            board.startTile = nil

        end 

    end 

    for i=1, rowNum do

        for j=1, colNum do

            local tile = display.newRect( sceneGroup, (width + margin ) * j, ( height + margin ) * i, width, height ) 
            tile.col = j 
            tile.row = i 
            tile.touch = touch
            -- Add listener and change color for walkable tile
            if board.map[i][j] == board.walkable then

                tile:addEventListener( 'touch' )
                tile:setFillColor( 0, 0.5, 0.5 )

            end 

            local id = colNum * ( i -1 ) + j
            board.tiles[id] = tile

        end

    end     

end

function scene:show( event )
    local sceneGroup = self.view
    local phase = event.phase
    if phase == 'will' then

    elseif phase == 'did' then

    end
end

function scene:hide( event )
    local sceneGroup = self.view
    local phase = event.phase
    if event.phase == 'will' then

    elseif phase == 'did' then

    end
end

function scene:destroy( event )
local sceneGroup = self.view


end

scene:addEventListener( 'create', scene )
scene:addEventListener( 'show', scene )
scene:addEventListener( 'hide', scene )
scene:addEventListener( 'destroy', scene )

return scene