日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android之SurfaceView

發(fā)布時(shí)間:2024/7/19 Android 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android之SurfaceView 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

SurfaceView也是繼承了View,但是我們并不需要去實(shí)現(xiàn)它的draw方法來繪制自己,為什么呢?
因?yàn)樗蚔iew有一個(gè)很大的區(qū)別,View在UI線程去更新自己;而SurfaceView則在一個(gè)子線程中去更新自己;這也顯示出了它的優(yōu)勢(shì),當(dāng)制作游戲等需要不斷刷新View時(shí),因?yàn)槭窃谧泳€程,避免了對(duì)UI線程的阻塞。
知道了優(yōu)勢(shì)以后,你會(huì)想那么不使用draw方法,哪來的canvas使用呢?
大家都記得更新View的時(shí)候draw方法提供了一個(gè)canvas,SurfaceView內(nèi)部?jī)?nèi)嵌了一個(gè)專門用于繪制的Surface,而這個(gè)Surface中包含一個(gè)Canvas。
有了Canvas,我們?nèi)绾潍@取呢?
SurfaceView里面有個(gè)getHolder方法,我們可以獲取一個(gè)SurfaceHolder。通過SurfaceHolder可以監(jiān)聽SurfaceView的生命周期以及獲取Canvas對(duì)象。

通常用法

public class SurfaceViewTemplate extends SurfaceView implements Callback, Runnable {private SurfaceHolder mHolder;/*** 與SurfaceHolder綁定的Canvas*/private Canvas mCanvas;/*** 用于繪制的線程*/private Thread t;/*** 線程的控制開關(guān)*/private boolean isRunning;public SurfaceViewTemplate(Context context){this(context, null);}public SurfaceViewTemplate(Context context, AttributeSet attrs){super(context, attrs);mHolder = getHolder();mHolder.addCallback(this);// setZOrderOnTop(true);// 設(shè)置畫布 背景透明// mHolder.setFormat(PixelFormat.TRANSLUCENT);//設(shè)置可獲得焦點(diǎn)setFocusable(true);setFocusableInTouchMode(true);//設(shè)置常亮this.setKeepScreenOn(true);}@Overridepublic void surfaceCreated(SurfaceHolder holder){// 開啟線程isRunning = true;t = new Thread(this);t.start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height){// TODO Auto-generated method stub}@Overridepublic void surfaceDestroyed(SurfaceHolder holder){// 通知關(guān)閉線程isRunning = false;}@Overridepublic void run(){// 不斷的進(jìn)行drawwhile (isRunning){draw();}}private void draw(){try{// 獲得canvasmCanvas = mHolder.lockCanvas();if (mCanvas != null){// drawSomething..}} catch (Exception e){} finally{if (mCanvas != null)mHolder.unlockCanvasAndPost(mCanvas);}} }

結(jié)合上面我們的介紹,我們?cè)跇?gòu)造中通過getHolder拿到SurfaceHolder對(duì)象,然后設(shè)置一個(gè)addCallback回調(diào),去監(jiān)聽SurfaceView的生命周期,生命周期有三個(gè)方法,分別為create,change,destory;我們一般在create里面進(jìn)行初始化的一些操作,然后開啟線程;在destroy里面設(shè)置關(guān)閉線程;
所有的繪制流程都是線程的run方法里面,可以看到我們的draw方法。
注意下,我們?cè)赿raw里面進(jìn)行了try catch然后很多的判空,主要是因?yàn)?#xff0c;當(dāng)用戶點(diǎn)擊back或者按下home鍵以后,surfaceview會(huì)被銷毀;
mHolder.lockCanvas();返回的就是null了,所以為了避免造成空指針錯(cuò)誤,我們各種判null,甚至還加了個(gè)try catch。

實(shí)例 抽獎(jiǎng)轉(zhuǎn)盤

效果圖

代碼如下

