Java开发小游戏——扫雷

代码如下:

package com.game.saolei;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class SaoLeiTest implements ActionListener {
    //游戏启动;
    public static void main(String[] args) {
        new SaoLeiTest();
    }
    JFrame jFrame=new JFrame();
    ImageIcon icon=new ImageIcon("src/com/game/saolei/image/index.png");
    ImageIcon gussn=new ImageIcon("src/com/game/saolei/image/gussn.jpg");
    ImageIcon bao=new ImageIcon("src/com/game/saolei/image/baozha.jpg");
    ImageIcon fail=new ImageIcon("src/com/game/saolei/image/fail.png");
    ImageIcon Victory=new ImageIcon("src/com/game/saolei/image/Victory.png");
    ImageIcon Xh=new ImageIcon("src/com/game/saolei/image/xiao.png");
    JButton bannerBtn=new JButton(icon);

    //数据结构;
    final static int Row=20;
    final static int COl=20;
    int[][] data=new int[Row][COl];
    JButton[][] btns=new JButton[Row][COl];
    //雷的数据;
    final static int LENCOUNT=50;  //共有多少颗雷;
    final static int LEICODE=-1;//表示雷;
    int unopen=Row*COl; //未开多少雷;
    int opened=0; //已开多少雷;;
    int second=0;//用时;


    JLabel label1=new JLabel("待开:"+unopen);
    JLabel label2=new JLabel("已开:"+opened);
    JLabel label3=new JLabel("用时:"+second+"s");
    Timer timer=new Timer(1000,this);

    public SaoLeiTest(){
        //游戏界面的大小;
        jFrame.setSize(1000,900);
        //能否改变页面大小;
        jFrame.setResizable(false);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setLayout(new BorderLayout());
        //游戏界面的头部;
        setHeader();
        //雷的方法;
        addLei();
        //按钮;
        setButtons();
        //启动游戏时间;
        timer.start();
        //显示游戏界面;
        jFrame.setVisible(true);
    }
    /**
     * 雷的相关设计方法;
     */
    private void addLei() {
        Random random=new Random();
        for(int i=0;i<LENCOUNT;){
            int r=random.nextInt(Row);
            int c=random.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(i>0&&j>0&&data[i-1][j-1]==LEICODE) tempCount++;
                if(i>0&&data[i-1][j]==LEICODE) tempCount++;
                if(i>0&&j<19&&data[i-1][j+1]==LEICODE) tempCount++;
                if(j>0&&data[i][j-1]==LEICODE) tempCount++;
                if(j<19&&data[i][j+1]==LEICODE) tempCount++;
                if(i<19&&j>0&&data[i+1][j-1]==LEICODE) tempCount++;
                if(i<19&&data[i+1][j]==LEICODE) tempCount++;
                if(i<19&&j<19&&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(gussn);
                btn.setOpaque(true);
                btn.setBackground(new Color(244,183,113));
                btn.addActionListener(this);
                con.add(btn);
                btns[i][j]=btn;
            }
        }
        jFrame.add(con,BorderLayout.CENTER);
    }

    /**
     * 游戏头部的设置;
     */
    private void setHeader() {
        jFrame.add(bannerBtn,BorderLayout.NORTH);

        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(bannerBtn,c1);

        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));

        bannerBtn.setOpaque(true);
        bannerBtn.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
        bannerBtn.setBackground(Color.WHITE);

        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);

        jFrame.add(panel,BorderLayout.NORTH);

    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() instanceof Timer){
            second++;
            label3.setText("用时:"+second+"s");
            timer.start();
            return;
        }

        JButton btn=(JButton)e.getSource();
        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 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==LENCOUNT){
            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(Xh);
                    }
                }
            }
            bannerBtn.setIcon(Victory);
            JOptionPane.showMessageDialog(jFrame,"你赢了!","游戏胜利",JOptionPane.PLAIN_MESSAGE);
        }
    }
    /**
     * 游戏失败的方法;
     */
    private void lose() {
        timer.stop();
        bannerBtn.setIcon(fail);
        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){
                        btns[i][j].setEnabled(false);
                        btns[i][j].setIcon(bao);
                        btns[i][j].setDisabledIcon(bao);
                    }else {
                        btn.setIcon(null);
                        btn.setEnabled(false);
                        btn.setOpaque(true);
                        btn.setText(data[i][j]+"");
                    }
                }
            }
        }
        //提示框:
        JOptionPane.showMessageDialog(jFrame,"你踩到雷了!","游戏失败",JOptionPane.PLAIN_MESSAGE);
    }

    /**
     * 开雷的相关操作以及数据统计;
     * @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);
        if(data[i][j]==-1)  btn.setBackground(Color.green);
        btn.setText(data[i][j]+"");

        //已开和未开雷的数量统计
        addOpenCount();

        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][1]==0) openCell(i-1,j);
            if(i>0&&j<19&&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<19&&data[i][j+1]==0) openCell(i,j+1);
            if(i<19&&j>0&&data[i+1][j-1]==0) openCell(i+1,j-1);
            if(i<19&&data[i+1][j]==0) openCell(i+1,j);
            if(i<19&&j<19&&data[i+1][j+1]==0) openCell(i+1,j+1);
        }
    }
    /**
     * 已开和未开雷的数量统计;
     */
    private void addOpenCount() {
        opened++;
        unopen--;
        label1.setText("待开:"+unopen);
        label2.setText("已开:"+opened);
    }
}
上一篇:不玩虚的,“云游戏”到底怎么开发?


下一篇:Educational Codeforces Round 4 B. HDD is Outdated Technology