import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
//生成的类负责创建Hannoi塔,Hannoi塔由A,B,C三个塔组成,可以用鼠标搬运各个塔上的盘子。
public class HannoiTower extends JPanel implements MouseListener,MouseMotionListener
{
TowerPoint point[]; //TowerPoint数组
int x,y; //x,y坐标,在绘制汉诺塔时用到
boolean move=false; //设置是否移动,初始值为否
Disk 盘子[];//实例化盘子
int startX,startY; //拖动的开始位置
int startI ; //用于判断开始是在哪个TowerPoint上
int 盘子数目=0;//塔上的盘子数目,初始值为0。
int width,height; //汉诺塔的塔高和塔宽
char towerName[]={'A','B','C'}; //三个塔的名字,分别是A、B、C
TextArea 信息条=null; // 设置信息条,用于描述塔上盘子移动的情况。
int p,t; //用于求是哪个盘子
//构造函数
public HannoiTower(int number,int w,int h,char[] name,TextArea text)
{
towerName=name;
盘子数目=number;
width=w;
height=h;
信息条=text;
setLayout(null);//未布局
addMouseListener(this);//添加鼠标事件
addMouseMotionListener(this);//添加鼠标移动事件
盘子= new Disk[盘子数目];//实例化盘子
point=new TowerPoint[3*盘子数目]; //设置塔上放盘子的点
int space=20; //用于设置点的高度
for(int i=0;i<盘子数目;i++) //实例A化塔上的点
{
point[i]=new TowerPoint(40+width,100+space,false);
space=space+height;
}
space=20;//用于设置点的高度
for(int i=盘子数目;i<2*盘子数目;i++) //实例化B塔上的点
{
point[i]=new TowerPoint(160+width,100+space,false);
space=space+height;
}
space=20;//用于设置点的高度
for(int i=2*盘子数目;i<3*盘子数目;i++) //实例化C塔上的点
{
point[i]=new TowerPoint(280+width,100+space,false);
space=space+height;
}
int tempWidth=width;//用于设置盘子宽度变量。
int sub=(int)(tempWidth*0.2);//用于设置盘子宽度变量。
for(int i=盘子数目-1;i>=0;i--) //初始化塔上的盘子
{
盘子[i]=new Disk(i,this);
盘子[i].setSize(tempWidth,height);
tempWidth=tempWidth-sub;
sub=(int)(tempWidth*0.3);
}
for(int i=0;i<盘子数目;i++) //放置盘子
{
point[i].放置盘子(盘子[i],this);
if(i>=1)
盘子[i].set上方有盘(true);
}
}
//绘制组件
public void paintComponent(Graphics g)
{
//Calls the UI delegate's paint method, if the UI delegate is non-null. We pass the delegate a copy of the Graphics object
//to protect the rest of the paint code from irrevocable changes (for example, Graphics.translate).
super.paintComponent(g);
//绘制汉诺塔
g.drawLine(point[0].getX(),point[0].getY(),
point[盘子数目-1].getX(),point[盘子数目-1].getY());
g.drawLine(point[盘子数目].getX(),point[盘子数目].getY(),
point[2*盘子数目-1].getX(),point[2*盘子数目-1].getY());
g.drawLine(point[2*盘子数目].getX(),point[2*盘子数目].getY(),
point[3*盘子数目-1].getX(),point[3*盘子数目-1].getY());
//绘制塔的底部
g.drawLine(point[盘子数目-1].getX()-width,point[盘子数目-1].getY(),
point[3*盘子数目-1].getX()+width,point[3*盘子数目-1].getY());
//绘制塔的底部
int leftx=point[盘子数目-1].getX()-width;
int lefty=point[盘子数目-1].getY();
int w=(point[3*盘子数目-1].getX()+width)-(point[盘子数目-1].getX()-width);
int h=height/2;
g.setColor(Color.orange);
g.fillRect(leftx,lefty,w,h);
//绘制TowerPoint
g.setColor(Color.red);
int size=4;
for(int i=0;i<3*盘子数目;i++)
{
g.fillOval(point[i].getX()-size/2,point[i].getY()-size/2,size,size);
}
//绘制塔下的文字描述
g.drawString(""+towerName[0]+"塔",point[盘子数目-1].getX(),point[盘子数目-1].getY()+30);
g.drawString(""+towerName[1]+"塔",point[2*盘子数目-1].getX(),point[盘子数目-1].getY()+30);
g.drawString(""+towerName[2]+"塔",point[3*盘子数目-1].getX(),point[盘子数目-1].getY()+30);
//绘制游戏说明
g.drawString("将全部盘子从"+towerName[0]+"塔搬运到"+towerName[1]+"塔或"+towerName[2]+"塔",
point[盘子数目-1].getX(),point[盘子数目-1].getY()+80);
}
//Invoked when a mouse button has been pressed on a component.
public void mousePressed(MouseEvent e)
{
Disk 盘子=null;
Rectangle rect=null;
if(e.getSource()==this)
move=false;//设置不能移动
if(move==false)
if(e.getSource() instanceof Disk)//若点击的对象是盘子
{
盘子=(Disk)e.getSource();
startX=盘子.getBounds().x; //设置开始位置x坐标
startY=盘子.getBounds().y; //设置开始位置y坐标
rect=盘子.getBounds();//初始化Rectangle
for(int i=0;i<3*盘子数目;i++) //判断开始实在哪个TowerPoint上的
{
int x=point[i].getX();
int y=point[i].getY();
if(rect.contains(x,y))
{
startI=i;
break;
}
}
}
}
//空事件
public void mouseMoved(MouseEvent e)
{
}
//用鼠标拖动按钮的事件
public void mouseDragged(MouseEvent e)
{
Disk disk=null;
if(e.getSource() instanceof Disk)
{
disk=(Disk)e.getSource();
move=true;
//Returns a MouseEvent similar to sourceEvent except that its x and y
//members have been converted to destination's coordinate system.
e=SwingUtilities.convertMouseEvent(disk,e,this);
}
//设置盘子的位置
if(e.getSource()==this)
{
if(move&&disk!=null)
{
x=e.getX();
y=e.getY();
if(disk.get上方有盘()==false)
disk.setLocation(x-disk.getWidth()/2,y-disk.getHeight()/2);
}
}
}
//释放鼠标事件
public void mouseReleased(MouseEvent e)
{
Disk disk=null;
move=false;
Rectangle rect=null;
//若释放之前,鼠标点在盘子上
if(e.getSource() instanceof Disk)
{
disk=(Disk)e.getSource();
rect=disk.getBounds();
//Returns a MouseEvent similar to sourceEvent except that its x and y
//members have been converted to destination's coordinate system.
e=SwingUtilities.convertMouseEvent(disk,e,this);
}
//用于判断disk是否在某个TowerPoint内
if(e.getSource()==this)
{
boolean containTowerPoint=false;//设置包含为错