扫雷游戏APP----简易版

背景方块类
/**
 * 方块
 */

class Block {
    //区域
    RectF rect;
    //周边雷的数量
    int num;
    //是否打开
    boolean isOpen;
    //是否是雷
    boolean isBomb;
    int line, row;
    //该块是否被标记
    boolean isMarked;

    public Block(int left, int top, int right, int bottom, int line, int row) {
        this.rect = new RectF(left, top, right, bottom);
        this.line = line;
        this.row = row;
    }

    private Rect textRect;
    private int x, y;

    void draw(Canvas canvas, Paint paint) {
        if (isOpen) {
            if (isBomb) {
                paint.setColor(Color.RED);
            } else {
                paint.setColor(0x55333333);
            }
            canvas.drawRoundRect(rect,10,10, paint);
            //检测是否需要画文本
            if (num > 0) {
                if (null == textRect) {
                    textRect = new Rect();
                    paint.getTextBounds(String.valueOf(num), 0, 1, textRect);
                    x = (int) (rect.centerX() - textRect.centerX());
                    y = (int) (rect.centerY() - textRect.centerY());
                }
                paint.setColor(Color.RED);
                canvas.drawText(String.valueOf(num), x, y, paint);
            }
        } else {
            if (isMarked) {
                paint.setColor(0xffffff33);
            } else {
                paint.setColor(0xff333333);
            }
            canvas.drawRoundRect(rect,10,10, paint);
        }
    }
}
游戏界面
public class GameView extends View {
    //场景中行/列
    private int line, row;
    //屏幕宽度
    private int screenWidth;
    //每个块的宽度
    private int blockWidth;
    //块之间的间距
    private static final int SPACING = 2;
    //砖块集合
    private Block[][] blocks;
    //画笔
    private Paint paint;
    private boolean isGameOver;

    public GameView(Context context) {
        super(context);
        init(context);
    }

    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    /**
     * 画出扫雷的每个方块铺满屏幕
     * @param context
     */
    private void init(Context context) {
        line = 9;
        row = 9;
        Point p = new Point();
        //获取窗口管理器
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getSize(p);
        screenWidth = p.x;
        //计算每个块的宽度
        blockWidth = (screenWidth - (row - 1) * SPACING) / row;
        blocks = new Block[line][row];
        for (int i = 0; i < line; i++) {
            for (int j = 0; j < row; j++) {
                int left = j * blockWidth + j * SPACING;
                int top = i * blockWidth + i * SPACING;
                blocks[i][j] = new Block(left, top, left + blockWidth, top + blockWidth, i, j);
            }
        }
        //初始化画笔
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextSize(blockWidth / 2);
        paint.setColor(Color.BLUE);

        //初始化雷
        initBomb();
    }

    /**
     * 初始化雷
     */
    private void initBomb() {
        LinkedList<Integer> nums = new LinkedList<>();
        int size = line * row;
        for (int i = 0; i < size; i++) {
            nums.add(i);
        }
        Random r = new Random();
        int bombNum = line + 1;
        for (int i = 0; i < bombNum; i++) {
            //随机一个雷的下标
            int index = r.nextInt(nums.size());
            //移除该雷所在的位置(0-81)
            int num = nums.remove(index);
            //将雷的位置对应到网格中
            int i1 = num / row;
            int j1 = num % row;
            blocks[i1][j1].isBomb = true;
            //该位置的周边都+1
            if (i1 - 1 >= 0) {
                blocks[i1 - 1][j1].num++;
                if (j1 - 1 >= 0) {
                    blocks[i1 - 1][j1 - 1].num++;
                }
                if (j1 + 1 < row) {
                    blocks[i1 - 1][j1 + 1].num++;
                }
            }
            if (j1 - 1 >= 0) {
                blocks[i1][j1 - 1].num++;
            }
            if (j1 + 1 < row) {
                blocks[i1][j1 + 1].num++;
            }
            if (i1 + 1 < line) {
                if (j1 - 1 >= 0) {
                    blocks[i1 + 1][j1 - 1].num++;
                }
                blocks[i1 + 1][j1].num++;
                if (j1 + 1 < row) {
                    blocks[i1 + 1][j1 + 1].num++;
                }
            }
        }
    }

    /**
     * 绘画方法
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        for (int i = 0; i < line; i++) {
            for (int j = 0; j < row; j++) {
                if (isGameOver) {
                    blocks[i][j].isOpen = true;
                }
                blocks[i][j].draw(canvas, paint);
            }
        }
    }

    private long downTime;
    //记录打开的顺序(队列,保持先进先出)
    private LinkedList<Block> openList = new LinkedList<>();

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                downTime = System.currentTimeMillis();
                break;
            case MotionEvent.ACTION_UP:
                long current = System.currentTimeMillis();
                long cTime = current - downTime;
                int x = (int) event.getX();
                int y = (int) event.getY();
                for (int i = 0; i < line; i++) {
                    for (int j = 0; j < row; j++) {
                        if (blocks[i][j].rect.contains(x, y)) {
                            if (cTime <= 400) {
                                //打开方块
                                //判断打开的块是不是一个雷,是则game over
                                if (blocks[i][j].isBomb) {
                                    //处理Game over
                                    //统计分数

                                    //打开所有
                                    isGameOver = true;
                                    invalidate();
                                    return true;
                                }
                                if (!blocks[i][j].isOpen && !blocks[i][j].isMarked) {
                                    //打开当前块
                                    blocks[i][j].isOpen = true;
                                    //检测块上的数字
                                    if (blocks[i][j].num == 0) {
                                        //打开周边,直到遇到数字为止
                                        openList.add(blocks[i][j]);
                                        while (!openList.isEmpty()) {
                                            openSround(openList.removeFirst());
                                        }
                                    }
                                    invalidate();
                                }
                            } else {
                                //标记为雷
                                if (!blocks[i][j].isOpen) {
                                    if (!blocks[i][j].isMarked) {
                                        blocks[i][j].isMarked = true;
                                        //处理标记的提示
                                    } else {
                                        blocks[i][j].isMarked = false;
                                    }
                                    invalidate();
                                }

                            }
                            return true;
                        }
                    }
                }
                break;
        }
        return true;
    }

    /**
     * 打开周围的块
     *
     * @param b
     */
    private void openSround(Block b) {
        int i1 = b.line;
        int j1 = b.row;
        if (i1 - 1 >= 0) {
            openBlock(blocks[i1 - 1][j1]);
            if (j1 - 1 >= 0) {
                openBlock(blocks[i1 - 1][j1 - 1]);
            }
            if (j1 + 1 < row) {
                openBlock(blocks[i1 - 1][j1 + 1]);
            }
        }
        if (j1 - 1 >= 0) {
            openBlock(blocks[i1][j1 - 1]);
        }
        if (j1 + 1 < row) {
            openBlock(blocks[i1][j1 + 1]);
        }
        if (i1 + 1 < line) {
            if (j1 - 1 >= 0) {
                openBlock(blocks[i1 + 1][j1 - 1]);
            }
            openBlock(blocks[i1 + 1][j1]);
            if (j1 + 1 < row) {
                openBlock(blocks[i1 + 1][j1 + 1]);
            }
        }
    }

    private void openBlock(Block b) {
        if (!b.isOpen && !b.isMarked) {
            b.isOpen = true;
            if (b.num == 0) {
                openList.add(b);
            }
        }
    }
}
MainActivity类
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GameView gView = new GameView(this);
        setContentView(gView);
    }
}

扫雷

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值