关于A*算法网上一大堆,我就不重复说明了,以下是JAVA实现的类
代码除了A*之外还有如何建立六边形网格,以及绘制六边形
图中红色是不可通过(山脉)
绿色是减速通过(森林)
灰色是加速通过(道路)
蓝色就是实际路径
修改参数结果也会有变化
具体实现看代码
核心工具类:APathfindingHex:
package gpp.util;
import java.util.ArrayList;
import java.util.List;
import gpp.object.Coordinate;
public class APathfindingHex {
List<Coordinate> allC;
public List<Coordinate> openList;
public List<Coordinate> closeList;
List<Coordinate> pathC;
public APathfindingHex(List<Coordinate> allC){
this.allC=new ArrayList<>();
for (Coordinate oldC : allC) {
Coordinate newC=new Coordinate(oldC.x, oldC.y);
newC.isBlock=oldC.isBlock;
newC.speed=oldC.speed;
this.allC.add(newC);
}
}
Coordinate findC(Coordinate inC,List<Coordinate> allC) {
for (Coordinate coordinate : allC) {
if (coordinate.equals(inC)) {
return coordinate;
}
}
return null;
}
public List<Coordinate> start(Coordinate oldStartC,Coordinate oldDesC) {
Coordinate startC=findC(oldStartC,allC);
Coordinate desC=findC(oldDesC,allC);
if (findC(startC,allC)==null||findC(desC,allC)==null) {
System.out.println("起点或者终点有误");
return null;
}
if (startC.isBlock||desC.isBlock) {
System.out.println("起点或者终点无法通过");
return null;
}
openList=new ArrayList<>();
closeList=new ArrayList<>();
pathC=new ArrayList<>();
boolean isFind=makeOne(startC,desC);
long count=0;
while (isFind==false&&openList.size()>0) {
count++;
//System.out.println("第"+count+"次计算:");
Coordinate minF=findMinFinOpen();
if (minF!=null) {
isFind=makeOne(minF,desC);
}
}
System.out.println("计算量:"+count);
return pathC;
}
boolean makeOne(Coordinate curC,Coordinate desC) {
closeList.add(curC);
openList.remove(curC);
List<Coordinate> nearListC=curC.findNear();
for (Coordinate coordinate : nearListC) {
Coordinate temp=findC(coordinate,allC);
if (temp!=null&&temp.isBlock==false&&!closeList.contains(temp)) {
int tempG=curC.G+temp.speed;
if (tempG<temp.G||temp.parent==null) {
temp.parent=curC;
temp.G=tempG;
temp.H=calcuH(temp,desC);
temp.F