拼图游戏指将一幅图片分割成若干拼块,并随机打乱顺序,当将所有拼块都放回原位置时就完成了拼图(游戏结束)。
01、游戏介绍
在游戏中,拼块以随机顺序排列,网格上有一个位置是空的。完成拼图的方法是利用这个空位置移动拼块,玩家通过单击空位置周围的拼块来交换它们的位置,直到所有拼块都回到原位置。拼图游戏的运行界面如图1所示。
▍图1拼图游戏的运行界面
02、程序设计的思路
在游戏中动态生成一个3×3的图片按钮数组cells。将图片woman.jpg分割成行、列数均为3的小图片,并按顺序编号;每个图片按钮显示一幅小图片,其位置成员place存储0~8的数,代表正确的位置编号。注意,最后一个图片按钮显示的是空白信息图片“9.jpg”,而位置成员place存储8。
在游戏开始时,随机打乱图片按钮数组cells,根据玩家的单击来交换图片按钮数组cells对应按钮与空白图片按钮的位置,通过判断图片按钮数组cells中所有元素的位置成员place是否有序来判断是否已经完成游戏。
03、关键技术
1、按钮显示图片的实现
Swing中的按钮可以显示图片(图像)。
JButton中显示图片的构造方法为
JButton(Icon icon),用来在按钮上显示图片。
JButton类的方法设置不同状态下按钮显示的图片。
- setIcon(Icon defaultIcon):用来设置按钮在默认状态下显示的图片。
- setRolloverIcon(Icon rolloverIcon):设置当鼠标指针移动到按钮上方时显示的图片。
- setPressedIcon(Icon pressedIcon):设置当按钮被按下时显示的图片。
下面是一个控制鼠标指针移动到按钮上方及按钮被按下时显示不同图片的示例。
程序运行结果如图2和图3所示。
▍图2按钮被按下去时显示的图片
▍图3鼠标滚动时显示的图片
2、图片按钮移动的实现
当图片按钮移动后,按钮的坐标发生改变,此操作通过setLocation()方法实现。setLocation()方法是从Component类继承的,其定义如下:
public void.setLocation(int x,int y)
其中,参数x是当前组件的左上角在父级坐标空间中新位置的x坐标,参数y是当前组件的左上角在父级坐标空间中新位置的y坐标。
3、从BufferedImage转化成ImageIcon
BufferedImage类是java.awt.Image的子类,在image的基础上增加了缓存功能。
ImageIcon类是一个Icon接口的实现,它根据Image绘制Icon,可使用URL、文件名或字节数组创建的图像。
从BufferedImage转化成ImageIcon只需要使用“ImageIcon im=new ImageIcon(BufferedImage实例)”。
另外,使用ImageIcon的Image getImage()方法返回此图标的Image。
04、程序设计的步骤
项目组成如图4所示。
▍图4项目组成
1、设计单元图片类
创建名称为Cell的类,用于封装一个单元图片对象,此类继承JButton对象,并对JButton按钮组件进行重写,其代码如下:
2、创建枚举类型
在项目中创建一个名称为Direction的枚举类型,用于定义图片移动的4个方向。
3、设计游戏面板类
在项目中创建一个名称为GamePanel的类,此类继承JPanel类,实现MouseListener接口,用于创建游戏面板对象。在GamePanel类中定义长度为9个单元的图片数组对象cells,并通过init()方法对所有单元图片对象进行实例化。
构造方法GamePanel()调用init()对所有单元图片对象进行实例化。在对单元图片对象进行实例化时可以直接用分割好的图片1.jpg~9.jpg(如图9.5所示)实现,其中9.jpg为空白图片。
▍图5拼图所用图片
单元图片对象直接用现成的分割好的图片进行实例化,代码如下:
当然也可以不用现成的分割好的图片,使用BufferedImage类的getSubimage()方法可以将一个大的图片woman.jpg任意分割成子图像。
在使用时先得到一幅原图片的长和宽,根据要求分块,算出每块的x、y坐标,这样就可以分割了。注意,分割出来的是BufferedImage对象,而按钮的图片需要ImageIcon类型,从BufferedImage转化成ImageIcon只需要使用ImageIcon im=new ImageIcon(BufferedImage对象)。
random()对图片进行随机排序,产生两个随机数 m、n(0~8)作为被交换图片按钮数组 元素的下标,对调这两个被交换图片按钮的位置。
在图片块单击事件中,通过e.getSource()获取触发事件的对象cell,与空白图片块cellBlank的位置进行比较,从而决定被单击对象cell和空白图片块cellBlank的移动方向。
isSuccess()判断游戏是否成功,只需要判断图片块的原始位置cells[i].getPlace()是否符合现在的位置,只要有一个单元图片的位置不正确就返回false,所有单元图片的位置都正确时返回true。
4、设计主窗口类
在项目中创建一个继承JFrame的MainFrame类,用于显示自定义游戏面板(GamePanel)。
拼图游戏的总体设计情况如上,并没有很高深的内容,实现的核心在于对按钮数组的操作。拼图游戏成功的效果如图6所示。
▍图6游戏成功的效果