问题遇到的现象和发生背景
最近用Java写了一个扫雷游戏,写到后面发现点击方格无法立即将方格打开,需要在点击方格后,再点击任务栏中的程序图标,将其隐藏并再次打开才能使其生效,求解决方法和问题原因
问题相关代码,请勿粘贴截图
public class MineSweeping extends JFrame {
/** 启动扫雷游戏 */
public void launch() {
MineSweeping mineSweeping = new MineSweeping();
mineSweeping.setVisible(true) /* 设置窗口大小可调整 */;
mineSweeping.setSize(width, height) /* 设置窗口大小 */;
mineSweeping.setTitle("扫雷") /* 设置窗口标题 */;
mineSweeping.setLocationRelativeTo(null) /* 设置窗口居中显示 */;
/*
* 设置窗口关闭方式
* 1. DO_NOTHING_ON_CLOSE 不执行任何操作
* 2. HIDE_ON_CLOSE 默认关闭操作,不会释放内存,只隐藏界面,调用setVisible(false)
* 3. DISPOSE_ON_CLOSE 隐藏并释放窗体,调用dispose(),当最后一个窗口被释放后,程序也随之结束
* 4. EXIT_ON_CLOSE 直接关闭应用程序,调用System.exit(0)
*/
mineSweeping.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
/* 鼠标监听事件
* MouseAdapter用于接收鼠标事件的抽象适配类
* mouseClicked: 鼠标点击事件
* mousePressed: 鼠标按下事件
* mouseReleased: 鼠标释放事件
* mouseEntered: 鼠标进入事件
* mouseExited: 鼠标退出事件
* mouseWheelMoved: 鼠标滚轮移动事件
* mouseDragged: 鼠标拖动事件
* mouseMoved: 鼠标移动事件
*/
mineSweeping.addMouseListener(new MouseAdapter() {
/* 鼠标点击事件
* MouseEvent.BUTTON1: 左键被使用
* MouseEvent.BUTTON2: 滚轮被使用
* MouseEvent.BUTTON3: 右键被使用
*/
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
switch (Map.GAME_STATE) {
case 0:
Mouse.X = e.getX();
Mouse.Y = e.getY();
/* 当前事件若为左键点击事件,则运行左键单击按钮的方法 */
if (MouseEvent.BUTTON1 == e.getButton()) Mouse.leftClickState = true;
/* 判断当前事件是否为右键点击事件 */
if (MouseEvent.BUTTON3 == e.getButton()) Mouse.rightClickState = true;
case 1:
case -1:
/* 重置游戏 */
if (MouseEvent.BUTTON1 == e.getButton()) {
if (e.getX() >= Map.OFFSET + Map.SQUARE_SIDE_LENGTH * (Map.X - 1) / 2 &&
e.getX() <= Map.OFFSET + Map.SQUARE_SIDE_LENGTH * (Map.X - 1) / 2 + Map.SQUARE_SIDE_LENGTH &&
e.getY() >= Map.OFFSET * 3 / 2 &&
e.getY() <= Map.OFFSET * 3 / 2 + Map.SQUARE_SIDE_LENGTH) {
Mouse.leftClickState = false;
Mouse.rightClickState = false;
MapBottom.resetTheUnderlyingMap();
MapTop.resetTopLevelMap();
}
}
Map.GAME_STATE = 0 /* 重置游戏状态 */;
break;
default:
}
}
});
/* 不停绘制地图 */
while (WindowConstants.DISPOSE_ON_CLOSE != mineSweeping.getDefaultCloseOperation()) {
repaint();
/* 睡眠40毫秒 */
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 绘制扫雷地图
* @param g 画图工具
*/
@Override
public void paint(Graphics g) {
/* 通过将顶层地图与底层地图绘制到一个新的画布中来解决窗体组件闪动问题 */
Image image = this.createImage(width, height);
Graphics graphics = image.getGraphics() /* 获取画笔 */;
graphics.setColor(new Color(181, 181, 181)) /* 设置背景颜色 */;
graphics.fillRect(0,0,width, height) /* 填充整个画布 */;
MapBottom.drawABottomMap(graphics) /* 将底层地图绘制到新画布中 */;
MapTop.drawATopLevelMap(graphics) /* 将顶层地图绘制到新画布中 */;
g.drawImage(image, 0,0,null) /* 将新生成的图片绘制到画布中 */;
}
}
public class MapTop {
/**
* 画扫雷顶层地图
* @param g 画笔对象
*/
public static void drawATopLevelMap(Graphics g) {
MapTop.gridOpen();
for (int i = 0; i < Map.X; i++) {
for (int j = 0; j < Map.Y; j++) {
switch (MapTop.DATA_TOP_LAYER[i][j]) {
case 0:
g.drawImage(TOPICON,
Map.OFFSET + i * Map.SQUARE_SIDE_LENGTH + 1,
3 * Map.OFFSET + j * Map.SQUARE_SIDE_LENGTH + 1,
Map.SQUARE_SIDE_LENGTH -2,
Map.SQUARE_SIDE_LENGTH -2,
null);
break;
case 1:
g.drawImage(FLAG_ICON,
Map.OFFSET + i * Map.SQUARE_SIDE_LENGTH + 1,
3 * Map.OFFSET + j * Map.SQUARE_SIDE_LENGTH + 1,
Map.SQUARE_SIDE_LENGTH -2,
Map.SQUARE_SIDE_LENGTH -2,
null);
break;
case 2:
g.drawImage(DEBUG_BOMB_ICON,
Map.OFFSET + i * Map.SQUARE_SIDE_LENGTH + 1,
3 * Map.OFFSET + j * Map.SQUARE_SIDE_LENGTH + 1,
Map.SQUARE_SIDE_LENGTH -2,
Map.SQUARE_SIDE_LENGTH -2,
null);
default:
}
}
}
}
/** 打开方格 */
private static void gridOpen() {
int x = 0,
y = 0;
if (Mouse.X > Map.OFFSET && Mouse.Y > 3 * Map.OFFSET) {
x = (Mouse.X - Map.OFFSET) / Map.SQUARE_SIDE_LENGTH;
y = (Mouse.Y - Map.OFFSET * 3) / Map.SQUARE_SIDE_LENGTH;
}
if (0 <= x && Map.X >= x && 0 <= y && Map.Y >= y) {
if (Mouse.leftClickState) {
if (MapTop.DATA_TOP_LAYER[x][y] == 0) MapTop.DATA_TOP_LAYER[x][y] = -1 /* 将未打开的方格打开 */;
MapTop.openBlankSquare(x, y);
Mouse.leftClickState = false;
}
if (Mouse.rightClickState) {
switch (MapTop.DATA_TOP_LAYER[x][y]) {
case -1:
openSquaresByNumbers(x, y);
break;
case 0:
MapTop.DATA_TOP_LAYER[x][y] = 1 /* 未插旗则插旗 */;
break;
case 1:
MapTop.DATA_TOP_LAYER[x][y] = 0 /* 已插旗则取消插旗 */;
break;
default:
}
Mouse.rightClickState = false;
}
}
if (triggerBomb()) {
showAllBombs();
Map.GAME_STATE = -1;
}
if (successfullyDefusedTheBomb()) {
Map.GAME_STATE = 1;
}
}
}
运行结果及报错内容
没有任何报错内容
我想要达到的结果
使其能够在被点击后立即打开,不在需要频繁的点击任务栏图标打开