JAVA實(shí)現(xiàn)經(jīng)典掃雷游戲的示例代碼
前言
windows自帶的游戲《掃雷》是陪伴了無(wú)數(shù)人的經(jīng)典游戲,本程序參考《掃雷》的規(guī)則進(jìn)行了簡(jiǎn)化,用java語(yǔ)言實(shí)現(xiàn),采用了swing技術(shù)進(jìn)行了界面化處理,設(shè)計(jì)思路用了面向?qū)ο笏枷搿?/p>
主要需求
1、要有難度等級(jí),初級(jí),中級(jí),高級(jí)
2、由玩家逐個(gè)翻開(kāi)方塊,以找出所有地雷為最終游戲目標(biāo)。如果玩家翻開(kāi)的方塊有地雷,則游戲結(jié)束
3、游戲主區(qū)域由很多個(gè)方格組成。使用鼠標(biāo)左鍵隨機(jī)點(diǎn)擊一個(gè)方格,方格即被打開(kāi)并顯示出方格中的數(shù)字;方格中數(shù)字則表示其周?chē)?個(gè)方格隱藏了幾顆雷。
4、用戶(hù)右鍵可標(biāo)記雷的位置
5、雷都被標(biāo)記出來(lái)則勝利
主要設(shè)計(jì)
1、格子格數(shù)固定為10*10格
2、難度等級(jí),初級(jí):12,中級(jí):24,高級(jí):36
3、點(diǎn)擊格子時(shí),產(chǎn)生沒(méi)有引爆的地圖效果;
4、點(diǎn)擊格子時(shí),此格子是雷,則顯示所有雷的位置,并遞歸清空非雷格子,結(jié)束游戲
5、實(shí)現(xiàn)檢查所有的雷是否都被標(biāo)記出來(lái)了,如果是,則勝利算法。
6、實(shí)現(xiàn)計(jì)時(shí)器算法,用來(lái)計(jì)時(shí)顯示游戲開(kāi)始多少秒
7、實(shí)現(xiàn)難度等級(jí),雷數(shù)的顯示
8、實(shí)現(xiàn)鼠標(biāo)左鍵的實(shí)現(xiàn)邏輯
9、實(shí)現(xiàn)鼠標(biāo)右鍵的標(biāo)記邏輯
功能截圖
開(kāi)始界面
左鍵選中格子效果
左鍵選中雷效果
右鍵標(biāo)記雷效果
勝利效果
代碼實(shí)現(xiàn)
程序啟動(dòng)類(lèi)
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); } }
地雷分布圖算法類(lèi)
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(); } }
總結(jié)
通過(guò)此次的《掃雷》游戲?qū)崿F(xiàn),讓我對(duì)swing的相關(guān)知識(shí)有了進(jìn)一步的了解,對(duì)java這門(mén)語(yǔ)言也有了比以前更深刻的認(rèn)識(shí)。
java的一些基本語(yǔ)法,比如數(shù)據(jù)類(lèi)型、運(yùn)算符、程序流程控制和數(shù)組等,理解更加透徹。java最核心的核心就是面向?qū)ο笏枷?,?duì)于這一個(gè)概念,終于悟到了一些。
到此這篇關(guān)于JAVA實(shí)現(xiàn)經(jīng)典掃雷游戲的示例代碼的文章就介紹到這了,更多相關(guān)JAVA掃雷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java四種訪(fǎng)問(wèn)控制修飾符知識(shí)點(diǎn)總結(jié)
本篇文章給大家詳細(xì)分析了Java四種訪(fǎng)問(wèn)控制修飾符的相關(guān)知識(shí)點(diǎn),有興趣的朋友可以參考學(xué)習(xí)下。2018-03-03Spring注解驅(qū)動(dòng)之ApplicationListener異步處理事件說(shuō)明
這篇文章主要介紹了Spring注解驅(qū)動(dòng)之ApplicationListener異步處理事件說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09Jmeter使用接口傳遞數(shù)據(jù)過(guò)程圖解
這篇文章主要介紹了Jmeter使用接口傳遞數(shù)據(jù)過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05Java中線(xiàn)程狀態(tài)+線(xiàn)程安全問(wèn)題+synchronized的用法詳解
這篇文章主要介紹了Java中線(xiàn)程狀態(tài)+線(xiàn)程安全問(wèn)題+synchronized的用法詳解,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04深入了解Spring中的@Autowired和@Resource注解
Spring中的@Autowired和@Resource注解都可以實(shí)現(xiàn)依賴(lài)注入,但使用方式、注入策略和適用場(chǎng)景略有不同。本文將深入探討這兩種注解的原理、使用方法及優(yōu)缺點(diǎn),幫助讀者更好地理解和運(yùn)用Spring依賴(lài)注入機(jī)制2023-04-04