java实现扫雷小游戏
程序员文章站
2022-03-11 21:13:55
本文实例为大家分享了java实现扫雷小游戏的具体代码,供大家参考,具体内容如下
代码:
package gui;
import java.util.random;...
本文实例为大家分享了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; } } } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: self.params的使用注意点
下一篇: Sp保存