package saolei;
import java.awt.Color;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class GamePanel extends JPanel {
private static final long serialVersionUID = 1L;
private static Icon[] num = new Icon[9];
private static Icon[] bomb = new Icon[4];
private static Icon[] block = new Icon[3];
static {
for (int i = 0; i < num.length; i++) {
num[i] = new ImageIcon("./image/" + i + ".gif");
}
for (int j = 0; j < bomb.length; j++) {
bomb[j] = new ImageIcon("./image/mine" + j + ".gif");
}
for (int k = 0; k < block.length; k++) {
block[k] = new ImageIcon("./image/block" + k + ".gif");
}
}
GameFrame Gameframe;
GamePanel Gamepanel;
// 界面行数
private int rows;
// 界面列数
private int cols;
// 炸弹数
private int bombCount;
// 炸弹剩余数
private int bombRemain;
// 每个方格宽度
private int BLOCKWIDTH = 16;
// 每个方格长度
private int BLOCKHEIGHT = 16;
// 0 1 -1分别代表无结果 赢 输
private int NOW = 0;
// 鼠标监听事件
MouseListener buttonListener;
private JLabel[][] labels;
private GameButton[][] buttons;
private AudioPlayer backgroundAudio;
private AudioPlayer ohAudio;
private AudioPlayer winAudio;
private AudioPlayer loseAudio;
// 代表点击位置周围八个位置,避免使用多个if else语句
private final int[][] offset = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 },
{ -1, 0 } };
// 判断是否第一次点击的标志量
private int openflag = 0;
// 构造方法,初始化参数
public GamePanel(GameFrame gameframe) {
Gameframe = gameframe;
Gamepanel = this;
this.rows = Gameframe.getrows();
this.cols = Gameframe.getcols();
this.bombCount = Gameframe.getbombcount();
this.bombRemain = bombCount;
this.labels = new JLabel[rows][cols];
this.buttons = new GameButton[rows][cols];
this.setBackground(Color.LIGHT_GRAY);
this.setLayout(null);
this.initaudio();
this.initButtons();
this.initLabels();
}
public int getrows() {
return rows;
}
public int getcols() {
return cols;
}
public int getbombCount() {
return bombCount;
}
public int getbombRemain() {
return bombRemain;
}
public AudioPlayer getbackgroundAudioPlayer() {
return backgroundAudio;
}
public AudioPlayer getohAudioPlayer() {
return ohAudio;
}
public AudioPlayer getwinAudioPlayer() {
return winAudio;
}
public AudioPlayer getloseAudioPlayer() {
return loseAudio;
}
// 初始化音频
private void initaudio() {
this.backgroundAudio = new AudioPlayer(new File("./audio/background.mp3"));
this.ohAudio = new AudioPlayer(new File("./audio/oh.mp3"));
this.winAudio = new AudioPlayer(new File("./audio/win.mp3"));
this.loseAudio = new AudioPlayer(new File("./audio/lose.mp3"));
}
// 监听初始化
private void Listener() {
buttonListener = new MouseListener() {
/**
* flag=0 按钮初始状态 flag=1 左键点击后最终状态 flag=2 右键点击第一下 flag=3 右键点击第二下 flag=4
* 左键点击到松开的中间状态
*/
int buttonflag = 0;
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
if (NOW != 0) {
return;
}
if (((e.getModifiers() == InputEvent.BUTTON1_MASK) && ((buttonflag == 0) || (buttonflag == 3)))) {
((GameButton) e.getSource()).setIcon(num[0]);
buttonflag = 4;
} else if ((e.getModifiers() == InputEvent.BUTTON3_MASK) && (buttonflag == 0)) {
buttonflag = 2;
bombRemain--;
Gameframe.getTimepanel().bombchange();
} else if ((e.getModifiers() == InputEvent.BUTTON3_MASK) && (buttonflag == 2)) {
buttonflag = 3;
bombRemain++;
Gameframe.getTimepanel().bombchange();
} else if ((e.getModifiers() == InputEvent.BUTTON3_MASK) && (buttonflag == 3)) {
buttonflag = 0;
}
ohAudio.stop();
ohAudio = new AudioPlayer(new File("./audio/oh.mp3"));
ohAudio.start();
Gameframe.getTimepanel().facechange(6);
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
if (NOW != 0) {
return;
}
if (buttonflag == 2) {
((GameButton) e.getSource()).setIcon(block[1]);
buttonflag = 2;
} else if (buttonflag == 3) {
((GameButton) e.getSource()).setIcon(block[2]);
buttonflag = 3;
} else if (buttonflag == 0) {
((GameButton) e.getSource()).setIcon(block[0]);
buttonflag = 0;
}
if (buttonflag == 4) {
open((GameButton) e.getSource());
buttonflag = 1;
}
Gameframe.getTimepanel();
if ((Gameframe.getTimepanel().facelabel.getIcon() != TimePanel.face[2])
&& (Gameframe.getTimepanel().facelabel.getIcon() != TimePanel.face[4])) {
Gameframe.getTimepanel().facechange(0);
}
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
};
}
// 界面初始化,绘制扫雷的边框
private void initLabels() {
for (int i = 0; i < this.rows; i++) {
for (int j = 0; j < this.cols; j++) {
JLabel l = new JLabel("", JLabel.CENTER);
// 设置每个小方格的边界
l.setBounds(j * BLOCKWIDTH, i * BLOCKHEIGHT, BLOCKWIDTH, BLOCKHEIGHT);
// 绘制方格边框
l.setBorder(null);
// l.setBorder(BorderFactory.createLineBorder(Color.GRAY));
// 设置方格为透明,便于我们填充颜色
l.setOpaque(true);
l.setBackground(Color.LIGHT_GRAY);
// 将方格加入到容器中(即面板JPanel)
this.add(l);
// 将方格存到类变量中,方便公用
labels[i][j] = l;
}
}
randomBomb();
writeNumber();
}
// 产生bombCount个炸弹,
private void randomBomb() {
for (int i = 0; i < this.bombCount;) {
// 生成一个随机数表示行坐标
int rRow = (int) (Math.random() * this.rows);
// 生成一个随机数表示列坐标
int rCol = (int) (Math.random() * this.cols);
if (this.labels[rRow][rCol].getIcon() == bomb[0]) {
continue;
}
// 根据坐标确定JLabel的位置,并显示*
this.labels[rRow][rCol].setIcon(bomb[0]);
i++;
}
}
// 改变炸弹图标
private void bombchange(int flag) {
if (flag < 4) {
for (int i = 0; i < this.rows; i++) {
for (int j = 0; j < this.cols; j++) {
if (this.labels[i][j].getIcon() == bomb[0]) {
labels[i][j].setIcon(bomb[flag]);
}
}
}
} else {
bombchange(flag - 4);
}
}
// 将炸弹的周围标注上数字
private void writeNumber() {
for (int i = 0; i < this.rows; i++) {
for (int j = 0; j < this.cols; j++) {
// 如果是炸弹,不标注任何数字
if (labels[i][j].getIcon() == bomb[0]) {
continue;
}
// 如果不是炸弹,遍历它周围的八个方块,将炸弹的总个数标注在这个方格上
// 方块周围的8个方块中炸弹个数
int bombCount = 0;
// 通过偏移量数组循环遍历8个方块
for (int[] off : offset) {
int row = i + off[1];
int col = j + off[0];
// 判断是否越界,是否为炸弹
if (verify(row, col) && (labels[row][col].getIcon() == bomb[0])) {
bombCount++;
}
}
// 如果炸弹的个数不为0,标注出来
if (bombCount >= 0) {
label