本文主要是介绍Java项目 拼图游戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
1 项目基本信息
1.1 项目名称
1.2 实训环境
2 实训内容简介
2.1 拼图游戏
3 项目开发过程
3.1 拼图游戏
3.1.1 核心类
3.1.2开发步骤
4 实训总结及心得
1 项目基本信息
1.1 项目名称
拼图游戏
1.2 实训环境
JDK1.8 、eclipse 、 mysql 、navicat、Windows
2 实训内容简介
2.1 拼图游戏
拼图游戏内容由若干小图像块组成的,其中有一个空白的小图像块,该图像块是来与别的图像块交换的,以此来实现大图像的拼凑。在Java标准环境下运行,通过鼠标点击图像块上下左右移动,完成大图像的拼凑。通过所创建的窗体类、菜单、中间面板和左右面板完成设计拼图的交互界面,实现游戏登录、开始游戏、退出游戏、选择图片、图片缩放、图片分割、调整难易度、计数计时、打乱图片、判断拼图成功等功能。游戏可以通过对图片文件的读取和加载,从多张图片中选择来进行拼图游戏,通过设置图像块的个数来实现对游戏难易度的调整,最后将游戏完成后所用时间和步数记录到游戏记录中,方便用户查看游戏记录。
3 项目开发过程
3.1 拼图游戏
3.1.1 核心类
1.MainJFrame类:继承JFrame类,实现Runnable接口,窗体用于存放发左右面板,添加组件等等。知识点有:
a.实现游戏关卡等级
itemeasy.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {rp.hs=2; //第一,传递2*2到右面板rp.ls=2;rp.init(url); //调用右面板组件初始化的方法}});
b. 游戏记录
itemchange.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {
//显示一个打开对话框,选择一个图片文件,将文件转换为url对象,调用左右面板的相应方法JFileChooser jfc=new JFileChooser();
//设置文件的扩展名jfc.setFileFilter(new FileNameExtensionFilter("图片格式(jpg|png|jif)", "jpg","png","gif"));
//弹出打开对话框int sd=jfc.showOpenDialog(MainJFrame.this);//null表示父容器是谁if(sd==jfc.APPROVE_OPTION)//如果用户选择打开了按钮{
//获取用户选择的文件完整名称String file=jfc.getSelectedFile().getAbsolutePath();try {url=new URL("file:\\"+file);lp.init(url);rp.init(url);} catch (MalformedURLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}});
c. //记录清空itemclear.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {File f=new File("c://a");if(f.exists()){f.delete();}}});
d. 实现计时并显示步数@Overridepublic void run() {//死循环,使得代码一直在执行while (true) {endTime = System.currentTimeMillis();total_time.setText("用时:"+(endTime - startTime) / 1000 );total_count.setText("步数:"+rp.times);try {Thread.sleep(500);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
2.LeftJPanel类:左面板,将完整图片展示在左面板。知识点:
实现图片的缩放:
public void init(URL url){ImageIcon icon=new ImageIcon(url);//使用链式编程方式实现图片缩放jl.setIcon(new ImageIcon(icon.getImage().getScaledInstance(width, height, 1)));//将标签添加到面板中this.add(jl);}
3.RightJPanel类:右面板实现ActionListener接口,右面板成为了监听器,实现拼图。重要知识点:
a.确定按钮的位置和大小
bs=new JButton[hs*ls]; //创建按钮数组
widthbut=width/ls;// 计算按钮的宽度高度heightbut=height/hs;
for(int i=0;i<jbs.length;i++){//为每一个按钮实现初始化操作jbs[i]=new JButton();jbs[i].setSize(widthbut, heightbut);jbs[i].setLocation(i%ls*widthbut,i/ls*heightbut);// 添加按钮前要确定坐标位置
b. //图片的获取
BufferedImage subimage=buf.getSubimage(i%ls*widthxt,i/ls*heightxt, widthxt, heightxt); //小图的获取
c. //图片的缩放
Image image=subimage.getScaledInstance(widthbut, heightbut, 1);
d. //将小图图片放到按钮上
jbs[i].setIcon(new ImageIcon(image));
e. //设置按钮变色,不可用
jbs[i].setEnabled(false);
f. //设置按钮的监听,当按钮被单击,找ActionListener方法执行
jbs[i].addActionListener(this);
g. //设置最后一个按钮图片为空jbs[hs*ls-1].setIcon(null);kb=jbs[hs*ls-1];
h. //打乱按钮在面板中的顺序Random rand=new Random();//创建随机数对象for(int i=0;i<hs*ls;i++){ //打乱多次 for//生成两个随机数表示数组下标,互换两个数组元素的位置int index1 = rand.nextInt(hs * ls);int index2 = rand.nextInt(hs * ls);// getX 和getY 可以获取按钮的坐标位置int x1 = jbs[index1].getX();int y1 = jbs[index1].getY();int x2 = jbs[index2].getX();int y2 = jbs[index2].getY();jbs[index1].setLocation(x2, y2);jbs[index2].setLocation(x1, y1);jbs[i].setEnabled(true);}
i. //获取用户单击的按钮,通过ActionEvent e的方法getSource获取事件源,需要将得到的object类型中转换为按钮类型
JButton jb=(JButton)e.getSource();
j. //获取单击按钮和空白按钮的坐标int x1=jb.getX();int y1=jb.getY();int x2=kb.getX();int y2=kb.getY();
k. //判断单击按钮和空白按钮是否相邻,相邻则位置互换
if(Math.abs((x1-x2)/widthbut)+Math.abs((y1-y2)/heightbut)==1){jb.setLocation(x2, y2);// 用Math.abs取绝对值kb.setLocation(x1, y1);times++;}
l. //判断是否拼图成功if(isWin()){JOptionPane.showMessageDialog(null, "恭喜,拼图成功,总共步数:"+times);//使得按钮不可用for(int i=0;i<jbs.length;i++){jbs[i].setEnabled(false);}
m. //创建文件字符输出流对象,指向c盘,追加数据到文件
String info=hs+"*"+ls+"拼图的记录:"+name+"步数是:"+times+"\r\n";
FileWriter fw=new FileWriter("c://a//1.dat",true);fw.write(info);fw.close();
n. //获取每个按钮的坐标for(int i=0 ; i<jbs.length;i++){int x=jbs[i].getX()/widthbut;int y=jbs[i].getY()/heightbut;//方法二:通过下标值,也可获取按钮坐标 横坐标:i%ls 纵坐标 i/lsif(i%ls!=x || i/ls!=y){return false;}}
4.TpJFrame类:实现图片分割功能。知识点有:
a. //显示一个打开对话框,选择一个图片文件,将文件转换为url对象, JFileChooser jfc=new JFileChooser();
b. //设置文件的扩展名jfc.setFileFilter(new FileNameExtensionFilter("图片文件", "jpg","bmp","jpeg"));
c. //获取用户选择的文件完整名称
jfc.getSelectedFile().getAbsolutePath()d.//获取图片后,将图片转换成Image类型的对象,进行缩放,然后再将Image类型对象转换成ImageIcon类型的对象,将图片放到jlb中
jlb.setIcon(new ImageIcon(new ImageIcon (jtf.getText()).getImage().getScaledInstance(100,100, 1)));
e. //从本地文本读取图片BufferedImage buf=ImageIO.read(new File(jtf.getText()));
f. //设置该面板标题
jp3.setBorder(BorderFactory.createTitledBorder("选择保存位置"));
3.1.2开发步骤
1.配置开发环境,进行环境变量的配置:JAVA_HOME,path。
2.创建窗体类MainJFrame,设置窗体大小、标题、窗体大小是否可变、窗体位置等等。在窗体内设置菜单、菜单项、单选菜单项等信息,并添加到窗体内。明确左面板、右面板、中间面板和窗体的关系:在窗体中设置一个中间面板,中间面板包括左面板和右面板。
3.中间面板布局方式为网格布局。添加左面板和右面板:左面板(LeftJPanel)为自定义面板,继承JPanel;右面板(RightJPanel)为自定义面板,继承JPanel。
4.左面板的设计:首先在主窗体中定义,将左面板添加到中间面板,再将中间面板添加到窗体,并进行初始化。然后在左面板类中添加一个标签,并在标签上显示图片,并实现图片缩放。
在标签上显示图片的方法为:
ImageIcon(URL location)根据指定的 URL 创建一个 ImageIcon。相对路径:url=this.getClass().getResource("s4.jpg");绝对路径:url=new URL(“file:\\”+”d:\\abc\\1.jpg”);
实现图片缩放的方法:图片放置在标签中,使用的类是ImageIcon,这个类没有缩放功能,Image类有缩放功能。所以要实现ImageIcon类和Image类相互转换。转换方法:
a.将ImageIcon的对象转换成Image类型的对象:public Image getImage()icon.getImage().getScaledInstance(700,700,1)b.将Image类型对象转换成ImageIcon类型的对象:ImageIcon的构造方法 ImageIcon(Image image)
5.右面板的设计:首先在主窗体中定义,将右面板添加到中间面板,再将中间面板添加到窗体,并进行初始化。然后在右面板定义按钮数组、按钮大小及位置。然后进行图片分割,使图片显示在按钮上,在未点击开始按钮时使所有按钮变灰,不可用。设置最后一个按钮为空白按钮,方便单击按钮和空白按钮的相互转换。具体分析为:
a.首先分析按钮的大小和位置的关系,定义按钮的宽度和高度、按钮数组、行数和列数,在游戏未开始时,设置按钮不可见。bs=new JButton[hs*ls]; //创建按钮数组
widthbut=width/ls;// 计算按钮的宽度高度heightbut=height/hs;
for(int i=0;i<jbs.length;i++){//为每一个按钮实现初始化操作jbs[i]=new JButton();jbs[i].setSize(widthbut, heightbut);jbs[i].setLocation(i%ls*widthbut,i/ls*heightbut);// 添加按钮前要确定坐标位置add(jbs[i]); //添加按钮到右面板jbs[i].setEnabled(false);// 使得按钮变灰色不可用
b.实现图片分割:使用ImageIO类对图片进行读写,然后使用BufferedImage类获取BufferedImage类的对象对图片进行分割,使用到的方法为:
读图片文件:public static BufferedImage read(URL input) throws IOException
写图片文件:public static boolean write(RenderedImage im, String formatName, File output) throws IOException
分割方法:public BufferedImage getSubimage(int x, int y, int w, int h)
代码:BufferedImage subimage=buf.getSubimage(i%ls*widthxt, i/ls*heightxt, widthxt, heightxt); //小图的获取
c.分割图片后,要对图片进行缩放。使用Image类中的getScaledInstance()方法对图片进行缩放。方法为:
public Image getScaledInstance(int width, int height,int hints)
代码: Image image=subimage.getScaledInstance(widthbut, heightbut, 1); //小图的缩放
d.最后添加一个空白按钮在右下角,为实现按钮的移动提供条件。
JButton kb; //空白按钮
jbs[hs*ls-1].setIcon(null); //设置最后一个按钮图片为空
kb=jbs[hs*ls-1];
6.拼图完成后与左面板的原图比较进行判赢。设置不同游戏等级,可分为简单、一般、困难。若想更换图片,可进行图片的更换。
a. 开始菜单单击时,执行具体操作只与右面板的组件相关,代码放到右面板类中
通过改变按钮的坐标位置打乱按钮的顺序。方法是:生成两个随机数表示数组下标,互换两个数组元素的位置,按钮的方法getX和getY可以获取按钮的坐标。
相关代码:
Random rand=new Random();//创建随机数对象int index1 = rand.nextInt(hs * ls); /生成两个随机数表示数组下标,互换两个数组元素的位置int index2 = rand.nextInt(hs * ls);
b. 当对右面板中的按钮单击的时候,移动按钮。通过按钮的单击事件的处理,设置按钮的监听事件ActionListener,将代码写在监听事件中。代码为:
jbs[i].addActionListener(this); //设置按钮的监听,当按钮被单击,找ActionListener方法执行
c.当用户拼图完成后,与原图进行比较判断是否拼图成功。判断拼图是否成功,主要取决于每一个按钮通过索引下标获取的位置值,与当前按钮的位置值是否相同。相关代码:
for(int i=0 ; i<jbs.length;i++){//获取每个按钮的坐标int x=jbs[i].getX()/widthbut;int y=jbs[i].getY()/heightbut;if(i%ls!=x || i/ls!=y){return false;}}return true;
d.设置游戏等级,即游戏的难易度。而游戏的难易度主要与右面板的行数和列数有关。可将行数hs和列数ls的值传给右面板,并对菜单进行监听和使用removeAll方法来清除所有组件来实现难易度。相关代码为:
rp.hs=2; //等级为简单时,传递2*2到右面板rp.ls=2;rp.init(url); //调用右面板组件初始化的方法
e.在菜单项中有更换图片选项,用户可单击该菜单项,选择当前电脑中的图片文件,替换游戏中已有的图片。通过使用url数据的传递替换选择的图片,在两个面板中都起作用,即左面板的标签的背景图要换,右面板中的分割原图也要变。可通过监听事件实现,涉及的类有涉及到的类JFileChooser、FileNameExtendsionFilter,具体实现如下:
//显示一个打开对话框,选择一个图片文件,将文件转换为url对象,调用左右面板的相应方法
JFileChooser jfc=new JFileChooser();
//设置文件的扩展名
jfc.setFileFilter(new FileNameExtensionFilter("图片格式(jpg|png|jif)", "jpg","png","gif"));
//null表示父容器是谁
int sd=jfc.showOpenDialog(MainJFrame.this);
if(sd==jfc.APPROVE_OPTION)//如果用户选择打开了按钮
{ String file=jfc.getSelectedFile().getAbsolutePath();
//获取用户选择的文件完整名称
url=new URL("file:\\"+file);lp.init(url);rp.init(url); }
f.整个框架实现完成后,可设置计时和计数功能。
计时:从单击开始菜单时计时开始,拼图成功计时结束。通过System类的currentTimeMillis ()方法,获取当前系统时间的毫秒值;通过线程的run()方法中,定时获取当前系统的时间点,线程的定义方法有两种:继承Thread类;实现Runnable接口,创建带实现接口的子类对象的Thread对象,重写run方法。通过公式(endTime-startTime)/1000计算出以秒为单位的时间段。
计数:设置一个标签 total_count,使计数显示在菜单栏中,在设置一个计数功能 int times,判断按钮是否可以移动使times加1来实现计数功能。
g.如果拼图成功,将信息记录到文件中,即菜单项中的游戏记录:显示用户之前的记录结果,读取文件并显示。通过FileWriter记录当前信息到文件中,FileReader读取文件。
h.如果不想保留之前的记录,可将文件删除,即实现菜单项中的清空记录。相关代码为:
File f=new File("c://a");if(f.exists()){f.delete();
7.可增加一个功能在菜单项中添加图片分割,新建一个TPJFrame类实现图片分割。
a.新建窗口,在新窗口中设置组件四个面板,三个按钮,四个文本框和标题等等。
b.首先通过单击选择图片按钮获取图片文件,将文件转换为url对象,获取用户选择的文件完整名称,获取图片后,将图片转换成Image类型的对象,进行缩放,然后再将Image类型对象转换成ImageIcon类型的对象,将图片放到jlb中。
4 实训总结及心得
见文档。
这篇关于Java项目 拼图游戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!