Android中利用畫圖類和線程畫出閃爍的心形


本文講解主要涉及的知識點:

1.線程控制 
2.畫圖類 
3.心形函數

大家先看圖片:

1.jpg

因爲前一段時間在寫畫圖類,剛好有一個線程控制畫圖閃爍的,我就想說我能不能做一個心形閃爍的,出來的效果就如圖,先貼再講解代碼:

裏面設置兩個類,一個是我們的activity類,這個類用來顯示示圖,然後建一個繼承SurfaceView的類,我們在這裏面畫圖。先貼兩個累的代碼:

主類名:GameMainActivity,畫圖類類名:Love.


  package com.cz.game.demo; 
  
  import android.app.Activity; 
  import android.os.Bundle; 
  
  public class GameMainActivity extends Activity { 
      /** Called when the activity is first created. */ 
  
      private Love love; 
     @Override 
     public void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
         this.love = new Love(this); 
         setContentView(love); 
     } 
 } 




畫圖類:

   /** 
    *  
    */ 
   package com.cz.game.demo; 
   
   import android.content.Context; 
   import android.graphics.Canvas; 
   import android.graphics.Color; 
   import android.graphics.Paint; 
  import android.graphics.RectF; 
  import android.graphics.Typeface; 
  import android.view.SurfaceHolder; 
  import android.view.SurfaceView; 
  
  /** 
   * @author CZ 
   *  
   */ 
  public class Love extends SurfaceView implements SurfaceHolder.Callback, 
          Runnable { 
  
      boolean mbloop = false; 
      SurfaceHolder mSurfaceHolder = null; 
      private Canvas canvas; 
      int miCount = 0; 
      int y = 50; 
  
      /** 
       * @param context 
       */ 
      public Love(Context context) { 
          super(context); 
          mSurfaceHolder = this.getHolder(); 
          mSurfaceHolder.addCallback(this); 
          this.setFocusable(true); 
          this.setKeepScreenOn(true); 
          mbloop = true; 
      } 
  
      /* 
       * (non-Javadoc) 
       *  
       * @see 
       * android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder 
       * , int, int, int) 
       */ 
      @Override 
      public void surfaceChanged(SurfaceHolder holder, int format, int width, 
              int height) { 
          // TODO Auto-generated method stub 
  
      } 
  
      /* 
       * (non-Javadoc) 
       *  
       * @see 
       * android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder 
       * ) 
       */ 
      @Override 
      public void surfaceCreated(SurfaceHolder holder) { 
          // TODO Auto-generated method stub 
          new Thread(this).start(); 
      } 
  
      /* 
       * (non-Javadoc) 
       *  
       * @seeandroid.view.SurfaceHolder.Callback#surfaceDestroyed(android.view. 
       * SurfaceHolder) 
       */ 
      @Override 
      public void surfaceDestroyed(SurfaceHolder holder) { 
          // TODO Auto-generated method stub 
          mbloop = false; 
      } 
  
      /* 
       * (non-Javadoc) 
       *  
       * @see java.lang.Runnable#run() 
       */ 
      @Override 
      public void run() { 
          // TODO Auto-generated method stub 
          while (mbloop) { 
              try { 
                  Thread.sleep(200); 
              } catch (Exception e) { 
                  // TODO: handle exception 
              } 
              synchronized (mSurfaceHolder) { 
                  Draw(); 
              } 
          } 
      } 
  
      /** 
      *  
      * Year:2011 Date:2011-7-27 Time:下午06:52:04 Author:CZ TODO 
      */ 
     private void Draw() { 
        // TODO Auto-generated method stub 
         canvas = mSurfaceHolder.lockCanvas(); 
         try { 
             if (mSurfaceHolder == null || canvas == null) { 
                 return; 
             } 
             if (miCount < 100) { 
                 miCount++; 
             } else { 
                 miCount = 0; 
             } 
             Paint paint = new Paint(); 
             paint.setAntiAlias(true); 
             paint.setColor(Color.BLACK); 
             canvas.drawRect(0, 0, 320, 480, paint); 
             switch (miCount % 6) { 
             case 0: 
                 paint.setColor(Color.BLUE); 
                 break; 
             case 1: 
                 paint.setColor(Color.GREEN); 
                 break; 
             case 2: 
                 paint.setColor(Color.RED); 
                 break; 
             case 3: 
                 paint.setColor(Color.YELLOW); 
                 break; 
             case 4: 
                 paint.setColor(Color.argb(255, 255, 181, 216)); 
                 break; 
             case 5: 
                 paint.setColor(Color.argb(255, 0, 255, 255)); 
                 break; 
             default: 
                 paint.setColor(Color.WHITE); 
                 break; 
             } 
             int i, j; 
             double x, y, r; 
 
             for (i = 0; i <= 90; i++) { 
                 for (j = 0; j <= 90; j++) { 
                     r = Math.PI / 45 * i * (1 - Math.sin(Math.PI / 45 * j)) 
                             * 20; 
                     x = r * Math.cos(Math.PI / 45 * j) 
                             * Math.sin(Math.PI / 45 * i) + 320 / 2; 
                     y = -r * Math.sin(Math.PI / 45 * j) + 400 / 4; 
                     canvas.drawPoint((float) x, (float) y, paint); 
                 } 
             } 
 
             paint.setTextSize(32); 
             paint.setTypeface(Typeface.create(Typeface.SERIF, Typeface.ITALIC)); 
 
             RectF rect = new RectF(60, 400, 260, 405); 
             canvas.drawRoundRect(rect, (float) 1.0, (float) 1.0, paint); 
             canvas.drawText("Loving You", 75, 400, paint); 
             mSurfaceHolder.unlockCanvasAndPost(canvas); 
         } catch (Exception e) { 
         } 
 
     } 
 
 } 
 





關於這個程序要講解的幾點:

1. 畫圖的時候你可以繼承View,也可以繼承SurfaceView,這兩者的區別在於:surfaceView是在一個新起的單獨線程中可以重新繪製畫面而View必須在UI的主線程中更新畫面。SurfaceView可以控制表面的格式,比如大小,顯示在屏幕中的位置,最關鍵是的提供了SurfaceHolder類,使用getHolder方法獲取,還有涉及的surfaceCreated(SurfaceHolder holder),surfaceDestroyed(SurfaceHolder holder),surfaceChanged(SurfaceHolder holder, int format, int width, int height)方法,而在SurfaceHolder.Callback 接口回調中可以通過重寫來改變這些方法

2.程序其實很簡單, 既然生命了Runnable接口,就有相對應的Run方法,在surfaceCreate()的時候開啓線程,線程每隔200ms就刷新一次,這樣我們看到的效果就是閃爍的,每200毫秒 畫一次圖,根據經過的間隔時間來設置畫筆的顏色,然後通過循環描點,畫出心形,然後設置字體大小,畫字和字下面的橫線。

3.關於心形函數,是從一個例子中看來得,關於x和y的得到,

x = r * Math.cos(Math.PI / 45 * j)  * Math.sin(Math.PI / 45 * i) + 320 / 2;  y = -r * Math.sin(Math.PI / 45 * j) + 400 / 4;

320是屏幕的寬度,本來豎屏我設置的是480,可是下面得寫字,就設置爲400的了,關於畫更好看的心形還有一個函數,大家可以看下:

1.jpg

有興趣的童鞋可以設置再做一下.

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