package com.zhy.view;import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView;import com.zhy.demo_zhy_06_choujiangzhuanpan.R;public class LuckyPanView extends SurfaceView implements Callback, Runnable {private SurfaceHolder mHolder;/*** 與SurfaceHolder綁定的Canvas*/private Canvas mCanvas;/*** 用于繪制的線程*/private Thread t;/*** 線程的控制開關(guān)*/private boolean isRunning;/*** 抽獎(jiǎng)的文字*/private String[] mStrs = new String[] { "單反相機(jī)", "IPAD", "恭喜發(fā)財(cái)", "IPHONE","妹子一只", "恭喜發(fā)財(cái)" };/*** 每個(gè)盤塊的顏色*/private int[] mColors = new int[] { 0xFFFFC300, 0xFFF17E01, 0xFFFFC300,0xFFF17E01, 0xFFFFC300, 0xFFF17E01 };/*** 與文字對(duì)應(yīng)的圖片*/private int[] mImgs = new int[] { R.drawable.danfan, R.drawable.ipad,R.drawable.f040, R.drawable.iphone, R.drawable.meizi,R.drawable.f040 };/*** 與文字對(duì)應(yīng)圖片的bitmap數(shù)組*/private Bitmap[] mImgsBitmap;/*** 盤塊的個(gè)數(shù)*/private int mItemCount = 6;/*** 繪制盤塊的范圍*/private RectF mRange = new RectF();/*** 圓的直徑*/private int mRadius;/*** 繪制盤快的畫筆*/private Paint mArcPaint;/*** 繪制文字的畫筆*/private Paint mTextPaint;/*** 滾動(dòng)的速度*/private double mSpeed;private volatile float mStartAngle = 0;/*** 是否點(diǎn)擊了停止*/private boolean isShouldEnd;/*** 控件的中心位置*/private int mCenter;/*** 控件的padding,這里我們認(rèn)為4個(gè)padding的值一致,以paddingleft為標(biāo)準(zhǔn)*/private int mPadding;/*** 背景圖的bitmap*/private Bitmap mBgBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.bg2);/*** 文字的大小*/private float mTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());public LuckyPanView(Context context){this(context, null);}public LuckyPanView(Context context, AttributeSet attrs){super(context, attrs);mHolder = getHolder();mHolder.addCallback(this);// setZOrderOnTop(true);// 設(shè)置畫布 背景透明// mHolder.setFormat(PixelFormat.TRANSLUCENT);setFocusable(true);setFocusableInTouchMode(true);this.setKeepScreenOn(true);}/*** 設(shè)置控件為正方形*/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = Math.min(getMeasuredWidth(), getMeasuredHeight());// 獲取圓形的直徑mRadius = width - getPaddingLeft() - getPaddingRight();// padding值mPadding = getPaddingLeft();// 中心點(diǎn)mCenter = width / 2;setMeasuredDimension(width, width);}@Overridepublic void surfaceCreated(SurfaceHolder holder){// 初始化繪制圓弧的畫筆mArcPaint = new Paint();mArcPaint.setAntiAlias(true);mArcPaint.setDither(true);// 初始化繪制文字的畫筆mTextPaint = new Paint();mTextPaint.setColor(0xFFffffff);mTextPaint.setTextSize(mTextSize);// 圓弧的繪制范圍mRange = new RectF(getPaddingLeft(), getPaddingLeft(), mRadius+ getPaddingLeft(), mRadius + getPaddingLeft());// 初始化圖片mImgsBitmap = new Bitmap[mItemCount];for (int i = 0; i < mItemCount; i++){mImgsBitmap[i] = BitmapFactory.decodeResource(getResources(),mImgs[i]);}// 開啟線程isRunning = true;t = new Thread(this);t.start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height){// TODO Auto-generated method stub}@Overridepublic void surfaceDestroyed(SurfaceHolder holder){// 通知關(guān)閉線程isRunning = false;}@Overridepublic void run(){// 不斷的進(jìn)行drawwhile (isRunning){long start = System.currentTimeMillis();draw();long end = System.currentTimeMillis();try{if (end - start < 50){Thread.sleep(50 - (end - start));}} catch (InterruptedException e){e.printStackTrace();}}}private void draw(){try{// 獲得canvasmCanvas = mHolder.lockCanvas();if (mCanvas != null){// 繪制背景圖drawBg();/*** 繪制每個(gè)塊塊,每個(gè)塊塊上的文本,每個(gè)塊塊上的圖片*/float tmpAngle = mStartAngle;float sweepAngle = (float) (360 / mItemCount);for (int i = 0; i < mItemCount; i++){// 繪制快快mArcPaint.setColor(mColors[i]); // mArcPaint.setStyle(Style.STROKE);mCanvas.drawArc(mRange, tmpAngle, sweepAngle, true,mArcPaint);// 繪制文本drawText(tmpAngle, sweepAngle, mStrs[i]);// 繪制IcondrawIcon(tmpAngle, i);tmpAngle += sweepAngle;}// 如果mSpeed不等于0,則相當(dāng)于在滾動(dòng)mStartAngle += mSpeed;// 點(diǎn)擊停止時(shí),設(shè)置mSpeed為遞減,為0值轉(zhuǎn)盤停止if (isShouldEnd){mSpeed -= 1;}if (mSpeed <= 0){mSpeed = 0;isShouldEnd = false;}// 根據(jù)當(dāng)前旋轉(zhuǎn)的mStartAngle計(jì)算當(dāng)前滾動(dòng)到的區(qū)域calInExactArea(mStartAngle);}} catch (Exception e){e.printStackTrace();} finally{if (mCanvas != null)mHolder.unlockCanvasAndPost(mCanvas);}}/*** 根據(jù)當(dāng)前旋轉(zhuǎn)的mStartAngle計(jì)算當(dāng)前滾動(dòng)到的區(qū)域 繪制背景,不重要,完全為了美觀*/private void drawBg(){mCanvas.drawColor(0xFFFFFFFF);mCanvas.drawBitmap(mBgBitmap, null, new Rect(mPadding / 2,mPadding / 2, getMeasuredWidth() - mPadding / 2,getMeasuredWidth() - mPadding / 2), null);}/*** 根據(jù)當(dāng)前旋轉(zhuǎn)的mStartAngle計(jì)算當(dāng)前滾動(dòng)到的區(qū)域* * @param startAngle*/public void calInExactArea(float startAngle){// 讓指針從水平向右開始計(jì)算float rotate = startAngle + 90;rotate %= 360.0;for (int i = 0; i < mItemCount; i++){// 每個(gè)的中獎(jiǎng)范圍float from = 360 - (i + 1) * (360 / mItemCount);float to = from + 360 - (i) * (360 / mItemCount);if ((rotate > from) && (rotate < to)){Log.d("TAG", mStrs[i]);return;}}}/*** 繪制圖片* * @param startAngle* @param sweepAngle* @param i*/private void drawIcon(float startAngle, int i){// 設(shè)置圖片的寬度為直徑的1/8int imgWidth = mRadius / 8;float angle = (float) ((30 + startAngle) * (Math.PI / 180));int x = (int) (mCenter + mRadius / 2 / 2 * Math.cos(angle));int y = (int) (mCenter + mRadius / 2 / 2 * Math.sin(angle));// 確定繪制圖片的位置Rect rect = new Rect(x - imgWidth / 2, y - imgWidth / 2, x + imgWidth/ 2, y + imgWidth / 2);mCanvas.drawBitmap(mImgsBitmap[i], null, rect, null);}/*** 繪制文本* * @param rect* @param startAngle* @param sweepAngle* @param string*/private void drawText(float startAngle, float sweepAngle, String string){Path path = new Path();path.addArc(mRange, startAngle, sweepAngle);float textWidth = mTextPaint.measureText(string);// 利用水平偏移讓文字居中float hOffset = (float) (mRadius * Math.PI / mItemCount / 2 - textWidth / 2);// 水平偏移float vOffset = mRadius / 2 / 6;// 垂直偏移mCanvas.drawTextOnPath(string, path, hOffset, vOffset, mTextPaint);}/*** 點(diǎn)擊開始旋轉(zhuǎn)* * @param luckyIndex*/public void luckyStart(int luckyIndex){// 每項(xiàng)角度大小float angle = (float) (360 / mItemCount);// 中獎(jiǎng)角度范圍(因?yàn)橹羔樝蛏?#xff0c;所以水平第一項(xiàng)旋轉(zhuǎn)到指針指向,需要旋轉(zhuǎn)210-270;)float from = 270 - (luckyIndex + 1) * angle;float to = from + angle;// 停下來時(shí)旋轉(zhuǎn)的距離float targetFrom = 4 * 360 + from;/*** <pre>* (v1 + 0) * (v1+1) / 2 = target ;* v1*v1 + v1 - 2target = 0 ;* v1=-1+(1*1 + 8 *1 * target)/2;* </pre>*/float v1 = (float) (Math.sqrt(1 * 1 + 8 * 1 * targetFrom) - 1) / 2;float targetTo = 4 * 360 + to;float v2 = (float) (Math.sqrt(1 * 1 + 8 * 1 * targetTo) - 1) / 2;mSpeed = (float) (v1 + Math.random() * (v2 - v1));isShouldEnd = false;}public void luckyEnd(){mStartAngle = 0;isShouldEnd = true;}public boolean isStart(){return mSpeed != 0;}public boolean isShouldEnd(){return isShouldEnd;}}

代碼下載

源代碼

參考鏈接

Android SurfaceView實(shí)戰(zhàn) 打造抽獎(jiǎng)轉(zhuǎn)盤 - Hongyang - 博客頻道 - CSDN.NET

實(shí)戰(zhàn) flabby bird

效果圖

分析

仔細(xì)觀察游戲,需要繪制的有:背景、地板、鳥、管道、分?jǐn)?shù);
游戲開始時(shí):
地板給人一種想左移動(dòng)的感覺;
管道與地板同樣的速度向左移動(dòng);
鳥默認(rèn)下落;
當(dāng)用戶touch屏幕時(shí),鳥上升一段距離后,下落;
運(yùn)動(dòng)過程中需要判斷管道和鳥之間的位置關(guān)系,是否觸碰,是否穿過等,需要計(jì)算分?jǐn)?shù)。

