Java Swing實現掃雷源碼
本文實例為大傢分享瞭Java Swing實現掃雷源碼的具體代碼,供大傢參考,具體內容如下
先來看下效果
運行時隻需要創建一個GameWindow的對象即可,可使用有參構造函數自定義雷區行列數及炸彈個數,也可使用無參構造函數設置默認值(小旗和炸彈的圖標自己去找吧,我就不在這裡放瞭)
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.LinkedList; public class GameWindow{ private static Font labelFont = new Font("隸書",Font.BOLD,45); private static Font buttonFont = new Font("隸書",Font.CENTER_BASELINE,20); private static Icon flag = new ImageIcon("src/images/小旗.jpg");//小旗圖標 private static Icon bomb = new ImageIcon("src/images/炸彈.png");//炸彈圖標 private static int labelWeight = 30;//小方塊(雷區)寬度 private static int labelHeigth = 30;//小方塊(雷區)高度 private static int labelSpace = 1;//小方塊(雷區)間距 private static int scoreHeight = 50;//積分區域高度 private static int[] x8 = {-1,-1,-1,0,0,1,1,1};//原坐標周圍 8 個坐標的 x 值變化 private static int[] y8 = {-1,0,1,-1,1,-1,0,1};//原坐標周圍 8 個坐標的 y 值變化 private static int[] x4 = {0,0,1,-1};//原坐標周圍 4 個坐標的 x 值變化 private static int[] y4 = {1,-1,0,0};//原坐標周圍 4 個坐標的 x 值變化 private JFrame frame; private int[][] data;//存儲和炸彈位置有關數據,值為-1時表示炸彈 private JLabel[][] labels; private JPanel mainPanel;//雷區主面板 private JPanel scorePanel;//積分區域面板 private JLabel areaLabel;//未掃雷區個數標簽 private JLabel bombLabel;//剩餘地雷數標簽 private int width;//窗體寬度 private int height;//窗體高度 private int row;//行數 private int column;//列數 private int bombNum;//炸彈個數 private int remainArea;//未掃雷區個數 private int remainBomb;//剩餘地雷數 public GameWindow(int row,int column,int bombNum){ frame = new JFrame("掃雷-洋仔小遊戲"); this.row = row; this.column = column; this.bombNum = bombNum; mainPanel = new JPanel(); init(); } public GameWindow(){ this(10,10,20); } private void setWidthAndHeight(){ width = labelWeight * column + (column + 1) * labelSpace; height = scoreHeight + labelHeigth * row + (row + 1) * labelSpace; } private void setBomb(){ if(bombNum > row * column) throw new RuntimeException("炸彈數設置過多!"); data = new int[row][column]; int count = 0; while (count < bombNum){ int r = (int)(Math.random() * row); int c = (int)(Math.random() * column); System.out.println("r = " + r + "\tc = " + c); if(data[r][c] == -1) continue; data[r][c] = -1; for(int i = 0; i < 8; i ++){ int x = r + x8[i]; int y = c + y8[i]; if(x < 0 || x >= row || y < 0 || y >= column || data[x][y] == -1) continue; data[r + x8[i]][c + y8[i]] ++; } count ++; System.out.println(count); } } private class ButtonListener extends MouseAdapter { private JButton button; private int r; private int w; private GameWindow window; private boolean disabled = true; public ButtonListener(JButton button,int r,int w,GameWindow window){ this.button = button; this.r = r; this.w = w; this.window = window; } @Override public void mouseClicked(MouseEvent mouseEvent) { synchronized (window){ if(!button.isEnabled()) return; if(mouseEvent.getButton() == MouseEvent.BUTTON3){ if(disabled) { button.setIcon(flag); data[r][w] -= 20; remainBomb --; remainArea --; } else { button.setIcon(null); data[r][w] += 20; remainBomb ++; remainArea ++; } disabled = !disabled; bombLabel.setText("" + remainBomb); areaLabel.setText("" + remainArea); return; } if(!disabled) return; int cnt = 1; button.setVisible(false); if(data[r][w] == -1){ gameOver(); // System.out.println("\n點到炸彈,全體按鈕已禁用"); return; } LinkedList<int[]> stack = new LinkedList<>(); stack.push(new int[]{r,w}); data[r][w] = -1; while (stack.size() > 0){ int[] source = stack.pop(); for(int i = 0; i < 4; i ++){ int x = source[0] + x4[i]; int y = source[1] + y4[i]; if(x < 0 || x >= row || y < 0 || y >= column || data[x][y] < 0) continue; if(data[x][y] == 0) stack.push(new int[]{x,y}); labels[x][y].getLabelFor().setVisible(false); cnt ++; data[x][y] = -1; } } remainArea -= cnt; areaLabel.setText("" + remainArea); if(remainArea == remainBomb){ gameOver(); } } } } private void gameOver(){ for(JLabel[] ls : labels){ for(JLabel l : ls){ JButton button = (JButton) l.getLabelFor(); button.setEnabled(false); } } } private void init(){ setWidthAndHeight(); frame.setBounds(380,100,width + 9,height + 32); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); frame.setLayout(null); mainPanel.setBackground(Color.GRAY); mainPanel.setBounds(1,scoreHeight + 1,width,height); mainPanel.setLayout(null); scorePanel = new JPanel(); scorePanel.setBounds(0,0,width,scoreHeight); scorePanel.setLayout(new GridLayout(1,3,0,0)); areaLabel = new JLabel(); areaLabel.setFont(labelFont); areaLabel.setHorizontalAlignment(JLabel.CENTER); scorePanel.add(areaLabel); JLabel buttonLabel = new JLabel(); scorePanel.add(buttonLabel); JButton resetButton = new JButton("重開"); resetButton.setFont(buttonFont); resetButton.setFocusPainted(false); resetButton.setBounds(width/ 24,10,width / 4,30); resetButton.addActionListener((event)->{ frame.setVisible(false); mainPanel.removeAll(); resetGame(); }); buttonLabel.add(resetButton); bombLabel = new JLabel(); bombLabel.setFont(labelFont); bombLabel.setHorizontalAlignment(JLabel.CENTER); scorePanel.add(bombLabel); frame.add(scorePanel); frame.add(mainPanel); resetGame(); } public void resetGame(){ setBomb(); remainArea = row * column; remainBomb = bombNum; labels = new JLabel[row][column]; System.gc(); for(int i = 0; i < row; i ++){ for(int j = 0; j < column; j ++){ labels[i][j] = new JLabel(); //設置元素居中 labels[i][j].setHorizontalAlignment(JLabel.CENTER); if(data[i][j] == -1) { labels[i][j].setIcon(bomb); } else if(data[i][j] > 0) labels[i][j].setText("" + data[i][j]); int y = (i + 1) * labelSpace + i * labelWeight; int x = (j + 1) * labelSpace + j * labelHeigth; labels[i][j].setBounds(x,y,labelWeight,labelHeigth); JButton button = new JButton(); button.addMouseListener(new ButtonListener(button,i,j,this)); button.setBounds(0,0,labelWeight,labelHeigth); labels[i][j].setLayout(null); labels[i][j].add(button); labels[i][j].setLabelFor(button); mainPanel.add(labels[i][j]); } } areaLabel.setText("" + remainArea); bombLabel.setText("" + remainBomb); frame.setVisible(true); } }
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。