用Android写一个扫雷的小游戏
时间: 2023-12-29 14:18:12 浏览: 27
好的,下面是一个简单的扫雷游戏的实现步骤:
1. 创建一个新的Android项目,命名为Minesweeper。
2. 在MainActivity布局文件中添加一个GridView来展示游戏的方格。
3. 创建一个MinesweeperAdapter继承自BaseAdapter,用于将每个方格显示在GridView中。
4. 在MinesweeperAdapter中定义一个数据结构表示每个方格的状态,包括是否是地雷、是否被揭开、周围地雷数量等。
5. 在MinesweeperAdapter中实现getView方法,用于根据方格的状态显示不同的图标。
6. 在MainActivity中,创建一个二维数组来表示整个游戏的方格,初始化每个方格的状态。
7. 在MainActivity中,设置GridView的适配器为MinesweeperAdapter。
8. 在MainActivity中,为GridView设置OnItemClickListener,处理方格被点击的事件。
9. 在点击事件中,根据点击的位置更新方格的状态,并更新MinesweeperAdapter的数据,通知GridView重新绘制。
10. 如果点击的是地雷方格,则游戏结束,弹出游戏结束的提示框。
11. 如果所有非地雷方格都被揭开,则游戏胜利,弹出游戏胜利的提示框。
下面是一些示例代码:
MinesweeperAdapter.java
```
public class MinesweeperAdapter extends BaseAdapter {
private Context mContext;
private int[][] mData;
public MinesweeperAdapter(Context context, int[][] data) {
mContext = context;
mData = data;
}
@Override
public int getCount() {
return mData.length * mData[0].length;
}
@Override
public Object getItem(int position) {
int row = position / mData[0].length;
int col = position % mData[0].length;
return mData[row][col];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(100, 100));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
imageView = (ImageView) convertView;
}
int row = position / mData[0].length;
int col = position % mData[0].length;
int state = mData[row][col];
if ((state & MineSweeperCell.FLAG_REVEALED) != 0) {
if ((state & MineSweeperCell.FLAG_MINE) != 0) {
imageView.setImageResource(R.drawable.ic_mine);
} else {
int count = state & MineSweeperCell.FLAG_COUNT;
if (count > 0) {
imageView.setImageResource(getNumberDrawable(count));
} else {
imageView.setImageResource(R.drawable.ic_empty);
}
}
} else if ((state & MineSweeperCell.FLAG_FLAGGED) != 0) {
imageView.setImageResource(R.drawable.ic_flag);
} else {
imageView.setImageResource(R.drawable.ic_unrevealed);
}
return imageView;
}
private int getNumberDrawable(int count) {
switch (count) {
case 1:
return R.drawable.ic_1;
case 2:
return R.drawable.ic_2;
case 3:
return R.drawable.ic_3;
case 4:
return R.drawable.ic_4;
case 5:
return R.drawable.ic_5;
case 6:
return R.drawable.ic_6;
case 7:
return R.drawable.ic_7;
case 8:
return R.drawable.ic_8;
default:
return R.drawable.ic_empty;
}
}
}
```
MainActivity.java
```
public class MainActivity extends AppCompatActivity {
private GridView mGridView;
private MinesweeperAdapter mAdapter;
private int[][] mData;
private int mNumMines;
private int mNumRevealed;
private static final int FLAG_MINE = 1;
private static final int FLAG_REVEALED = 2;
private static final int FLAG_FLAGGED = 4;
private static final int FLAG_COUNT = 24;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGridView = findViewById(R.id.grid_view);
mGridView.setNumColumns(10);
mData = new int[10][10];
mNumMines = 10;
initGame();
}
private void initGame() {
// 初始化所有方格为未揭开状态
for (int i = 0; i < mData.length; i++) {
for (int j = 0; j < mData[i].length; j++) {
mData[i][j] = 0;
}
}
// 随机布置地雷
Random random = new Random();
int count = 0;
while (count < mNumMines) {
int row = random.nextInt(mData.length);
int col = random.nextInt(mData[0].length);
if ((mData[row][col] & FLAG_MINE) == 0) {
mData[row][col] |= FLAG_MINE;
count++;
}
}
// 计算每个方格周围的地雷数量
for (int i = 0; i < mData.length; i++) {
for (int j = 0; j < mData[i].length; j++) {
if ((mData[i][j] & FLAG_MINE) != 0) {
continue;
}
int countMines = 0;
for (int row = i - 1; row <= i + 1; row++) {
for (int col = j - 1; col <= j + 1; col++) {
if (row >= 0 && row < mData.length && col >= 0 && col < mData[0].length) {
if ((mData[row][col] & FLAG_MINE) != 0) {
countMines++;
}
}
}
}
mData[i][j] |= (countMines << FLAG_COUNT);
}
}
mAdapter = new MinesweeperAdapter(this, mData);
mGridView.setAdapter(mAdapter);
mNumRevealed = 0;
}
private void revealCell(int row, int col) {
if ((mData[row][col] & FLAG_REVEALED) != 0) {
return;
}
mData[row][col] |= FLAG_REVEALED;
mNumRevealed++;
if ((mData[row][col] & FLAG_MINE) != 0) {
showGameOverDialog();
return;
}
if (mNumRevealed == mData.length * mData[0].length - mNumMines) {
showGameWinDialog();
return;
}
if ((mData[row][col] & FLAG_COUNT) == 0) {
// 如果周围没有地雷,则递归揭开周围的方格
for (int i = row - 1; i <= row + 1; i++) {
for (int j = col - 1; j <= col + 1; j++) {
if (i >= 0 && i < mData.length && j >= 0 && j < mData[0].length) {
revealCell(i, j);
}
}
}
}
mAdapter.notifyDataSetChanged();
}
private void flagCell(int row, int col) {
if ((mData[row][col] & FLAG_REVEALED) != 0) {
return;
}
if ((mData[row][col] & FLAG_FLAGGED) != 0) {
mData[row][col] &= ~FLAG_FLAGGED;
} else {
mData[row][col] |= FLAG_FLAGGED;
}
mAdapter.notifyDataSetChanged();
}
private void showGameOverDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.game_over);
builder.setMessage(R.string.try_again);
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
initGame();
}
});
builder.setCancelable(false);
builder.show();
}
private void showGameWinDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.game_win);
builder.setMessage(R.string.play_again);
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
initGame();
}
});
builder.setCancelable(false);
builder.show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_reset) {
initGame();
return true;
}
return super.onOptionsItemSelected(item);
}
private class GridItemClickListener implements AdapterView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int row = position / mData[0].length;
int col = position % mData[0].length;
if (view.getTag() == null || !view.getTag().equals("flagged")) {
revealCell(row, col);
}
}
}
private class GridItemLongClickListener implements AdapterView.OnItemLongClickListener {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
int row = position / mData[0].length;
int col = position % mData[0].length;
flagCell(row, col);
view.setTag(view.getTag() == null ? "flagged" : null);
return true;
}
}
}
```