📄 drawtools.java
字号:
}
}
}
class AAsterisk {
private boolean m_closeList[][];
/*
* 开启列表就像一张购物清单。 你的路径可能会通过它包含的方格,也可能不会。 基本上,这是一个待检查方格的列表。
*/
public int[][][] m_openList;
private int m_openListLength = 0;
private int m_closeListLength = 0;
public int m_xPosition=0;
public int m_yPosition=0;
public AAsterisk() {
m_closeList = new boolean[GameLogic.MAP_COLUM_NUM][GameLogic.MAP_ROW_NUM];
m_openList = new int[GameLogic.MAP_COLUM_NUM][GameLogic.MAP_ROW_NUM][5];
}
private void addInOpenList(int x, int y)
{
m_openList[y][x][0] = 1;
m_openListLength++;
}
private boolean isBalk(int x, int y)
{
if(x < 0||x >=GameLogic.MAP_ROW_NUM||y < 0||y >=GameLogic.MAP_COLUM_NUM){
return true;
}
if(m_closeList[y][x])return true;
if(GameLogic.map_element[y][x][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE] !=1){
return true;
}
return false;
}
//设置父节点,f:0本身,1,上,2,下,3 左,4,右
private void setFather(int x, int y, int f)
{
m_openList[y][x][4] = f;
}
// * G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。
//父节点的G+自身耗费
private int getG(int x, int y)
{
switch(m_openList[y][x][4])
{
default:
return GameLogic.map_element[y][x][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE];
case 3:
return m_openList[y+1][x][1]+GameLogic.map_element[y][x][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE];
case 4:
return m_openList[y-1][x][1]+GameLogic.map_element[y][x][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE];
case 1:
return m_openList[y][x+1][1]+GameLogic.map_element[y][x][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE];
case 2:
return m_openList[y][x-1][1]+GameLogic.map_element[y][x][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE];
}
}
// * H = 从网格上那个方格移动到终点B的预估移动耗费。
//这经常被称为启发式的,可能会让你有点迷惑。这样叫的原因是因为它只是个猜测。
//H值可以用不同的方法估算。
//我们这里使用的方法被称为曼哈顿方法,
//它计算从当前格到目的格之间水平和垂直的方格的数量总和,忽略对角线方向。
private int getH(int x, int y, int tx, int ty)
{
return Math.abs(x - tx) + Math.abs(y - ty);
}
private void getGHF(int x, int y, int tx, int ty)
{
m_openList[y][x][1] = getG(x,y);
System.out.println("X=" +x+"Y="+y+"G="+m_openList[y][x][1]);
m_openList[y][x][2] = getH(x,y,tx,ty);
m_openList[y][x][3] = m_openList[y][x][2]+m_openList[y][x][1];
System.out.println("X=" +x+"Y="+y+"F="+m_openList[y][x][3]);
}
public void find_path(int bx,int by, int tx,int ty){
try {
m_openListLength = 0;
m_closeListLength = 0;
for(int i = 0; i < GameLogic.MAP_COLUM_NUM; i++){
for(int j = 0; j < GameLogic.MAP_ROW_NUM; j++){
//加入标志
m_openList[i][j][0] = 0;
// * G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。
m_openList[i][j][1] = GameLogic.map_element[i][j][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE];
// * H = 从网格上那个方格移动到终点B的预估移动耗费。
//这经常被称为启发式的,可能会让你有点迷惑。这样叫的原因是因为它只是个猜测。
//H值可以用不同的方法估算。
//我们这里使用的方法被称为曼哈顿方法,
//它计算从当前格到目的格之间水平和垂直的方格的数量总和,忽略对角线方向。
m_openList[i][j][2] = Math.abs(i - ty) + Math.abs(j - tx);
//F = G+H
m_openList[i][j][3] = m_openList[i][j][1] + m_openList[i][j][2];
//父节点
m_openList[i][j][4] = 0;
m_closeList[i][j]=false;
}
}
/*
1,从点A开始,并且把它作为待处理点存入一个“开启列表”。
开启列表就像一张购物清单。
尽管现在列表里只有一个元素,但以后就会多起来。
你的路径可能会通过它包含的方格,也可能不会。
基本上,这是一个待检查方格的列表。*/
addInOpenList(bx,by);
/*
2,寻找起点周围所有可到达或者可通过的方格,跳过有墙,水,或其他无法通过地形的方格。
也把他们加入开启列表。
为所有这些方格保存点A作为“父方格”。
当我们想描述路径的时候,父方格的资料是十分重要的。
后面会解释它的具体用途。
*/
if(!isBalk(bx+1,by)){
addInOpenList(bx+1,by);
setFather(bx+1,by,2);//down
getGHF(bx+1,by,tx,ty);
}
if(!isBalk(bx-1,by)){
addInOpenList(bx-1,by);//up
setFather(bx-1,by,1);
getGHF(bx-1,by,tx,ty);
}
if(!isBalk(bx,by+1)){
addInOpenList(bx,by+1);//right
setFather(bx,by+1,4);
getGHF(bx,by+1,tx,ty);
}
if(!isBalk(bx,by-1)){
addInOpenList(bx,by-1);
setFather(bx,by-1,3);
getGHF(bx,by-1,tx,ty);
}
// 3,从开启列表中删除点A,把它加入到一个“关闭列表”
removeFromOpenList(bx,by);
addInCloseList(bx,by);
// // 从开启列表中选择F值最低的方格。
int ttx = bx,tty=by,minf=255;
for(int i = 0; i < GameLogic.MAP_COLUM_NUM; i++){
for(int j = 0; j < GameLogic.MAP_ROW_NUM; j++){
if(m_openList[i][j][0] == 1){
if(minf>m_openList[i][j][3]){
minf = m_openList[i][j][3];
ttx = j;tty = i;
}
}
}
}
m_xPosition=ttx;
m_yPosition=tty;
System.out.println( "find path X=" + m_xPosition +" Y="+m_yPosition);
} catch (Exception e) {
e.printStackTrace();
}
}
public void AAsterisk_t(int ttx,int tty, int tx,int ty){
/*
* 把目标格添加进了开启列表,这时候路径被找到,或者
* 没有找到目标格,开启列表已经空了。这时候,路径不存在。
*/
if((ttx==tx&&tty == ty)||m_openListLength==0)
return;
// 4,把它从开启列表中删除,然后添加到关闭列表中。
removeFromOpenList(ttx,tty);
addInCloseList(ttx,tty);
/*5,检查所有相邻格子。
跳过那些已经在关闭列表中的或者不可通过的
(有墙,水的地形,或者其他无法通过的地形),
把他们添加进开启列表,如果他们还不在里面的话。
把选中的方格作为新的方格的父节点。
*/
if(!isBalk(ttx+1,tty)){//down
if(m_openList[tty][ttx+1][0]==0){
addInOpenList(ttx+1,tty);
setFather(ttx+1,tty,2);
getGHF(ttx+1,tty,tx,ty);
}else
/*
如果某个相邻格已经在开启列表里了,
检查现在的这条路径是否更好。
换句话说,检查如果我们用新的路径到达它的话,
G值是否会更低一些。如果不是,那就什么都不做。
另一方面,如果新的G值更低,
那就把相邻方格的父节点改为目前选中的方格
*/
if(m_openList[tty][ttx+1][0]==1){
if(m_openList[tty][ttx][1] + GameLogic.map_element[tty][ttx+1][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE]<m_openList[tty][ttx+1][1]){
setFather(ttx+1,tty,2);
getGHF(ttx+1,tty,tx,ty);
}
}
}
if(!isBalk(ttx-1,tty)){//up
if(m_openList[tty][ttx-1][0]==0){
addInOpenList(ttx-1,tty);
setFather(ttx-1,tty,1);
getGHF(ttx-1,tty,tx,ty);
}else
/*
如果某个相邻格已经在开启列表里了,
检查现在的这条路径是否更好。
换句话说,检查如果我们用新的路径到达它的话,
G值是否会更低一些。如果不是,那就什么都不做。
另一方面,如果新的G值更低,
那就把相邻方格的父节点改为目前选中的方格
*/
if(m_openList[tty][ttx-1][0]==1){//
if(m_openList[tty][ttx][1] + GameLogic.map_element[tty][ttx-1][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE]<m_openList[tty][ttx-1][1]){
setFather(ttx-1,tty,1);
getGHF(ttx-1,tty,tx,ty);
}
}
}
if(!isBalk(ttx,tty+1)){//right
if(m_openList[tty+1][ttx][0]==0){
addInOpenList(ttx,tty+1);
setFather(ttx,tty+1,4);
getGHF(ttx,tty+1,tx,ty);
}else
/*
如果某个相邻格已经在开启列表里了,
检查现在的这条路径是否更好。
换句话说,检查如果我们用新的路径到达它的话,
G值是否会更低一些。如果不是,那就什么都不做。
另一方面,如果新的G值更低,
那就把相邻方格的父节点改为目前选中的方格
*/
if(m_openList[tty+1][ttx][0]==1){
if(m_openList[tty][ttx][1] + GameLogic.map_element[tty+1][ttx][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE]<m_openList[tty+1][ttx][1]){
setFather(ttx,tty+1,4);
getGHF(ttx,tty+1,tx,ty);
}
}
}
if(!isBalk(ttx,tty-1)){//left
if(m_openList[tty-1][ttx][0]==0){
addInOpenList(ttx,tty-1);
setFather(ttx,tty-1,3);
getGHF(ttx,tty-1,tx,ty);
}else
/*
如果某个相邻格已经在开启列表里了,
检查现在的这条路径是否更好。
换句话说,检查如果我们用新的路径到达它的话,
G值是否会更低一些。如果不是,那就什么都不做。
另一方面,如果新的G值更低,
那就把相邻方格的父节点改为目前选中的方格
*/
if(m_openList[tty-1][ttx][0]==1){
if(m_openList[tty][ttx][1] + GameLogic.map_element[tty-1][ttx][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE]<m_openList[tty-1][ttx][1]){
setFather(ttx,tty-1,3);
getGHF(ttx,tty-1,tx,ty);
}
}
}
// 从开启列表中选择F值最低的方格。
int bx=ttx,by=tty,minf=255;
for(int i = 0; i < GameLogic.MAP_COLUM_NUM; i++){
for(int j = 0; j < GameLogic.MAP_ROW_NUM; j++){
if(m_openList[i][j][0] == 1){
if(minf>m_openList[i][j][3]){
minf = m_openList[i][j][3];
bx = j;by = i;
}
}
}
}
m_xPosition=bx;
m_yPosition=by;
System.out.println( "next position X=" + m_xPosition +" Y="+m_yPosition);
}
private void removeFromOpenList(int x, int y)
{
m_openList[y][x][0] = 0;
m_openListLength--;
}
private void addInCloseList(int x, int y)
{
m_closeList[y][x] = true;
m_closeListLength++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -