上一篇博客分享了Java版的自动寻路,但是只是上下左右四个方向的,今天把八方向的也分享出来。
既然四方向的已经成功了,那么改进成八方向的,只要注意两个地方就可以了,一个是获取四周方块的时候,一个是移动的时候。
在autofindway.java中添加静态变量,用来标识上下左右四个方向是否可通过。
//在获取上下左右四个方块的时候,判断各个方块是否满足条件(比如:只有右边和下边的方块都可通过的时候,才能去判断右下方的方块是否满足条件,否则就是穿墙了)
private static boolean top = false;
private static boolean down = false;
private static boolean left = false;
private static boolean right = false;
在获取四周方块的方法aroundFk中,考虑左上、右上、右下、左下四个方块的判断。
其中,上下左右四个方块的判断中,如果可以通过,则将对应的方向(top/down/left/right)标识为true。只有在左边和上边方块都是true的时候,才能去判断左上方方块是否满足条件,否则就存在穿墙现象。
比如下图的四种情况,红点想要移动到左上方的绿点,只有左边和上边(①)都可穿过的时候才能正常移动过去。像图②③④这三种情况如果直接移动,都存在穿墙的现象。
代码如下:只要替换掉四方向版本中的aroundFk就可以了。
/**
* 获取周围方块
* ①判断是否超越边界
* ②判断是否是障碍物/已计算过的方块
* @param fk 中心方块
* @return 周围方块结集合
*/
public List aroundFk(FangKuaiPosition fk){
//重置
top = false;
down = false;
left = false;
right = false;
List list = new ArrayList();
//判断上面的方块是否符合条件
//判断是否超过越边界
if(fk.getY() - 1 >= 0){
FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX(), fk.getY() - 1, fk);
//判断是否是障碍物/已计算过的方块
if(!BasePanel.zhangaiList.contains(tmpFk)
&& !BasePanel.closedList.contains(tmpFk)){
list.add(tmpFk);
top = true;//上方方块符合条件
}
}
//判断下面的方块是否符合条件
if(fk.getY() + 1 < BasePanel.heightLength){
FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX(), fk.getY() + 1, fk);
if(!BasePanel.zhangaiList.contains(tmpFk)
&& !BasePanel.closedList.contains(tmpFk)){
list.add(tmpFk);
down = true;//下方方块符合条件
}
}
//判断左面的方块是否符合条件
if(fk.getX() - 1 >= 0){
FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() - 1, fk.getY(), fk);
if(!BasePanel.zhangaiList.contains(tmpFk)
&& !BasePanel.closedList.contains(tmpFk)){
list.add(tmpFk);
left = true;//左方方块符合条件
}
}
//判断右面的方块是否符合条件
if(fk.getX() + 1 < BasePanel.widthLength){
FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() + 1, fk.getY(), fk);
if(!BasePanel.zhangaiList.contains(tmpFk)
&& !BasePanel.closedList.contains(tmpFk)){
list.add(tmpFk);
right = true;//右方方块符合条件
}
}
//左上方方块校验(左移一格不超过边界&&上移一格不超过边界&&左边方块符合条件&&上边方块符合条件,下面的类似原理)
if(fk.getX() - 1 >= 0 && fk.getY() - 1 >= 0 && left && top){
FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() - 1, fk.getY() - 1, fk);
//判断是否是障碍物/已计算过的方块
if(!BasePanel.zhangaiList.contains(tmpFk)
&& !BasePanel.closedList.contains(tmpFk)){
list.add(tmpFk);
}
}
//右上方方块校验
if(fk.getX() + 1 < BasePanel.widthLength && fk.getY() - 1 >= 0 && right && top){
FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() + 1, fk.getY() - 1, fk);
//判断是否是障碍物/已计算过的方块
if(!BasePanel.zhangaiList.contains(tmpFk)
&& !BasePanel.closedList.contains(tmpFk)){
list.add(tmpFk);
}
}
//右下方方块校验
if(fk.getX() + 1 < BasePanel.widthLength && fk.getY() + 1 < BasePanel.heightLength && right && down){
FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() + 1, fk.getY() + 1, fk);
//判断是否是障碍物/已计算过的方块
if(!BasePanel.zhangaiList.contains(tmpFk)
&& !BasePanel.closedList.contains(tmpFk)){
list.add(tmpFk);
}
}
//左下方方块校验
if(fk.getX() - 1 >= 0 && fk.getY() + 1 < BasePanel.heightLength && left && down){
FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() + 1, fk.getY() + 1, fk);
//判断是否是障碍物/已计算过的方块
if(!BasePanel.zhangaiList.contains(tmpFk)
&& !BasePanel.closedList.contains(tmpFk)){
list.add(tmpFk);
}
}
//将中心方块添加到已处理过的集合中
BasePanel.closedList.add(fk);
getFGH(list,fk);
return list;
}
在basepanel.java中的movePanel方法里面,四方向的版本只做了上下左右四个方向的移动判断,所以这里需要将左上、右上、右下、左下的移动判断添加进来。同样,也是替换掉四方向版本中的这个movePanel方法就可以了。
/**
* 方块移动
* @param wayList 移动路线
* @throws InterruptedException
*/
public void movePanel(List wayList) throws InterruptedException{
if(wayList == null || wayList.size() == 0){
System.out.println("无法 到达终点 !");
return;
}
for(int i = wayList.size() - 2; i >= 0; i--){
FangKuaiPosition fk = wayList.get(i);
//向左上移动
while(cat.getY() > fk.getY() * MyPanel.size && cat.getX() > fk.getX() * MyPanel.size){
cat.setBounds(cat.getX() - 2, cat.getY() - 2, MyPanel.size, MyPanel.size);
Thread.sleep(sleepTime);
}
//向右上移动
while(cat.getY() > fk.getY() * MyPanel.size && cat.getX() < fk.getX() * MyPanel.size){
cat.setBounds(cat.getX() + 2, cat.getY() - 2, MyPanel.size, MyPanel.size);
Thread.sleep(sleepTime);
}
//向右下移动
while(cat.getY() < fk.getY() * MyPanel.size && cat.getX() < fk.getX() * MyPanel.size){
cat.setBounds(cat.getX() + 2, cat.getY() + 2, MyPanel.size, MyPanel.size);
Thread.sleep(sleepTime);
}
//向左下移动
while(cat.getY() < fk.getY() * MyPanel.size && cat.getX() > fk.getX() * MyPanel.size){
cat.setBounds(cat.getX() - 2, cat.getY() + 2, MyPanel.size, MyPanel.size);
Thread.sleep(sleepTime);
}
//向上
while(cat.getY() > fk.getY() * MyPanel.size && cat.getX() == fk.getX() * MyPanel.size){
cat.setBounds(cat.getX(), cat.getY() - 2, MyPanel.size, MyPanel.size);
Thread.sleep(sleepTime);
}
//向下
while(cat.getY() < fk.getY() * MyPanel.size && cat.getX() == fk.getX() * MyPanel.size){
cat.setBounds(cat.getX(), cat.getY() + 2, MyPanel.size, MyPanel.size);
Thread.sleep(sleepTime);
}
//向左
while(cat.getX() > fk.getX() * MyPanel.size && cat.getY() == fk.getY() * MyPanel.size){
cat.setBounds(cat.getX() - 2, cat.getY(), MyPanel.size, MyPanel.size);
Thread.sleep(sleepTime);
}
//向右
while(cat.getX() < fk.getX() * MyPanel.size && cat.getY() == fk.getY() * MyPanel.size){
cat.setBounds(cat.getX() + 2, cat.getY(), MyPanel.size, MyPanel.size);
Thread.sleep(sleepTime);
}
}
System.out.println("寻路结束!");
}
好了,给大家展示一下结果: