基于Java的拼图游戏设计与实现

2019-03-15 13:31苟雨晴兰全祥
电脑知识与技术 2019年2期

苟雨晴 兰全祥

摘要:利用Java的图形界面和图形图像绘制、鼠标监听以及键盘监听等技术实现了一个拼图游戏。对拼图游戏的功能进行分析和设计,实现了拼图随机打乱、难度设置、移动次数统计、原图预览、还原检测以及排行榜等功能。基于Java的拼图游戏设计与实现综合了Java開发基础、Java反射、事件处理、图形界面编程以及多线程等知识,不仅对Java课程的教学有一定的辅助作用,还能提高学习者对Java的兴趣,锻炼程序设计思维。

关键词:swing;拼图;游戏开发;事件处理

中图分类号:TP311      文献标识码:A      文章编号:1009-3044(2019)02-0045-03

1 概述

拼图游戏一般是以九宫格形式展现,玩家通过鼠标或者键盘移动其中某一滑块将乱序的图片还原,图片还原则游戏成功[1]。Java作为目前最流行的编程语言之一,在JDK 1.2之后的java.swing包、java.awt包中提供了功能强大的图形用户界面设计,开发人员可以使用少量的代码设计具有界面效果的游戏[2]。

本文在Java Swing的基础上,利用Java的图形界面、多线程和事件监听等技术来实现此拼图游戏[3]。对拼图游戏的功能进行分析和设计,实现了拼图原图预览、随机打乱、难度设置、移动次数统计、还原检测以及排行榜等功能。

2功能分析与设计

2.1功能设计

设计完成一个拼图游戏需要实现以下功能:

1)游戏初始化:程序运行,启动游戏窗口。游戏窗口包括为玩家提供操作方法的功能区以及供玩家拼图的游戏区。

2)游戏难度设置:玩家可以自由改变游戏难度。游戏难度分为入门(3行3列)、一般(4行4列)、困难(5行5列)三个级别,同时图片也将分割成不同的块数。

3)图片乱序:玩家点击“开始游戏”之后,程序将随机打乱所有滑块。打乱之后应保证可以还原。

4)步数统计:玩家可以利用鼠标点击滑块或键盘控制滑块进行移动,每移动一次步数加一,并在界面上显示移动的总步数。

5)排行榜:在游戏开始前,玩家可以查看游戏排行榜;在游戏结束后,玩家可以输入自己的名字,游戏会根据步数计算分数并更新排行榜。

6)退出游戏:点击结束游戏按钮和窗口上的关闭按钮都可以结束游戏。

2.2游戏界面

本游戏利用Swing的相关组件实现游戏界面,如图1所示。

游戏界面主要分为上下两个区域,上方区域为功能区,包括预览、计步、难度设置、开始游戏、结束游戏、排行榜等功能按钮;下方区域为游戏区,玩家在此区域进行拼图游戏。

3 游戏设计与实现

3.1游戏整体设计

通过对游戏需求进行分析,对所需对象及功能进行抽象和封装,形成游戏整体类图,如图2所示。

3.2 功能实现

3.2.1 游戏初始化

游戏初始化阶段,主要对游戏界面进行生成并在游戏区中加载拼图游戏图片。游戏区初始化时,根据图片的宽度和高度以及游戏难度使用BufferedImage类的getSubimage()方法将对图片进行分割,然后使用继承了JButton的Cell类来保存所有的滑块,并使用javax.swing.Icon类的方法将分割之后的图片设置给Cell类的对象,其实现的关键代码如下。

cells[index] = new Cell(new ImageIcon(image), index, width, height);

其中,image是分割之后的图片,index是滑块的下标,width和hight是滑块的宽度和高度。

3.2.2 游戏难度设置

本游戏采用下拉列表进行游戏难度的设置。在下拉列表中添加入门、一般和困难三个值,并为下拉框设置监听事件。当下拉列表的值发生改变之后,游戏区将根据新的难度重新分割图片并加载新的游戏面板。

comboBoxn.addItemListener(

new ItemListener() {

public void itemStateChanged(ItemEvent e){/*根据所选游戏难度重置游戏面板*/});

3.2.3 开始游戏

随机获得不同的移动方向(上下左右,分别用0-3数字表示),然后将白色滑块与该方向上的滑块进行交换[4]。重复执行10*col*row次交换后既实现了随机打乱,且能保证能经过有限次移动能够将拼图还原[5]。

int times = row * col * 10;

Random random = new Random();

for (int i = 0; i < times; i++) {

int dir = random.nextInt(4);

move(blankCell,dir); } }

其中,move(blankCell,dir)方法表示空白滑块向dir方向移动。当空白滑块向dir方向移动时,该方向上的其他滑块移动至空白滑块处。

