您的位置:首页 > 编程语言 > Java开发

基于Java的拼图游戏

2015-08-18 12:46 337 查看


项目需求:

用户可通过目录,选定要进行拼图的照片,照片经过处理后,被分割为3*3的小块;

将其中的小块放置到3*3的框中,其中的最右下角留白;

按上下左右方向键,移动方框中的照片小块,直到拼接出原始的图像,游戏结束;

已有资料:

http://blog.sina.com.cn/s/blog_5e3ab00c0100igqh.html

http://blog.sina.com.cn/s/blog_5e3ab00c0100ipz6.html

参考上述的源代码来完成自己的设计。

任务表:

完成对话框定位目录的功能(优先级低);

对定位到的图片进行标准化,分割处理(优先级高);

将分割后的图片贴在图文框中(优先级高);

添加对键盘的监听,重绘图像,形成移动的效果;每移动一次判断是否完成拼图(优先级高);

如何判断当前初始的拼图是否可拼?(优先级高)

任务2:

需要将图片进行分割,参考的源代码目录如下:

按照代码的名字,我们可以到Split中去看看是否有我们需要的内容,发现该类中的divid方法,正好完成对图片的分割工作,该部分代码可以拿来用。

public BufferedImage[][] divid(int type)

{

try

{

if(filename == null)

return null;

BufferedImage image = ImageIO.read(new File(path));

int len = level[type];

int cal = image.getWidth() / len;

int row = image.getHeight() / len;

BufferedImage [][] subimage = new BufferedImage[row][cal];

for (int i = 0; i < row; i++)

for (int j = 0; j < cal; j++)

subimage[i][j] = image.getSubimage(j*len, i*len, len, len);

return subimage;

}

catch (Exception e)

{

return null;

}

}

}

任务3:将分割后的图片贴在图文框中(优先级高);

此处是要对分割后的image进行处理,暂时我们跟着参考源代码看看,他是怎么做的:

public void menuNewClick()

{

Split sp = Split.get();

BufferedImage [][] image;

if(!sp.set(getFilename()) || (image = sp.divid(getType())) == null)

{

JOptionPane.showMessageDialog(null, "File"+getFilename()+" not exists!\nPlease select again~");

return;

}

startGame();

this.setSize(fWidth, fHeight);

this.setVisible(true);

intlen = Split.level[getType()];

introw = image.length;

intcal = image[0].length;

gOver = new GameOver(this);

JButton [][] button = new JButton[row][cal];

Matrix matrix = new Matrix(button, panel[0], len, gOver);

matrix.init(image);

从上述的代码可见,对于image分割方法的调用在image
= sp.divid(getType())),而对于image的进一步处理就落在matrix部分的init方法中。

public void init(BufferedImage [][] image)

{



icon = new ImageIcon(image[d/cal][d%cal]);

button[i/cal][i%cal].setIcon(icon);

}

}

从上述的代码可见,其主要的思路:将分割得到的image转化成为icon对象,然后再将icon对象设置给button;而在matrix的初始化函数中:

public Matrix(JButton [][] b, JPanel p, intlen, GameOver g){



for(int i = 0; i < row; i++)

for (int j = 0; j < cal; j++)

{

button[i][j] = new JButton();

button[i][j].setBounds(j*len, i*len, len, len);

button[i][j].addActionListener(new ButtonClick(button, pint, matrix, i,j, gOver));

panel.add(button[i][j]);

}

}

}

上述的代码给我们的设计指出大方向:将整个的panel划分为3*3的区域,其中的依次无缝隙放置9个按钮;然后再将我们的图片分割为3*3的小块,再将每个小块转化为icon类型贴在每个按钮的表面,如此完成游戏的静态设置。

任务4:添加对键盘的监听,重绘图像,形成移动的效果;每移动一次判断是否完成拼图(优先级高);

本任务总体可分解得子任务:

如何产生移动的效果?

如何判断拼图是否完成?

