拼图游戏 任务说明 本实例实现了拼图游戏的开发 运行程序, 单击 开始 按钮将打乱图片的位置, 效果如图 1 所示, 然后通过鼠标单击图片进行移动, 直到将所有图片都移动到正确位置, 游戏过关, 过关后的效果如图 2 所示 图 1 打乱图片位置的效果图 2 图片移动到正确位置的效果 关键技术 本程序主要通过 Swing 与枚举类实现, 程序将一幅完整的图片平均分成 9 部分, 每一部分为一个正方形, 并将最后一个图片修改为空白图片, 作为游戏中的一个空位置 对于每一个图片部分, 程序封装了一个按钮对象进行装载, 当该按钮对象被单击后, 程序将调换该按钮与装载空白图片的按钮, 其关键技术是使用枚举类控制方向, 以及使用 setlocation() 方法设置按钮的位置 (1) 本实例通过枚举类定义了图片移动的 4 个方向, 分别为上 下 左 右, 其定义方式与定义一个类相似, 但定义枚举类使用关键字 enmu, 枚举类 Direction 的定义如下 : 01 public enum Direction { UP, DOWN, // 上 // 下
LEFT, RIGHT // 左 // 右 (2) 当图片移动后, 按钮的坐标发生改变, 此操作通过 setloca tion() 方法实现 setlocation() 方法是从 Component 类继承的, 其定义如下 : public void setlocation(int x, int y) 参数说明 x: 当前控件左上角在父级坐标空间中新位置的 x 坐标 y: 当前控件左上角在父级坐标空间中新位置的 y 坐标 实现过程 (1) 新建一个项目 (2) 在项目中创建一个名称为 Direction 的枚举类, 用于定义图片移动的 4 个方向, 其关键代码见关键技术部分 (3) 创建名称为 Cell 的类, 用于封装一个单元图片对象, 此类继承 JButton 对象, 并对 JButton 按钮组件进行重写, 其关键代码如下 : 01 public class Cell extends JButton { private static final long serialversionuid = 718623114650657819L; public static final int IMAGEWIDTH = 117; private 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 UP: // 向上移动 this.setlocation(rec.x, rec.y - IMAGEWIDTH); case DOWN: // 向下移动 this.setlocation(rec.x, rec.y + IMAGEWIDTH); case LEFT: // 向左移动
this.setlocation(rec.x - IMAGEWIDTH, rec.y); case RIGHT: // 向右移动 this.setlocation(rec.x + IMAGEWIDTH, rec.y); public int getx() { return this.getbounds().x; // 获取单元图片的 x 坐标 public int gety() { return this.getbounds().y; // 获取单元图片的 y 坐标 public int getplace() { return place; // 获取单元图片的位置 (4) 创建名称为 GamePanel 的类, 此类继承 Jpanel 类 实现 M ouselistener 接口, 用于创建游戏面板对象 在 GamePanel 类中定义长度为 9 单元的图片数组对象, 并通过 init() 方法对所有单元图片对象进行实例化, 其关键代码如下 : 01 public class GamePanel extends JPanel implements MouseListener { private static final long serialversionuid = -653831947783440122L; private Cell[] cells = new Cell[9]; // 创建单元图片数组 private Cell cellblank = null; // 空白 public GamePanel() { super(); setlayout(null); // 设置空布局 init(); // 初始化 // 初始化游戏 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(); // 实例化 Random int m, n, x, y; if (cellblank == null) { // 判断空白的图片位置是否为空 cellblank = cells[cells.length - 1]; // 取出空白的图片 if (i!= cells.length - 1) { // 对非空白图片注册鼠标监听 cells[i].addmouselistener(this); 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); @Override public void mousepressed(mouseevent e) { Cell cell = (Cell) e.getsource(); // 获取触发时间的对象 int x = cellblank.getx(); int y = cellblank.gety(); if ((x - cell.getx()) == Cell.IMAGEWIDTH && cell.gety() == y) { cell.move(direction.right); // 向右移动 cellblank.move(direction.left); else if ((x - cell.getx()) == -Cell.IMAGEWIDTH && cell.gety() == y) { cell.move(direction.left); // 向左移动
cellblank.move(direction.right); else if (cell.getx() == x && (cell.gety() - y) == Cell.IMAGEWIDTH) { cell.move(direction.up); // 向上移动 cellblank.move(direction.down); else if (cell.getx() == x && (cell.gety() - y) == -Cell.IMAGEWIDTH) { cell.move(direction.down); // 向下移动 cellblank.move(direction.up); if (issuccess()) { // 判断是否拼图成功 int i = JOptionPane.showConfirmDialog(this, " 成功, 再来一局?", " 拼图成功 ", JOptionPane.YES_NO_OPTION); // 提示成功 if (i == JOptionPane.YES_OPTION) { random(); // 开始新一局 /** * 判断是否拼图成功 * @return 布尔值 */ public boolean issuccess() { int x = cells[i].getx(); int y = cells[i].gety(); if (i!= 0) { if (y / Cell.IMAGEWIDTH * 3 + x / Cell.IMAGEWIDTH!= cells[i].getplace()) { // 判断单元图片位置是否正确 return false;// 只要有一个单元图片的位置不正确, 就返回 false return true; // 所有单元图片的位置都正确返回 true