JAVA实现经典扫雷游戏的示例代码
作者:小虚竹and掘金 时间:2022-01-26 04:20:18
前言
windows自带的游戏《扫雷》是陪伴了无数人的经典游戏,本程序参考《扫雷》的规则进行了简化,用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想。
主要需求
1、要有难度等级,初级,中级,高级
2、由玩家逐个翻开方块,以找出所有地雷为最终游戏目标。如果玩家翻开的方块有地雷,则游戏结束
3、游戏主区域由很多个方格组成。使用鼠标左键随机点击一个方格,方格即被打开并显示出方格中的数字;方格中数字则表示其周围的8个方格隐藏了几颗雷。
4、用户右键可标记雷的位置
5、雷都被标记出来则胜利
主要设计
1、格子格数固定为10*10格
2、难度等级,初级:12,中级:24,高级:36
3、点击格子时,产生没有引爆的地图效果;
4、点击格子时,此格子是雷,则显示所有雷的位置,并递归清空非雷格子,结束游戏
5、实现检查所有的雷是否都被标记出来了,如果是,则胜利算法。
6、实现计时器算法,用来计时显示游戏开始多少秒
7、实现难度等级,雷数的显示
8、实现鼠标左键的实现逻辑
9、实现鼠标右键的标记逻辑
功能截图
开始界面
左键选中格子效果
左键选中雷效果
右键标记雷效果
胜利效果
代码实现
程序启动类
public class JMine extends JFrame implements MouseListener, ActionListener {
private JMineArth mine;
private JMineButton[][] mineButton;
private GridBagConstraints constraints;
private JPanel pane;
private GridBagLayout gridbag;
private boolean gameStarted;
private static JCounter mineCounter;
private static JCounter timeCounter;
private Timer timer;
private Timer winTimer = new Timer();
public int numMine;
public int numFlaged;
private JMenuBar mb;
private JMenu mGame;
private JMenuItem miEasy;
private JMenuItem miMiddle;
private JMenuItem miHard;
private JMenuItem miExit;
private JMenu mHelp;
private JMenuItem miAbout;
private JPanel controlPane;
private JButton bTest;
private AboutFrame about;
private WinFrame winFrame;
private ImageIcon[] mineNumIcon = { new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif")),
new ImageIcon(JMine.class.getClassLoader().getResource("1.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("2.gif")),
new ImageIcon(JMine.class.getClassLoader().getResource("3.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("4.gif")),
new ImageIcon(JMine.class.getClassLoader().getResource("5.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("6.gif")),
new ImageIcon(JMine.class.getClassLoader().getResource("7.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("8.gif")),
new ImageIcon(JMine.class.getClassLoader().getResource("0.gif"))};
private ImageIcon[] mineStatus = { new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif")),
new ImageIcon(JMine.class.getClassLoader().getResource("flag.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("question.gif")) };
private ImageIcon[] mineBombStatus = { new ImageIcon(JMine.class.getClassLoader().getResource("0.gif")),
new ImageIcon(JMine.class.getClassLoader().getResource("mine.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("wrongmine.gif")),
new ImageIcon(JMine.class.getClassLoader().getResource("bomb.gif")) };
private ImageIcon[] faceIcon = { new ImageIcon(JMine.class.getClassLoader().getResource("smile.gif")),
new ImageIcon(JMine.class.getClassLoader().getResource("Ooo.gif")) };
// You lose
private void bomb(int row, int col){
try{
//System.out.println("Bomb!");
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
mineButton[i][j].setIcon(mineBombStatus[0]);
int toShow;
toShow = mine.mine[i][j] != 9 ? 0 : 1;
mineButton[i][j].setClickFlag(true);
if (toShow == 1 && (i != row || j != col)) {
mineButton[i][j].setIcon(mineBombStatus[toShow]);
mineButton[i][j].setClickFlag(true);
} else if (toShow == 1 && (i == row && j == col)) {
mineButton[i][j].setIcon(mineBombStatus[3]);
mineButton[i][j].setClickFlag(true);
} else if (toShow == 0 && mineButton[i][j].getFlag() != 1) {
mineButton[i][j].setEnabled(false);
} else if (toShow == 0 && mineButton[i][j].getFlag() == 1) {
mineButton[i][j].setIcon(mineBombStatus[2]);
mineButton[i][j].setClickFlag(true);
}
}
}
timer.cancel();
}catch (Exception e){
}
}
// check if you win() {
private boolean isWin() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (mine.mine[i][j] == 9 && mineButton[i][j].getFlag() != 1) {
return (false);
}
if (mine.mine[i][j] != 9 && mineButton[i][j].getFlag() == 1) {
return (false);
}
if (mine.mine[i][j] != 9
&& mineButton[i][j].getClickFlag() == false) {
return (false);
}
}
}
return (true);
}
// You Win
private void win(){
timer.cancel();
winFrame.setVisible(true);
winTimer.schedule(new TimerTask(){
public void run() {
while(!winFrame.getWinOk()){
}
numMine = winFrame.getMineNum();
winFrame.setVisible(false);
setNewGame(numMine);
//System.out.println("Jerry Debug:"+numMine);
this.cancel();
winFrame.setWinOk(false);
}
},0L);
}
// Constructor of the game
public JMine() {
super("JMine Game");
setSize(250, 350);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Insets space = new Insets(0, 0, 0, 0);
// Game vars
gameStarted = false;
numMine = 12;
numFlaged = 0;
ImageIcon myIcon = new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif"));
gridbag = new GridBagLayout();
constraints = new GridBagConstraints();
pane = new JPanel();
pane.setLayout(gridbag);
constraints.fill = GridBagConstraints.BOTH;
constraints.anchor = GridBagConstraints.CENTER;
// Begin Menu Set
mb = new JMenuBar();
mGame = new JMenu("Game");
miEasy = new JMenuItem("Easy");
miEasy.addActionListener(this);
miMiddle = new JMenuItem("Middle");
miMiddle.addActionListener(this);
miHard = new JMenuItem("Hard");
miHard.addActionListener(this);
miExit = new JMenuItem("Exit");
miExit.addActionListener(this);
mGame.add(miEasy);
mGame.add(miMiddle);
mGame.add(miHard);
mGame.addSeparator();
mGame.add(miExit);
mb.add(mGame);
mHelp = new JMenu("Help");
miAbout = new JMenuItem("About...");
mHelp.add(miAbout);
miAbout.addActionListener(this);
mb.add(mHelp);
this.setJMenuBar(mb);
// end of Menu Set
// Control Panel
controlPane = new JPanel();
bTest = new JButton(faceIcon[0]);
bTest.setSize(26, 27);
bTest.setMargin(space);
bTest.addMouseListener(this);
bTest.setPressedIcon(faceIcon[1]);
mineCounter = new JCounter(numMine);
timeCounter = new JCounter();
controlPane.add(mineCounter);
controlPane.add(bTest);
controlPane.add(timeCounter);
buildConstraints(constraints, 0, 0, 10, 2, 100, 100);
gridbag.setConstraints(controlPane, constraints);
pane.add(controlPane);
// Bottons
mineButton = new JMineButton[10][10];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
mineButton[i][j] = new JMineButton(i, j, myIcon);
mineButton[i][j].addMouseListener(this);
mineButton[i][j].setMargin(space);
buildConstraints(constraints, j, i + 3, 1, 1, 100, 100);
gridbag.setConstraints(mineButton[i][j], constraints);
pane.add(mineButton[i][j]);
}
}
// Content Pane
setContentPane(pane);
setLocation(200, 150);
setVisible(true);
// About Frame
about = new AboutFrame("JMine About");
winFrame = new WinFrame("You win!");
}
// Set the GUI objects positions
void buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw,
int gh, int wx, int wy) {
gbc.gridx = gx;
gbc.gridy = gy;
gbc.gridwidth = gw;
gbc.gridheight = gh;
gbc.weightx = wx;
gbc.weighty = wy;
}
// the methods to check if there were mines, to be nested
void checkMine(int row, int col){
int i, j;
i = row < 0 ? 0 : row;
i = i > 9 ? 9 : i;
j = col < 0 ? 0 : col;
j = j > 9 ? 9 : j;
//System.out.println("Check Mine row:"+i + ",col:" +j);
if (mine.mine[i][j] == 9) {
bomb(i, j);
} else if (mine.mine[i][j] == 0
&& mineButton[i][j].getClickFlag() == false) {
mineButton[i][j].setClickFlag(true);
showLabel(i, j);
for (int ii = i - 1; ii <= i + 1; ii++)
for (int jj = j - 1; jj <= j + 1; jj++)
checkMine(ii, jj);
} else {
showLabel(i, j);
mineButton[i][j].setClickFlag(true);
}
if (isWin()) {
win();
}
}
private void clearAll(int row, int col){
int top, bottom, left, right;
top = row - 1 > 0 ? row - 1 : 0;
bottom = row + 1 < 10 ? row + 1 : 9;
left = col - 1 > 0 ? col - 1 : 0;
right = col + 1 < 10 ? col + 1 : 9;
for (int i = top; i <= bottom; i++) {
for (int j = left; j <= right; j++) {
if (mineButton[i][j].getFlag() != 1)
checkMine(i, j);
}
}
}
private void resetAll() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
mineButton[i][j].setFlag(0);
mineButton[i][j].setClickFlag(false);
mineButton[i][j].setIcon(mineStatus[0]);
mineButton[i][j].setEnabled(true);
mineButton[i][j].setVisible(true);
}
}
}
// to flag the mine you want to flag out
void flagMine(int row, int col) {
//System.out.println("Jerry Arrives here!");
int i, j;
i = row < 0 ? 0 : row;
i = i > 9 ? 9 : i;
j = col < 0 ? 0 : col;
j = j > 9 ? 9 : j;
if (mineButton[i][j].getFlag() == 0) {
numFlaged++;
} else if (mineButton[i][j].getFlag() == 1) {
numFlaged--;
}
mineCounter.resetCounter(numMine - numFlaged >= 0 ? numMine - numFlaged
: 0);
mineButton[i][j].setFlag((mineButton[i][j].getFlag() + 1) % 3);
showFlag(i, j);
if (isWin()) {
win();
}
}
// show the numbers of the nearby mines
void showLabel(int row, int col) {
//System.out.println("ShowLabel row:" + row + ",col:" + col);
int toShow;
toShow = mine.mine[row][col];
if (toShow != 0) {
mineButton[row][col].setIcon(mineNumIcon[toShow]);
mineButton[row][col].setClickFlag(true);
//mineButton[row][col].setEnabled(false);
} else {
//mineButton[row][col].setIcon(mineNumIcon[0]);
//mineButton[row][col].setClickFlag(true);
mineButton[row][col].setEnabled(false);
}
}
// circle the flag with blank, flaged, questioned
void showFlag(int row, int col) {
mineButton[row][col]
.setIcon(mineStatus[mineButton[row][col].getFlag()]);
}
// the mouse events listener methods
public void mouseEntered(MouseEvent e) {
//System.out.println("Jerry Test");
}
// method to start the new game
private void startNewGame(int num, int row, int col){
mine = new JMineArth(num, row, col);
//mine.printMine();
gameStarted = true;
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
public void run() {
timeCounter.counterAdd();
//System.out.println(timeCounter.getCounterNum());
}
},1000,1000);
}
public void setNewGame(int num) {
resetAll();
numMine = num;
numFlaged = 0;
gameStarted = false;
mineCounter.resetCounter(numMine);
timeCounter.resetCounter(0);
}
// the event handle to deal with the mouse click
public void mouseClicked(MouseEvent e) {
if (e.getSource() == bTest) {
setNewGame(numMine);
return;
}
int row, col;
row = ((JMineButton) e.getSource()).getRow();
col = ((JMineButton) e.getSource()).getCol();
if (!gameStarted) {
startNewGame(numMine, row, col);
}
if (e.getModifiers() == (InputEvent.BUTTON1_MASK + InputEvent.BUTTON3_MASK)) {
//System.out.println("HA");
clearAll(row, col);
}
if (!mineButton[row][col].getClickFlag()) {
if (e.getModifiers() == InputEvent.BUTTON1_MASK) {
//System.out.println("LeftButton");
if (mineButton[row][col].getFlag() == 1) {
return;
} else {
checkMine(row, col);
}
} else if (e.getModifiers() == InputEvent.BUTTON3_MASK) {
//System.out.println("RightButton");
flagMine(row, col);
} else {
//System.out.println("MiddleButton");
}
}
}
public void mousePressed(MouseEvent e) {
//System.out.println("Jerry Press");
}
public void mouseReleased(MouseEvent e) {
//System.out.println("Jerry Release");
}
public void mouseExited(MouseEvent e) {
//System.out.println("Jerry Exited");
}
public void actionPerformed(ActionEvent e) {
try {
if (e.getSource() == miEasy) {
setNewGame(12);
return;
}
if (e.getSource() == miMiddle) {
setNewGame(24);
return;
}
if (e.getSource() == miHard) {
setNewGame(36);
return;
}
if (e.getSource() == miExit) {
System.exit(0);
}
if (e.getSource() == miAbout) {
about.setVisible(true);
}
} catch (Exception ie) {
}
}
public static void main(String [] args) {
JMine jmine = new JMine();
jmine.setVisible(true);
}
}
地雷分布图算法类
public class JMineArth {
public int [][] mine;
private boolean fMineSet;
JMineArth(int mineNum, int row, int col) {
mine = new int[10][10];
setMine(mineNum, row, col);
setMineNum();
}
private void setMine(int mineNum, int Outrow, int Outcol) {
int col=0, row = 0, i=0;
//Math.srand(now);
while (i < mineNum) {
col = (int)(Math.random()*100)%10;
row = (int)(Math.random()*100)%10;
if (mine[col][row]==0 && (row!=Outrow || col!=Outcol || Outrow==10 )) {
mine[row][col]=9;
i++;
}
}
}
private void setMineNum() {
for ( int i=0 ; i <10; i++) {
for (int j=0; j < 10; j++) {
mine[i][j]=mine[i][j]==9?9:checkMineNum(i,j);
}
}
fMineSet = true;
}
private int checkMineNum(int ii,int jj) {
int top,bottom, left, right, count=0;
top=ii-1>0?ii-1:0;
bottom=ii+1<10?ii+1:9;
left=jj-1>0?jj-1:0;
right=jj+1<10?jj+1:9;
for (int i=top; i<=bottom; i++) {
for(int j=left; j<= right; j++) {
if (mine[i][j]==9) count++;
}
}
return(count);
}
public void printMine() {
for (int i = 0; i < 10; i++) {
for (int j=0; j < 10; j++) {
System.out.print(this.mine[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
JMineArth mine = new JMineArth(Integer.parseInt(args[0]),Integer.parseInt(args[1]),Integer.parseInt(args[2]));
mine.printMine();
}
}
来源:https://juejin.cn/post/7056745934566195230
标签:Java,扫雷
0
投稿
猜你喜欢
jdbc与druid连接池的使用详解
2023-09-18 17:50:11
使用newInstance()来实例化fragment并传递数据操作
2022-07-11 15:41:57
Java实现驼峰和下划线互相转换的示例代码
2023-12-16 15:23:48
Android性能优化及性能优化工具
2023-11-12 09:24:00
JAVA中实现链式操作(方法链)的简单例子
2022-12-16 00:54:50
Android自定义双向滑动控件
2022-04-30 04:11:18
Eclipse+Java+Swing+Mysql实现工资管理系统
2023-07-26 08:51:05
http协议进阶之Transfer-Encoding和HttpCore实现详解
2023-11-03 14:22:05
Android提高之ListView实现自适应表格的方法
2023-04-05 17:25:09
C# 使用Dictionary复制克隆副本及比较是否相等
2021-05-29 21:33:06
Android使用SoundPool播放短音效
2022-03-02 12:33:00
.Net WInform开发笔记(五)关于事件Event
2023-11-22 01:00:18
SSM框架搭建图文教程(推荐)
2023-11-10 20:39:07
Java的关键字与保留字小结
2021-05-30 10:20:50
FragmentStatePagerAdapter保存恢复下拉刷新Fragment内存数据
2023-07-17 20:36:40
java安全编码指南之:表达式规则说明
2021-06-01 17:48:44
Retrofit 创建网络请求接口实例过程
2023-11-23 22:26:43
Android自定义Chronometer实现短信验证码秒表倒计时功能
2022-02-22 10:52:47
C#中的Socket编程详解
2021-10-24 01:25:00
Quartz.Net调度框架配置解析
2021-10-13 01:35:02