java拼图游戏代码.docx
java拼图游戏代码Puzzle类: package com.eavan; public class Puzzle public static void main(String args) / TODO Auto-generated method stub new PuzzleWin; PuzzleWin类: /* * 可以为游戏添加一个计时的功能,让时间成为一个判定标准 * 可以分析一下为什么图片不清楚 * 可以向怎么能够让选择图片和选择难度没有顺序性 * */ package com.eavan; import java.awt.Color; import java.awt.FileDialog; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.GridLayout; import java.awt.HeadlessException; import java.awt.Image; import java.awt.Transparency; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Random; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextArea; public class PuzzleWin extends JFrame implements ActionListener int dif = 0; /设置难度级数 int k = 0; /标记是随机数list中的第几个随机数 String filename="a.jpg" /设置的图片打开路径。默认路径其实是没用的 int step = 0; /用于记录总共用了多少步完成拼图 JMenuBar mBar = new JMenuBar; JMenu jmSysten = new JMenu("系统"); JMenu jmGame = new JMenu("游戏"); JMenuItem restart = new JMenuItem("重新开始"); JMenuItem quit = new JMenuItem("退出"); JMenuItem choosepic = new JMenuItem("选择图片"); JMenu choosedif = new JMenu("选择难度"); JMenuItem easy = new JMenuItem("3*3"); JMenuItem hard = new JMenuItem("4*4"); JPanel mainPanel = new JPanel; JButton btn = null; /用于显示被分割的图片 ImageIcon checkIcon = null; /用于存放一个正确顺序放置被分割后的图片的数组,最后与btn的icon对比检测是否完成拼图 JLabel piclab = new JLabel; /用于显示对照图片 JLabel namelab = new JLabel("对照图片:"); /用于在对照图片上面给出提醒 JLabel steplab = new JLabel; /用于记录步数信息 JTextArea helpArea = new JTextArea; /用于显示操作提示信息 JLabel designLabel = new JLabel; /用于显示者设计信息 public PuzzleWin this.setTitle("拼图游戏"); this.setSize(600, 500); this.setLayout(null); this.setLocation(200,120); this.setResizable(false); /因使用的大多是绝对布局,还是不要更改窗体大小吧 this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); /添加menu,用于显示各种菜单 mBar.add(jmSysten); mBar.add(jmGame); setJMenuBar(mBar); jmSysten.add(restart); jmSysten.add(quit); jmGame.add(choosedif); jmGame.add(choosepic); choosedif.add(easy); choosedif.add(hard); /设置分割图片显现的位置,使用的都是绝对布局 mainPanel.setBounds(30,30,360,360); mainPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK); this.add(mainPanel); /设置对照图片的大小坐标(用一个label作为盛放pic的容器) /显示对照图片 namelab.setBounds(450, 10, 80, 15); steplab.setBounds(450, 160, 80, 15); piclab.setBorder(BorderFactory.createLineBorder(Color.BLACK); steplab.setText("步数:"+step); piclab.setBounds(450, 30, 110, 110); helpArea.setBounds(420, 220, 150, 120); helpArea.setBackground(new Color(192, 192, 192); helpArea.setText("由于本人水平有限,请按照rn先在游戏菜单中选择游戏难rn度,再选择图片的顺序进行rn游戏。rnrn祝玩得开心-.-"); helpArea.setEditable(false); designLabel.setBounds(30, 370, 200, 100); designLabel.setText("Design By Eavan In Haust"); this.add(namelab); this.add(piclab); this.add(steplab); this.add(helpArea); this.add(designLabel); /对menu里的各种按钮注册监听 restart.addActionListener(this); quit.addActionListener(this); choosepic.addActionListener(this); easy.addActionListener(this); hard.addActionListener(this); /实现从Image对象转化为BufferedImage对象的方法 public static BufferedImage toBufferedImage(Image image) if (image instanceof BufferedImage) return (BufferedImage)image; image = new ImageIcon(image).getImage; BufferedImage bimage = null; GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment; try int transparency = Transparency.OPAQUE; GraphicsDevice gs = ge.getDefaultScreenDevice; GraphicsConfiguration gc = gs.getDefaultConfiguration; bimage = gc.createCompatibleImage( image.getWidth(null), image.getHeight(null), transparency); catch (HeadlessException e) if (bimage = null) int type = BufferedImage.TYPE_INT_RGB; bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type); Graphics g = bimage.createGraphics; g.drawImage(image, 0, 0, null); g.dispose; return bimage; /实现将图片分割的方法,返回的对象是一个存放Image对象的数组。 public ArrayList<Image> splitImage(ImageIcon i,int n) Image im = i.getImage; BufferedImage bi = toBufferedImage(im); int baseHeight = bi.getHeight; int basewidth = bi.getWidth; int x = 0; int y = 0; / / / / / / / / / ArrayList<Image> image = new ArrayList<Image> if (n = 3) int a = basewidth/n; int b = baseHeight/n; for (int j = 0; j < n*n; j+) Image tempImage = bi.getSubimage(x, y, a, b); image.add(tempImage); x = x+a; if(x = 3*a) x = 0; y = y+b; int j = 0; while (j<n*n) image.add(bi.getSubimage(x, y, a, b); x = x+a; if(x = 3*a) x = 0; y = y+b; if (n = 4) int a = basewidth/n; int b = baseHeight/n; for (int j = 0; j < n*n; j+) Image tempImage = bi.getSubimage(x, y, a, b); image.add(tempImage); x = x+a; if(x = n*a) x = 0; y = y+b; return image; /产生一个长度为n的不重复随机数arraylist public ArrayList<Integer> randomNum(int n) ArrayList<Integer> list = new ArrayList<Integer> Random rand = new Random; boolean bool = new booleann; int num =0; for (int i = 0; i<n; i+) do /如果产生的数相同继续循环 num = rand.nextInt(n); while(boolnum); boolnum =true; list.add(num); return list; public boolean isOver int mark = 0; boolean b = false; for (int i = 0; i < dif; i+) for (int j = 0; j < dif; j+) if (i = dif-1&&j = dif-1) break; if (btnij.getIcon = checkIconij) mark+; if (mark = dif*dif-1) b = true; return b; public void actionPerformed(ActionEvent e) / TODO Auto-generated method stub if (e.getSource=restart) dif = 0; k = 0; step = 0; filename="a.jpg" for (int i = 0; i < 3; i+) for (int j = 0; j < 3; j+) btnij = null; mainPanel.removeAll; piclab.setIcon(null); steplab.setText("步数:"+step); repaint; else if (e.getSource=quit) System.exit(0); else if (e.getSource=choosepic) /实现图片选择功能 FileDialog df=new FileDialog(this,"图片选择",FileDialog.LOAD); df.setVisible(true); if(df.getFile=null) return; /获取文件的路径 filename=df.getDirectory+df.getFile;/文件路径+文件名 /System.out.println(filename); /测试路径是否正确 ImageIcon image = new ImageIcon(filename); ImageIcon labImage = image; labImage.setImage(image.getImage.getScaledInstance(110, Image.SCALE_DEFAULT); piclab.setIcon(labImage); if (dif = 3) ArrayList<Image> iList = splitImage(image, 3); 110, /实际上只会用到list中的前8张图片,故只需产生07这八个数就行 ArrayList<Integer> numList = randomNum(8); ImageIcon tempIcon = new ImageIcon8; checkIcon = new ImageIcon33; for (int j = 0; j < 3; j+) for (int i = 0; i < 3; i+) /用于消除数组越界异常:这里的btn会有9个,而image只有8个,故最后一个btn是没有对象可以给它赋图片的。 /所以当最后一个ImageIcon对象要出来时,break if(i = 2&&j = 2) break; checkIconij = new ImageIcon(iList.get(k).getScaledInstance(120, 120, Image.SCALE_AREA_AVERAGING); tempIconk = checkIconij; / ImageIcon changedIcon = null; / changedIcon = new ImageIcon33; / ImageIcon smallIcon = new ImageIcon(iList.get(numList.get(k).getScaledInstance(120, 120, Image.SCALE_AREA_AVERAGING); / ImageIcon changedIcon = new ImageIcon(iList.get(k).getScaledInstance(120, 120, Image.SCALE_AREA_AVERAGING); /btnij.setIcon(changedIconij); /btnij.setIcon(changedIcon); /changedIcon = null; k = k+1; int t = 0; for (int j = 0; j < 3; j+) for (int i = 0; i < 3; i+) if(i = 2&&j = 2) break; btnij.setIcon(tempIconnumList.get(t); t+; if (dif = 4) ArrayList<Image> iList = splitImage(image, 4); /实际上只会用到list中的前8张图片,故只需产生07这八个数就行 ArrayList<Integer> numList = randomNum(15); ImageIcon tempIcon = new ImageIcon15; checkIcon = new ImageIcon44; for (int j = 0; j < 4; j+) for (int i = 0; i < 4; i+) /用于消除数组越界异常:这里的btn会有16个,而image只有15个,故最后一个btn是没有对象可以给它赋图片的。 /所以当最后一个ImageIcon对象要出来时,break if(i = 3&&j = 3) break; checkIconij = new ImageIcon(iList.get(k).getScaledInstance(90, 90, Image.SCALE_AREA_AVERAGING); tempIconk = checkIconij; / ImageIcon changedIcon = null; / changedIcon = new ImageIcon33; / ImageIcon smallIcon = ImageIcon(iList.get(numList.get(k).getScaledInstance(120, Image.SCALE_AREA_AVERAGING); / ImageIcon changedIcon = ImageIcon(iList.get(k).getScaledInstance(120, 120, Image.SCALE_AREA_AVERAGING); /btnij.setIcon(changedIconij); /btnij.setIcon(changedIcon); /changedIcon = null; k = k+1; int t = 0; for (int j = 0; j < 4; j+) for (int i = 0; i < 4; i+) if(i = 3&&j = 3) break; btnij.setIcon(tempIconnumList.get(t); t+; else if (e.getSource=easy) dif = 3; btn = new JButton33; /mainPanel.setLayout(new GridLayout(3,3); mainPanel.setLayout(null); for (int i = 0; i < 3; i+) for (int j = 0; j < 3; j+) btnij = new JButton; btnij.setBounds(i*120, j*120, 120, 120); btnij.setBackground(Color.WHITE); /将按钮添加到mainpanel面板上。 for (int i = 0; i < 3; i+) for (int j = 0; j < 3; j+) mainPanel.add(btnij); btnij.addActionListener(this); new 120, new repaint; /利用reapint方法重回mainpanel,使得新加的按钮显示出来 else if (e.getSource=hard) dif = 4; btn = new JButton44; /mainPanel.setLayout(new GridLayout(3,3); mainPanel.setLayout(null); for (int i = 0; i < 4; i+) for (int j = 0; j < 4; j+) btnij = new JButton; btnij.setBounds(i*90, j*90, 90, 90); btnij.setBackground(Color.WHITE); /将按钮添加到mainpanel面板上。 for (int i = 0; i < 4; i+) for (int j = 0; j < 4; j+) mainPanel.add(btnij); btnij.addActionListener(this); repaint; else for (int i = 0; i < dif; i+) for (int j = 0; j < dif; j+) if (btnij = e.getSource) /产生数组越界异常,因为当对最右边一组进行操作的时候,有一个if语句中是含有i+1这样的语句的 /事实上i+1是不存在的,于是会产生数组越界异常。 /已经通过改变i和j的取值范围解决 /向左移动 if(i>0&&btni-1j.isVisible&&btni-1j.getIcon=null) btni-1j.setIcon(btnij.getIcon);/获取当前图标给上一个控件为图标 btnij.setIcon(null);/当前图标设置为空 /向右移动 下一个控件为图标 左一个控件为图标 右一个控件为图标 if(i<dif-1&&btni+1j.isVisible&&btni+1j.getIcon=null) btni+1j.setIcon(btnij.getIcon);/获取当前图标给 btnij.setIcon(null);/当前图标设置为空 /向上移动 if(j>0&&btnij-1.isVisible&&btnij-1.getIcon=null) /向下移动 if(j<dif-1&&btnij+1.isVisible&&btnij+1.getIcon=null) btnij+1.setIcon(btnij.getIcon);/获取当前图标给 btnij.setIcon(null);/当前图标设置为空 btnij-1.setIcon(btnij.getIcon);/获取当前图标给btnij.setIcon(null);/当前图标设置为空 step+; steplab.setText("步数:"+step); repaint; if (isOver = true) System.out.println("结束"); JOptionPane.showMessageDialog( null, "恭喜你完成了拼图n总步数为:"+step, "结果显示", JOptionPane.INFORMATION_MESSAGE);