zoukankan      html  css  js  c++  java
  • Java Swing开发扫雷小游戏

    用Java来开发了以下经典小游戏扫雷,作为学习Java Swing的练手。

    主要代码是有三个类:setting类存放游戏的一些设定,Map是new一个游戏开始的框架,MapFrame是游戏框架以及响应点击等方法。

    以下是3个类的代码,初学者写的代码难免有许多不成熟的地方,请各位轻喷。

    setting

     1 package map;
     2 
     3 public class Setting {
     4     public int row;
     5     public int col;
     6     public int mine;
     7     public Setting(int row,int col,int mine) {
     8         this.row=row;
     9         this.col=col;
    10         this.mine=mine;
    11     }
    12 }

    Map

     1 package map;
     2 
     3 import java.awt.*;
     4 import javax.swing.*;
     5 import java.util.Random;
     6 
     7 public class Map {
     8     public static final int[] dx=new int[]{-1,-1,-1,0,1,1,1,0};
     9     public static final int[] dy=new int[]{-1,0,1,1,1,0,-1,-1};
    10     public Setting setting;
    11     public int[][] map;
    12     
    13     public Map() {
    14         NewMap();
    15     }
    16     
    17     public static void NewMap() {
    18         Setting setting=new Setting(9,9,10);
    19         EventQueue.invokeLater(()->{
    20             JFrame frame=new MapFrame(setting);
    21             frame.setTitle("Minesweeper");
    22             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    23             frame.setVisible(true);
    24         });        
    25     }
    26 }

    MapFrame

      1 package map;
      2 
      3 import java.awt.*;
      4 import java.awt.event.*;
      5 import java.awt.geom.*;
      6 
      7 import javax.swing.*;
      8 import javax.swing.border.Border;
      9 
     10 import java.util.LinkedList;
     11 import java.util.Queue;
     12 import java.util.Random;
     13 
     14 public class MapFrame extends JFrame {
     15     public int row,col,mine;
     16     public int[][] map;
     17     public boolean[][] visit;
     18     public JButton[][] mine_button;
     19     public static final int[] dx=new int[] {-1,0,1,0,-1,-1,1,1};
     20     public static final int[] dy=new int[] {0,1,0,-1,-1,1,1,-1};
     21     
     22     public int total_visit;
     23     
     24     public MapFrame(Setting setting) {
     25         this.row=setting.row; this.col=setting.col; this.mine=setting.mine; 
     26         this.map=calc_map(setting);
     27         mine_button=new JButton[row][col];
     28         visit=new boolean[row][col];
     29         total_visit=0;
     30         int fwidth=row/9*400,fheight=col/9*400+70;
     31         setSize(fwidth,fheight);
     32         JPanel TimeJpanel=new JPanel();
     33         JPanel MapJpanel=new JPanel();
     34         
     35         JLabel TimeText=new JLabel("Time : 0");
     36         TimeJpanel.add(TimeText);
     37         
     38         myTimer timer =new myTimer(TimeText);
     39         Timer timelistener =new Timer(1000,timer);
     40         timelistener.start();  //开始定时器
     41         
     42         MapJpanel.setPreferredSize(new Dimension(row/9*400,col/9*400));
     43         MapJpanel.setLayout(new GridLayout(row,col));
     44         for (int i=0;i<row*col;i++) {
     45             int x=i/this.col;
     46             int y=i%this.row;
     47             mine_button[x][y]=new JButton();
     48             mine_button[x][y].setBackground(new Color(81,168,221));
     49             mine_button[x][y].addActionListener(new click_listener(x,y));
     50             MapJpanel.add(mine_button[x][y]);
     51         }
     52         
     53         setLayout(new BorderLayout());
     54         add(TimeJpanel,BorderLayout.NORTH);
     55         add(MapJpanel,BorderLayout.SOUTH);        
     56     }
     57     
     58     class click_listener implements ActionListener {
     59         public int x,y;
     60         public click_listener(int x,int y) {
     61             this.x=x; this.y=y;
     62         }
     63         
     64         public void actionPerformed(ActionEvent event) {
     65             if (visit[this.x][this.y]) return;
     66             int num=map[this.x][this.y];
     67             if (num!=-1) {
     68                 mine_button[this.x][this.y].setBackground(Color.WHITE);
     69                 if (num==0) whitebfs(this.x,this.y);
     70                 else {
     71                     if (!visit[this.x][this.y]) total_visit++; visit[this.x][this.y]=true;
     72                     mine_button[this.x][this.y].setText(""+num);
     73                 }
     74                 if (total_visit+mine==row*col) {
     75                     //游戏成功
     76                     int selection=JOptionPane.showConfirmDialog(null,"你成功排掉所有雷,是否重新开始?","游戏成功",
     77                             JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE);
     78                     if (selection==JOptionPane.YES_OPTION) {
     79                         //重新开始游戏
     80                         dispose();
     81                         Map.NewMap();
     82                     }
     83                 }
     84             } else {
     85                 //游戏失败
     86                 mine_button[this.x][this.y].setIcon(new ImageIcon("./Image/mine.jpg"));
     87                 int selection=JOptionPane.showConfirmDialog(null,"你踩到雷了,是否重新开始?","游戏失败",
     88                         JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE);
     89                 if (selection==JOptionPane.YES_OPTION) {
     90                     //重新开始游戏    
     91                     dispose();
     92                     Map.NewMap();
     93                 }
     94             }
     95         }
     96     
     97         public void whitebfs(int x,int y) {
     98              Queue<Integer> q=new LinkedList<>();
     99              q.offer(x*col+y);
    100              while (q.size()>0) {
    101                  int now=q.poll();
    102                  x=now/col; y=now%col;
    103                  if (!visit[x][y]) total_visit++; visit[x][y]=true;
    104                  mine_button[x][y].setBackground(Color.WHITE);
    105                  around(x,y);
    106                  for (int i=0;i<4;i++) {
    107                      int tx=x+dx[i],ty=y+dy[i];
    108                      if (tx<0 || tx>=row || ty<0 || ty>=col) continue;
    109                      if (visit[tx][ty]) continue;
    110                      if (map[tx][ty]!=0) continue;
    111                      q.offer(tx*col+ty);
    112                  }
    113              }
    114         }
    115         
    116         public void around(int x,int y) {
    117             for (int i=0;i<8;i++) {
    118                 int tx=x+dx[i],ty=y+dy[i];
    119                 if (tx<0 || tx>=row || ty<0 || ty>=col) continue;
    120                 if (map[tx][ty]>0) {
    121                     if (!visit[tx][ty]) total_visit++; visit[tx][ty]=true;
    122                     mine_button[tx][ty].setBackground(Color.WHITE);
    123                     if (map[tx][ty]>0)mine_button[tx][ty].setText(""+map[tx][ty]);
    124                 }
    125             }
    126         }
    127     }
    128     
    129     /**
    130      * 计时器
    131      */
    132     class myTimer implements ActionListener {
    133         JLabel text;
    134         long start;
    135         public myTimer(JLabel text) {
    136             this.text=text;
    137             start=System.currentTimeMillis();
    138         }
    139         public void actionPerformed(ActionEvent event) {
    140             text.setText("Time : "+(System.currentTimeMillis()-start)/1000);
    141         }
    142     }
    143     
    144     /**
    145      * 计算map数字大小
    146      */
    147     public int[][] calc_map(Setting setting) {
    148         int[][] map=new int[setting.row+2][setting.col+2];
    149         for (int i=0;i<=setting.row+1;i++)
    150             for (int j=0;j<=setting.col+1;j++)
    151                 map[i][j]=0;
    152         
    153         int now_mine=0;
    154         Random rand=new Random(System.currentTimeMillis());
    155         while (now_mine<setting.mine) {
    156             int mine_x=rand.nextInt(setting.row);
    157             int mine_y=rand.nextInt(setting.col);
    158             if (map[mine_x][mine_y]==0) {
    159                 map[mine_x][mine_y]=-1;
    160                 now_mine++;
    161             }
    162         }
    163         
    164         for (int i=1;i<=setting.row;i++)
    165             for (int j=1;j<=setting.col;j++) {
    166                 if (map[i][j]==-1) continue;
    167                 for (int k=0;k<8;k++) map[i][j]+=(map[i+dx[k]][j+dy[k]]==-1 ? 1 : 0);
    168             }    
    169         
    170         return map;
    171     }
    172 }
     
  • 相关阅读:
    HDOJ 5347 MZL's chemistry 【打表】
    自定义轮播图插件
    Twitter Bootstrap:前端框架利器
    左边定宽,右边自适应两列布局
    JS 断点调试心得
    关于将多个json对象添加到数组中的测试
    普通选项卡+自动播放功能+向前/向后按钮 原生js
    线程队列、事件以及协程
    GIL锁、进程池与线程池、同步异步
    JoinableQueue类与线程
  • 原文地址:https://www.cnblogs.com/clno1/p/12451128.html
Copyright © 2011-2022 走看看