3.2.4 滑块移动(键盘、鼠标)

玩家可以通过键盘或鼠标将滑块向上下左右四个方向移动,因此本文设计并实现了方向枚举类、移动方法move、键盘监听以及鼠标监听。

1)方向枚举

定义方向枚举类Direction,存放上下左右四个方向。

public enum Direction {

UP,DOWN,LEFT,RIGHT}

2)move方法

图片移动方法的本质是将滑块的坐标直接设置为目标位置坐标,目标位置坐标将由当前滑块位置以及移动方向来决定,部分关键代码如下。

Rectangle rec = getBounds();

switch (dir) {

case UP:// 向上移动

if (rec.y - HEIGHT>=0) {

setLocation(rec.x, rec.y- HEIGHT);

}break;

/*省略其他方向移动代码*/

其中dir表示移动方向的枚举,HEIGHT表示滑块的高度。

3)键盘监听

要实现键盘移动滑块功能,则需要对游戏窗体进行键盘事件监听,因此对游戏窗体GameFrame添加keyPressed事件监听。当监听到键盘事件时,将触发游戏区中滑块的移动,关键代码如下。

int index = e.getKeyCode();

boolean flag = false;

switch (index){

case KeyEvent.VK_W: //按下键盘w上升

case KeyEvent.VK_UP:{

flag = swap(cell, Direction.UP);

break;}

需要注意的是由于面板上存在功能区,因此在开始游戏之后应使用了setEnabled()方法,禁用面板上的按钮组件,并使面板重新获得焦点,以确保键盘监听有效。

4)鼠标监听

在游戏过程中玩家可以点击滑块进行移动。为了实现鼠标移动滑块的功能,在初始化阶段将对所有滑块添加鼠标事件监听。

for (int i = 0; i < cells.length-1; i++) {

cells[i].addMouseListener(this);}

当鼠标点击滑块时,先得到该滑块的坐标位置,然后与空白滑块的横纵坐标位置进行比较,即将滑块是否能移动转换为数学问题[6]。如果两个刚好相差一个滑塊的高度或宽度(代表被点击滑块刚好位于空白滑块周围),则将两者进行交换;否则,不进行交换。

if (compared(cell, blankCell)==width){ cell.move(Direction.LEFT);

blankCell.move(Direction.RIGHT);}

如果当前滑块与空白块横纵坐标相差为width,则说明当前滑块在空白块的右边,则代表当前滑块可以与空白块进行交换,即当前滑块左移,空白块右移。

3.2.5步数统计

为了对玩家成绩进行排名,游戏设计了计步功能。在程序中定义了一个静态变量用于存放游戏步数,当点击鼠标或敲击键盘时该静态变量的值增加1。

public static void changeStep() {count++;}

3.2.6还原检测

在游戏开始前,程序将使用一个字符串来存储未打乱时各个滑块的位置,然后用另一个字符串来存储打乱或移动之后的滑块位置。每次移动滑块之后都将对这两个字符串进行比较,如果两个字符串的值相同,则表示图片已还原,弹出消息提示框告知玩家拼图成功。

for (int i = 0; i< cells.length;i++ ){

newStr+=cells[i].getX()+cells[i].getY();}

if(!oldStr.equals(newStr)){return false;}

else{return true;}

3.2.7排行榜

当拼图成功之后,游戏将显示一个消息框供玩家输入姓名。定义一个玩家信息类PlayerInfo,游戏结束后程序将用获取到游戏步数与玩家姓名初始化该类的对象,并将信息写入文件score中。当用户点击排行榜进行查看时,程序将对score文件进行反序列化,将文件中的信息读出并排序,然后使用Graphics重写paint方法绘制在界面上,排行榜效果图如下。

4 结束语

基于Java的拼图游戏设计与实现综合了Java反射、事件处理、图形界面编程以及多线程等知识,不仅对Java课程的教学有一定的辅助作用,还能提高学习者对Java的兴趣,锻炼程序设计思维。

参考文献:

[1] 曹戴. 智能数字拼图算法研究及其应用[D].无锡:江南大学,2017.

[2] 耿祥义, 张跃平. Java 2实用教程[M]. 4版.北京:清华大学出版社, 2012.

[3] 张会.基于Java的指法练习小游戏的设计与实现[J].电脑知识与技术,2017,13(32):85-86+96.

[4] 黄俊.基于Unity3d拼图游戏的设计与实现[J].电子世界,2017(16):145.

[5] JiongXing[EB/OL]. (2018-05-04)[2018-12-14]. https://github.com/JiongXing/PuzzleGame.

[6] 余战秋.基于App Inventor的九宫格拼图游戏设计与实现[J].电脑编程技巧与维护,2017(18):34-36.