国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

如何使用SurfaceView實現魚兒游動動畫

2019-10-22 18:12:24
字體:
來源:轉載
供稿:網友

本文實例為大家分享了使用SurfaceView實現動畫的具體代碼,供大家參考,具體內容如下

與自定義view繪圖進行對比:

1.view繪圖沒有雙緩沖機制,而surfaceview有

2.view繪圖更新時,要全部更新整張圖片,而surfaceview可以更新部分區域

3.新線程無法直接更新view繪圖,需要handler配合。

魚兒游動的動畫:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="vertical"  android:layout_width="match_parent"  android:layout_height="match_parent">  <com.example.liuyan.testbutfly.FishView   android:layout_width="match_parent"   android:layout_height="match_parent" /> </LinearLayout> 

java代碼:

public class FishView extends SurfaceView implements SurfaceHolder.Callback{  private SurfaceHolder holder;  private UpdateViewThread updatethread;  private boolean hasSurface;  private Bitmap back;  private Bitmap[] fishs;  private int fishIndex = 0;//繪制第幾張魚  //魚的初始位置  private float fishx = 778;  private float fishy = 500;  private float fishSpeed = 6; //魚的游動速度  //魚的游動角度  private int fishAngle = new Random().nextInt(60);  Matrix matrix = new Matrix();   public FishView(Context context) {   super(context);   Log.i("mydate" , "開始");   //獲取surfaceview的surfaceholder,并將該類的實例作為其callback   holder = getHolder();   holder.addCallback(this);//以自身作為callback,回調方法   hasSurface = false;   back = BitmapFactory.decodeResource(context.getResources() , R.drawable.fishbg);//背景   int[] id = new int[]{R.drawable.fish0 , R.drawable.fish1 , R.drawable.fish2 ,R.drawable.fish3 ,R.drawable.fish4 ,R.drawable.fish5 ,R.drawable.fish6 ,R.drawable.fish7 ,R.drawable.fish8, R.drawable.fish9};   fishs = new Bitmap[10];   //初始化 魚游動的10張圖   for (int i = 0 ; i < 10 ; i++){    try {     fishs[i] = BitmapFactory.decodeResource(context.getResources() , id[i]);    } catch (Exception e){     e.printStackTrace();    }   }   Log.i("mydate" , "結束");  }   public FishView(Context context, AttributeSet attrs) {   super(context, attrs);   Log.i("mydate" , "開始");   //獲取surfaceview的surfaceholder,并將該類的實例作為其callback   holder = getHolder();   holder.addCallback(this);//以自身作為callback,回調方法   hasSurface = false;   back = BitmapFactory.decodeResource(context.getResources() , R.drawable.fishbg);//背景   int[] id = new int[]{R.drawable.fish0 , R.drawable.fish1 , R.drawable.fish2 ,R.drawable.fish3 ,R.drawable.fish4 ,R.drawable.fish5 ,R.drawable.fish6 ,R.drawable.fish7 ,R.drawable.fish8, R.drawable.fish9};   fishs = new Bitmap[10];   //初始化 魚游動的10張圖   for (int i = 0 ; i < 10 ; i++){    try { //    int fishId = (Integer) R.drawable.class.getField("fish" + i).get(null);//反射機制獲取圖片 //    Log.i("mydate" , " "+ fishId);     fishs[i] = BitmapFactory.decodeResource(context.getResources() , id[i]);    } catch (Exception e){     e.printStackTrace();    }   }   Log.i("mydate" , "結束");  }    public void resume(){   //創建和啟動 圖片更新線程   if (updatethread == null){    updatethread = new UpdateViewThread();    if (hasSurface == true){     updatethread.start();    }   }  }   public void pause(){   //停止 圖像更新線程   if (updatethread != null){    updatethread.requestExitAndWait();    updatethread = null;   }  }    @Override  public void surfaceCreated(SurfaceHolder holder) { //surfaceview被創建時回調該方法   hasSurface = true;   resume(); //開啟線程更新  }   @Override  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {//surfaceview改變時回調該方法   if (updatethread != null){    updatethread.onWindowResize(width , height);   }  }   @Override  public void surfaceDestroyed(SurfaceHolder holder) {//surfaceview銷毀時回調該方法   hasSurface = false;   pause(); //停止線程更新  }   class UpdateViewThread extends Thread{   //定義圖像是否更新完成的標志   private boolean done;    public UpdateViewThread() {    super();    done = false;   }    @Override   public void run() {    SurfaceHolder surfaceholder = holder;    //循環繪制,直到線程停止    while (!done){     Canvas canvas = surfaceholder.lockCanvas();//鎖定surfaceview,準備繪制     //繪制背景     canvas.drawBitmap(back , 0 , 0 , null);     //魚游出屏幕外,重新初始化魚的位置     if (fishx < 0 ){      fishx = 778;      fishy = 500;      fishAngle = new Random().nextInt(60);     }     if (fishy < 0){      fishx = 778;      fishy = 500;      fishAngle = new Random().nextInt(60);     }     //用matrix控制魚的旋轉角度和位置     matrix.reset();     matrix.setRotate(fishAngle);//下面的位置計算看圖片的解釋如下:     matrix.postTranslate(fishx -= fishSpeed * Math.cos(Math.toRadians(fishAngle)) , fishy -= fishSpeed * Math.sin(Math.toRadians(fishAngle)));     canvas.drawBitmap(fishs[fishIndex++%fishs.length] , matrix , null);     surfaceholder.unlockCanvasAndPost(canvas);//解鎖canvas,渲染繪制圖像     try {      Thread.sleep(60);     } catch (Exception e){      e.printStackTrace();     }    }   }    public void requestExitAndWait() {    //將繪制線程 標記為完成 ,并合并到主線程中    done = true;    try {     join();    } catch (Exception e){     e.printStackTrace();    }   }    public void onWindowResize(int width, int height) {    //處理surfaceview的大小改變事件   }  }  } 

位置計算圖片解釋如下:

Math.toRadians(fishAngle) 

先理解這句代碼的意思:將0-360的角度制角度轉化為pi弧度制角度

SurfaceView,動畫

魚兒不停的游動,坐標改變其實就是:

當前的x坐標 - 速度*cos角度 , 當前的y坐標 - 速度*sin角度

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 长宁县| 榆中县| 都江堰市| 饶阳县| 衡东县| 北票市| 乳源| 丽江市| 当阳市| 邓州市| 若尔盖县| 蛟河市| 四平市| 黔东| 汾阳市| 根河市| 阳高县| 肇东市| 石景山区| 定边县| 靖江市| 平谷区| 库伦旗| 新昌县| 长宁县| 郁南县| 老河口市| 霍城县| 迁安市| 佛坪县| 迭部县| 宾川县| 江孜县| 泾阳县| 嵊泗县| 天柱县| 襄垣县| 汶上县| 腾冲县| 庆城县| 凭祥市|