zoukankan      html  css  js  c++  java
  • A星寻路示例

    package autoFindPath;
    
    
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    /**
     * 自动寻路示例
     * @author tiger
     * 
     * 鼠标点到哪里,则寻路到哪里。
     * 点到人物,则清理掉路径。
     * 红色方块为行动路径。绿色方块为人物。
     * 灰色方块可通行。黑色方块不可通行。
     * 
     */
    public class FindPathTest extends JPanel implements MouseListener{
    
    	private int size = 20;
    	private int row, column;
    	
    	/**
    	 * 0为可通过点, 1为不可通过点
    	 */
    	private int[][] map = {
    			{0,0,0,0,0,0,0,0,0,0,0},	
    			{0,0,0,0,0,1,0,0,0,0,0},	
    			{0,1,0,0,0,1,0,0,0,1,0},	
    			{0,1,0,0,0,1,0,0,0,1,0},	
    			{0,0,0,0,0,0,0,0,0,0,0},	
    			{0,0,1,0,0,0,0,0,1,0,0},	
    			{0,0,1,0,0,0,0,0,1,0,0}
    	};
    	
    	/**
    	 * 人物位置
    	 */
    	private int playerX, playerY = 2;
    	
    	/**
    	 * 目标位置
    	 */
    	private int targetX, targetY;
    	
    	
    	public FindPathTest() {
    		row = map.length;
    		column = map[0].length;
    		this.setPreferredSize(new Dimension(column * size, row * size));
    		this.setFocusable(true);
    		this.addMouseListener(this);
    	}
    	
    	@Override
    	public void paint(Graphics g) {
    		super.paint(g);
    		
    		//地图
    		for (int i = 0; i < map.length; i++) {
    			for (int j = 0; j < map[i].length; j++) {
    				if(map[i][j] == 0)
    				{
    					g.setColor(Color.gray);
    				}
    				else if(map[i][j] == 1)
    				{
    					g.setColor(Color.black);
    				}
    				g.fillRect(j * size, i * size, size, size);
    			}
    		}
    		
    		//演示路径
    		g.setColor(Color.red);
    		for (int i = 0; i < pathList.size(); i++) {
    			int[] obj = (int[]) pathList.get(i);
    			g.fillRect(obj[0] * size, obj[1] * size, size, size);
    		}
    		//人物
    		g.setColor(Color.green);
    		g.fillRect(playerX * size, playerY * size, size, size);
    	}
    	
    
    	@Override
    	public void mousePressed(MouseEvent e) {
    		targetX = e.getX() / size;
    		targetY = e.getY() / size ;
    		
    		try {
    			openlist.clear();
    			closelist.clear();
    			pathList.clear();
    			if(targetX == playerX && targetY == playerY) //点击为当前位置,不做处理
    			{
    				this.repaint();
    				return;
    			}
    			
    			playerMove(); //人物运动到目标点
    			repaint();
    		} catch (Exception e2) {
    			e2.printStackTrace();
    		}
    		
    		
    	}
    	@Override
    	public void mouseClicked(MouseEvent e) {
    	}
    	@Override
    	public void mouseEntered(MouseEvent e) {
    	}
    	@Override
    	public void mouseExited(MouseEvent e) {
    	}
    	@Override
    	public void mouseReleased(MouseEvent e) {
    	}
    	
    	/**
    	 * 人物运动
    	 */
    	@SuppressWarnings("unchecked")
    	private void playerMove() {
    		int[] dirs = findPath();
    	}
    	
    	
    	@SuppressWarnings("unchecked")
    	private int[] findPath()
    	{
    		int[] dirs = null;
    		
    		int x = playerX, y = playerY;
    		
    		while (true) {
    			List aroundPos = this.getAroundPos(x, y);
    			if(aroundPos.isEmpty()) //说明从x,y处无法到达终点
    			{
    				this.removeList(openlist, x, y); //openlist中删除位置为x, y的元素
    				this.removeList(closelist, x, y); //openlist中删除位置为x, y的元素
    			}else{				
    				openlist.addAll(aroundPos);
    			}
    			
    			int[] nearestPos = getNearPos();
    			if(nearestPos == null)
    			{
    				System.out.println("找不到路径!");
    				return null;
    			}
    			closelist.add(nearestPos);
    			
    			//到达了终点
    			if(nearestPos[0] == targetX && nearestPos[1] == targetY)
    			{
    				break;
    			}
    			else //没有到终点,继续寻找
    			{ 
    				x = nearestPos[0];
    				y = nearestPos[1];
    			}
    		}
    		
    		//打印一下
    		for (int i = 0; i < closelist.size(); i++) {
    			int[] data = (int[]) closelist.get(i);
    			System.out.println(data[0] + ", " + data[1] + ", " + data[2]);
    		}
    		
    		System.out.println();
    		
    		//得到最终的路径
    		int[] temp = (int[]) closelist.get(closelist.size() - 1);
    		pathList.add(temp);
    		while(temp[0] != playerX || temp[1] != playerY)
    		{
    			temp = getPrePos(temp);
    			int[] data;
    			for (int i = 0; i < closelist.size(); i++) {
    				data = (int[]) closelist.get(i);
    				if(data[0] == temp[0] && data[1] == temp[1])
    				{
    					temp = data;
    					pathList.add(temp);
    					break;
    				}
    			}
    		}
    		
    		
    		//打印一下
    		for (int i = 0; i < pathList.size(); i++) {
    			int[] data = (int[]) pathList.get(i);
    			System.out.println(data[0] + ", " + data[1] + ", " + data[2]);
    		}
    		playerX = targetX;
    		playerY = targetY;
    		
    		
    		
    		return dirs;
    	}
    	
    	private List pathList = new LinkedList();
    	
    	
    	private List openlist = new LinkedList();
    	private List closelist = new LinkedList();
    	
    	private void removeList(List list, int x, int y) {
    		for (int i = 0; i < list.size(); i++) {
    			int[] listData = (int[]) list.get(i);
    			if(listData[0] == x && listData[1] == y)
    			{
    				list.remove(i);
    				return;
    			}
    		}
    	}
    	
    	/**
    	 * 得到上一步的位置
    	 * @param temp
    	 * @return
    	 */
    	private int[] getPrePos(int[] temp) {
    		switch(temp[2])
    		{
    		case LEFT:
    			return new int[]{temp[0] + 1, temp[1], temp[2]};
    		case RIGHT:
    			return new int[]{temp[0] - 1, temp[1], temp[2]};
    		case UP:
    			return new int[]{temp[0], temp[1] + 1, temp[2]};
    		case DOWN:
    			return new int[]{temp[0], temp[1] - 1, temp[2]};
    		}
    		return null;
    	}
    	
    	
    	private int[] getNearPos() {
    		int distance = Integer.MAX_VALUE;
    		int[] result = null;
    		for (int i = 0; i < openlist.size(); i++) {
    			int[] obj = (int[]) openlist.get(i);
    			int temp = this.getDistance(obj[0], obj[1], targetX, targetY);
    			if(temp < distance)
    			{
    				distance = temp;
    				result = obj;
    			}
    		}
    		return result;
    	}
    	
    	
    	/**
    	 * 得到x,y位置周围的位置(这些位置不在openlist和closelist中且可以通过)
    	 * @return
    	 */
    	private List getAroundPos(int x, int y)
    	{
    		List list = new ArrayList();
    		
    		//左边
    		if(x > 0 && map[y][x - 1] != 1)
    		{
    			int[] obj = new int[3];
    			obj[0] = x - 1;
    			obj[1] = y;
    			obj[2] = LEFT;
    			if(this.isExistAtList(openlist, obj) == false && this.isExistAtList(closelist, obj) == false)
    			{				
    				list.add(obj);
    			}
    		}
    		//右边
    		if(x < column - 1 && map[y][x + 1] != 1)
    		{
    			int[] obj = new int[3];
    			obj[0] = x + 1;
    			obj[1] = y;
    			obj[2] = RIGHT;
    			if(this.isExistAtList(openlist, obj) == false && this.isExistAtList(closelist, obj) == false)
    			{				
    				list.add(obj);
    			}
    		}
    		//上边
    		if(y > 0 && map[y - 1][x] != 1)
    		{
    			int[] obj = new int[3];
    			obj[0] = x;
    			obj[1] = y - 1;
    			obj[2] = UP;
    			if(this.isExistAtList(openlist, obj) == false && this.isExistAtList(closelist, obj) == false)
    			{				
    				list.add(obj);
    			}
    		}
    		//下边
    		if(y < row - 1 && map[y + 1][x] != 1)
    		{
    			int[] obj = new int[3];
    			obj[0] = x;
    			obj[1] = y + 1;
    			obj[2] = DOWN;
    			if(this.isExistAtList(openlist, obj) == false && this.isExistAtList(closelist, obj) == false)
    			{				
    				list.add(obj);
    			}
    		}
    		return list;
    	}
    	
    	
    	
    	
    	private final int LEFT = -1, RIGHT = 1, UP = -2, DOWN = 2;
    	
    	
    	/**
    	 * 判断list中是否已有了obj位置
    	 * @return
    	 */
    	private boolean isExistAtList(List list, int[] obj)
    	{
    		for (int i = 0; i < list.size(); i++) {
    			int[] listData = (int[]) list.get(i);
    			if(listData[0] == obj[0] && listData[1] == obj[1])
    			{
    				return true;
    			}
    		}
    		return false;
    	}
    	
    	
    	
    	
    	private int getDistance(int x1, int y1, int x2, int y2)
    	{
    		int a = (x1 - x2) * (x1 - x2);
    		int b = (y1 - y2) * (y1 - y2);
    		return (int) Math.sqrt(a + b);
    	}
    	
    	
    	public static void main(String[] args) {
    		JFrame frame = new JFrame("A星寻路示例");
    		JPanel panel = new FindPathTest();
    		frame.getContentPane().add(panel);
    		frame.pack();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
    	}
    	
    	
    }
    
  • 相关阅读:
    maven公共库
    java截取当前屏幕图片
    JAVE视频处理
    jar在maven仓库里面没有时 , 把jar导入本地仓库步骤
    3 .shell 之linux四剑客sed/grep/awk/find
    Spring学习(四)-基于注解的Bean管理
    Spring学习(三)-Bean的种类,作用域,生命周期
    Spring学习(一)-基本入门
    dubbo服务连接zookeeper报错:java.net.ConnectException: Connection refused
    idea-常用设置二
  • 原文地址:https://www.cnblogs.com/chaohi/p/2064109.html
Copyright © 2011-2022 走看看