可以分為

  • piple類
  • bird類
  • floor類
  • Game類
  • 等來實(shí)現(xiàn)

    GameFlabbyBird類代碼

    package com.zhy.view;import java.util.ArrayList; import java.util.List;import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView;import com.zhy.surfaceViewDemo.R;public class GameFlabbyBird extends SurfaceView implements Callback, Runnable {private SurfaceHolder mHolder;/*** 與SurfaceHolder綁定的Canvas*/private Canvas mCanvas;/*** 用于繪制的線程*/private Thread t;/*** 線程的控制開關(guān)*/private boolean isRunning;private Paint mPaint;/*** 當(dāng)前View的尺寸*/private int mWidth;private int mHeight;private RectF mGamePanelRect = new RectF();/*** 背景*/private Bitmap mBg;/*** *********鳥相關(guān)***********************/private Bird mBird;private Bitmap mBirdBitmap;/*** 地板*/private Floor mFloor;private Bitmap mFloorBg;/*** *********管道相關(guān)***********************//*** 管道*/private Bitmap mPipeTop;private Bitmap mPipeBottom;private RectF mPipeRect;private int mPipeWidth;/*** 管道的寬度 60dp*/private static final int PIPE_WIDTH = 60;private List<Pipe> mPipes = new ArrayList<Pipe>();/*** 分?jǐn)?shù)*/private final int[] mNums = new int[] { R.drawable.n0, R.drawable.n1,R.drawable.n2, R.drawable.n3, R.drawable.n4, R.drawable.n5,R.drawable.n6, R.drawable.n7, R.drawable.n8, R.drawable.n9 };private Bitmap[] mNumBitmap;private int mGrade = 0;private int mRemovedPipe = 0;private static final float RADIO_SINGLE_NUM_HEIGHT = 1 / 15f;private int mSingleGradeWidth;private int mSingleGradeHeight;private RectF mSingleNumRectF;private int mSpeed = Util.dp2px(getContext(), 2);/***********************************/private enum GameStatus{WAITTING, RUNNING, STOP;}/*** 記錄游戲的狀態(tài)*/private GameStatus mStatus = GameStatus.WAITTING;/*** 觸摸上升的距離,因?yàn)槭巧仙?#xff0c;所以為負(fù)值*/private static final int TOUCH_UP_SIZE = -16;/*** 將上升的距離轉(zhuǎn)化為px;這里多存儲(chǔ)一個(gè)變量,變量在run中計(jì)算* */private final int mBirdUpDis = Util.dp2px(getContext(), TOUCH_UP_SIZE);private int mTmpBirdDis;/*** 鳥自動(dòng)下落的距離*/private final int mAutoDownSpeed = Util.dp2px(getContext(), 2);/*** 兩個(gè)管道間距離*/private final int PIPE_DIS_BETWEEN_TWO = Util.dp2px(getContext(), 300);/*** 記錄移動(dòng)的距離,達(dá)到 PIPE_DIS_BETWEEN_TWO 則生成一個(gè)管道*/private int mTmpMoveDistance;/*** 記錄需要移除的管道*/private List<Pipe> mNeedRemovePipe = new ArrayList<Pipe>();/*** 處理一些邏輯上的計(jì)算*/private void logic(){switch (mStatus){case RUNNING:mGrade = 0;// 更新我們地板繪制的x坐標(biāo),地板移動(dòng)mFloor.setX(mFloor.getX() - mSpeed);logicPipe();// 默認(rèn)下落,點(diǎn)擊時(shí)瞬間上升mTmpBirdDis += mAutoDownSpeed;mBird.setY(mBird.getY() + mTmpBirdDis);// 計(jì)算分?jǐn)?shù)mGrade += mRemovedPipe;for (Pipe pipe : mPipes){if (pipe.getX() + mPipeWidth < mBird.getX()){mGrade++;}}checkGameOver();break;case STOP: // 鳥落下// 如果鳥還在空中,先讓它掉下來if (mBird.getY() < mFloor.getY() - mBird.getWidth()){mTmpBirdDis += mAutoDownSpeed;mBird.setY(mBird.getY() + mTmpBirdDis);} else{mStatus = GameStatus.WAITTING;initPos();}break;default:break;}}/*** 重置鳥的位置等數(shù)據(jù)*/private void initPos(){mPipes.clear();//立即增加一個(gè)mPipes.add(new Pipe(getContext(), getWidth(), getHeight(), mPipeTop,mPipeBottom));mNeedRemovePipe.clear();// 重置鳥的位置// mBird.setY(mHeight * 2 / 3);mBird.resetHeigt();// 重置下落速度mTmpBirdDis = 0;mTmpMoveDistance = 0 ;mRemovedPipe = 0;}private void checkGameOver(){// 如果觸碰地板,ggif (mBird.getY() > mFloor.getY() - mBird.getHeight()){mStatus = GameStatus.STOP;}// 如果撞到管道for (Pipe wall : mPipes){// 已經(jīng)穿過的if (wall.getX() + mPipeWidth < mBird.getX()){continue;}if (wall.touchBird(mBird)){mStatus = GameStatus.STOP;break;}}}private void logicPipe(){// 管道移動(dòng)for (Pipe pipe : mPipes){if (pipe.getX() < -mPipeWidth){mNeedRemovePipe.add(pipe);mRemovedPipe++;continue;}pipe.setX(pipe.getX() - mSpeed);}// 移除管道mPipes.removeAll(mNeedRemovePipe);mNeedRemovePipe.clear();// Log.e("TAG", "現(xiàn)存管道數(shù)量:" + mPipes.size());// 管道mTmpMoveDistance += mSpeed;// 生成一個(gè)管道if (mTmpMoveDistance >= PIPE_DIS_BETWEEN_TWO){Pipe pipe = new Pipe(getContext(), getWidth(), getHeight(),mPipeTop, mPipeBottom);mPipes.add(pipe);mTmpMoveDistance = 0;}}@Overridepublic boolean onTouchEvent(MotionEvent event){int action = event.getAction();if (action == MotionEvent.ACTION_DOWN){switch (mStatus){case WAITTING:mStatus = GameStatus.RUNNING;break;case RUNNING:mTmpBirdDis = mBirdUpDis;break;}}return true;}public GameFlabbyBird(Context context){this(context, null);}public GameFlabbyBird(Context context, AttributeSet attrs){super(context, attrs);mHolder = getHolder();mHolder.addCallback(this);setZOrderOnTop(true);// 設(shè)置畫布 背景透明mHolder.setFormat(PixelFormat.TRANSLUCENT);// 設(shè)置可獲得焦點(diǎn)setFocusable(true);setFocusableInTouchMode(true);// 設(shè)置常亮this.setKeepScreenOn(true);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setDither(true);initBitmaps();// 初始化速度// mSpeed = Util.dp2px(getContext(), 2);mPipeWidth = Util.dp2px(getContext(), PIPE_WIDTH);}/*** 初始化圖片*/private void initBitmaps(){mBg = loadImageByResId(R.drawable.bg1);mBirdBitmap = loadImageByResId(R.drawable.b1);mFloorBg = loadImageByResId(R.drawable.floor_bg2);mPipeTop = loadImageByResId(R.drawable.g2);mPipeBottom = loadImageByResId(R.drawable.g1);mNumBitmap = new Bitmap[mNums.length];for (int i = 0; i < mNumBitmap.length; i++){mNumBitmap[i] = loadImageByResId(mNums[i]);}}@Overridepublic void surfaceCreated(SurfaceHolder holder){Log.e("TAG", "surfaceCreated");// 開啟線程isRunning = true;t = new Thread(this);t.start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height){Log.e("TAG", "surfaceChanged");// TODO Auto-generated method stub}@Overridepublic void surfaceDestroyed(SurfaceHolder holder){Log.e("TAG", "surfaceDestroyed");// 通知關(guān)閉線程isRunning = false;}@Overridepublic void run(){while (isRunning){long start = System.currentTimeMillis();logic();draw();long end = System.currentTimeMillis();try{if (end - start < 50){Thread.sleep(50 - (end - start));}} catch (InterruptedException e){e.printStackTrace();}}}private void draw(){try{// 獲得canvasmCanvas = mHolder.lockCanvas();if (mCanvas != null){// drawSomething..drawBg();drawBird();drawPipes();drawFloor();drawGrades();}} catch (Exception e){} finally{if (mCanvas != null)mHolder.unlockCanvasAndPost(mCanvas);}}private void drawFloor(){mFloor.draw(mCanvas, mPaint);}/*** 繪制背景*/private void drawBg(){mCanvas.drawBitmap(mBg, null, mGamePanelRect, null);}private void drawBird(){mBird.draw(mCanvas);}/*** 繪制管道*/private void drawPipes(){for (Pipe pipe : mPipes){// pipe.setX(pipe.getX() - mSpeed);pipe.draw(mCanvas, mPipeRect);}}/*** 初始化尺寸相關(guān)*/@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh){super.onSizeChanged(w, h, oldw, oldh);mWidth = w;mHeight = h;mGamePanelRect.set(0, 0, w, h);// 初始化mBirdmBird = new Bird(getContext(), mWidth, mHeight, mBirdBitmap);// 初始化地板mFloor = new Floor(mWidth, mHeight, mFloorBg);// 初始化管道范圍mPipeRect = new RectF(0, 0, mPipeWidth, mHeight);Pipe pipe = new Pipe(getContext(), w, h, mPipeTop, mPipeBottom);mPipes.add(pipe);// 初始化分?jǐn)?shù)mSingleGradeHeight = (int) (h * RADIO_SINGLE_NUM_HEIGHT);mSingleGradeWidth = (int) (mSingleGradeHeight * 1.0f/ mNumBitmap[0].getHeight() * mNumBitmap[0].getWidth());mSingleNumRectF = new RectF(0, 0, mSingleGradeWidth, mSingleGradeHeight);}/*** 繪制分?jǐn)?shù)*/private void drawGrades(){String grade = mGrade + "";mCanvas.save(Canvas.MATRIX_SAVE_FLAG);mCanvas.translate(mWidth / 2 - grade.length() * mSingleGradeWidth / 2,1f / 8 * mHeight);// draw single num one by onefor (int i = 0; i < grade.length(); i++){String numStr = grade.substring(i, i + 1);int num = Integer.valueOf(numStr);mCanvas.drawBitmap(mNumBitmap[num], null, mSingleNumRectF, null);mCanvas.translate(mSingleGradeWidth, 0);}mCanvas.restore();}/*** 根據(jù)resId加載圖片* * @param resId* @return*/private Bitmap loadImageByResId(int resId){return BitmapFactory.decodeResource(getResources(), resId);} }

    MainActivity代碼

    package com.zhy.surfaceViewDemo;import com.zhy.view.GameFlabbyBird;import android.app.Activity; import android.os.Bundle; import android.view.Window; import android.view.WindowManager;public class MainActivity extends Activity {GameFlabbyBird mGame;@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);requestWindowFeature(Window.FEATURE_NO_TITLE);mGame = new GameFlabbyBird(this);setContentView(mGame);}}

    代碼下載

    代碼下載

    參考鏈接

    Android SurfaceView實(shí)戰(zhàn) 帶你玩轉(zhuǎn)flabby bird (上) - Hongyang - 博客頻道 - CSDN.NET

    Android SurfaceView實(shí)戰(zhàn) 帶你玩轉(zhuǎn)flabby bird (下) - Hongyang - 博客頻道 - CSDN.NET

    轉(zhuǎn)載于:https://www.cnblogs.com/jjx2013/p/6223641.html

    總結(jié)

    以上是生活随笔為你收集整理的Android之SurfaceView的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。