Yonaba / Jumper

Fast, lightweight and easy-to-use pathfinding library for grid-based games
http://yonaba.github.io/Jumper
MIT License
614 stars 124 forks source link

jumper.lua:379: attempt to index field 'startNode' (a nil value) #1

Closed tbergeron closed 11 years ago

tbergeron commented 11 years ago

Hi,

I'm trying to get the latest version of Jumper to work but I always get this error:

jumper.lua:379: attempt to index field 'startNode' (a nil value)

Here's my code:

    elseif button == "r" then
        messages.showMessage("Right clickin'")

        table.foreach(employee_instances, function(i)
            employee = employee_instances[i]

            if employee.selected then
                local map_tile_x, map_tile_y = math.floor(math.floor(x)/32), math.floor(math.floor(y)/32)

                see(x)
                see(y)

                if pather.grid:isWalkableAt(map_tile_x, map_tile_y) then
                    messages.showMessage("Checking for a path...")

                    local start_tick = love.timer.getMicroTime()*1000
                    local path, length = pather:getPath(employee.x, employee.y, map_tile_x, map_tile_y)
                    local time = (love.timer.getMicroTime()*1000 - start_tick)

                    if path then
                        messages.showMessage("Go!!!")
                        employee:orderMove(path)
                    end
                end
            end
        end)
    end

I based this code on the Examples you provided for Löve.

Am I doing something wrong or is it a bug? Please tell me if you need any more infos.

Thanks and keep up the good work!

/tommy

Yonaba commented 11 years ago

Hi, The problem seems to occur with this line:

local path, length = pather:getPath(employee.x, employee.y, map_tile_x, map_tile_y)

The method is prototyped as follows:

pather:getPath(startX,startY,endX,endY)

startX and startY should be the coordinates of the starting point on the tile map, and endX and endY the coordinates for the goal point (still on the tile map). Therefore, are you sure that employee.x and employee.y are valid coordinates on the tile map and not screen pixels/world coordinates ?

Maybe you can try this:

local start_tick = love.timer.getMicroTime()*1000
print(employee.x, employee.y, pather.grid:getNodeAt(employee.x,employee.y)
local path, length = pather:getPath(employee.x, employee.y, map_tile_x, map_tile_y)
local time = (love.timer.getMicroTime()*1000 - start_tick)
tbergeron commented 11 years ago

Hi and thanks for your support. It prints "128 128 nil". The coordinates are right but getNodeAt always returns nil :-/

Yonaba commented 11 years ago

Well, that is strange. I am assuming here that you already have your 2D grid map in a 2-dimensional array. When you inits a pather, (passing a map and optional search parameters to Jumper), it actually keeps track of the map passed to init Jumper and is accessible through pather.grid.map (actually it isn't internally used, I just set it for future plans). Anyway, you might want to check if, in the meanwhile, you didn't accidentally set some values to nil.

Just for debugging purposes, try to add these extra lines, run this, so you can workout what's possibly going on :

print('Start Node Tile Coordinates',employee.x, employee.y)
print('Map passed to Jumper',pather.grid.map[employee.y], pather.grid.map[employee.y][employee.x])
print('Internal Matching Node',pather.grid:getNodeAt(employee.x,employee.y))
local path, length = pather:getPath(employee.x, employee.y, map_tile_x, map_tile_y)

Alternatively, so can provide your souce (a *.love file, as it seems you're using Löve2D).

tbergeron commented 11 years ago

Thanks again for helping me, it's very appreciated.

The second print goes crashing because of a nil value. I've joined a *.love file this time hehe. https://dl.dropbox.com/u/199126/test.love The debug code you just told me is located in Game.lua:85

Yonaba commented 11 years ago

Hi, Actually I can't run the game, after cloking the continue button, it crashes. See the traceback. Anyway, I think I saw what the problem was. The map defined inside office is a 33 (width) x 25 (height) map. Therefore it means that when you are making a pathfinding request, startX, startY and endX, endY shouldn't be values higher than 33 (on X) or 25 (on Y), as they refer to specifics tiles. These values should represent the grid position (not the world position) of your entities.

Looking at your employee class, it appears to x and y attributes stand for their position on the screen. You will have to calculate and keep updated their grid position. In pseudocode, that would be

employee.grid_x = math.floor(employee.x/tileWidth)+1
employee.grid_y = math.floor(employee.y/tileHeight)+1

I am adding +1 here because your map starts indexing at 1,1.

Then you can use these new attributes to make path request:

pather:getPath(employee.grid_x, employee.grid_y, map_tile_x, map_tile_y)
tbergeron commented 11 years ago

Nevermind that, I had a typo. So far so good, it almost work! I'll keep you updated on my progress :-) Thanks for the help!

tbergeron commented 11 years ago

Wow it works!!! Thanks a lot, and very good job on the library!

Yonaba commented 11 years ago

You are welcome! Good luck on this project, though. I like the gameplay, reminds me GameDev Story that I played like hell on Android.

tbergeron commented 11 years ago

Haha! GameDev Story is my #1 inspiration for this game. It'll be very different though, more interactive, but still the same vision. I'm glad you like it :-)