📄 gamepanel.java
字号:
statusLabel1.setForeground(OVER_COLOR);
statusLabel1.setText("Game Over");
}
public void setActive(boolean b) {//设置游戏状态
removeMouseListener(this);//移除原有的侦听器
if (b) {//可以进行游戏
addMouseListener(this);//添加侦听器
//设置状态条面板
statusLabel1.setForeground(ACTIVE_COLOR);
statusLabel1.setText("Game begin ");
statusLabel2.setText(flagNum + "/" + mineNum);
}
}
public void setGameParam(int mineNum, int r, int c) {//设置游戏参数
if (mineNum <= 0 || r <= 0 || c <= 0 || mineNum >= r * c)
throw new IllegalArgumentException("游戏参数设置错误!!!");
w = c*32+(c-1)*2;//单元宽度
h = r*32+(r-1)*2;//单元高度
setPreferredSize(new Dimension(w, h));
this.mineNum = mineNum;
this.r = r;
this.c = c;
totalNum = r * c;
//生成游戏数据
cells = new FieldCell[r][c];
//生成雷区
for (int i=0; i<r; i++) {
for (int j=0; j<c; j++) {
cells[i][j] = new FieldCell();
}
}
int count = 0;//扫雷计数器
while (count < mineNum) {//随机埋雷
int s = (int) (Math.random() * totalNum);//产生随机数
FieldCell fc = cells[s/c][s%c];//产生随机位置
if (!fc.isMine()) {
fc.setMine(true);//埋雷
count++;
}
}
//计算某个位置相邻的地雷数
for (int i=0; i<r; i++) {
for (int j=0; j<c; j++) {
if (!cells[i][j].isMine()) {//不是地雷的单元才显示相邻的地雷数
int num = 0;
if (i-1 >= 0) {//计算左侧3个相邻位置的雷数
if (j-1 >= 0 && cells[i-1][j-1].isMine())//左上位置
num++;
if (cells[i-1][j].isMine())//左中位置
num++;
if (j+1 < c && cells[i-1][j+1].isMine())//左下位置
num++;
}
{ //计算上下2个相邻位置的雷数
if (j-1 >= 0 && cells[i][j-1].isMine())//上方位置
num++;
//if (cells[i][j].isMine())
//num++;
if (j+1 < c && cells[i][j+1].isMine())//下方位置
num++;
}
if (i+1 < r) { //计算右侧3个相邻位置的雷数
if (j-1 >= 0 && cells[i+1][j-1].isMine())//右上位置
num++;
if (cells[i+1][j].isMine())//右中位置
num++;
if (j+1 < c && cells[i+1][j+1].isMine())//右下位置
num++;
}
cells[i][j].setNumber(num);//设定相邻的地雷数
}
}
}
// 重置游戏数据
flagNum = 0;
revealNum = 0;
}
protected void paintComponent(Graphics g) {//画出游戏界面
g.setColor(Color.lightGray);
g.fillRect(0, 0, w, h);
for (int i=0; i<r; i++) {
for (int j=0; j<c; j++) {
cells[i][j].draw(g, j*34, i*34);
}
}
}
public void mouseClicked(MouseEvent e) {//MouseEvent鼠标事件处理
int j = (e.getX() + 2) / 34;
int i = (e.getY() + 2) / 34;
FieldCell cell = cells[i][j];
//如果该单元已经翻开,则返回
if (cell.getState() == FieldCell.REVEALED)
return;
if (e.getButton() == MouseEvent.BUTTON1) {//按下鼠标按键1(左键),进行翻雷
//如果已经扫雷(标上红旗),则返回
if (cell.getState() == FieldCell.FLAGGED)
return;
if (cell.isMine()) {//如果该单元为地雷,则翻开后游戏结束(失败)
cell.setState(FieldCell.REVEALED);
setActive(false);
revealAll();
gameOver();
} else {
cell.setState(FieldCell.UNKNOWN);//先设成未扫单元
reveal(i, j);//再翻雷
if (checkVictory()) {//检查是否胜利
setActive(false);
gameWin();
}
}
} else if (e.getButton() == MouseEvent.BUTTON3) {//按下鼠标按键3(右键),进行扫雷或标记疑问
if (cell.getState() == FieldCell.UNKNOWN) {//对于未扫单元进行扫雷或疑问标记
if (flagNum < mineNum) {//如果已扫雷数低于总雷数则进行扫雷
cell.setState(FieldCell.FLAGGED);
flagNum++;
statusLabel2.setText(flagNum+"/"+mineNum);
if (checkVictory()) {//检查是否胜利
setActive(false);
gameWin();
}
} else {//如果已扫雷数不低于总雷数则进行疑问标记
cell.setState(FieldCell.DOUBTED);
}
} else if (cell.getState() == FieldCell.FLAGGED) {//对于已扫单元进行疑问标记
cell.setState(FieldCell.DOUBTED);
flagNum--;
statusLabel2.setText(flagNum+"/"+mineNum);
} else if (cell.getState() == FieldCell.DOUBTED) {//对于疑问标记单元则再设置成未扫单元
cell.setState(FieldCell.UNKNOWN);
}
}
repaint();//重画
}
private boolean checkVictory() {//检查是否胜利
return flagNum + revealNum == totalNum;
}
//游戏失败时显示所有的地雷以及挖错的和标记错的位置
private void revealAll() {
for (int i=0; i<r; i++) {
for (int j=0; j<c; j++) {
FieldCell cell = cells[i][j];
if (cell.isMine()) {
if (cell.getState() == FieldCell.UNKNOWN)
cell.setState(FieldCell.REVEALED);//显示地雷
} else {
switch (cell.getState()) {
case FieldCell.FLAGGED:
cell.setState(FieldCell.WRONG_F);//显示挖错的地雷
break;
case FieldCell.DOUBTED:
cell.setState(FieldCell.WRONG_D);//显示标记错的地雷
break;
}
}
}
}
}
//用递归的方法显示其它非地雷的位置
private void reveal(int i, int j) {
if (i < 0 || i >= r || j < 0 || j >= c)
return;
FieldCell cell = cells[i][j];
if (cell.getState() == FieldCell.REVEALED
|| cell.getState() == FieldCell.FLAGGED
|| cell.getState() == FieldCell.DOUBTED)
return;
cell.setState(FieldCell.REVEALED);
revealNum++;
if (cell.getNumber() != 0)
return;
reveal(i-1, j-1);
reveal(i-1, j);
reveal(i-1, j+1);
reveal(i, j-1);
reveal(i, j+1);
reveal(i+1, j-1);
reveal(i+1, j);
reveal(i+1, j+1);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -