贝塞尔曲线,很多人可能不太了解,什么叫做贝塞尔曲线呢?这里先做一下简单介绍:贝塞尔曲线也可以叫做贝济埃曲线或者贝兹曲线,它由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋。一般的矢量图形软件常利用贝塞尔曲线来精确画出曲线。
       上面的介绍中,“线段像可伸缩的皮筋”这句话非常关键,但也特别好理解。至于贝塞尔曲线的详细内容大家可以查阅相关资料。
       Android提供的贝塞尔曲线绘制接口
       在Android开发中,要实现贝塞尔曲线其实还是很简单的,因为Android已经给我们提供了相关接口,但此接口方法被藏的有点深,藏于Path类中。此方法如下:
       android.graphics.Path.quadTo(float x1, float y1, float x2, float y2)
       Since: API Level 1
       参数说明:
       x1:操作点的x坐标
       y1:操作点的y坐标
       x2:结束点的x坐标
       y2:结束点的y坐标
       从API中看出,贝塞尔曲线从API-1就开始支持了。
       Android贝塞尔曲线的绘制实例
       熟悉方法后,下面就来实现:
       SurfaceView框架不多讲,看过我博客的都应该知道的。
       直接看MySurfaceView类,此类继承SurfaceView,是游戏的主视图。
       这里为了更清晰的讲解:这里部分代码先不贴出来了,最后会整体贴出。
       首先是定义相关的成员变量:
Java代码
    -   
- private int startX, startY, controlX, controlY, endX, endY;   
-   
- private Path path;   
-   
- private Paint paintQ;   
-   
- private Random random;  
       本类构造函数:
Java代码
    -  
-  
-   
- public MySurfaceView(Context context) {   
-     super(context);   
-     ...   
-           
-         path = new Path();   
-         paintQ = new Paint();   
-         paintQ.setAntiAlias(true);   
-         paintQ.setStyle(Style.STROKE);   
-         paintQ.setStrokeWidth(5);   
-         paintQ.setColor(Color.WHITE);   
-         random = new Random();   
-     ...   
- }  
       接着我把贝赛尔曲线的绘制封装成一个方法了,函数如下:
Java代码
    -  
-  
-  
-  
-   
- public void drawQpath(Canvas canvas) {   
-     path.reset();  
-       
-     path.moveTo(startX, startY);   
-       
-     path.quadTo(controlX, controlY, endX, endY);   
-       
-     canvas.drawPath(path, paintQ);   
- }  
       最后是用户触屏监听函数以及逻辑函数:
Java代码
    -  
-  
-   
- @Override  
- public boolean onTouchEvent(MotionEvent event) {   
-     endX = (int) event.getX();   
-     endY = (int) event.getY();   
-     return true;   
- }   
-  
-  
-   
- private void logic() {   
-     if (endX != 0 && endY != 0) {   
-           
-         controlX = random.nextInt((endX - startX) / 2);   
-         controlY = random.nextInt((endY - startY) / 2);   
-     }   
- }  
       整个代码很easy,主要是贝赛尔函数的参数,尤其是操作点,操作点的各种不同可以实现不同的效果,这里我简单的统一的讲操作点设置成用户触屏点的x、y的一半,呵呵偷懒了~~
       我把贝赛尔的操作点写在了逻辑logic()函数中,不断的执行,并且每次利用nextInt函数得到随机的操作点,主要为了让其曲线不断的变化从而形成一个震动的曲线运动轨迹。
       运行效果截图如下:

       这里可能由于图片是静止的,所以效果看起来不是很明显,大家可以运行源码来观察。
       下面贴出整个MySurfaceView的源码:
Java代码
    - package com.qpath;   
- import java.util.Random;   
- import android.content.Context;   
- import android.graphics.Canvas;   
- import android.graphics.Color;   
- import android.graphics.Paint;   
- import android.graphics.Paint.Style;   
- import android.graphics.Path;   
- import android.view.KeyEvent;   
- import android.view.MotionEvent;   
- import android.view.SurfaceHolder;   
- import android.view.SurfaceHolder.Callback;   
- import android.view.SurfaceView;   
-  
-  
-  
-  
-   
- public class MySurfaceView extends SurfaceView implements Callback, Runnable {   
-     private SurfaceHolder sfh;   
-     private Paint paint;   
-     private Thread th;   
-     private boolean flag;   
-     private Canvas canvas;   
-     public static int screenW, screenH;   
-       
-       
-     private int startX, startY, controlX, controlY, endX, endY;   
-       
-     private Path path;   
-       
-     private Paint paintQ;   
-       
-     private Random random;   
-      
-  
-   
-     public MySurfaceView(Context context) {   
-         super(context);   
-         sfh = this.getHolder();   
-         sfh.addCallback(this);   
-         paint = new Paint();   
-         paint.setColor(Color.WHITE);   
-         paint.setAntiAlias(true);   
-         setFocusable(true);   
-           
-           
-         path = new Path();   
-         paintQ = new Paint();   
-         paintQ.setAntiAlias(true);   
-         paintQ.setStyle(Style.STROKE);   
-         paintQ.setStrokeWidth(5);   
-         paintQ.setColor(Color.WHITE);   
-         random = new Random();   
-     }   
-      
-  
-   
-     public void surfaceCreated(SurfaceHolder holder) {   
-         screenW = this.getWidth();   
-         screenH = this.getHeight();   
-         flag = true;   
-           
-         th = new Thread(this);   
-           
-         th.start();   
-           
-     }   
-      
-  
-   
-     public void myDraw() {   
-         try {   
-             canvas = sfh.lockCanvas();   
-             if (canvas != null) {   
-                 canvas.drawColor(Color.BLACK);   
-                   
-                 drawQpath(canvas);   
-             }   
-         } catch (Exception e) {   
-               
-         } finally {   
-             if (canvas != null)   
-                 sfh.unlockCanvasAndPost(canvas);   
-         }   
-     }   
-      
-  
-  
-  
-   
-     public void drawQpath(Canvas canvas) {   
-         path.reset();  
-           
-         path.moveTo(startX, startY);   
-           
-         path.quadTo(controlX, controlY, endX, endY);   
-           
-         canvas.drawPath(path, paintQ);   
-     }   
-      
-  
-   
-     @Override  
-     public boolean onTouchEvent(MotionEvent event) {   
-         endX = (int) event.getX();   
-         endY = (int) event.getY();   
-         return true;   
-     }   
-      
-  
-   
-     private void logic() {   
-         if (endX != 0 && endY != 0) {   
-               
-             controlX = random.nextInt((endX - startX) / 2);   
-             controlY = random.nextInt((endY - startY) / 2);   
-         }   
-     }   
-      
-  
-   
-     @Override  
-     public boolean onKeyDown(int keyCode, KeyEvent event) {   
-         return super.onKeyDown(keyCode, event);   
-     }   
-     public void run() {   
-         while (flag) {   
-             long start = System.currentTimeMillis();   
-             myDraw();   
-             logic();   
-             long end = System.currentTimeMillis();   
-             try {   
-                 if (end - start < 50) {   
-                     Thread.sleep(50 - (end - start));   
-                 }   
-             } catch (InterruptedException e) {   
-                 e.printStackTrace();   
-             }   
-         }   
-     }   
-      
-  
-   
-     public void surfaceChanged(SurfaceHolder holder, int format, int width,   
-             int height) {   
-     }   
-      
-  
-   
-     public void surfaceDestroyed(SurfaceHolder holder) {   
-         flag = false;   
-     }   
- }