A*算法javafx可视化-以曼哈顿算法为F的自动寻路算法Astar的可视化实现

最近在用javafx尝试做一款简单的2D游戏,涉及到自动寻路问题,经过搜索后发现A*算法可用性高。因为没有扎实的算法基础,就用了简单的曼哈顿函数做为F来实现A*算法。实现了通过修改代码来设置障碍。



基本步骤按照百度百科中的伪代码来实现:

原文地址:https://baike.baidu.com/item/A%2A%E7%AE%97%E6%B3%95/215793?fr=aladdin

while(OPEN!=NULL)
{
    从OPEN表中取f(n)最小的节点n;
    if(n节点==目标节点)
        break;
    for(当前节点n的每个子节点X)
    {
        计算f(X);
        if(XinOPEN)
            if(新的f(X)<OPEN中的f(X))
            {
                把n设置为X的父亲;
                更新OPEN表中的f(n);
            }
        if(XinCLOSE)
            continue;
        if(Xnotinboth)
        {
            把n设置为X的父亲;
            求f(X);
            并将X插入OPEN表中;//还没有排序
        }
    }//endfor
    将n节点插入CLOSE表中;
    按照f(n)将OPEN表中的节点排序;//实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。
}//endwhile(OPEN!=NULL)

然后把伪代码中的步骤一个个具体实现。

最后用java实现出来的东西

long begin = System.currentTimeMillis();
		mainControl.openList.add(mainControl.startPoint);

		while(!mainControl.openList.isEmpty()) {
			/**
			 * Find the note with the min F in the open list
			 */
			starShape minFpoint = null;
			for(starShape ss : mainControl.openList) {
				if(minFpoint == null) {
					minFpoint = ss;
					continue;
				}
				if(ss.getStarNote().getF()<minFpoint.getStarNote().getF()) {
					minFpoint = ss;
				}
			}
			/**
			 * Check if it finds the destination successfully
			 */
			if(minFpoint.getStarNote().getF()==0) break;
			/**
			 * check this note's neighbors
			 */
			ArrayList<starShape> minsNeighbors = minFpoint.getNeighbor();
			for(starShape ss : minsNeighbors) {
				int newF = calculateNewF(ss, minFpoint);
				if(mainControl.openList.contains(ss)) {
					/*
					 * if new F less than old F
					 * set this note's sup note as minFpoint
					 * refresh its F
					 */
					if(newF < ss.getStarNote().getF()) {
						ss.getStarNote().setSup(minFpoint.getStarNote());
						ss.getStarNote().G = MahattnUtil.OneStepDistance(ss, minFpoint) + minFpoint.getStarNote().G;
					}
				}else if(mainControl.closeList.contains(ss)) {
					continue;
				}else {
					/*
					 * set ss's sup as minFpoint
					 * calculate F
					 * put ss into openlist
					 */
					ss.getStarNote().setSup(minFpoint.getStarNote());
					ss.getStarNote().G = MahattnUtil.OneStepDistance(ss, minFpoint) + minFpoint.getStarNote().G;
					ss.getStarNote().H = MahattnUtil.MahattnDistance(ss, mainControl.desShape);
					mainControl.openList.add(ss);
				}	
			}
			mainControl.closeList.add(minFpoint);
			mainControl.openList.remove(minFpoint);
		}
		
		findRoute(mainControl.desShape);
		long end = System.currentTimeMillis();
		System.out.println(end - begin +"ms");

每次生成路径的时间大概在10ms-14ms

以下是一些较难思考的东西:

这里每个节点用了一个名为starNote的类来实现,其属性包含了:

	protected int x = -1;
	protected int y = -1;
	public    int G =  0;
	public    int H = -1;
	protected String  status;
	protected boolean avilable = true;
	private starNote sup;
	public starShape shape;

使用x,y即可确定一个点。

扫描二维码关注公众号,回复: 5783888 查看本文章

计算前将所有节点都用这个类实例化出来,再一个个进行操作即可。

曼哈顿函数计算G,以及直接计算H:

	public static int MahattnDistance(starShape s1, starShape s2) {
		return Math.abs(s1.getStarNote().getX()/5-s2.getStarNote().getX()/5)+Math.abs(s1.getStarNote().getY()/5-s2.getStarNote().getY()/5);
	}
	public static int MahattnDistance(starNote s1, starNote s2) {
		return Math.abs(s1.getX()/5-s2.getX()/5)+Math.abs(s1.getY()/5-s2.getY()/5);
	}

最后附上代码:

https://github.com/kingsmanmikey/Astar_Mahattn


猜你喜欢

转载自blog.csdn.net/weixin_40804987/article/details/80966020