汉诺塔动画

------多读多思,不停进取。


翻翻数据结构,以前一直没理解这东西,最近一看就懂了。想着普林斯顿大学貌似有个将算法做成动画的课程,动手做了一下。

总结:swing中,setVisible(true)之后获取画布。

   重写paint()方法才可画图。

     调用repaint()会闪屏,因为repaint()还会调用update(Graphics g)方法。

     直接调用update(Graphics g)方法就不闪了。

   线程可extends Thread或者implements Runnable。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;

import javax.swing.JFrame;

public class test2 extends JFrame implements Runnable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 85441201828193036L;
	Graphics2D grph;
	//柱子中心横坐标
	final int x1_mind=145;
	final int x2_mind=355;
	final int x3_mind=565;
	//栈元素
	Dish dish1;
	Dish dish2;
	Dish dish3;
	Dish dish4;
	//栈指针
	int Acount=4;
	int Bcount=0;
	int Ccount=0;
	ArrayList<Dish> Al_A;
	ArrayList<Dish> Al_B;
	ArrayList<Dish> Al_C;
	int point[]={350,280,210,140};
	public test2(){
		this.setTitle("汉诺塔");
		this.setLocation(200, 150);
		this.setSize(700, 500);
		this.setDefaultCloseOperation(3);
		
		this.setVisible(true);
		
		grph=(Graphics2D) this.getGraphics();
		
		//初始化栈
		Al_A=new ArrayList<Dish>();
		Al_B=new ArrayList<Dish>();
		Al_C=new ArrayList<Dish>();
		dish1=new Dish(x1_mind,350,100,30,Color.orange);
		dish2=new Dish(x1_mind,280,90,30,Color.orange);
		dish3=new Dish(x1_mind,210,80,30,Color.orange);
		dish4=new Dish(x1_mind,140,70,30,Color.orange);
		Al_A.add(dish1);
		Al_A.add(dish2);
		Al_A.add(dish3);
		Al_A.add(dish4);
		

	}
	public void HanioTower(int n ,char A,char B,char C)
	{
	
		if(n==1)
			MoveTo(A,C);
		else{
			HanioTower(n-1,A,C,B);
			MoveTo(A,C);
			HanioTower(n-1,B,A,C);
		}
		
	}
	public void MoveTo(char A,char C){
		System.out.println(A+"->"+C);
		if(A=='A' && C=='C')
		{
			Dish d_temp=Al_A.get(Acount-1);
			d_temp.setCenterX(x3_mind);
			Al_A.remove(Acount-1);
			Acount--;
			Al_C.add(d_temp);
			Ccount++;
		}else if(A=='A' && C=='B'){
			Dish d_temp=Al_A.get(Acount-1);
			d_temp.setCenterX(x2_mind);
			Al_A.remove(Acount-1);
			Acount--;
			Al_B.add(d_temp);
			Bcount++;
		}else if(A=='B' && C=='C'){
			Dish d_temp=Al_B.get(Bcount-1);
			d_temp.setCenterX(x3_mind);
			Al_B.remove(Bcount-1);
			Bcount--;
			Al_C.add(d_temp);
			Ccount++;
		}else if(A=='B' && C=='A'){
			Dish d_temp=Al_B.get(Bcount-1);
			d_temp.setCenterX(x1_mind);
			Al_B.remove(Bcount-1);
			Bcount--;
			Al_A.add(d_temp);
			Acount++;
		}else if(A=='C' && C=='A')
		{
			Dish d_temp=Al_C.get(Ccount-1);
			d_temp.setCenterX(x1_mind);
			Al_C.remove(Ccount-1);
			Ccount--;
			Al_A.add(d_temp);
			Acount++;
		}else if(A=='C' && C=='B')
		{
			Dish d_temp=Al_C.get(Ccount-1);
			d_temp.setCenterX(x2_mind);
			Al_C.remove(Ccount-1);
			Ccount--;
			Al_B.add(d_temp);
			Bcount++;
		}
		System.out.println("Acount="+Acount+" Bcount="+Bcount+" Ccount="+Ccount);
		update(grph);

		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	//画图方法
	public void paint(Graphics g){
			super.paint(g);	
			g.setColor(Color.BLACK);
			//中心x=145,355,565 y∈[80,400]
			g.fillRect(140, 80, 10, 320);
			g.fillRect(350, 80, 10, 320);
			g.fillRect(560, 80, 10, 320);
			
			grph.setColor(dish1.getRectColor());
			for(int i=0;i<Al_A.size();i++){
				grph.fillRect(Al_A.get(i).getCenterX()-Al_A.get(i).getHalf_len(), point[i]-Al_A.get(i).getHalf_wide(), 
						2*Al_A.get(i).getHalf_len(), 2*Al_A.get(i).getHalf_wide());
//				System.out.println((Al_A.get(i).getCenterX()-Al_A.get(i).getHalf_len())+"    "+(point[i]-Al_A.get(i).getHalf_wide()));
//				System.out.println((2*Al_A.get(i).getHalf_len())+"    "+(2*Al_A.get(i).getHalf_wide()));
			}
			for(int i=0;i<Al_B.size();i++){
				grph.fillRect(Al_B.get(i).getCenterX()-Al_B.get(i).getHalf_len(), point[i]-Al_B.get(i).getHalf_wide(), 
						2*Al_B.get(i).getHalf_len(), 2*Al_B.get(i).getHalf_wide());
			}
			for(int i=0;i<Al_C.size();i++){
				grph.fillRect(Al_C.get(i).getCenterX()-Al_C.get(i).getHalf_len(), point[i]-Al_C.get(i).getHalf_wide(), 
						2*Al_C.get(i).getHalf_len(), 2*Al_C.get(i).getHalf_wide());
			}
	}

	public static void main(String[] args) {
		test2 t=new test2();
		Thread t1=new Thread(t);
		t1.start();
	
	}
	//线程方法
	@Override
	public void run() {


		//不知道是不是画图线程和申请内存线程不大一样
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		

		//初始化塔
		grph.setColor(dish1.getRectColor());
		for(int i=0;i<4;i++)
			grph.fillRect(Al_A.get(i).getCenterX()-Al_A.get(i).getHalf_len(), Al_A.get(i).getCenterY()-Al_A.get(i).getHalf_wide(), 
					2*Al_A.get(i).getHalf_len(), 2*Al_A.get(i).getHalf_wide());

		try {
			Thread.sleep(1500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		HanioTower(4, 'A', 'B', 'C');
		
	}

}
class Dish{
	int centerX;
	int centerY;
	int half_len;
	int half_wide;
	Color rectColor;
	public Color getRectColor() {
		return rectColor;
	}
	public void setRectColor(Color rectColor) {
		this.rectColor = rectColor;
	}
	public int getCenterX() {
		return centerX;
	}
	public void setCenterX(int centerX) {
		this.centerX = centerX;
	}
	public int getCenterY() {
		return centerY;
	}
	public void setCenterY(int centerY) {
		this.centerY = centerY;
	}
	public int getHalf_len() {
		return half_len;
	}
	public void setHalf_len(int half_len) {
		this.half_len = half_len;
	}
	public int getHalf_wide() {
		return half_wide;
	}
	public void setHalf_wide(int half_wide) {
		this.half_wide = half_wide;
	}

	public Dish(int x,int y,int len,int wide,Color c)
	{
		centerX=x;
		centerY=y;
		half_len=len;
		half_wide=wide;
		rectColor=c;
	}
	
}

  设计思路:主要把目光放在MoveTo(char A,char C)方法上,移动之后刷新三个栈的内容,再遍历重绘。做成了一个定值,不想花时间去把参数改成活动性的了。

原文地址:https://www.cnblogs.com/chentingk/p/5644321.html