surfaceView使用,製作小遊戲
自定義View,遊戲界面
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.text.TextPaint; 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; /** * Created by Administrator on 2017/6/13. */ public class aaGameBackGround extends SurfaceView implements SurfaceHolder.Callback, Runnable { private int screenW; //屏幕寬度 private int screenH; //屏幕高度 private Paint paint; //定義畫筆 private float cx; private float cy; private List<a> balls; private Paint backPaint; private TextPaint textPaint; private int radius = 10; //小球半徑 private float centerR; //中心圓半徑 private int speed = 0; private boolean isGo = false; private boolean isOver = false; //定義顏色數組 private int colorArray[] = {Color.BLACK, Color.BLACK, Color.GREEN, Color.YELLOW, Color.RED}; private int paintColor = colorArray[0]; //定義畫筆默認顏色 private Canvas canvas = null; //定義畫布 private Thread th = null; //定義線程 private SurfaceHolder sfh = null; public aaGameBackGround(Context context) { this(context, null); } public aaGameBackGround(Context context, AttributeSet attrs) { this(context, attrs, 0); } public aaGameBackGround(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); /**備註1:在此處獲取屏幕高、寬值爲0,以爲此時view還未被創建, * 在接口Callback的surfaceCreated方法中view才被創建 */ /*screenW = getWidth(); screenH = getHeight();*/ //初始化畫筆 initPaint(); sfh = getHolder(); sfh.addCallback(this); th = new Thread(this); balls = new ArrayList<>(); for (int i = 0; i < 3; i++) { balls.add(new a(i + 1, i * (360 / 3))); } } @Override public void surfaceCreated(SurfaceHolder holder) { //獲取屏幕寬度 screenW = getWidth(); //獲取屏幕高度 screenH = getHeight(); //獲取圓環半徑 centerR = (screenW - 6 * radius) / 2; //啓動繪圖線程 th.start(); } private void initPaint() { paint = new Paint(); backPaint = new Paint(); textPaint = new TextPaint(); //設置消除鋸齒 paint.setAntiAlias(true); backPaint.setAntiAlias(true); textPaint.setAntiAlias(true); //設置畫筆顏色 paint.setColor(paintColor); backPaint.setColor(paintColor); textPaint.setColor(0xffffffff); textPaint.setTextSize(25); } @Override public void run() { while (!isOver) { try { myDraw(); Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 備註2:切記,在自定SurfaceView中定義的myDraw方法,自定義View(繼承自View的子類)中的onDraw方法 * 完全是兩碼事: * 1)自定義View(繼承自View的子類)中的onDraw方法是重寫父類的onDraw方法,在調用postInvalidate後會自動回調該onDraw()方法。 * 2)此處的myDraw方法需要手動調用,所以此處故意將方法命名爲myDraw,突出爲該方法是自己寫的,非重寫父類的方法 。 */ //重寫onDraw方法實現繪圖操作 protected void myDraw() { //獲取canvas實例 canvas = sfh.lockCanvas(); if (canvas != null) { //將屏幕設置爲白色 canvas.drawColor(Color.WHITE); QUA(); //繪製中心大圓 canvas.drawCircle(screenW / 2, screenH / 2, dp2px(getContext(), 30), paint); if (isGo) { canvas.drawCircle(screenW / 2, screenH / 5 * 3 + centerR - (speed++ * 4), dp2px(getContext(), 10), paint); if (screenH / 5 * 3 + centerR - (speed++ * 4) <= screenH / 2 + centerR) { isGameOver(); balls.add(new a(balls.size() + 1, 270)); isGo = false; speed = 0; } } else { canvas.drawCircle(screenW / 2, screenH / 5 * 3 + centerR, dp2px(getContext(), 10), paint); } //將畫好的畫布提交 sfh.unlockCanvasAndPost(canvas); } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: goBall(); break; case MotionEvent.ACTION_UP: break; } return true; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } //發射小球 public void goBall() { if ((centerR * 3) - (speed++ * 5) > centerR) { isGo = true; } } /** * 碰撞判斷 */ public void isGameOver() { for (int i = 0; i < balls.size(); i++) { cx = screenW / 2 - balls.get(i).getX(); cy = screenH / 2 + centerR - balls.get(i).getY(); if (Math.sqrt(cx * cx + cy * cy) <= 2 * radius) { isOver = true; canvas.drawColor(0x88ff0000); } } } public float getSin(int angle) { return (float) Math.sin(angle * Math.PI / 180); } public float getCos(int angle) { return (float) Math.cos(angle * Math.PI / 180); } //繪製圖形 public void QUA() { for (int i = 0; i < balls.size(); i++) { balls.get(i).setAngle(balls.get(i).getAngle() + 1); balls.get(i).setY(screenH / 2 - centerR * getSin(balls.get(i).getAngle())); balls.get(i).setX(screenW / 2 - centerR * getCos(balls.get(i).getAngle())); //繪製小球連線 canvas.drawLine(balls.get(i).getX(), balls.get(i).getY(), screenW / 2, screenH / 2, backPaint); //繪製小圓作爲小球 canvas.drawCircle(balls.get(i).getX(), balls.get(i).getY(), dp2px(getContext(), radius), paint); //繪製小球數字 canvas.drawText(balls.get(i).getId() + "", balls.get(i).getX() - textPaint.measureText(balls.get(i).getId() + "") * 0.5f, balls.get(i).getY() + textPaint.getFontMetrics().bottom * 1.5f, textPaint); } } /** * dp轉化爲px工具 */ private int dp2px(Context context, int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); } /** * 內部類,小球實體類 */ class a { private int id;//小球id private int angle;//角度 private float x;//x座標 private float y;//y座標 public a(int id, int angle) { this.id = id; this.angle = angle; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAngle() { return angle; } public void setAngle(int angle) { this.angle = angle; } public float getX() { return x; } public void setX(float x) { this.x = x; } public float getY() { return y; } public void setY(float y) { this.y = y; } } }Activity中直接調用遊戲界面,設置禁止橫屏。ok,又一個火及一時的小遊戲誕生。