JAVA实现经典扫雷游戏的示例代码
作者:小虚竹and掘金
windows自带的游戏《扫雷》是陪伴了无数人的经典游戏,本程序参考《扫雷》的规则进行了简化,用java语言实现,采用了swing技术进行了界面化处理。感兴趣的可以学习一下
前言
windows自带的游戏《扫雷》是陪伴了无数人的经典游戏,本程序参考《扫雷》的规则进行了简化,用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想。
主要需求
1、要有难度等级,初级,中级,高级
2、由玩家逐个翻开方块,以找出所有地雷为最终游戏目标。如果玩家翻开的方块有地雷,则游戏结束
3、游戏主区域由很多个方格组成。使用鼠标左键随机点击一个方格,方格即被打开并显示出方格中的数字;方格中数字则表示其周围的8个方格隐藏了几颗雷。
4、用户右键可标记雷的位置
5、雷都被标记出来则胜利
主要设计
1、格子格数固定为10*10格
2、难度等级,初级:12,中级:24,高级:36
3、点击格子时,产生没有引爆的地图效果;
4、点击格子时,此格子是雷,则显示所有雷的位置,并递归清空非雷格子,结束游戏
5、实现检查所有的雷是否都被标记出来了,如果是,则胜利算法。
6、实现计时器算法,用来计时显示游戏开始多少秒
7、实现难度等级,雷数的显示
8、实现鼠标左键的实现逻辑
9、实现鼠标右键的标记逻辑
功能截图
开始界面
左键选中格子效果
左键选中雷效果
右键标记雷效果
胜利效果
代码实现
程序启动类
public class JMine extends JFrame implements MouseListener, ActionListener { private JMineArth mine; private JMineButton[][] mineButton; private GridBagConstraints constraints; private JPanel pane; private GridBagLayout gridbag; private boolean gameStarted; private static JCounter mineCounter; private static JCounter timeCounter; private Timer timer; private Timer winTimer = new Timer(); public int numMine; public int numFlaged; private JMenuBar mb; private JMenu mGame; private JMenuItem miEasy; private JMenuItem miMiddle; private JMenuItem miHard; private JMenuItem miExit; private JMenu mHelp; private JMenuItem miAbout; private JPanel controlPane; private JButton bTest; private AboutFrame about; private WinFrame winFrame; private ImageIcon[] mineNumIcon = { new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("1.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("2.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("3.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("4.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("5.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("6.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("7.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("8.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("0.gif"))}; private ImageIcon[] mineStatus = { new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("flag.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("question.gif")) }; private ImageIcon[] mineBombStatus = { new ImageIcon(JMine.class.getClassLoader().getResource("0.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("mine.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("wrongmine.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("bomb.gif")) }; private ImageIcon[] faceIcon = { new ImageIcon(JMine.class.getClassLoader().getResource("smile.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("Ooo.gif")) }; // You lose private void bomb(int row, int col){ try{ //System.out.println("Bomb!"); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { mineButton[i][j].setIcon(mineBombStatus[0]); int toShow; toShow = mine.mine[i][j] != 9 ? 0 : 1; mineButton[i][j].setClickFlag(true); if (toShow == 1 && (i != row || j != col)) { mineButton[i][j].setIcon(mineBombStatus[toShow]); mineButton[i][j].setClickFlag(true); } else if (toShow == 1 && (i == row && j == col)) { mineButton[i][j].setIcon(mineBombStatus[3]); mineButton[i][j].setClickFlag(true); } else if (toShow == 0 && mineButton[i][j].getFlag() != 1) { mineButton[i][j].setEnabled(false); } else if (toShow == 0 && mineButton[i][j].getFlag() == 1) { mineButton[i][j].setIcon(mineBombStatus[2]); mineButton[i][j].setClickFlag(true); } } } timer.cancel(); }catch (Exception e){ } } // check if you win() { private boolean isWin() { for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { if (mine.mine[i][j] == 9 && mineButton[i][j].getFlag() != 1) { return (false); } if (mine.mine[i][j] != 9 && mineButton[i][j].getFlag() == 1) { return (false); } if (mine.mine[i][j] != 9 && mineButton[i][j].getClickFlag() == false) { return (false); } } } return (true); } // You Win private void win(){ timer.cancel(); winFrame.setVisible(true); winTimer.schedule(new TimerTask(){ public void run() { while(!winFrame.getWinOk()){ } numMine = winFrame.getMineNum(); winFrame.setVisible(false); setNewGame(numMine); //System.out.println("Jerry Debug:"+numMine); this.cancel(); winFrame.setWinOk(false); } },0L); } // Constructor of the game public JMine() { super("JMine Game"); setSize(250, 350); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Insets space = new Insets(0, 0, 0, 0); // Game vars gameStarted = false; numMine = 12; numFlaged = 0; ImageIcon myIcon = new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif")); gridbag = new GridBagLayout(); constraints = new GridBagConstraints(); pane = new JPanel(); pane.setLayout(gridbag); constraints.fill = GridBagConstraints.BOTH; constraints.anchor = GridBagConstraints.CENTER; // Begin Menu Set mb = new JMenuBar(); mGame = new JMenu("Game"); miEasy = new JMenuItem("Easy"); miEasy.addActionListener(this); miMiddle = new JMenuItem("Middle"); miMiddle.addActionListener(this); miHard = new JMenuItem("Hard"); miHard.addActionListener(this); miExit = new JMenuItem("Exit"); miExit.addActionListener(this); mGame.add(miEasy); mGame.add(miMiddle); mGame.add(miHard); mGame.addSeparator(); mGame.add(miExit); mb.add(mGame); mHelp = new JMenu("Help"); miAbout = new JMenuItem("About..."); mHelp.add(miAbout); miAbout.addActionListener(this); mb.add(mHelp); this.setJMenuBar(mb); // end of Menu Set // Control Panel controlPane = new JPanel(); bTest = new JButton(faceIcon[0]); bTest.setSize(26, 27); bTest.setMargin(space); bTest.addMouseListener(this); bTest.setPressedIcon(faceIcon[1]); mineCounter = new JCounter(numMine); timeCounter = new JCounter(); controlPane.add(mineCounter); controlPane.add(bTest); controlPane.add(timeCounter); buildConstraints(constraints, 0, 0, 10, 2, 100, 100); gridbag.setConstraints(controlPane, constraints); pane.add(controlPane); // Bottons mineButton = new JMineButton[10][10]; for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { mineButton[i][j] = new JMineButton(i, j, myIcon); mineButton[i][j].addMouseListener(this); mineButton[i][j].setMargin(space); buildConstraints(constraints, j, i + 3, 1, 1, 100, 100); gridbag.setConstraints(mineButton[i][j], constraints); pane.add(mineButton[i][j]); } } // Content Pane setContentPane(pane); setLocation(200, 150); setVisible(true); // About Frame about = new AboutFrame("JMine About"); winFrame = new WinFrame("You win!"); } // Set the GUI objects positions void buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw, int gh, int wx, int wy) { gbc.gridx = gx; gbc.gridy = gy; gbc.gridwidth = gw; gbc.gridheight = gh; gbc.weightx = wx; gbc.weighty = wy; } // the methods to check if there were mines, to be nested void checkMine(int row, int col){ int i, j; i = row < 0 ? 0 : row; i = i > 9 ? 9 : i; j = col < 0 ? 0 : col; j = j > 9 ? 9 : j; //System.out.println("Check Mine row:"+i + ",col:" +j); if (mine.mine[i][j] == 9) { bomb(i, j); } else if (mine.mine[i][j] == 0 && mineButton[i][j].getClickFlag() == false) { mineButton[i][j].setClickFlag(true); showLabel(i, j); for (int ii = i - 1; ii <= i + 1; ii++) for (int jj = j - 1; jj <= j + 1; jj++) checkMine(ii, jj); } else { showLabel(i, j); mineButton[i][j].setClickFlag(true); } if (isWin()) { win(); } } private void clearAll(int row, int col){ int top, bottom, left, right; top = row - 1 > 0 ? row - 1 : 0; bottom = row + 1 < 10 ? row + 1 : 9; left = col - 1 > 0 ? col - 1 : 0; right = col + 1 < 10 ? col + 1 : 9; for (int i = top; i <= bottom; i++) { for (int j = left; j <= right; j++) { if (mineButton[i][j].getFlag() != 1) checkMine(i, j); } } } private void resetAll() { for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { mineButton[i][j].setFlag(0); mineButton[i][j].setClickFlag(false); mineButton[i][j].setIcon(mineStatus[0]); mineButton[i][j].setEnabled(true); mineButton[i][j].setVisible(true); } } } // to flag the mine you want to flag out void flagMine(int row, int col) { //System.out.println("Jerry Arrives here!"); int i, j; i = row < 0 ? 0 : row; i = i > 9 ? 9 : i; j = col < 0 ? 0 : col; j = j > 9 ? 9 : j; if (mineButton[i][j].getFlag() == 0) { numFlaged++; } else if (mineButton[i][j].getFlag() == 1) { numFlaged--; } mineCounter.resetCounter(numMine - numFlaged >= 0 ? numMine - numFlaged : 0); mineButton[i][j].setFlag((mineButton[i][j].getFlag() + 1) % 3); showFlag(i, j); if (isWin()) { win(); } } // show the numbers of the nearby mines void showLabel(int row, int col) { //System.out.println("ShowLabel row:" + row + ",col:" + col); int toShow; toShow = mine.mine[row][col]; if (toShow != 0) { mineButton[row][col].setIcon(mineNumIcon[toShow]); mineButton[row][col].setClickFlag(true); //mineButton[row][col].setEnabled(false); } else { //mineButton[row][col].setIcon(mineNumIcon[0]); //mineButton[row][col].setClickFlag(true); mineButton[row][col].setEnabled(false); } } // circle the flag with blank, flaged, questioned void showFlag(int row, int col) { mineButton[row][col] .setIcon(mineStatus[mineButton[row][col].getFlag()]); } // the mouse events listener methods public void mouseEntered(MouseEvent e) { //System.out.println("Jerry Test"); } // method to start the new game private void startNewGame(int num, int row, int col){ mine = new JMineArth(num, row, col); //mine.printMine(); gameStarted = true; timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask(){ public void run() { timeCounter.counterAdd(); //System.out.println(timeCounter.getCounterNum()); } },1000,1000); } public void setNewGame(int num) { resetAll(); numMine = num; numFlaged = 0; gameStarted = false; mineCounter.resetCounter(numMine); timeCounter.resetCounter(0); } // the event handle to deal with the mouse click public void mouseClicked(MouseEvent e) { if (e.getSource() == bTest) { setNewGame(numMine); return; } int row, col; row = ((JMineButton) e.getSource()).getRow(); col = ((JMineButton) e.getSource()).getCol(); if (!gameStarted) { startNewGame(numMine, row, col); } if (e.getModifiers() == (InputEvent.BUTTON1_MASK + InputEvent.BUTTON3_MASK)) { //System.out.println("HA"); clearAll(row, col); } if (!mineButton[row][col].getClickFlag()) { if (e.getModifiers() == InputEvent.BUTTON1_MASK) { //System.out.println("LeftButton"); if (mineButton[row][col].getFlag() == 1) { return; } else { checkMine(row, col); } } else if (e.getModifiers() == InputEvent.BUTTON3_MASK) { //System.out.println("RightButton"); flagMine(row, col); } else { //System.out.println("MiddleButton"); } } } public void mousePressed(MouseEvent e) { //System.out.println("Jerry Press"); } public void mouseReleased(MouseEvent e) { //System.out.println("Jerry Release"); } public void mouseExited(MouseEvent e) { //System.out.println("Jerry Exited"); } public void actionPerformed(ActionEvent e) { try { if (e.getSource() == miEasy) { setNewGame(12); return; } if (e.getSource() == miMiddle) { setNewGame(24); return; } if (e.getSource() == miHard) { setNewGame(36); return; } if (e.getSource() == miExit) { System.exit(0); } if (e.getSource() == miAbout) { about.setVisible(true); } } catch (Exception ie) { } } public static void main(String [] args) { JMine jmine = new JMine(); jmine.setVisible(true); } }
地雷分布图算法类
public class JMineArth { public int [][] mine; private boolean fMineSet; JMineArth(int mineNum, int row, int col) { mine = new int[10][10]; setMine(mineNum, row, col); setMineNum(); } private void setMine(int mineNum, int Outrow, int Outcol) { int col=0, row = 0, i=0; //Math.srand(now); while (i < mineNum) { col = (int)(Math.random()*100)%10; row = (int)(Math.random()*100)%10; if (mine[col][row]==0 && (row!=Outrow || col!=Outcol || Outrow==10 )) { mine[row][col]=9; i++; } } } private void setMineNum() { for ( int i=0 ; i <10; i++) { for (int j=0; j < 10; j++) { mine[i][j]=mine[i][j]==9?9:checkMineNum(i,j); } } fMineSet = true; } private int checkMineNum(int ii,int jj) { int top,bottom, left, right, count=0; top=ii-1>0?ii-1:0; bottom=ii+1<10?ii+1:9; left=jj-1>0?jj-1:0; right=jj+1<10?jj+1:9; for (int i=top; i<=bottom; i++) { for(int j=left; j<= right; j++) { if (mine[i][j]==9) count++; } } return(count); } public void printMine() { for (int i = 0; i < 10; i++) { for (int j=0; j < 10; j++) { System.out.print(this.mine[i][j] + " "); } System.out.println(); } } public static void main(String[] args) { JMineArth mine = new JMineArth(Integer.parseInt(args[0]),Integer.parseInt(args[1]),Integer.parseInt(args[2])); mine.printMine(); } }
总结
通过此次的《扫雷》游戏实现,让我对swing的相关知识有了进一步的了解,对java这门语言也有了比以前更深刻的认识。
java的一些基本语法,比如数据类型、运算符、程序流程控制和数组等,理解更加透彻。java最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。
到此这篇关于JAVA实现经典扫雷游戏的示例代码的文章就介绍到这了,更多相关JAVA扫雷内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!