2019年3月31日日曜日

Android游戏编程之从零开始, 練習

Android游戏编程之从零开始, 練習

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MySurfaceView2 extends SurfaceView implements SurfaceHolder.Callback, Runnable {
    private final String T = "### MySurfaceView2";
    private SurfaceHolder surfaceHolder;
    private boolean flag;
    private Canvas canvas;
    private Paint paintA, paintB, paintC;
    private Rect rectA, rectB, rectC;
    private int rectAx, rectAy, rectBx, rectBy, rectCx, rectCy;
    private int tag;
    private int px, py;
    private Region regionA, regionB, regionC;
    private Bitmap bitmapA, bitmapB, bitmapC;
    private Matrix matrixA, matrixB, matrixC;
    private Thread th;
    private int screenW, screenH;

    public MySurfaceView2(Context context) {
        super(context);
        surfaceHolder = this.getHolder();
        surfaceHolder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        flag = true;
        th = new Thread(this);
        th.start();
        init();
    }

    private void init() {
        screenH = getHeight();
        screenW = getWidth();
        TGA();
        TGB();
        TGC();
    }

    private void TGA() {
        bitmapA = BitmapFactory.decodeResource(getResources(), R.mipmap.a);
        rectAx = 0;
        rectAy = 0;
        paintA = new Paint();
        rectA = new Rect();
        rectA.set(rectAx, rectAy, rectAx + bitmapA.getWidth(), rectAy + bitmapA.getHeight());
        regionA = new Region();
        regionA.op(rectA, Region.Op.XOR);
        matrixA = new Matrix();
    }

    private void TGB() {
        bitmapB = BitmapFactory.decodeResource(getResources(), R.mipmap.b);
        rectBx = this.getWidth() - bitmapB.getWidth();
        rectBy = 0;
        paintB = new Paint();
        rectB = new Rect();
        rectB.set(rectBx, rectBy, rectBx + bitmapB.getWidth(), rectBy + bitmapB.getHeight());
        regionB = new Region();
        regionB.op(rectA, Region.Op.DIFFERENCE);
        matrixB = new Matrix();
    }

    private void TGC() {
        bitmapC = BitmapFactory.decodeResource(getResources(), R.mipmap.c);
        rectCx = 0;
        rectCy = this.getHeight() - bitmapC.getHeight();
        paintC = new Paint();
        rectC = new Rect();
        rectC.set(rectCx, rectCy, rectCx + bitmapC.getWidth(), rectCy + bitmapC.getHeight());
        regionC = new Region();
        regionC.op(rectC, Region.Op.REVERSE_DIFFERENCE);
        matrixC = new Matrix();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_UP:
            tag = 0;
            break;
        case MotionEvent.ACTION_MOVE:
            switch (tag) {
            case 1:
                rectAx = (int) event.getX() + px;
                rectAy = (int) event.getY() + py;
                break;
            case 2:
                rectBx = (int) event.getX() + px;
                rectBy = (int) event.getY() + py;
                break;
            case 3:
                rectCx = (int) event.getX() + px;
                rectCy = (int) event.getY() + py;
                break;
            default:
            }

            break;
        case MotionEvent.ACTION_DOWN: {
            if (regionA.contains((int) event.getX(), (int) event.getY())) {
                px = (int) (rectA.left - event.getX());
                py = (int) (rectA.top - event.getY());
                tag = 1;
            }
            if (regionB.contains((int) event.getX(), (int) event.getY())) {
                px = (int) (rectB.left - event.getX());
                py = (int) (rectB.top - event.getY());
                tag = 2;
            }
            if (regionC.contains((int) event.getX(), (int) event.getY())) {
                px = (int) (rectC.left - event.getX());
                py = (int) (rectC.top - event.getY());
                tag = 3;
            }
            break;
        }
        default:
        }
        return true;
    }

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

    }

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

    private void T1(Canvas canvas) {
        canvas.drawColor(Color.CYAN);
        mA(canvas);
        mB(canvas);
        mC(canvas);
    }

    private void mA(Canvas canvas) {
        matrixA.postTranslate(rectAx, rectAy);
        rectA.set(rectAx, rectAy, rectAx + bitmapA.getWidth(), rectAy + bitmapA.getHeight());
        regionA.set(rectA);
        paintA.setAlpha(0);
        canvas.drawRect(rectA, paintA);
        paintA.setAlpha(255);
        canvas.drawBitmap(bitmapA, matrixA, paintA);
        matrixA.reset();
    }

    private void mB(Canvas canvas) {
        matrixB.postTranslate(rectBx, rectBy);
        rectB.set(rectBx, rectBy, rectBx + bitmapB.getWidth(), rectBy + bitmapB.getHeight());
        regionB.set(rectB);
        canvas.drawRect(rectB, paintB);
        canvas.drawBitmap(bitmapB, matrixB, paintB);
        matrixB.reset();
    }

    private void mC(Canvas canvas) {
        matrixC.postTranslate(rectCx, rectCy);
        rectC.set(rectCx, rectCy, rectCx + bitmapC.getWidth(), rectCy + bitmapC.getHeight());
        regionC.set(rectC);
        canvas.drawRect(rectC, paintC);
        canvas.drawBitmap(bitmapC, matrixC, paintC);
        matrixC.reset();
    }

    private void MyDraw() {
        try {
            canvas = surfaceHolder.lockCanvas();
            if (canvas != null) {
                T1(canvas);
            }
        } catch (Exception e) {
            Log.i(T, "MyDraw Exception");
            e.printStackTrace();
        } finally {
            if (canvas != null) {
                surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }
    }

    @Override
    public void run() {
        while (true) {
            long s = System.currentTimeMillis();
            MyDraw();
            long e = System.currentTimeMillis();
            if (50 - (e - s) > 0) {
                try {
                    Thread.sleep(50 - (e - s));
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
}




0 件のコメント: