标签:
一个简单的扫雷小游戏,在12*12的方格盘上,首先可以设定雷的个数,然后点击开始程序就会随机布雷,开始游戏后如果点到雷就会显示游戏结束,如果没有,会出现数字表示周围一圈雷的个数,以此推理当扫出所有雷将显示游戏胜利。
游戏项目规划:
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 public class Frame 5 extends JFrame { 6 JTextField text; 7 JLabel nowBomb, setBomb; 8 int BombNum, BlockNum; //当前雷数,当前方块数 9 int rightBomb, restBomb, restBlock; //找到的地雷数,剩余雷数,剩余方块数 10 11 JButton start = new JButton(" 开始 ");//初始化一个开始的按钮 12 JPanel MenuPanel = new JPanel();//新建一个区域,作为菜单 13 JPanel bombPanel = new JPanel();//新建一个区域,作为雷区 14 Bomb[][] bombButton;//2维数组,防地雷 15 16 JPanel c; 17 BorderLayout borderLayout1 = new BorderLayout();//布局管理器边界布局 18 GridLayout gridLayout1 = new GridLayout();//布局一个网格布局 19 public Frame() { 20 try { 21 setDefaultCloseOperation(EXIT_ON_CLOSE);//关闭操作并结束进程 22 jbInit();//一般用于对程序进行初始化 23 } 24 catch (Exception exception) {//异常处理 25 exception.printStackTrace(); 26 } 27 } 28 29 private void jbInit() throws Exception { 30 c = (JPanel) getContentPane();//设定一个空间 31 setTitle("扫雷");//标题为扫雷 32 c.setBackground(Color.WHITE);//背景颜色为白色 33 MenuPanel.setBackground(Color.GRAY);//菜单颜色为灰色 34 c.setLayout(borderLayout1); 35 setSize(new Dimension(700, 700));//界面大小700*700 36 setResizable(false); 37 38 BlockNum = 144;//设定方块数144个 39 BombNum = 10;//设定初始地雷数10个 40 text = new JTextField("10 ", 3);//设定一个字符框长度为3 41 nowBomb = new JLabel("当前雷数" + ":" + BombNum); 42 setBomb = new JLabel("设置地雷数");//标明解释 43 start.addActionListener(new Frame1_start_actionAdapter(this)); 44 45 MenuPanel.add(setBomb); 46 MenuPanel.add(text); 47 MenuPanel.add(start); 48 MenuPanel.add(nowBomb);//添加菜单元素 49 c.add(MenuPanel, java.awt.BorderLayout.SOUTH);//给界面下方的界面设定布局 50 51 bombPanel.setLayout(gridLayout1); 52 gridLayout1.setColumns( (int) Math.sqrt(BlockNum));//纵列设定 53 gridLayout1.setRows( (int) Math.sqrt(BlockNum));//横排设定 54 bombButton = new Bomb[ (int) Math.sqrt(BlockNum)][ (int) Math.sqrt(BlockNum)]; 55 for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) { 56 for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {//嵌套for循环表示所有的格子 57 bombButton[i][j] = new Bomb(i, j); 58 59 bombButton[i][j].setFont(new Font("", Font.PLAIN, 14));//设计字体显示效果 60 61 bombButton[i][j].setForeground(Color.white);//背景颜色为白色 62 bombButton[i][j].addMouseListener(new Bomb_mouseAdapter(this)); 63 bombButton[i][j].addActionListener(new Bomb_actionAdapter(this)); 64 bombPanel.add(bombButton[i][j]); 65 } 66 } 67 c.add(bombPanel, java.awt.BorderLayout.CENTER);//给界面中间的界面设定布局 68 69 startBomb(); 70 } 71 72 /* 开始按钮 */ 73 74 public void start_actionPerformed(ActionEvent e) { 75 int num=Integer.parseInt(text.getText().trim());//调用Integer.parseInt()把一个String转换成一个Double基本类型的值并赋值给了num 76 if (num >= 5 && num < 50) { 77 BombNum = num;//如果当前雷数在5-50之间 78 startBomb();//可以开始布雷。 79 } 80 else if (num < 5) {//如果当前雷数在5以下 81 JOptionPane.showMessageDialog(null, "您设置的地雷数太少了,请重设!", "错误", 82 JOptionPane.ERROR_MESSAGE);//消息提示框显示错误。 83 num=10; 84 BombNum = num;//自动将雷数改为10. 85 } 86 else { 87 JOptionPane.showMessageDialog(null, "您设置的地雷数太多了,请重设!", "错误", 88 JOptionPane.ERROR_MESSAGE);//同上,消息提示框提醒输入有误。 89 num=10; 90 BombNum = num; 91 } 92 } 93 /* 开始,布雷 */ 94 95 96 public void startBomb() { 97 nowBomb.setText("当前雷数" + ":" + BombNum);//利用setText设置现在的雷数。 98 for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {//由按钮组成的二维数组,i表示行,j表示列,构成了一个方形网格 99 for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {//循环条件判断isRight的值,如果为false循环否则退出 100 bombButton[i][j].isBomb = false;//当前按钮是否为雷 101 bombButton[i][j].isClicked = false;//是否已被点击 102 bombButton[i][j].isRight = false;//是否被(标注)正确 103 bombButton[i][j].BombFlag = 0;//是否被标注为雷 104 bombButton[i][j].BombRoundCount = 9;//周围 105 bombButton[i][j].setEnabled(true); 106 bombButton[i][j].setText(""); 107 bombButton[i][j].setFont(new Font("", Font.PLAIN, 14));//设置字体大小 108 bombButton[i][j].setForeground(Color.BLUE);//设置颜色为蓝色 109 rightBomb = 0;//正确标出的雷数为0 110 restBomb = BombNum; 111 restBlock = BlockNum - BombNum; 112 } 113 } 114 115 for (int i = 0; i < BombNum; ) { 116 int x = (int) (Math.random() * (int) (Math.sqrt(BlockNum) - 1)); 117 int y = (int) (Math.random() * (int) (Math.sqrt(BlockNum) - 1)); 118 119 if (bombButton[x][y].isBomb != true) { 120 bombButton[x][y].isBomb = true; 121 i++; 122 } 123 } 124 CountRoundBomb(); 125 } 126 127 /* 计算方块周围雷数 */ 128 129 public void CountRoundBomb() { 130 for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {//开方 障碍数 131 for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) { 132 int count = 0;//当需要检测的单元格本身无雷的情况下,统计周围的地雷个数 133 134 if (bombButton[i][j].isBomb != true) {//如果不是雷 135 for (int x = i - 1; x < i + 2; x++) {//从左边到右,一个三个 136 for (int y = j - 1; y < j + 2; y++) { 137 if ( (x >= 0) && (y >= 0) 138 && (x < ( (int) Math.sqrt(BlockNum))) 139 && (y < ( (int) Math.sqrt(BlockNum)))) {//因前面x=i-1,所以排除超出边界的情况 140 if (bombButton[x][y].isBomb == true) {//如果是雷 141 count++;//加一 142 } 143 } 144 } 145 } 146 bombButton[i][j].BombRoundCount = count;//设置该Bomb环绕数的值 147 } 148 } 149 } 150 } 151 152 /* 是否挖完了所有的雷 */ 153 154 public void isWin() { 155 restBlock = BlockNum - BombNum; 156 for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) { 157 for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) { 158 if (bombButton[i][j].isClicked == true) { 159 restBlock--; 160 } 161 } 162 } 163 164 if (rightBomb == BombNum || restBlock == 0) { 165 JOptionPane.showMessageDialog(this, "您挖完了所有的雷,您胜利了!", "胜利", 166 JOptionPane.INFORMATION_MESSAGE); 167 startBomb(); 168 } 169 } 170 171 /** 当选中的位置为空,则翻开周围的地图* */ 172 173 public void isNull(Bomb ClickedButton) { 174 int i, j; 175 i = ClickedButton.num_x; //点击的方块,周围地图 176 j = ClickedButton.num_y; 177 178 for (int x = i - 1; x < i + 2; x++) { //从左边到右边,一至三个 179 for (int y = j - 1; y < j + 2; y++) { 180 if ( ( (x != i) || (y != j)) && (x >= 0) && (y >= 0) 181 && (x < ( (int) Math.sqrt(BlockNum))) //因为设定x=i-1,所以排除超出边界的情况 182 && (y < ( (int) Math.sqrt(BlockNum)))) { 183 if (bombButton[x][y].isBomb == false //如果方块中不是雷 184 && bombButton[x][y].isClicked == false //如果方块未被点击 185 && bombButton[x][y].isRight == false) { //如果方块未被标记 186 turn(bombButton[x][y]); 187 } //选中位置为空,周围地图被翻开 188 } 189 } 190 } 191 } 192 193 /* 翻开 */ 194 195 public void turn(Bomb ClickedButton) { 196 ClickedButton.setEnabled(false); 197 ClickedButton.isClicked = true; 198 if (ClickedButton.BombRoundCount > 0) { 199 ClickedButton.setText(ClickedButton.BombRoundCount + ""); 200 } 201 else { 202 isNull(ClickedButton); 203 } 204 } 205 206 207 /* 左键点击 */ 208 public void actionPerformed(ActionEvent e) { 209 if ( ( (Bomb) e.getSource()).isClicked == false 210 && ( (Bomb) e.getSource()).isRight == false) { 211 if ( ( (Bomb) e.getSource()).isBomb == false) { 212 turn( ( (Bomb) e.getSource())); 213 isWin(); 214 } 215 216 else { 217 for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) { 218 for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) { 219 if (bombButton[i][j].isBomb == true) { 220 bombButton[i][j].setText("b"); 221 } 222 } 223 } 224 ( (Bomb) e.getSource()).setForeground(Color.RED); 225 ( (Bomb) e.getSource()).setFont(new Font("", Font.BOLD, 20)); 226 ( (Bomb) e.getSource()).setText("X"); 227 JOptionPane.showMessageDialog(this, "你踩到地雷了,按确定重来", "踩到地雷", 2); 228 startBomb(); 229 } 230 } 231 } 232 233 234 /* 右键点击 */ 235 public void mouseClicked(MouseEvent e) { 236 Bomb bombSource = (Bomb) e.getSource(); 237 boolean right = SwingUtilities.isRightMouseButton(e); 238 239 if ( (right == true) && (bombSource.isClicked == false)) { 240 bombSource.BombFlag = (bombSource.BombFlag + 1) % 3; 241 if (bombSource.BombFlag == 1) { 242 if (restBomb > 0) { 243 bombSource.setForeground(Color.RED); 244 bombSource.setText("F"); 245 bombSource.isRight = true; 246 restBomb--; 247 } 248 else { 249 bombSource.BombFlag = 0; 250 } 251 } 252 else if (bombSource.BombFlag == 2) { 253 restBomb++; 254 bombSource.setText("Q"); 255 bombSource.isRight = false; 256 } 257 else { 258 bombSource.setText(""); 259 } 260 261 if (bombSource.isBomb == true) { 262 if (bombSource.BombFlag == 1) { 263 rightBomb++; 264 } 265 else if (bombSource.BombFlag == 2) { 266 rightBomb--; 267 } 268 } 269 nowBomb.setText("当前雷数" + ":" + restBomb); 270 isWin(); 271 } 272 } 273 274 public static void main(String[] args) { 275 Frame frame = new Frame(); 276 frame.setVisible(true); 277 } 278 } 279 280 class Frame1_start_actionAdapter 281 implements ActionListener { 282 private Frame adaptee; 283 Frame1_start_actionAdapter(Frame adaptee) { 284 this.adaptee = adaptee; 285 } 286 287 public void actionPerformed(ActionEvent e) { 288 adaptee.start_actionPerformed(e); 289 } 290 } 291 292 //////////////////////////// 293 class Bomb 294 extends JButton { 295 int num_x, num_y; //第几号方块 296 int BombRoundCount; //周围雷数 297 boolean isBomb; //是否为雷 298 boolean isClicked; //是否被点击 299 int BombFlag; //测试雷标记 300 boolean isRight; //是否点击右键 301 302 public Bomb(int x, int y) { 303 num_x = x; 304 num_y = y;//累的位置,获得是参数值,嵌套了两个for循环 305 BombFlag = 0;//是否已经插旗了 306 BombRoundCount = 9;//环绕数 307 isBomb = false;//是雷 308 isClicked = false;//被点击 309 isRight = false;//是真的 310 } 311 } 312 313 class Bomb_actionAdapter 314 implements ActionListener { 315 private Frame adaptee; 316 Bomb_actionAdapter(Frame adaptee) { 317 this.adaptee = adaptee; 318 } 319 320 public void actionPerformed(ActionEvent e) { 321 adaptee.actionPerformed(e); 322 } 323 } 324 325 class Bomb_mouseAdapter 326 extends MouseAdapter { 327 private Frame adaptee; 328 Bomb_mouseAdapter(Frame adaptee) { 329 this.adaptee = adaptee; 330 } 331 332 public void mouseClicked(MouseEvent e) { 333 adaptee.mouseClicked(e); 334 } 335 }
初始界面:
设置雷数为10,开始游戏,会显示数字:
踩到雷,游戏结束:
扫完雷,游戏胜利:
通过团队项目,我们认识到了合作的重要性,紧密的合作能够提高我们的能力。代码测试过程中出现很多错误,但经过互相的合作和探讨,加以改进,便可以成功运行。 小组各组员的课程总结已发到个人博客。
HeyWeGo小组《Java程序设计》 2015—2016年学期团队项目总结
标签:
原文地址:http://www.cnblogs.com/heywego/p/5599067.html