按照任务3中的总体设计,实现移动的效果:要么移动按钮在panel中的位置,要么重置按钮上的icon;上述只是粗略的技术路线,还需要具体到:

每条路线的具体实现难度;

该技术路线与后续任务协同上的难易程度;

启发:技术路线的除了考虑自身的难易程度,还需要考虑与其他技术的协同难度;

先不想动手?那就在脑子里跑火车,看看上述两条技术路线的技术难度:

如果采用重置icon的方式,那就是每次沿着按键方向,将前者的icon置为空白的即可;而判断是否已经处于拼图完成状态,只需要检查每个按钮上的icon是否按顺序排列;

如果采用移动按钮的方式,只不过是带着icon一起移动而已,因为我们要的只是icon的移动,所以两者方式的对比,更合理的是第一种方式。

任务5.2:如何判断拼图当前是否已经完成?

此处需要记录各个icon所对应的imag变化的情况,也即记录当前的icon重置后,需要记录其位置的变化。此处的思路可以有:1.
根据icon身上附加的属性,根据icon身上的信息判断当前的布局是否满足拼图完成的条件;2.
建立icon位置相对应的数据结构,比如3*3的二维数组,给每个icon设定一个初始的编号:

如果第8个位置对应的icon,移动到空格的位置,那么对应的二维数组变为:

拥有这样的对应icon位置的二维数组,那么判断当前的拼图是否出于完成状态就简单很多了,只要查看下二维数组中的数据是否按序排列即可。

任务5:判断初始化的拼图是否可拼?

我们百度下,看看网上是否有相关资料:

/article/5092382.html

/article/8953433.html

数学终于派上用场,使用到数学是大学一年级的线性代数。此处具体的细节与数学证明略过。主要的结论:二维数组中数的逆序对,如果逆序对为偶数,说明可拼图;否则,就不可以。那剩下的就只是用两层循环来判断下逆序对的数量。

按照上述的设计,拼图的技术框架构建完成。

拼图游戏-实现方案

以下罗列技术方案中的主要任务:

完成对话框定位目录的功能(优先级低);

对定位到的图片进行标准化,分割处理(优先级高);

将分割后的图片贴在图文框中(优先级高);

添加对键盘的监听,重绘图像,形成移动的效果;每移动一次判断是否完成拼图(优先级高);

如何判断当前初始的拼图是否可拼?(优先级高)

实现1:

任务2中对图形的处理和分割可以独立到一个类中,如参考源代码中的处理方式,独立为handlePic类;

主要方法:完成对该图像的分割,并且返回分割后的对象;

实现2:

判断当前的拼图是否已经完成,使用二维数组,该二维数组还需要提供必要的方法,所以将其设计为独立的类Matrix类;

主要方法1:提供二维数组中的数据交换;

主要方法2:检查当前的二维数组,查看是否已经处于拼图完成状态;

主要方法3:提供初始(可拼接)的二维数组,根据该二维数组来完成分割后image到按钮的对应;

实现3:

界面的创建:创建一个主界面类,其中添加Panel以及3*3个的button对象,再调用handlePic类和Matrix类完成icon的初始化;将类的名字暂时命名为puzzle;

实现4:

对于按键或者鼠标的响应:出于简单,我们只实现关于鼠标点击按钮的事务处理。问题来了:并不是点击所有的按钮都有反应,有反应的按钮主要是其周边存在空白的那个按钮。所以需要判断当前被点击的按钮与空白按钮的距离;只有当两者相邻的时候才能进行icon重置的操作。
此处就涉及到两个对象,其中一个负责按钮的事务处理;另一个表示当前空白的那个按钮;

事务处理的按钮暂停命名为:buttonClick。

而空白按钮也作为一个对象hole,其包含的主要方法:

方法1:设置当前空白按钮所在的坐标;

方法2:判断当前hole的位置是否与被点击的按钮相邻;

按照上述方案,拼图游戏基本可以实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: