连连看java版
主界面
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.util.Random; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /** * 悲剧 长宽没有控制好 忘了给添加按钮留空间了 * @author Administrator * */ public class MyFrame extends JFrame implements MouseListener { public static final int COL = 4; //图像列数 public static final int ROW = 4; //图像行数 public static final int ONE = 80; //每幅图像的宽度与高度 public static final int STANCE = 30; private static final int WIDTH = COL*ONE; //界面的宽度 private static final int HEIGHT = ROW*ONE + STANCE; //界面的长度 public static final int number = COL*ROW/2; //图像数目 private JPanel functionJPanel = null; //最上方 用来保存功能键的panel private JPanel imagesJPanel = null; // 中间用来保存图像的panel private JPanel chooseJPanel = null; //下面用来选择重新开始和结束的panel private JButton restartJButton = null; //重新开始的按钮 private JButton closeJButton = null; //关闭按钮 private JLabel functionJLabel = null; private MyImages myImages ; private int point1_x = -1; //第一下点击的x坐标 private int point1_y = -1; // 第一下点击的y坐标 private int point2_x = -1; //第二下点击的x坐标 private int point2_y = -1; //第二下点击的y坐标 private static Random random = new Random(); private CanGet canGet; //用来存放图像的button 暂时不考虑用这种做法 // private JButton[][] myImageJButtons = new JButton[ROW][COL]; //用来保存地图的数组 素组下标表示位置 此位置上的值表示图像编号 0表示无图像 private int[][] myMap = new int[ROW][COL]; public int[][] getMyMap(){ return myMap; } // 将一对一对的数随机到数组中 (1-8)随机生成地图 private void setMap(){ for(int i=0;i<number;i++){ for(int j=0 ;j<2;j++){ int x = random.nextInt(COL); int y = random.nextInt(ROW); while(myMap[x][y]!=0){ x = random.nextInt(COL); y = random.nextInt(ROW); } myMap[x][y] = (i+1)/2+1; //在这里将每个位置上的图片编号设定好 } } } private void init(){ setMap(); //将地图生成 //读图 myImages = new MyImages(this); canGet = new CanGet(this); //初始化JPanel // functionJPanel = new JPanel(); // imagesJPanel = new JPanel(); // chooseJPanel = new JPanel(); //将JPanel放到适当的位置 // Container container = this.getContentPane(); // container.setLayout(new BorderLayout()); // container.add(imagesJPanel, "Center"); // container.add(functionJPanel, "North"); // container.add(chooseJPanel, "South"); //初始化JPanel上各个组件 // functionJLabel = new JLabel("00000000000"); // functionJPanel.add(functionJLabel); // restartJButton = new JButton("重新开始"); // closeJButton = new JButton("退出游戏"); // chooseJPanel.add(restartJButton); // chooseJPanel.add(closeJButton); //初始化frame的位置大小 Toolkit toolkit = Toolkit.getDefaultToolkit(); int width = toolkit.getScreenSize().width; int height = toolkit.getScreenSize().height; this.setLocation((width-WIDTH)/2, (height-HEIGHT)/2); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setSize(WIDTH, HEIGHT); this.addMouseListener(this); this.setBackground(Color.WHITE); this.setResizable(false); this.setVisible(true); } @Override public void paint(Graphics g) { BufferedImage backScreen = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_3BYTE_BGR); Graphics g2 = backScreen.getGraphics(); Color c = g2.getColor(); g2.setColor(Color.WHITE);//設置背景顏色 g2.fillRect(0, 0, WIDTH, HEIGHT); g2.setColor(c); for(int i=0;i<ROW;i++){ for(int j=0;j<COL;j++){ if(0 != myMap[i][j]){ // System.out.println(myMap[i][j]); myImages.drawAnImage(g2, i, j, myMap[i][j]); } } } c = g2.getColor(); g2.setColor(Color.BLACK); if(point1_x != -1){ g2.drawRect( point1_y*ONE,point1_x*ONE, ONE, ONE); } if(point2_x != -1){ g2.drawRect( point2_y*ONE,point2_x*ONE, ONE, ONE); } g2.setColor(c); g.drawImage(backScreen, 0, 30, null); } public MyFrame(){ init(); } /** * @param args */ public static void main(String[] args) { new MyFrame(); } @Override public void mouseClicked(MouseEvent e) { int col = e.getX()/ONE; int row = (e.getY()-STANCE)/ONE; if(-1 == point1_x || -1 == point1_y){ //System.out.println("sssssssssssssssss"); point1_x = row; point1_y = col; System.out.println("flag111111111"); }else if (-1 == point2_x || -1 == point2_y) { point2_x = row; point2_y = col; canGet = new CanGet(this); System.out.println("flag22222222222"); if(myMap[point1_x][point1_y] == myMap[point2_x][point2_y] &&(point1_x != point2_x || point1_y != point2_y) &&canGet.isConnect(point1_x,point1_y, point2_x,point2_y)){ //在此处检测是否联通 System.out.println("flag333333333"); //如果联通 则将两个位置的图片消去(变成0) setMapPointNull(point1_x, point1_y); setMapPointNull(point2_x, point2_y); //重置第两个选中的点 resetPoint1(); resetPoint2(); //重画界面 }else{ System.out.println("flag44444444444444"); point1_x = point2_x; point1_y = point2_y; resetPoint2(); } }else{ System.out.println("flag55555555555"); resetPoint1(); resetPoint2(); } // System.out.println("point1 ("+point1_x + "," +point1_y+")"); // System.out.println("point2 ("+point2_x + "," +point2_y+")"); // System.out.println(row + "," +col); repaint(); } //将一个点重置为0 private void setMapPointNull(int row,int col){ myMap[row][col] = 0; } //重置所有的点 生成新的地图 private void resetMapAllPoints(){ setMap(); } //重置两个鼠标选择的点 为未选中状态 private void resetPoint1(){ point1_x = -1; point1_y = -1; } private void resetPoint2(){ point2_x = -1; point2_y = -1; } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } }
判断连通的类
import java.util.Stack; public class CanGet { private Stack<Node> mySteps = new Stack<>(); private Stack<Node> myRecord = new Stack<>(); private int[][] myMap; private int current_row; private int current_col; private int rowNumber; private int colNumber; public CanGet(MyFrame myFrame){ this(myFrame.getMyMap()); } public CanGet(int[][] map){ this.myMap = map; this.rowNumber = this.myMap.length; this.colNumber = this.myMap[0].length; } private void setCurrent(int row ,int col){ current_col = col; current_row = row; } public boolean isConnect(int start_row,int start_col,int end_row,int end_col){ boolean flag = false; setCurrent(start_row, start_col); keepRecord(); while(!flag){ if(nextIsTarget(end_row, end_col)){ flag = true; break; }else { if(mySteps.isEmpty()){ flag = false; return flag; }else if(goLeft() || goUp() || goRigth() || goDown()){ keepRecord(); }else { Node node = mySteps.pop(); setCurrent(node.getRow(), node.getCol()); } } } return flag; } private void keepRecord(){ Node node = new Node(current_row, current_col); mySteps.push(node); myRecord.push(node); } private boolean goLeft(){ if(current_col-1 >= 0 && !myRecord.contains(new Node(current_row, current_col-1)) && myMap[current_row][current_col-1] == 0){ current_col -= 1; return true; } return false; } private boolean goUp(){ if(current_row-1 >= 0 && !myRecord.contains(new Node(current_row-1, current_col)) && myMap[current_row-1][current_col] == 0){ current_row -= 1; return true; } return false; } private boolean goRigth(){ if(current_col+1 < this.colNumber && !myRecord.contains(new Node(current_row, current_col+1)) && myMap[current_row][current_col+1] == 0){ current_col += 1; return true; } return false; } //探测向下 private boolean goDown(){ if(current_row+1 < this.rowNumber && !myRecord.contains(new Node(current_row+1, current_col)) && myMap[current_row+1][current_col] == 0){ current_row += 1; return true; } return false; } //用来判断当前点的周围是否是目标点 private boolean nextIsTarget(int target_row,int target_col){ int row = current_row; int col = current_col; boolean flag = false; Node[] nodes = getNear(current_row,current_col); for(int i=0;i<nodes.length;i++){ if(nodes[i] != null && (nodes[i].getRow() == target_row && nodes[i].getCol() == target_col)){ flag = true; break; } } return flag; } private Node[] getNear(int row,int col){ Node[] nodes = new Node[4]; // 四个方向的临近点 if(row-1 >= 0){ nodes[0] = new Node(row-1, col); } if(col-1 >= 0){ nodes[1] = new Node(row, col-1); } if(row+1 < this.rowNumber){ nodes[2] = new Node(row+1, col); } if(col+1 < this.colNumber){ nodes[3] = new Node(row, col+1); } return nodes; } private boolean isSmoothTo(int row,int col,Dir dir){ boolean isSmooth = false; boolean flag = false; int next_row = -1; int next_col = -1; switch(dir){ case L: next_col = col - 1; next_row = row ; //当数组下表不越界 标识为真 if(next_col>=0){ flag = true; } break; case U: next_row = row - 1; next_col = col; //当数组下表不越界 标识为真 if(next_row>=0 ){ flag = true; } break; case R: next_col = col + 1; next_row = row; //当数组下表不越界 标识为真 if(next_col < this.colNumber){ flag = true; } break; case D: next_row = row + 1; next_col = col; //当数组下表不越界 标识为真 if(next_row < this.rowNumber){ flag = true; } break; } //当标识与 地图在这个位置没有障碍物 为0表示没有障碍物 且当前路线没有走过 if(flag && 0 == myMap[next_row][next_col]){ isSmooth = true; } return isSmooth; } private boolean goToNextPoint(Dir dir){ boolean flag = false; System.out.println("go to next point"); if (isSmoothTo(current_row, current_col, dir)) { flag = true; switch (dir) { case R: current_col += 1; break; case D: current_row += 1; break; case L: current_col -= 1; break; case U: current_row -= 1; break; } } return flag; } private class Node{ private int row; private int col; public Node(int row, int col){ this.row = row; this.col = col; } public int getRow() { return row; } public int getCol() { return col; } @Override public boolean equals(Object o) { Node node = (Node)o; return (node.getCol() == this.col && node.getRow() == this.row)? true:false; } } }
方向枚举
public enum Dir { L,U,R,D }
缓存绘制图像
import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class MyImages { private static final int IMAGENUM = MyFrame.COL*MyFrame.ROW/2; private BufferedImage[] images = new BufferedImage[IMAGENUM]; private MyFrame myFrame; public MyImages(MyFrame myFrame){ this.myFrame = myFrame; //将八幅图像读进来 每幅图像的编号与其名字相同 是下标加1 for(int i=0;i<IMAGENUM;i++){ try { images[i] = ImageIO.read(new File((i+1)+".jpg")); } catch (IOException e) { e.printStackTrace(); } } } //第一个参数是画笔 第二个参数是图像所在行数 第三个参数为列数 第四个参数是图像编号 为 1-8; public void drawAnImage(Graphics g,int row,int col,int imageNum){ //根据行和列算出图像所在位置 画出图像 // System.out.println("image 编号:"+(imageNum)); g.drawImage(images[imageNum-1] , col*MyFrame.ONE,row*MyFrame.ONE, null); } }
放上去几张图片 点击这里下载