首先设置窗体和布局
使用BorderLayout,这是一个布置容器的边框布局,它可以对容器组件进行安排,并调整其大小,使其符合下列五个区域:北、南、东、西、中。每个区域最多只能包含一个组件,并通过相应的常量进行标识:NORTH、SOUTH、EAST、WEST、CENTER。当使用边框布局将一个组件添加到容器中时,要使用这五个常量之一,例如:
Panel p = new Panel();
p.setLayout(new BorderLayout());
p.add(new Button("Okay"), BorderLayout.SOUTH);
在这个项目中我们只需要两部分,将一个开始按钮添加到North区域,游戏面板添加到Center区域。
首先创建一个窗体,设置边框布局,添加容器,设置一个动作监听器
public void ShowUI() { // 主窗体的构造方法
// 设置窗体内容面板的布局为边界布局
JFrame draw=new JFrame();
draw.setLayout(new BorderLayout());
draw.setTitle("拼图游戏"); // 设置窗体的标题
draw.setSize(358, 414);
draw.setLocationRelativeTo(null);//设置相对位置
//draw.setBounds(300, 300, 358, 414); // 设置窗体的位置和宽高
draw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗体的关闭方式
// 实例化一个用来摆放“开始”按钮的面板
final JPanel panel = new JPanel();
// 把用来摆放“开始”按钮的面板添加到内容面板的上方(北部)
draw.add(panel, BorderLayout.NORTH);
// 实例化游戏面板
final GamePanel gamePanel = new GamePanel();
// 把游戏面板添加到内容面板的中间
draw.add(gamePanel, BorderLayout.CENTER);
// 实例化“开始”按钮
DrawListener d=new DrawListener();
d.set(gamePanel);
final JButton button = new JButton();
// 为“开始”按钮添加动作事件监听器
button.addActionListener(d);
button.setText("开始"); // 设置按钮中的文本内容
panel.add(button); // 把按钮添加到面板中
draw.setVisible(true); // 使主窗体可见
// 根据路径找到音乐路径,并创建音乐播放类
AudioPlayWave audioPlayWave = new AudioPlayWave("src/music/讨喜.wav");
audioPlayWave.start(); // 播放音乐
}
每个方格的设置
每个方格相当于一个按钮,让她可以点击,我们实现的是如果附近有一个空白,那么点击后就会移动位置。因为可以向四个方向移动,那么我们可以设置一个枚举类型。
public enum Direction{//移动的方向
Right,
Left,
Up,
Down
}
public static final int IMAGEWIDTH=117;
public int place;
public Cell(Icon icon,int place){
this.setSize(IMAGEWIDTH, IMAGEWIDTH);//图片的大小
this.setIcon(icon);//单元图片的图标
this.place=place;//图片的位置
}
public void move(Direction dir){
Rectangle rec=this.getBounds();//获取图片的Rectangle对象,获得左上角坐标和宽度
switch(dir){
case Right:
this.setLocation(rec.x+IMAGEWIDTH, rec.y);
break;
case Left:
this.setLocation(rec.x-IMAGEWIDTH, rec.y);
break;
case Up:
this.setLocation(rec.x, rec.y-IMAGEWIDTH);
break;
case Down:
this.setLocation(rec.x, rec.y+IMAGEWIDTH);
break;
}
}
public int GetX(){
return this.getBounds().x;
}
public int GetY(){
return this.getBounds().y;
}
public int GetP(){
return place;
}
初始化以及判断是否成功
将空白以外的图片设置鼠标监听,这样点击之后会移动位置,点击空白则不可以。利用一个random随机生成两个0~9之间的数,将这两个位置的图片交换位置。这样点击开始按钮之后就可以玩游戏了
public void init(){
int num = 0;
Icon icon=null;
Cell cell=null;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
num=i*3+j;
icon=SwingResourceManager.getIcon(GamePanel.class,"/pic/"+(num+1)+".jpg");
cell=new Cell(icon,num);//实例化单元图片对象
cell.setLocation(j*Cell.IMAGEWIDTH,i*Cell.IMAGEWIDTH);//设置坐标
cells[num]=cell;
}
}
for(int i=0;i<cells.length;i++){
this.add(cells[i]);
}
}
public void random(){
Random rand=new Random();
int m,n,x,y;
if(cellblack==null){
cellblack=cells[cells.length-1];
for(int i=0;i<cells.length-1;i++){
cells[i].addMouseListener(this);//对非空白图片添加鼠标监听器
}
}
for(int i=0;i<cells.length;i++){
m=rand.nextInt(cells.length);
n=rand.nextInt(cells.length);
x=cells[m].GetX();
y=cells[m].GetY();
cells[m].setLocation(cells[n].GetX(), cells[n].GetY());
cells[n].setLocation(x, y);
}
}
public boolean isSuccess(){
for(int i=0;i<cells.length;i++){
int x=cells[i].GetX();
int y=cells[i].GetY();
if(i!=0){
//判断单元图片的位置是否正确
if(y/Cell.IMAGEWIDTH*3+x/Cell.IMAGEWIDTH!=cells[i].place){
return false;
}
}
}
return true;
}
/**
* Invoked when a mouse button has been pressed on a component.
*/
public void mousePressed(MouseEvent e){
Cell cell =(Cell)e.getSource();//获取触发的时间对象
int x=cellblack.GetX();
int y=cellblack.GetY();
if ((x - cell.getX()) == Cell.IMAGEWIDTH && cell.getY() == y) {
cell.move(Direction.Right); // 向右移动
cellblack.move(Direction.Left);
} else if ((x - cell.getX()) == -Cell.IMAGEWIDTH && cell.getY() == y) {
cell.move(Direction.Left); // 向左移动
cellblack.move(Direction.Right);
} else if (cell.getX() == x && (cell.getY() - y) == Cell.IMAGEWIDTH) {
cell.move(Direction.Up); // 向上移动
cellblack.move(Direction.Down);
} else if (cell.getX() == x && (cell.getY() - y) == -Cell.IMAGEWIDTH) {
cell.move(Direction.Down); // 向下移动
cellblack.move(Direction.Up);
}
if(isSuccess()){
int i = JOptionPane.showConfirmDialog(this, "成功,再来一局?", "拼图成功", JOptionPane.YES_NO_OPTION); // 提示成功
if (i == JOptionPane.YES_OPTION) {
random(); // 开始新一局
}
}
}