The other piece of information that we need to know about each neighboring tile is how hard, compared to other tiles, it is to take the step into that tile from the one we are considering. We'll add this information to the terrain engine and attach it to the spaces to make it easy to find.
This model will keep things simple, basing costs to enter a space solely on the type of space being entered. This means we can use a simple table.
Add a new local table near the top of forest.lua
:
local forest = {} local entryCosts = { } function forest:Expand(kind)
Add values for the basic terrain types found in the map:
local entryCosts = { bush= math.huge, ['=grass']=1, }
We'll also provide a function that selects costs from the following table as needed:
}; }; Cost-function(start,neighbour) end; Polish=function(tile)
Polished terrain maps may have variants on the same terrain type, so we use only the core type; terrain types are stored as strings where any subcategory comes after the basic terrain type, separated by a colon:
function forest.Cost(start, neighbor)
local name = neighbor.Ground
end
Finally, we return the appropriate value from the table, with a default that ensures unrecognized terrain types will not be crossed:
function forest.Cost(start, neighbor)
local name = neighbor.Ground
return entryCosts[name] or math.huge
end
Save forest.lua
.
Return to the nextNeighbor
function in map.lua
. Remember from path.lua
that the iterator needs to return two values, the next neighbor and the cost, like the following iterator code does:
local space = row and row[start.x + dX]
if space then
return space, start.map.Terrain.Cost(start, space)
end
until dY = -1
We completed the neighbor analysis process by adding weights to different tile transitions, allowing the different terrain types to offer specifics about what type each square represents.
This cost-assessment function is not terribly efficient. Since it is called many times for each pass through the map, if there are many monsters, all calculating a path regularly, this inefficiency will be multiplied enough to have a serious impact on game performance.
One way to make it more efficient is to precalculate each square's neighbors and costs, since they don't change. You can store a table in each map square that records the neighbors and their costs, such as by using neighbor square tables as keys and costs as the values. Scanning for neighbors then becomes a matter of simply iterating that table.
18.118.137.243