📄 minepanel.java
字号:
package clearminegame;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class MinePanel extends JPanel {
private Random rnd = new Random();
private DecimalFormat fmt = new DecimalFormat("000");
private int rowCount;
private int columnCount;
private int mineCount;
private int warnCount;
private int secondCount = 0;
private int rightCount = 0;//正确翻开的方块数
private MineLabel [][]mineArray;
private JPanel pnlArea = new JPanel();
private JPanel pnlControl = new JPanel(new BorderLayout());
private JButton btnStart = new JButton("重玩");
private JLabel lblMineCount = createDisplayLabel("剩余雷数");
private JLabel lblTime = createDisplayLabel("游戏计时");
private GridLayout mineLayout = new GridLayout(1, 1);
private Timer timer;
private boolean ready;
public MinePanel() {
setLayout(new BorderLayout());
//
JPanel pnlWest = new JPanel();
pnlWest.add(lblTime);
pnlControl.add("West", pnlWest);
JPanel pnlCenter = new JPanel();
pnlCenter.add( btnStart );
pnlControl.add(pnlCenter);
JPanel pnlEast = new JPanel();
pnlEast.add(lblMineCount);
pnlControl.add("East", pnlEast);
//
add("North", pnlControl);
//
pnlArea.setBorder( BorderFactory.createLoweredBevelBorder() );
pnlArea.setLayout(mineLayout);
JPanel containPanel = new JPanel();
containPanel.add(pnlArea);
add(containPanel);
//
btnStart.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
restart();
}
});
//
timer = new Timer(1000, new ActionListener(){
public void actionPerformed(ActionEvent e) {
secondCount ++;
lblTime.setText(fmt.format(secondCount));
if (secondCount==999) {
fail();
}
}
});
}
//
private JLabel createDisplayLabel(String toolTipText)
{
JLabel lbl = new JLabel();
lbl.setHorizontalAlignment(JLabel.CENTER);
lbl.setPreferredSize(new Dimension(48, 24));
lbl.setBorder(BorderFactory.createLoweredBevelBorder());
lbl.setFont(new Font(null, Font.BOLD, 18));
lbl.setForeground(Color.RED);
lbl.setToolTipText(toolTipText);
return lbl;
}
//按指定的参数开始新的游戏
public void startNew(int rowCount, int columnCount, int mineCount)
{
this.rowCount = rowCount;
this.mineLayout.setRows(rowCount);
this.columnCount = columnCount;
this.mineLayout.setColumns(columnCount);
this.mineCount = mineCount;
//确定雷区大小
int width = columnCount * MineLabel.SIZE;
int height = rowCount * MineLabel.SIZE;
pnlArea.setPreferredSize(new Dimension(width + 4, height + 4));
//
pnlArea.setVisible(false);
//清除原有方块
MineLabel lblMine;
if(mineArray!=null)
{
for (int i = 0; i < mineArray.length; i++) {
for (int j = 0; j < mineArray[i].length; j++) {
lblMine = mineArray[i][j];
if(lblMine!=null)
{
pnlArea.remove(lblMine);
mineArray[i][j] = lblMine = null;
}
}
}
}
//重新添加方块
mineArray = new MineLabel[rowCount][columnCount];
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < columnCount; j++) {
lblMine = new MineLabel(this, i, j);
mineArray[i][j] = lblMine;
pnlArea.add(lblMine);
}
}
//
pnlArea.setVisible(true);
//
ready();
}
//重玩
private void restart()
{
//技巧:先隐藏再显示,避免给方块设置边界时不断更新
setVisible(false);
//恢复所有按钮到初始状态
for (int i = 0; i < mineArray.length; i++) {
for (int j = 0; j < mineArray[i].length; j++) {
mineArray[i][j].init();
}
}
//
setVisible(true);
//
ready();
}
private void ready()
{
timer.stop();
//计数清零
rightCount = 0;
secondCount = 0;
lblTime.setText(fmt.format(secondCount));
setWarnCount(0);
//
ready = true;
}
void start(int startRow, int startColumn)
{
ready = false;
//随机布雷
for (int i = 0; i < mineCount; i++) {
//随机坐标
int rowIndex, columnIndex;
//
MineLabel lblMine;
do
{
rowIndex = rnd.nextInt(rowCount);
columnIndex = rnd.nextInt(columnCount);
lblMine = mineArray[rowIndex][columnIndex];
}while( rowIndex==startRow && columnIndex==startColumn || lblMine.isMine() );//如果是开始位置或为雷则继续获取下一可能的位置
//设置为雷
lblMine.setMine(true);
//处理周围的按钮,value都应加1
for (int r = rowIndex - 1 ; r <= rowIndex + 1 ; r++) {
if (r<0 || r>=rowCount ) {
continue;
}
for (int c = columnIndex - 1 ; c <= columnIndex + 1; c++) {
if ( c<0 || c>=columnCount || ( c==columnIndex && r==rowIndex )/*跳过自己*/ ) {
continue;
}
mineArray[r][c].addValue();
}
}
}
//刷新界面
//repaint(0, 0, 0, getWidth(), getHeight());
//开始计时
timer.start();
}
public void fail()
{
//停止计时
timer.stop();
//
MineLabel lblMine;
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < columnCount; j++) {
lblMine = mineArray[i][j];
//如果是雷
if (lblMine.isMine() ) {
if(!lblMine.isClicked())//如果没有点击过则显示雷的状态
{
lblMine.setForeground(MineLabel.COLOR_MINE);
lblMine.setText(MineLabel.TEXT_MINE);
}
}
else if(lblMine.isWarn())//如果不是雷但标记为警告则提示错误
{
lblMine.setForeground(MineLabel.COLOR_ERROR);
lblMine.setText(MineLabel.TEXT_ERROR);
}
lblMine.setClicked(true);
}
}
}
//检查是否已获胜
private void check()
{
//如果正确数和警告数加起来等于总方块数,则说明过关
if(rightCount+warnCount==rowCount*columnCount)
{
timer.stop();
JOptionPane.showMessageDialog(this, "恭喜过关!您的成绩是 " + secondCount + " 秒。", "消息", JOptionPane.INFORMATION_MESSAGE);
}
}
public synchronized void addRigthCount()
{
rightCount ++;
check();
}
public int getColumnCount() {
return columnCount;
}
public int getMineCount() {
return mineCount;
}
public int getRowCount() {
return rowCount;
}
public MineLabel[][] getMineArray() {
return mineArray;
}
public int getWarnCount() {
return warnCount;
}
public synchronized void setWarnCount(int warnCount) {
this.warnCount = warnCount;
this.lblMineCount.setText( fmt.format(mineCount - warnCount) );
check();
}
public boolean isReady()
{
return ready;
}
public boolean isPlaying()
{
return timer.isRunning();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -