仿別踩白塊demo

別踩白塊新鮮出爐,使用的還是SurfaceView。

package com.example.administrator.whitegrid;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by Administrator on 2017/6/8.
 */

public class GridGameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    private boolean isDrawing;
    private Paint mPaint;
    /**
     * 被點擊
     */
    private boolean isTouch;

    /**
     * surface持有者
     */
    private SurfaceHolder mHolder;
    /**
     * 當前畫布
     */
    private Canvas mCanvas;
    /**
     * view的寬度
     */
    private int mWidth;
    /**
     * View的高度
     */
    private int mHeight;
    /**
     * 每格寬度
     */
    private int gridWidth;
    /**
     * 每格高度
     */
    private int gridHeight;
    /**
     * 每行格子個數
     */
    private int gridNumX = 5;
    /**
     * 每列格子個數
     */
    private int gridNumY = 5;
    /**
     * 偏移量
     */
    private int mOffSet;

    /**
     * 格子集合
     */
    private List<Integer> grids;

    /**
     * 生成隨機位置的格子
     */
    private Random random;

    /**
     * 點擊位置橫座標
     */
    private float pointX;
    /**
     * 點擊位置縱座標
     */
    private float pointY;
    /**
     * 被點擊方塊的下標
     */
    private int touchPosition;
    /**
     * 默認寬度設置爲300dp
     */
    private static final int DEFAULT_WIDTH = 300;
    /**
     * 默認高度設置爲400dp
     */
    private static final int DEFAULT_HEIGHT = 400;

    public GridGameView(Context context) {
        this(context, null);
    }

    public GridGameView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public GridGameView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mHolder = getHolder();
        mHolder.addCallback(this);
        // 設置可以獲取焦點
        setFocusable(true);
        // 進入觸摸輸入模式後,該控件是否還有獲得焦點的能力
        setFocusableInTouchMode(true);
        // 是否保持屏幕常亮
        setKeepScreenOn(true);

        random = new Random();
        grids = new ArrayList<>();

        //初始化一組方塊,屏幕外的上方下方個加一個方塊
        for (int i = 0; i < gridNumY + 2; i++) {
            grids.add(random.nextInt(gridNumX));
        }

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);
    }

    /**
     * 設置一些變量的尺寸
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthMode == MeasureSpec.AT_MOST) {
            mWidth = dp2px(DEFAULT_WIDTH);
        } else {
            mWidth = Math.max(widthSize, dp2px(DEFAULT_WIDTH));
        }
        if (heightMode == MeasureSpec.AT_MOST) {
            mHeight = dp2px(DEFAULT_HEIGHT);
        } else {
            mHeight = Math.max(heightSize, dp2px(DEFAULT_HEIGHT));
        }
        gridWidth = mWidth / gridNumX;
        gridHeight = mHeight / gridNumY;
        setMeasuredDimension(mWidth, mHeight);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // 開始繪畫
        isDrawing = true;
        // 啓動繪畫線程
        new Thread(this).start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isDrawing = false;
    }

    @Override
    public void run() {
        while (isDrawing) {
            try {
                mOffSet++;
                Thread.sleep(10);
                draw();
                if (mOffSet == gridHeight) {
                    if (grids.get(0) == gridNumX) {
                        //移出屏幕外的黑塊到達最大偏移量,遊戲繼續
                        mOffSet = 0;
                        grids.remove(0);
                        grids.add(random.nextInt(gridNumX));
                    } else {
                        //屏幕內的黑塊到達最大偏移量,遊戲結束
                        isDrawing = false;
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 繪圖
     */
    private void draw() {
        mCanvas = mHolder.lockCanvas();

        if (mCanvas != null) {
            // 設置畫布背景爲白色
            mCanvas.drawColor(0xffffffff);
            //繪製豎線
            drawLineY();
            //繪製橫線
            drawLineX();
            //點擊事件
            eventTouchDown();
            //畫黑白塊
            drawGrid();
            // 保證每次都將繪製的內容提交到服務器
            mHolder.unlockCanvasAndPost(mCanvas);
        }
    }

    /**
     * 繪製縱向線
     */
    private void drawLineY() {
        mCanvas.save();
        for (int i = 0; i < gridNumX + 1; i++) {
            mCanvas.drawLine(gridWidth * i, 0, gridWidth * i, mHeight, mPaint);
        }
    }

    /**
     * 繪製橫向線
     */
    private void drawLineX() {
        mCanvas.save();
        for (int i = 0; i < gridNumY + 1; i++) {
            mCanvas.drawLine(0, gridHeight * i + mOffSet, mWidth, gridHeight * i + mOffSet, mPaint);
        }
    }

    /**
     * 繪製格子
     */
    private void drawGrid() {
        mCanvas.save();
        mPaint.setColor(Color.BLACK);
        for (int i = 0; i < grids.size(); i++) {
            mCanvas.drawRect(grids.get(i) * gridWidth, mHeight - gridHeight * (i + 1) + mOffSet, grids.get(i) * gridWidth + gridWidth,
                    mHeight - gridHeight * i + mOffSet, mPaint);
        }
    }

    /**
     * 處理點擊事件
     */
    private void eventTouchDown() {
        if (isTouch) {
            touchPosition = (int) (mHeight + mOffSet - pointY) / gridHeight;
            if (pointX - grids.get(touchPosition) * gridWidth > 0 && pointX - grids.get(touchPosition) * gridWidth < gridWidth) {
                //被點擊的方塊移出屏幕外
                grids.set(touchPosition, gridNumX);
            } else {
                //點擊白塊遊戲結束
                isDrawing = false;
            }
            isTouch = false;
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                pointX = event.getX();
                pointY = event.getY();
                isTouch = true;
                break;
        }
        return true;
    }

    /**
     * dp轉化爲px工具
     */
    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                getContext().getResources().getDisplayMetrics());
    }
}
Activity中,和佈局文件直接引用自定義的view,跟上一篇小鳥過柱子的遊戲一樣,就不貼代碼了。

view中的屬性都可以通過get、set方法在activity中設置遊戲的開始,暫停,方塊移動速度,橫向縱向方塊的數量等。

另外可以加回調接口,監測遊戲結束

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章