从扫雷的历史讲起
扫雷是微软在1992年发布的一款经典益智小游戏,游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷。相信玩法大家也都懂,经典WinXp和Win7的扫雷也都伴随大家成长。那么我们今天就看看怎么在Android上实现经典小游戏扫雷。
难点分析
绘制默认的格子页面
打开游戏,首先需要绘制这样一个默认的格子页面,这个实现方案很容易想到,首先获取屏幕的宽高,然后除以我们每个格子的长宽,就得到需要的行数和列数,然后我们可以用一个GridLayout来包裹这些格子元素,当然也可以用其他方式。
Point point = new Point();
WindowManager wm =(WindowManager)this.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getSize(point);
int screenWidth = point.x;
int screenHeight = point.y;
int pxCellWidth = Utils.dip2px(this, CellImageView.DEFAULT_CELL_WIDTH);
int pxCellHeight = Utils.dip2px(this, CellImageView.DEFAULT_CELL_HEIGHT);
int rowCount = screenHeight / pxCellHeight;
int columnCount = screenWidth / pxCellWidth;
这样可以获取需要绘制的格子的行数和列数,但是可能并不能完全填充满屏幕,因为上述整除以后可能还会有余数,也就是说如果固定每一个格子的长宽,那么可能就无法整除,所以需要对每一个格子的长宽做微调,以使屏幕完全填充满。
boolean reComputeCellWidth = screenWidth % pxCellWidth > 0;
boolean reComputeCellHeight = freeScreenHeight % pxCellHeight > 0;
int rowCount = freeScreenHeight / pxCellHeight;
int columnCount = screenWidth / pxCellWidth;
if (reComputeCellWidth) {
pxCellWidth = screenWidth / columnCount;
}
if (reComputeCellHeight) {
pxCellHeight = freeScreenHeight / rowCount;
}
默认的页面绘制好了,现在就需要设置地雷和地雷计数了
地雷可以用一个二维数组来表示,数组的行和列就是上一步中我们就计算出来的格子行数和列数。然后我们再设置一个默认的地雷总数,再随机生成在这个二维数组中就可以了。
Random random = new Random();
int i = 0;
while (i < bombNumber) {
int row = random.nextInt(mTotalRows);
int column = random.nextInt(mTotalColumns);
// 如果还没有安放炸弹,此处可以安放
if (!bombs[row][column]) {
i++;
bombs[row][column] = true;
// 炸弹的位置设为12,标识此处为炸弹,不需要计数
ambients[row][column] = 12;
// 周围8个相邻地方格子
increase(row - 1, column - 1);
increase(row - 1, column);
increase(row - 1, column + 1);
increase(row, column + 1);
increase(row + 1, column + 1);
increase(row + 1, column);
increase(row + 1, column - 1);
increase(row, column - 1);
}
}
这里讲一下地雷计数的规则,当设置了一个地雷之后,这个地雷的四周的8个位置都需要做一次计数,也就是increase所做的事,很好理解。
今天就讲到这里,下一篇中我会分析用户点击每一个雷区开始玩游戏后的事件操作和逻辑处理,源码我后续整理后也会放在github上。如果你也对扫雷感兴趣,欢迎留言讨论。