Выделите путь в сетке
В моей игре, основанной на сетке, игрок нажимает на юнит, затем он двигает пальцем, чтобы определить, куда этот юнит должен двигаться. Я использую библиотеку "Jumper" для поиска пути. Код для получения пути работает отлично, но кода для выделения пути не так уж и много.
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
Линия не выглядит правильно, когда создается в "перемещенной" фазе. Тем не менее, он выглядит очень точно, когда создается в фазе "начальный", а затем добавляется в фазе "перемещенный". Но в этом случае рисуется еще одна дополнительная линия, которая не следует по пути, но попадает непосредственно из начальной плитки в конечную плитку. Моя вторая проблема с методом "начального этапа" - я не знаю, как продолжать удалять старую строку и создавать новую с новым правильным путем.
Дайте мне знать, если нужна дополнительная информация.
1 ответ
Я не уверен, что именно вы хотите, поэтому я подготовил свою собственную версию:
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