自学了java一段时间后,根据网上的扫雷项目自己动手写了一个简单的扫雷游戏,菜单功能不够完善,但已经实现了扫雷的逻辑,能够正常运行扫雷的效果!!!
(1)主文件:MineSquare.java
package com.dy.lkd;
import java.awt.Color;
import javax.swing.ImageIcon;
public class MineSquare {
public static void main(String[] args){
new MyFrame(300,100,300,329,Color.gray); //窗口大小设定不合理,因为按钮有边框线
}
}
(2)MyFrame.java 显示界面
package com.dy.lkd;
//import java.awt.*;
//import java.awt.event.WindowAdapter;
//import java.awt.event.WindowEvent;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyFrame extends JFrame {
public static int[][] xy={{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}};
JPanel jPanel = new JPanel();
GridLayout grid; //布局
public static JButton[][] buttons = new JButton[15][15];
public static int[][] number = new int[15][15]; //记录雷的位置
public static int[][] numberL = new int[15][15]; //记录周围雷的数量
MyFrame(int x, int y, int width, int height, Color color) {
super("扫雷");
init();
JOptionPane.showMessageDialog(null,"欢迎进入扫雷游戏");
setBackground(color);
setBounds(x, y, width, height);
grid = new GridLayout(15,15);
jPanel.setLayout(grid);
add(jPanel);
setVisible(true);
setResizable(false); //窗口大小不可以调整
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //释放当前窗口
/* super("扫雷"); //以前的java.awt.*
GridLayout glLayout = new GridLayout(20, 20); // 用表格布局管理器,分成10行10列
Panel p = new Panel();
p.setLayout(null);
this.setSize(width, height);
this.setLocation(x, y);
for (int b_x = 0; b_x <= 180; b_x += 20) {
for (int b_y = 0; b_y <= 180; b_y += 20) {
Button b = new Button();
b.setLocation(b_x, b_y);
b.setSize(width / 10, height / 10);
p.add(b);
}
}
this.add(p);
setResizable(false); //窗口大小不可以调整
setVisible(true); //窗口可见
this.addWindowListener(new WindowAdapter() { //局部类,或匿名内部类
public void windowClosing(WindowEvent e){ //像类体,没有名字,new出(父类)对象当成WindowAdapter来用,实际从WindowsAdapter继承
setVisible(false); //设置为不可见
System.exit(0); //(0)正常退出,(-1)为非异常退出
}
}); */
}
public void init(){
initMenu(); //加载菜单
initNumber(30); //随机生成50个雷
countL(); //计算对应坐标周围雷的数量,并保存到bunberL数组
printQP(); //生成按钮方法
}
void initMenu(){ //加载菜单
JMenuBar menuBar = new JMenuBar(); //创建菜单条
JMenu menu = new JMenu("菜单"); //创建菜单,一个实例就是一个菜单
JMenu subMenu = new JMenu("难度");
JMenuItem item1,item2; //设置菜单选项
JMenuItem item3,item4,item5; //设置难度
item1 = new JMenuItem("新游戏");
item2 = new JMenuItem("退出");
item1.setAccelerator(KeyStroke.getKeyStroke('A')); //设置快捷方式
item2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,InputEvent.CTRL_MASK));
item2.addActionListener(new ActionListener() { //监听退出按钮
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.exit(0);
}
});
menu.add(item1);
menu.addSeparator(); //设置分界线
menu.add(subMenu);
item3=new JMenuItem("新手");
item4=new JMenuItem("中级");
item5=new JMenuItem("高级");
subMenu.add(item3);
subMenu.add(item4);
subMenu.add(item5);
menu.add(item2);
menuBar.add(menu);
setJMenuBar(menuBar); //添加菜单条到JFrame
}
private void countL() { //计算周围雷的数量
// TODO Auto-generated method stub
for(int i=0;i<number.length;i++)
for(int j=0;j<number[i].length;j++){
int sum=0;
if(number[i][j]==0){
for(int k=0;k<xy.length;k++){
int[] tempXY=xy[k];
int tx=i+tempXY[0];
int ty=j+tempXY[1];
if(tx>=0&&ty>=0&&tx<=14&&ty<=14){
if(number[tx][ty]==1) //如果该坐标是雷,则加一
sum++;
}
}
numberL[i][j]=sum; //将该位置的周围的雷数量保存到数组里面
}
else if(number[i][j]==1){
numberL[i][j]=9;
}
}
}
void printQP(){ //按钮的生成,并为每个按钮添加监听器
for(int i=0;i<buttons.length;i++)
for(int j=0;j<buttons[i].length;j++){
JButton jb=new JButton();
jb.addActionListener(new AddClick()); //为每个按钮添加点击事件
buttons[i][j]=jb;
jPanel.add(buttons[i][j]);
}
}
private void initNumber(int count) { //随机生成35个雷
int x=(int)(Math.random()*15);
int y=(int)(Math.random()*15);
int i=0;
while(i<count){ //雷的数量
if(i==0)
number[x][y] = 1; //有雷的位置定为1
else{
while(number[x][y]==1){ //避免重复
x=(int)(Math.random()*15);
y=(int)(Math.random()*15);
}
number[x][y]=1;
}
i++;
}
}
public static int[][] getBounds(int x,int y){ //得到所在位置的周围8个按钮的坐标
return new int[][]{
{x-1,y-1},
{x-1,y},
{x-1,y+1},
{x,y+1},
{x+1,y+1},
{x+1,y},
{x+1,y-1},
{x,y-1},
};
}
}
(3)AddClick.java 按钮的监听类
package com.dy.lkd;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
public class AddClick implements ActionListener {
public static int[][] c= new int[15][15];
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JButton jb=(JButton)e.getSource(); //获取按钮的对象
int x=0;
int y=0;
for(int i=0;i<MyFrame.buttons.length;i++)
for(int j=0;j<MyFrame.buttons[i].length;j++){
if(MyFrame.buttons[i][j].equals(jb)){ //找到对应的按钮
x=i;
y=j;
}
}
if(MyFrame.number[x][y]==1){ //如果按钮 的位置为雷
MyFrame.buttons[x][y].setIcon(new ImageIcon("F:\\workplace\\Saolei\\src\\Image\\bomb0.jpg"));
for(int a=0;a<MyFrame.number.length;a++) //遍历所有雷的位置
for(int b=0;b<MyFrame.number[a].length;b++){
if(MyFrame.number[a][b]==1&&a!=x&&b!=y){
MyFrame.buttons[a][b].setIcon(new ImageIcon("F:\\workplace\\Saolei\\src\\Image\\bomb.jpg"));
}
}
JOptionPane.showMessageDialog(null,"对不起,您输了!!");
}else
space(x, y);
}
public static void space(int x,int y){ //循环遍历
if(MyFrame.numberL[x][y]!=0){ //如果所点击位置周围有雷,显示雷的数量
c[x][y]=8; //记录打开的位置,将其记录为8
MyFrame.buttons[x][y].setIcon(new ImageIcon("F:\\workplace\\Saolei\\src\\Image\\"+MyFrame.numberL[x][y]+".jpg"));
}else{
c[x][y]=8;
MyFrame.buttons[x][y].setIcon(new ImageIcon("F:\\workplace\\Saolei\\src\\Image\\0.jpg"));
if(x>=0&&y>=0&&x<=14&&y<=14){
int[][] bounds =MyFrame.getBounds(x,y);
for(int i=0;i<bounds.length;i++){
int tx=bounds[i][0];
int ty=bounds[i][1];
if(tx>=0&&ty>=0&&tx<=14&&ty<=14&&c[tx][ty]!=8){
space(tx, ty);
}
}
}
}
}
}
进入游戏:
进入游戏界面:
菜单功能(但没有完善,只写了退出)
扫雷游戏画面:
游戏失败画面: