1
Programming with Blackvoxel / Re: A* pathfinding routine
« on: October 31, 2013, 10:53:12 pm »
Here is an example script that uses AStar.nut to walk a programmable robot to a point.
The goal is defined by:
You can place the robot anywhere and it will try and find it's way to that location in the shortest possible route without going through any solid blocks.
Example Code:
It's the function MoveTo(x,y,z) that is the meat of the example.
The goal is defined by:
Code: [Select]
DestX <- 44;
DestY <- 0;
DestZ <- 11;
You can place the robot anywhere and it will try and find it's way to that location in the shortest possible route without going through any solid blocks.
Example Code:
Code: [Select]
// Test of pathfinding
Time <- 0;
DestX <- 44;
DestY <- 0;
DestZ <- 11;
MovePath <- null;
MyAstar <- null;
function Voxel_Load()
{
Time = GetGameTime();
log_info("Voxel_Load()");
dofile(GetPath(3)+GetInfo(20)+"AStar.nut",true);
MyAstar = AStar(); // Create instance of AStar
//MyAstar.SetMax(32); // Limit search area
MyAstar.Set3D(); // Enable full 3D search
}
function Voxel_Step()
{
if (GetGameTime() - Time > 0) {
Time = GetGameTime();
} else {
// Fix for funky GetGameTime()
if (GetGameTime() - Time < -60000)
Time = GetGameTime();
return;
}
if (MoveTo(DestX,DestY,DestZ)) {
if (GetX() == DestX && GetY() == DestY && GetZ() == DestZ) {
log_info("We have arrived!");
Time = GetGameTime() + 10000;
} else {
log_err("Failed to arrive");
Time = GetGameTime() + 10000;
}
}
}
function MoveTo(x, y, z)
{
if (MovePath == null) { // We need to keep calling GetPath until we get an array back.
MovePath = MyAstar.GetPath(Node(GetX(),GetY(),GetZ()),Node(x,y,z));
}
if (MovePath != null && MovePath.len()>0) {
local d = MovePath.pop(); // Get move direction from array
if (GetVoxelProp(Look(d),0)) {
if (Move(d)) {
if (MovePath.len() == 0)
return true; // We should have arrived.
} else {
MovePath.push(d); // Save move direction to path again.
log_err("Failed to move along the path! d="+d);
Time = GetGameTime() + 5000;
}
} else {
log_err("Path is obstructed. Getting new move path!");
Time = GetGameTime() + 5000;
MyAstar.Clear();
MovePath = null;
}
} else if (typeof MovePath=="array" && MovePath.len()==0) {
return true; // We did not arrive, but we still have to tell the caller we are done.
}
return false; // Not there yet.
}
function log_info(msg)
{
local s;
s = format("5.nut at %d,%d,%d Info: %s", GetX(), GetY(), GetZ(), msg);
Display( s, 2000, 4, 1000);
error(s+"\n");
}
function log_err(msg)
{
local s;
s = format("5.nut at %d,%d,%d Err: %s", GetX(), GetY(), GetZ(), msg);
Display( s, 4000, 4, 4000);
error(s+"\n");
Time = Time + 1500;
}
It's the function MoveTo(x,y,z) that is the meat of the example.