//要导包
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.graphics.Color;
import android.opengl.Visibility;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener,OnLongClickListener {
public static final int NUMBER = 10;
LinearLayout.LayoutParams viewParams;
private int[][] map = new int[NUMBER][NUMBER];
List<TextView> tvList = new ArrayList<>();
List<Button> btnList = new ArrayList<Button>();
int[] boomColor = { Color.BLUE, Color.GREEN, Color.RED, Color.BLACK,Color.GRAY, Color.LTGRAY, Color.MAGENTA };
public static final String FLAG = "✈";
private TextView tvBoom;
private TextView tvTime;
private int boomNumber;
private LinearLayout layout;
Timer timer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
initData();
}
private void initData() {
// 初始化NUMBER个地雷
boomNumber = NUMBER;
tvBoom.setText("地雷:" + boomNumber);
// 为NUMBER个地雷周围设置好数字
// 用-1来代替地雷
// 初始化地雷
for (int i = 0; i < NUMBER * NUMBER; i++) {
map[i / NUMBER][i % NUMBER] = 0;
}
if (timer != null)
timer.cancel();
timer = null;
tvTime.setText("时间:0");
// 1.随机10个地雷
HashSet<Integer> sets = new HashSet<Integer>();
while (sets.size() != boomNumber) {
sets.add((int) (Math.random() * NUMBER * NUMBER));
}
// 2.将地雷添加到map数组
for (Integer integer : sets) {// 33 9
map[integer / NUMBER][integer % NUMBER] = -1;// 1-->2
}
// 3.将每个格子的地雷数算好
for (int i = 0; i < NUMBER; i++) {
for (int j = 0; j < NUMBER; j++) {
// 如果当前的map中不是地雷,就要算周围的地雷数
if (map[i][j] != -1) {
int num = calcMine(i, j);
map[i][j] = num;
}
}
}
// 4. 将所有的map对应到 TextView上去
for (int i = 0; i < NUMBER; i++) {
for (int j = 0; j < NUMBER; j++) {
TextView tv = tvList.get(i * NUMBER + j);
if (map[i][j] == -1) {
tv.setText("۞");
} else if (map[i][j] != 0) {
int num = map[i][j];
tv.setText(num + "");
tv.setTextColor(boomColor[num - 1]);
}
}
}
// 5. 为所有的button设置点击事件
// 在创建的时候 添加的
}
private int calcMine(int i, int j) {
int number = 0;
for (int m = i - 1; m <= i + 1; m++) {
for (int n = j - 1; n <= j + 1; n++) {
if (m == i && n == j)
continue;
try {
if (map[m][n] == -1)
number++;
} catch (Exception e) {
continue;
}
}
}
return number;
}
// 最外层的框架
private void initView() {
layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
// 添加了 顶部的相对布局
layout.addView(getBoomTime());
// 添加了 主要的框架
layout.addView(mainFrame());
layout.setPadding(50, 50, 50, 50);
setContentView(layout);
}
private FrameLayout mainFrame() {
// 10*10的视图
// int width = getWindowManager().getDefaultDisplay().getWidth();
int width = (getResources().getDisplayMetrics().widthPixels - 100)
/ NUMBER;
viewParams = new LinearLayout.LayoutParams(width, width);
// 主要视图部分
FrameLayout layout = new FrameLayout(this);
// 添加了底层的TextView
layout.addView(getTextViews());
// 添加了上层的Button
layout.addView(getButtons());
return layout;
}
private RelativeLayout getBoomTime() {
RelativeLayout layout = new RelativeLayout(this);
tvTime = new TextView(this);
tvTime.setText("时间:0");
tvTime.setPadding(20, 20, 20, 20);
tvBoom = new TextView(this);
tvBoom.setText("地雷:" + NUMBER + "");
tvBoom.setPadding(20, 20, 20, 20);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
tvBoom.setLayoutParams(params);
layout.addView(tvTime);
layout.addView(tvBoom);
return layout;
}
// 创建一个100个TextView的布局
private LinearLayout getTextViews() {
tvList.clear();
LinearLayout layout = new LinearLayout(this);
layout.setBackgroundResource(R.drawable.store);
layout.setPadding(1, 1, 1, 1);
layout.setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i < NUMBER; i++) {
// 每一行都是一个水平线性布局
LinearLayout hLayout = new LinearLayout(this);
hLayout.setOrientation(LinearLayout.HORIZONTAL);
for (int j = 0; j < NUMBER; j++) {
// 内层水平布局,添加TextView10个
TextView tv = new TextView(this);
tv.setGravity(Gravity.CENTER);
tv.setTextSize(18);
tv.setBackgroundResource(R.drawable.store);
tv.setLayoutParams(viewParams);
hLayout.addView(tv);
// 将所有TextView添加到集合
tvList.add(tv);
}
// 外层垂直布局添加内层水平布局10个
layout.addView(hLayout);
}
return layout;
}
// 创建一个100个Button的布局
private LinearLayout getButtons() {
btnList.clear();
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i < NUMBER; i++) {
LinearLayout hLayout = new LinearLayout(this);
hLayout.setOrientation(LinearLayout.HORIZONTAL);
for (int j = 0; j < NUMBER; j++) {
Button btn = new Button(this);
btn.setBackgroundResource(R.drawable.btn_bg);
btn.setLayoutParams(viewParams);
btn.setTag(i * NUMBER + j);
btn.setOnClickListener(this);
btn.setOnLongClickListener(this);
hLayout.addView(btn);
btnList.add(btn);
}
layout.addView(hLayout);
}
return layout;
}
@Override
public void onClick(View v) {
// 判断是否是第一次点击按钮,点击就开始计时
if (timer == null) {
startTimer();
}
// v==button
// 需要知道当前button的坐标
// 每个view都可以设置一个别名(tag) 这个tag是一个object对象,可以存放任意的对象。
// 根据设置的Tag来知道当前是哪一个button被点击了
int i = Integer.parseInt(v.getTag().toString()) / NUMBER;
int j = Integer.parseInt(v.getTag().toString()) % NUMBER;
// 插旗子不允许点击
Button btn = (Button) v;
if (btn.getText().toString().equals(FLAG))
return;
Log.e("TAG", "-------------" + i + " " + j + " " + map[i][j]);
// 1.只要点击,肯定需要将当前的坐标 的Button 隐藏
v.setVisibility(View.INVISIBLE);
if (map[i][j] == -1) {
gameOver();
} else if (map[i][j] == 0) {
// 展开周围8个方向
// 如果碰到继续是0
// 继续递归展开这个0的8个方向
expansionButton(i, j);
}
}
int downTime;
private void startTimer() {
downTime = 100;
// 倒计时100秒开始
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// android 不允许在 子线程中 修改UI视图
// 在Activity中可以使用runonUiThread方法来 将线程转换到主线程
downTime--;
runOnUiThread(new Runnable() {
@Override
public void run() {
// runOnUiThread的run方法 是在主线程中的, UI线程就是主线程
tvTime.setText("时间:" + downTime);
if (downTime == 0) {
gameOver();
}
}
});
}
}, 0, 1000);
}
private void expansionButton(int i, int j) {
for (int m = i - 1; m <= i + 1; m++) {
for (int n = j - 1; n <= j + 1; n++) {
if (m == i && n == j)
continue;
else {
try {
Button button = btnList.get(m * NUMBER + n);
if (button.getVisibility() == View.VISIBLE
&& !button.getText().toString().equals(FLAG)) {
if (map[m][n] == 0) {
button.setVisibility(View.INVISIBLE);
expansionButton(m, n);
} else {
button.setVisibility(View.INVISIBLE);
}
}
} catch (Exception e) {
}
}
}
}
}
private void gameWin() {
showGame("GameWin\n点击重新开始");
}
private void gameOver() {
showGame("GameOver\n点击重新开始");
}
private void showGame(String msg) {
if (timer != null) {
timer.cancel();
timer = null;
}
TextView tv = new TextView(this);
tv.setText(msg);
tv.setGravity(Gravity.CENTER);
tv.setTextColor(Color.RED);
tv.setTextSize(48);
layout.addView(tv);
tv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
initView();
initData();
}
});
}
@Override
public boolean onLongClick(View v) {
if (timer == null) {
startTimer();
}
// 长按一个Button 判断上面有没有旗子,有的话呢,就取消
Button btn = (Button) v;
if (btn.getText().toString().equals(FLAG)) {
btn.setText("");
boomNumber++;
} else {
btn.setText(FLAG);
boomNumber--;
}
tvBoom.setText("地雷:" + boomNumber);
// 如果旗子用完了,就要计算输赢
if (boomNumber == 0) {
isGameOver();
}
return true;
}
private void isGameOver() {
for (int i = 0; i < NUMBER; i++) {
for (int j = 0; j < NUMBER; j++) {
Button btn = btnList.get(i * NUMBER + j);
// 在map中找到所有的地雷,这些地雷上面,一定要插上旗子
if (map[i][j] == -1) {
if (!btn.getText().equals(FLAG)) {
gameOver();
return;
}
}
}
}
gameWin();
}
}
扫雷
最新推荐文章于 2023-08-09 21:33:59 发布