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);
}
}
版权声明:本文为moxiaolong原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。