您好,登錄后才能下訂單哦!
本文實例為大家分享了java實現掃雷小游戲的具體代碼,供大家參考,具體內容如下
代碼:
package GUI; import java.util.Random; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.Font; import java.awt.Color; import java.awt.EventQueue; import java.awt.event.InputEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JTextField; import javax.swing.JMenuBar; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.UIManager; import javax.swing.ImageIcon; import javax.swing.BorderFactory; import javax.swing.border.EmptyBorder; public class MineSweeperFrame extends JFrame { // 游戲模式編號 public static final int Custom_Mode = 0; public static final int Elementary_Mode = 1; public static final int Intermediate_Mode = 2; public static final int Advanced_Mode = 3; // 游戲模式參數 public static final int[] Elementary = {9, 9, 10, Elementary_Mode}; public static final int[] Intermediate = {16, 16, 40, Intermediate_Mode}; public static final int[] Advanced = {16, 30, 99, Advanced_Mode}; // 游戲字體、圖片、文字顏色 private static final Font FontC = new Font("Consolas", Font.PLAIN, 22); private static final Font FontD = new Font("等線", Font.PLAIN, 20); private static final ImageIcon imgicon = new ImageIcon( MineSweeperFrame.class.getResource("/Images/icon.jpg")); private static final ImageIcon imgflag = new ImageIcon( MineSweeperFrame.class.getResource("/Images/flag.png")); private static final ImageIcon imgbomb = new ImageIcon( MineSweeperFrame.class.getResource("/Images/bomb.png")); private static final Color[] NumberColor = {Color.blue, Color.green, Color.orange, Color.magenta, Color.red, Color.cyan, Color.black, Color.gray}; // 數據文件及高分記錄 private static File file = new File("MineSweeper.txt"); private static int HighScore_Elementary; private static int HighScore_Intermediate; private static int HighScore_Advanced; private int gamemode; private int row; private int column; private int area; private int minecount; private int flagcount; private int enablecount; private boolean[][] minearea; private boolean[][] flagmark; private boolean isGameOver; private boolean isFirstClick; private TimeThread timeThread; private JPanel contentPane; private JMenuBar menuBar; private JPanel pnlCount; private JPanel pnlMine; private MineButton[][] btnMine; private JTextField txtTime; private JTextField txtCount; /** * Launch the application. */ public static void main(String[] args) { int[] i = getDataFromFile(); EventQueue.invokeLater(new Runnable() { public void run() { try { new MineSweeperFrame(i[0], i[1], i[2], i[3]); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public MineSweeperFrame(int row, int column, int minecount, int mode) { // 設置各組件的默認字體 UIManager.put("Menu.font", FontD); UIManager.put("Label.font", FontD); UIManager.put("Button.font", FontD); UIManager.put("MenuBar.font", FontD); UIManager.put("MenuItem.font", FontD); UIManager.put("TextField.font", FontD); UIManager.put("OptionPane.buttonFont", FontD); UIManager.put("OptionPane.messageFont", FontD); setTitle("掃雷"); setResizable(false); // 設置窗口不可改變大小 setVisible(true); // 設置窗口初始可見 setIconImage(imgicon.getImage()); // 設置窗體的icon setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 注冊監聽器,響應窗口關閉事件 addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e){ saveDataToFile(); } }); menuBar = new JMenuBar(); setJMenuBar(menuBar); JMenu mGame = new JMenu("游戲"); menuBar.add(mGame); JMenu mRestart = new JMenu("重新開始"); mGame.add(mRestart); JMenuItem mitRestart = new JMenuItem("重新開始本局"); mitRestart.addActionListener(new RestartListener()); mRestart.add(mitRestart); JMenuItem mitReset = new JMenuItem("開始新的游戲"); mitReset.addActionListener(new ResetMineListener()); mRestart.add(mitReset); JMenu mDifficulty = new JMenu("難度設置"); mGame.add(mDifficulty); JMenuItem mitElementary = new JMenuItem("初級"); mitElementary.addActionListener(new ResetModeListener(Elementary)); mDifficulty.add(mitElementary); JMenuItem mitIntermediate = new JMenuItem("中級"); mitIntermediate.addActionListener(new ResetModeListener(Intermediate)); mDifficulty.add(mitIntermediate); JMenuItem mitAdvanced = new JMenuItem("高級"); mitAdvanced.addActionListener(new ResetModeListener(Advanced)); mDifficulty.add(mitAdvanced); JMenuItem mitCustom = new JMenuItem("自定義"); mitCustom.addActionListener(new CustomSizeFrameListener()); mDifficulty.add(mitCustom); JMenuItem mitHighScore = new JMenuItem("高分榜"); mitHighScore.addActionListener(new HighScoreListener()); mGame.add(mitHighScore); mGame.addSeparator(); JMenuItem mitExit = new JMenuItem("退出"); // 注冊監聽器,監聽“退出”菜單項 mitExit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { saveDataToFile(); System.exit(0); } }); mGame.add(mitExit); JMenu mHelp = new JMenu("幫助"); mHelp.add(new JMenuItem("http://www.baidu.com/")); menuBar.add(mHelp); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(10, 10, 10, 10)); contentPane.setLayout(new BorderLayout(0, 0)); setContentPane(contentPane); pnlCount = new JPanel(); contentPane.add(pnlCount, BorderLayout.NORTH); JLabel lblTime = new JLabel("時間"); pnlCount.add(lblTime); txtTime = new JTextField("0", 3); txtTime.setEditable(false); pnlCount.add(txtTime); JLabel lblCount = new JLabel("計數"); pnlCount.add(lblCount); txtCount = new JTextField("0/" + minecount, 5); txtCount.setEditable(false); pnlCount.add(txtCount); pnlMine = new JPanel(); contentPane.add(pnlMine, BorderLayout.CENTER); gamemode = mode; setMineArea(row, column, minecount); setMinePosition(); setMineButton(); UIManager.put("Label.font", FontC); } // 從文件中讀取數據 public static int[] getDataFromFile() { try { FileInputStream fis = new FileInputStream(file); byte[] buffer = new byte[256]; int size = fis.read(buffer); fis.close(); String[] s = new String(buffer, 0, size).split(" "); HighScore_Elementary = Integer.parseInt(s[0]); HighScore_Intermediate = Integer.parseInt(s[1]); HighScore_Advanced = Integer.parseInt(s[2]); int[] i = {Integer.parseInt(s[3]), Integer.parseInt(s[4]), Integer.parseInt(s[5]), Integer.parseInt(s[6])}; return i; } catch (Exception e) { HighScore_Elementary = Integer.MAX_VALUE; HighScore_Intermediate = Integer.MAX_VALUE; HighScore_Advanced = Integer.MAX_VALUE; return Elementary; } } // 保存數據到文件 public void saveDataToFile() { try { String s = HighScore_Elementary + " " + HighScore_Intermediate + " " + HighScore_Advanced + " " + row + " " + column + " " + minecount + " " + gamemode; FileOutputStream fos = new FileOutputStream(file); fos.write(s.getBytes()); fos.close(); } catch (IOException e) { e.printStackTrace(); } } // 初始化面板的各項參數 private void setMineArea(int row, int column, int minecount) { setSize(30 * column + 20, 30 * row + 120); // 設置窗口在屏幕的正中心 setLocationRelativeTo(null); this.row = row; this.column = column; this.minecount = minecount; area = row * column; flagcount = 0; enablecount = area; minearea = new boolean[row][column]; flagmark = new boolean[row][column]; isGameOver = false; isFirstClick = true; } // 隨機生成地雷的位置 private void setMinePosition(){ // 生成minecount個不重復的隨機數 int[] pos = new int[area]; for (int i = 0; i < area; i++) { pos[i] = i; } Random rand = new Random(); for (int i = 0; i < minecount; i++) { int n = rand.nextInt(area - i); minearea[pos[n] / column][pos[n] % column] = true; pos[n] = pos[area - i - 1]; } } // 向地雷面板上添加按鈕 private void setMineButton() { pnlMine.setLayout(new GridLayout(row, column)); btnMine = new MineButton[row][column]; for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { btnMine[i][j] = new MineButton(i, j); pnlMine.add(btnMine[i][j]); } } } // “重新開始本局”菜單項監聽類 private class RestartListener implements ActionListener { public void actionPerformed(ActionEvent e) { new MenuFunction().Restart(); } } // “開始新的的游戲”菜單項監聽類 private class ResetMineListener implements ActionListener { public void actionPerformed(ActionEvent e) { new MenuFunction().ResetMine(); } } // “游戲模式設置”菜單項監聽類 private class ResetModeListener implements ActionListener { private int[] mode; public ResetModeListener(int[] mode) { this.mode = mode; } public void actionPerformed(ActionEvent e) { if (gamemode == mode[3]) { new MenuFunction().ResetMine(); } else { new MenuFunction().ResetSize(mode[0], mode[1], mode[2]); gamemode = mode[3]; } } } // “自定義”菜單項監聽類,JFrame窗口的子類 private class CustomSizeFrameListener extends JFrame implements ActionListener { public CustomSizeFrameListener() { setTitle("自定義"); setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); setSize(320, 220); setLocationRelativeTo(null); // 設置窗口在屏幕的正中心 setResizable(false); // 設置窗體不可改變大小 JPanel contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); contentPane.setLayout(new GridLayout(4, 0)); setContentPane(contentPane); JPanel pnlRow = new JPanel(); contentPane.add(pnlRow); pnlRow.add(new JLabel("行數:")); JTextField txtRow = new JTextField(10); pnlRow.add(txtRow); JPanel pnlColumn = new JPanel(); contentPane.add(pnlColumn); pnlColumn.add(new JLabel("列數:")); JTextField txtColumn = new JTextField(10); pnlColumn.add(txtColumn); JPanel pnlMineCount = new JPanel(); contentPane.add(pnlMineCount); pnlMineCount.add(new JLabel("雷數:")); JTextField txtMineCount = new JTextField(10); pnlMineCount.add(txtMineCount); JPanel pnlButton = new JPanel(); contentPane.add(pnlButton); JButton btnOK = new JButton("確定"); btnOK.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { int r = Integer.parseInt(txtRow.getText().trim()); int c = Integer.parseInt(txtColumn.getText().trim()); int count = Integer.parseInt(txtMineCount.getText().trim()); if (r <= 0 || c <= 0 || r > 24 || c > 30) { JOptionPane.showMessageDialog(null, "限制行數:1~24\n限制列數:1~30", "警告", JOptionPane.WARNING_MESSAGE); return; } if (count <= 0 || count > r * c) { JOptionPane.showMessageDialog(null, "限制雷數:1~" + (r * c), "警告", JOptionPane.WARNING_MESSAGE); return; } new MenuFunction().ResetSize(r, c, count); gamemode = Custom_Mode; setVisible(false); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, "無效輸入!", "錯誤", JOptionPane.ERROR_MESSAGE); } } }); pnlButton.add(btnOK); } public void actionPerformed(ActionEvent e) { setVisible(true); } } // “高分榜”菜單項監聽類 private class HighScoreListener implements ActionListener { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(null, "初級:" + HighScore_Elementary + "秒\n中級:" + HighScore_Intermediate + "秒\n高級:" + HighScore_Advanced + "秒", "高分榜", JOptionPane.INFORMATION_MESSAGE); } } // 菜單欄事件監聽函數類 private class MenuFunction { // “重新開始本局”函數 public void Restart() { flagcount = 0; enablecount = area; if (!isFirstClick) { timeThread.interrupt(); isFirstClick = true; txtTime.setText("0"); } txtCount.setText("0/" + minecount); for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { flagmark[i][j] = false; btnMine[i][j].removeLabel(); btnMine[i][j].setIcon(null); btnMine[i][j].setOriginalStyle(); btnMine[i][j].setEnabled(true); } } if (isGameOver) { for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { btnMine[i][j].setMineListener(); } } isGameOver = false; } } // “開始新的游戲”函數 public void ResetMine() { minearea = new boolean[row][column]; setMinePosition(); Restart(); } // “游戲模式設置”函數 public void ResetSize(int r, int c, int count) { Restart(); txtCount.setText("0/" + count); pnlMine.removeAll(); setMineArea(r, c, count); setMinePosition(); setMineButton(); } } // 地雷區按鈕監聽類 private class MineListener extends MouseAdapter { private int r; private int c; private boolean bothpress; private MouseFunction mousefunction; public MineListener(int r, int c) { this.r = r; this.c = c; mousefunction = new MouseFunction(r, c); } // 鼠標點擊時觸發 public void mousePressed(MouseEvent e) { // 判斷是否為左右雙鍵同時點擊 int d = e.getModifiersEx(); if (d == InputEvent.BUTTON1_DOWN_MASK + InputEvent.BUTTON3_DOWN_MASK) { bothpress = true; } else { bothpress = false; } if (bothpress) { mousefunction.bothPressed(); } } // 鼠標釋放時觸發 public void mouseReleased(MouseEvent e) { if (bothpress) { mousefunction.bothReleased(); } else if (e.getButton() == MouseEvent.BUTTON1) { mousefunction.leftReleased(r, c); } else if (e.getButton() == MouseEvent.BUTTON3 && !bothpress) { mousefunction.rightReleased(); } if (minecount == enablecount) { mousefunction.Success(); } } } // 地雷區鼠標點擊事件監聽函數類 private class MouseFunction { private int r; private int c; private boolean[] bool; public MouseFunction(int r, int c) { this.r = r; this.c = c; bool = surroundingButtons(r, c); } // 判斷被點擊按鈕周邊3*3范圍內有無其它按鈕 private boolean[] surroundingButtons(int r, int c) { boolean[] bool = {true, true, true, true, true, true, true, true, true}; if (r == 0) {bool[0] = bool[1] = bool[2] = false;} if (r == row - 1) {bool[6] = bool[7] = bool[8] = false;} if (c == 0) {bool[0] = bool[3] = bool[6] = false;} if (c == column - 1) {bool[2] = bool[5] = bool[8] = false;} return bool; } // 左鍵釋放函數 public void leftReleased(int r, int c) { if (isFirstClick) { timeThread = new TimeThread(); timeThread.start(); isFirstClick = false; } if (flagmark[r][c] || !btnMine[r][c].isEnabled()) {return;} if (minearea[r][c]) {GameOver(r, c); return;} boolean[] bool = surroundingButtons(r, c); int i = 0; if (bool[0] && minearea[r - 1][c - 1]) {i++;} if (bool[1] && minearea[r - 1][c]) {i++;} if (bool[2] && minearea[r - 1][c + 1]) {i++;} if (bool[3] && minearea[r][c - 1]) {i++;} if (bool[5] && minearea[r][c + 1]) {i++;} if (bool[6] && minearea[r + 1][c - 1]) {i++;} if (bool[7] && minearea[r + 1][c]) {i++;} if (bool[8] && minearea[r + 1][c + 1]) {i++;} btnMine[r][c].setDisabledStyle(); btnMine[r][c].setEnabled(false); enablecount--; if (i != 0) { btnMine[r][c].setLabel(i); } else { if (bool[0]) {leftReleased(r - 1, c - 1);} if (bool[1]) {leftReleased(r - 1, c);} if (bool[2]) {leftReleased(r - 1, c + 1);} if (bool[3]) {leftReleased(r, c - 1);} if (bool[5]) {leftReleased(r, c + 1);} if (bool[6]) {leftReleased(r + 1, c - 1);} if (bool[7]) {leftReleased(r + 1, c);} if (bool[8]) {leftReleased(r + 1, c + 1);} } } // 右鍵釋放函數 public void rightReleased() { if (flagmark[r][c]) { btnMine[r][c].setIcon(null); flagmark[r][c] = false; flagcount--; txtCount.setText(flagcount + "/" + minecount); } else { if (btnMine[r][c].isEnabled()) { btnMine[r][c].setIcon(imgflag); flagmark[r][c] = true; flagcount++; txtCount.setText(flagcount + "/" + minecount); } } } // 雙鍵點擊函數 public void bothPressed() { if (flagmark[r][c]) {return;} int k = 0; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (bool[k++] && btnMine[r + i][c + j].isEnabled() && !flagmark[r + i][c + j]) { btnMine[r + i][c + j].setClickedStyle(); } } } } // 雙鍵釋放函數 public void bothReleased() { if (flagmark[r][c]) {return;} int k = 0, m = 0, n = 0; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (bool[k++]) { if (btnMine[r + i][c + j].isEnabled() && !flagmark[r + i][c + j]) { btnMine[r + i][c + j].setOriginalStyle(); } if (minearea[r + i][c + j]) { m++; } if (flagmark[r + i][c + j]) { n++; } } } } if (btnMine[r][c].isEnabled()) {return;} if (m == n) { if (bool[0] && !flagmark[r - 1][c - 1]) {leftReleased(r - 1, c - 1);} if (bool[1] && !flagmark[r - 1][c]) {leftReleased(r - 1, c);} if (bool[2] && !flagmark[r - 1][c + 1]) {leftReleased(r - 1, c + 1);} if (bool[3] && !flagmark[r][c - 1]) {leftReleased(r, c - 1);} if (bool[5] && !flagmark[r][c + 1]) {leftReleased(r, c + 1);} if (bool[6] && !flagmark[r + 1][c - 1]) {leftReleased(r + 1, c - 1);} if (bool[7] && !flagmark[r + 1][c]) {leftReleased(r + 1, c);} if (bool[8] && !flagmark[r + 1][c + 1]) {leftReleased(r + 1, c + 1);} } } // 游戲結束函數 public void GameOver(int r, int c) { btnMine[r][c].setBackground(Color.red); for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { if (minearea[i][j]) { btnMine[i][j].setIcon(imgbomb); } btnMine[i][j].removeMineListener(); } } timeThread.interrupt(); JOptionPane.showMessageDialog(null, "Game Over", "提示", JOptionPane.INFORMATION_MESSAGE); isGameOver = true; } // 游戲勝利函數 public void Success() { txtCount.setText(minecount + "/" + minecount); for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { if (minearea[i][j]) { btnMine[i][j].setIcon(imgflag); } btnMine[i][j].removeMineListener(); } } if (timeThread != null) { timeThread.interrupt(); } String s = "You Win!"; int time = Integer.parseInt(txtTime.getText()); switch (gamemode) { case Elementary_Mode: if (time < HighScore_Elementary) { HighScore_Elementary = time; s = "New Record!"; } break; case Intermediate_Mode: if (time < HighScore_Intermediate) { HighScore_Intermediate = time; s = "New Record!"; } break; case Advanced_Mode: if (time < HighScore_Advanced) { HighScore_Advanced = time; s = "New Record!"; } } JOptionPane.showMessageDialog(null, s + "\n用時:" + time + "秒", "提示", JOptionPane.INFORMATION_MESSAGE); isGameOver = true; } } // 地雷區按鈕類,JButton按鈕的子類 private class MineButton extends JButton { private MineListener mineListener; private JLabel lbl; private MineButton() { super(null, null); setBackground(Color.lightGray); // 設置凸起來的按鈕 setBorder(BorderFactory.createRaisedBevelBorder()); } public MineButton(int r, int c) { this(); mineListener = new MineListener(r, c); addMouseListener(mineListener); } public void setMineListener() { addMouseListener(mineListener); } public void removeMineListener() { removeMouseListener(mineListener); } public void setOriginalStyle() { setBackground(Color.lightGray); // 設置凸起來的按鈕 setBorder(BorderFactory.createRaisedBevelBorder()); } public void setDisabledStyle() { setBackground(null); // 設置按鈕邊框線條 setBorder(BorderFactory.createLineBorder(Color.lightGray)); } public void setClickedStyle() { setBackground(Color.lightGray); // 設置凹下去的按鈕 setBorder(BorderFactory.createLoweredBevelBorder()); } public void setLabel(int i) { lbl = new JLabel(String.valueOf(i)); lbl.setHorizontalAlignment(JLabel.CENTER); lbl.setVerticalAlignment(JLabel.CENTER); lbl.setForeground(NumberColor[i - 1]); setLayout(new BorderLayout(0, 0)); add(lbl, BorderLayout.CENTER); } public void removeLabel() { if (lbl != null) { remove(lbl); lbl = null; } } } // 線程類,游戲開始后每隔一秒刷新txtTime文本框里顯示的時間 private class TimeThread extends Thread { // 重寫run()方法 public void run() { // 獲取當前系統時間 long startTime = System.currentTimeMillis(); // 非阻塞過程中通過判斷中斷標志來退出 while (!isInterrupted()) { // 獲取當前的系統時間,與初始時間相減就是程序運行的毫秒數,除以1000就是秒數 long endTime = System.currentTimeMillis(); long usedTime = (endTime - startTime) / 1000; txtTime.setText(String.valueOf(usedTime)); try { // 線程掛起一秒鐘 Thread.sleep(1000); // 阻塞過程捕獲中斷異常來退出 } catch (InterruptedException e) { e.printStackTrace(); // 捕獲到異常之后,執行break跳出循環 break; } } } } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。