java+Swing实现一个简单的“扫雷”游戏
程序员文章站
2022-04-03 08:51:34
...
java+Swing实现一个简单的“扫雷”游戏
比较适合Java初学者
我是一个Java初学者,前几天跟着网络课程简单的敲了一个“扫雷”,欢迎大家评论指出不足之处。
废话少说,直接上代码。个别没有注释到的地方,请大家百度。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
public class MineSweeper1 extends JFrame implements ActionListener {
public static void main(String[] args) {
new MineSweeper1();
}
JFrame frame=new JFrame();//创建窗体
//这里的图片大家可以根据自己的喜欢设置
ImageIcon BannerIcon=new ImageIcon("C:\\Users\\csycsycsy\\eclipse-workspace\\扫雷1.0\\src\\image\\alien.png");
ImageIcon guessIcon=new ImageIcon("C:/Users/csycsycsy/eclipse-workspace/扫雷1.0/src/image/Guess.png");
ImageIcon boomIcon=new ImageIcon("C:/Users/csycsycsy/eclipse-workspace/扫雷1.0/src/image/boom.png");
ImageIcon failIcon=new ImageIcon("C:/Users/csycsycsy/eclipse-workspace/扫雷1.0/src/image/fail.png");
ImageIcon winIcon=new ImageIcon("C:/Users/csycsycsy/eclipse-workspace/扫雷1.0/src/image/win.png");
ImageIcon winflagIcon=new ImageIcon("C:/Users/csycsycsy/eclipse-workspace/扫雷1.0/src/image/winflag.png");
int row=8;//行
int col=8;//列
int data[][]=new int[row][col];//row是行,col是列
JButton btns[][]=new JButton[row][col];
int leicode=-1;//雷的代号
int leinum=10;//雷的数量
int time=0;//设置时间
int opened=0;
int unopened=row*col;
JButton BannerBut=new JButton(BannerIcon);//创建按钮BannerIcon
JLabel label1=new JLabel("待开:"+unopened);
JLabel label2=new JLabel("已开:"+opened);
JLabel label3=new JLabel("用时:"+time+"秒");
Timer timer=new Timer(1000,this);
public MineSweeper1() {
frame.setSize(850, 850);
frame.setTitle("扫雷1.0");
frame.setResizable(true);//设置窗口是否可以任意改变大小
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击窗口的“×”后不做任何操作,直接退出
frame.setLayout(new BorderLayout());//设置Banner为BorderLayout
SetHeader();//设置顶部
addlei();//埋雷的方法
SetButtons();
timer.start();//开启定时
frame.setLocationRelativeTo(null);//设置Jframe居中显示
frame.setVisible(true);//显示出窗口
}
/**
* 埋雷
*/
private void addlei() {
Random rand=new Random();
for(int i=0;i<leinum;) {
int r=rand.nextInt(row);
int c=rand.nextInt(col);
if(data[r][c]!=leicode) {
data[r][c]=leicode;
i++;
}
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if(data[i][j] == leicode) continue;
int tempCount = 0;
//这里那么多的if是为了防止数组越界
if (i>0 && j>0 && data[i-1][j-1] == leicode) tempCount++;
if (i>0 && data[i-1][j] == leicode) tempCount++;
if (i>0 && j<(col-1) && data[i-1][j+1] == leicode) tempCount++;
if (j>0 && data[i][j-1] == leicode) tempCount++;
if (j<(row-1) && data[i][j+1] == leicode) tempCount++;
if (i<(row-1) && j>0 && data[i+1][j-1] == leicode) tempCount++;
if (i<(row-1) && data[i+1][j] == leicode) tempCount++;
if (i<(row-1) && j<(col-1) && data[i+1][j+1] == leicode) tempCount++;
data[i][j] = tempCount;
}
}
}
/**
* 设置雷区
*/
private void SetButtons() {
Container con=new Container();
con.setLayout(new GridLayout(row,col));
for(int i=0;i<row;i++) {
for(int j=0;j<col;j++) {
JButton btn=new JButton(guessIcon);
btn.addActionListener(this);
btn.setOpaque(true);
btn.setBackground(Color.ORANGE);
//JButton btn=new JButton(data[i][j] + "");
btn.setFont(new Font("楷体",Font.BOLD,40));
btn.setMargin(new Insets(0,0,0,0));
con.add(btn);
btns[i][j]=btn;
}
}
frame.add(con, BorderLayout.CENTER);
}
/**
* 设置顶部
*/
private void SetHeader() {
JPanel panel=new JPanel(new GridBagLayout());//设置“画布”
GridBagConstraints c1= new GridBagConstraints(0,0,3,1,1.0,1.0,GridBagConstraints . CENTER, GridBagConstraints . BOTH, new Insets(0,0,0,0), 0,0);
panel. add(BannerBut, c1);
BannerBut.addActionListener(this);
label1.setOpaque(true);//设置不透明
label1.setBackground(Color.white);//设置背景色为白色
label1.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));//设置灰边
label2.setOpaque(true);
label2.setBackground(Color.white);
label2.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
label3.setOpaque(true);
label3.setBackground(Color.white);
label3.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
BannerBut.setOpaque(true);
BannerBut.setBackground(Color.white);
BannerBut.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
GridBagConstraints c2= new GridBagConstraints(0,1,1,1,1.0,1.0,GridBagConstraints . CENTER, GridBagConstraints . BOTH, new Insets(0,0,0,0), 0,0);
panel. add(label1, c2);
GridBagConstraints c3= new GridBagConstraints(1,1,1,1,1.0,1.0,GridBagConstraints . CENTER, GridBagConstraints . BOTH, new Insets(0,0,0,0), 0,0);
panel. add(label2, c3);
GridBagConstraints c4= new GridBagConstraints(2,1,1,1,1.0,1.0,GridBagConstraints . CENTER, GridBagConstraints . BOTH, new Insets(0,0,0,0), 0,0);
panel. add(label3, c4);
frame.add(panel,BorderLayout.NORTH);
}
/**监听鼠标
* @Override
*/
public void actionPerformed(ActionEvent e) {
if(e.getSource() instanceof Timer) {//计时器
time++;
label3.setText("用时:"+time);
timer.start();
return;
}
JButton btn=(JButton)e.getSource();//
if(btn.equals(BannerBut)) {
restart();
return;
}
for(int i=0;i<row;i++) {
for(int j=0;j<col;j++) {
if(btn.equals(btns[i][j])) {
if(data[i][j]==leicode) {
lose();
}else {
opencell(i,j);
checkWin();
}
return;
}
}
}
}
/**
* 重新开始
*/
private void restart() {
for(int i=0;i<row;i++) {
for(int j=0;j<col;j++) {
data[i][j]=0;
btns[i][j].setBackground(Color.ORANGE);
btns[i][j].setEnabled(true);
btns[i][j].setText("");
btns[i][j].setIcon(guessIcon);
}
}
unopened=row*col;
opened=0;
time=0;
label1.setText("待开:"+unopened);
label2.setText("已开:"+opened);
label3.setText("用时:"+time);
addlei();
timer.start();
}
/**
* 赢了游戏的处理
*/
private void checkWin() {
int count = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if(btns[i][j].isEnabled()) count++;
}
}
if(count == leinum) {
timer.stop();
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if(btns[i][j].isEnabled()) {
btns[i][j].setIcon(winflagIcon);
}
}
}
BannerBut.setIcon(winIcon);
JOptionPane.showMessageDialog(frame, "你赢了, Yeah!\n点击Banner重新开始", "赢了", JOptionPane.PLAIN_MESSAGE );
}
}
/**
* 游戏失败的判定
*/
private void lose() {
timer.stop();
BannerBut.setIcon(failIcon);
for(int i=0;i<row;i++) {
for(int j=0;j<col;j++) {
if(btns[i][j].isEnabled()) {
JButton btn=btns[i][j];
if(data[i][j]==leicode) {
btn.setEnabled(false);
btn.setIcon(boomIcon);
btn.setDisabledIcon(boomIcon);
}else if(data[i][j]==0) {
btn.setText("");
btn.setIcon(null);
btn.setEnabled(false);
}else {
btn.setIcon(null);
btn.setEnabled(false);//已经被打开
btn.setOpaque(true);
btn.setText(data[i][j]+"");
}
}
}
}
JOptionPane.showMessageDialog(frame, "你输了!");
}
/**
* 打开格子
* @param i
* @param j
*/
private void opencell(int i,int j) {
JButton btn=btns[i][j];
if(!btn.isEnabled())return;
btn.setIcon(null);
btn.setEnabled(false);//已经被打开
btn.setOpaque(true);
btn.setBackground(Color.WHITE);
btn.setText(data[i][j]+"");
update_dates();
//同上,防止数组越界
if(data[i][j]==0) {
if (i>0 && j>0 && data[i-1][j-1] == 0) opencell(i-1,j-1);
if (i>0 && data[i-1][j] == 0) opencell(i-1,j);
if (i>0 && j<(col-1) && data[i-1][j+1] == 0) opencell(i-1,j+1);
if (j>0 && data[i][j-1] == 0) opencell(i,j-1);
if (j<(row-1) && data[i][j+1] == 0) opencell(i,j+1);
if (i<(row-1) && j>0 && data[i+1][j-1] == 0) opencell(i+1,j-1);
if (i<(row-1) && data[i+1][j] == 0) opencell(i+1,j);
if (i<(row-1) && j<(col-1) #&& data[i+1][j+1] == 0) opencell(i+1,j+1);
btn.setText("");
}
}
/**
* 更新数据
*/
private void update_dates() {
opened++;
unopened--;
label1.setText("待开:"+unopened);
label2.setText("已开:"+opened);
}
}
实现效果截图
我打包了一个可执行的jar包,里面有源代码,需要的小伙伴请点击下方链接。
链接:https://x-x.fun/i/RU7425cfc83rY
更多Java学习资料,请点击以下链接
链接:https://pan.baidu.com/s/1xYtkXyDqWJVM34vkjtIKHw
提取码:l1mv