【Android遊戲開發二十五】在Android上的使用《貝賽爾曲線》!

來源:互聯網
上載者:User


 李華明Himi 原創,轉載務必在明顯處註明:
轉載自【黑米GameDev街區】 原文連結: http://www.himigame.com/android-game/386.html

 

 

很多童鞋說My Code運行後,點擊home或者back後會程式異常,如果你也這樣遇到過,那麼你肯定沒有仔細讀完Himi的博文,第十九篇Himi專門寫了關於這些錯誤的原因和解決方案,這裡我在部落格都補充說明下,省的童鞋們總疑惑這一塊;請點擊下面聯絡進入閱讀:

【Android遊戲開發十九】(必看篇)SurfaceView運行機制詳解—剖析Back與Home按鍵及切入後台等異常處理!

 

   首先對於《賽貝爾曲線》不是很瞭解的童鞋,請自覺白度百科、google等等...

 

為了方便偷懶的童鞋,這裡給個《貝賽爾曲線》百科地址,以及一段話簡述《貝賽爾曲線》:

《貝賽爾曲線》白度百科快速地址:http://baike.baidu.com/view/4019466.htm

貝茲路徑又稱貝茲曲線或貝濟埃曲線,一般的向量圖形軟體通過它來精確畫出曲線,貝茲曲線由線段與節點群組成,節點是可拖動的支點,線段像可伸縮的皮筋;


上面這一段話其實就“線段像可伸縮的皮筋”這一句比較重要,也很容易理解;

 

        至於貝賽爾曲線的實現,在Android中極其的簡單,因為它是Android封裝的一個方法,這個能不簡單麼。。。。。。只不過它隱藏的比較深,它隱藏於Path類中,方法如下:

android.graphics.Path.quadTo(float x1, float y1, float x2, float y2)

Since: API Level 1

此方參數解釋:

第一個參數:操作點的x座標

第二個參數:操作點的y座標

第三個參數:結束點的x座標

第四個參數:結束點的y座標

從API中看出,賽貝爾曲線從API-1就開始支援了;

 

熟悉方法後,下面就來實現:

SurfaceView架構不多講,看過我部落格的都應該知道的;

 

直接看MySurfaceView類,此類繼承SurfaceView ,是遊戲的主視圖

 

這裡為了更清晰的講解:這裡部分代碼先不貼出來了,最後會整體貼出,當然源碼也是免費在最後提供~

首先是定義相關的成員變數:

// 貝賽爾曲線成員變數(起始點,控制(操作點),終止點,3點座標)<br />private int startX, startY, controlX, controlY, endX, endY;<br />// Path<br />private Path path;<br />// 為了不影響主畫筆,這裡繪製貝賽爾曲線單獨用一個新畫筆<br />private Paint paintQ;<br />// 隨機庫(讓貝賽爾曲線更明顯)<br />private Random random; 

本類建構函式:

/**<br /> * SurfaceView初始化函數<br /> */<br />public MySurfaceView(Context context) {<br />super(context);<br />...<br />//貝賽爾曲線相關初始化<br />path = new Path();<br />paintQ = new Paint();<br />paintQ.setAntiAlias(true);<br />paintQ.setStyle(Style.STROKE);<br />paintQ.setStrokeWidth(5);<br />paintQ.setColor(Color.WHITE);<br />random = new Random();<br />...<br />} 

  接著我把繪製貝賽爾曲線封裝一個方法了,函數如下:

/**<br /> * 繪製貝賽爾曲線<br /> *<br /> * @param canvas 主畫布<br /> */<br />public void drawQpath(Canvas canvas) {<br />path.reset();// 重設path<br />// 貝賽爾曲線的起始點<br />path.moveTo(startX, startY);<br />// 設定貝賽爾曲線的操作點以及終止點<br />path.quadTo(controlX, controlY, endX, endY);<br />// 繪製貝賽爾曲線(Path)<br />canvas.drawPath(path, paintQ);<br />} 

最後是使用者觸屏監聽函數以及邏輯函數:

/**<br /> * 觸屏事件監聽<br /> */<br />@Override<br />public boolean onTouchEvent(MotionEvent event) {<br />endX = (int) event.getX();<br />endY = (int) event.getY();<br />return true;<br />}<br />/**<br /> * 遊戲邏輯<br /> */<br />private void logic() {<br />if (endX != 0 && endY != 0) {<br />// 設定作業點為線段x/y的一半<br />controlX = random.nextInt((endX - startX) / 2);<br />controlY = random.nextInt((endY - startY) / 2);<br />}<br />} 

 

 

整個代碼很easy~主要是貝賽爾函數的參數,尤其是操作點,操作點的各種不同可以實現不同的效果,這裡我簡單的統一的講操作點設定成使用者觸屏點的x,y的一半,呵呵偷懶了~嘻嘻~

我把貝賽爾的操作點寫在了邏輯logic()函數中,不斷的執行,並且每次利用nextInt函數得到隨機的操作點,主要為了讓其曲線不斷的變化從而形成一個震動的曲線運動軌跡;

 

ok,效果接圖如下:

 

 

 

 

     這裡可能由於圖片是靜止的效果看起來不是很明顯,大家可以運行源碼來觀察 ,好了~本節就這樣吧;下面貼出整個MySurfaceView的源碼:(最後有本項目的源碼)

package com.qpath;<br />import java.util.Random;<br />import android.content.Context;<br />import android.graphics.Canvas;<br />import android.graphics.Color;<br />import android.graphics.Paint;<br />import android.graphics.Paint.Style;<br />import android.graphics.Path;<br />import android.view.KeyEvent;<br />import android.view.MotionEvent;<br />import android.view.SurfaceHolder;<br />import android.view.SurfaceHolder.Callback;<br />import android.view.SurfaceView;<br />/**<br /> * 賽貝爾曲線<br /> * @author Himi<br /> *<br /> */<br />public class MySurfaceView extends SurfaceView implements Callback, Runnable {<br />private SurfaceHolder sfh;<br />private Paint paint;<br />private Thread th;<br />private boolean flag;<br />private Canvas canvas;<br />public static int screenW, screenH;<br />// -----------以上是SurfaceView遊戲架構<br />// 貝賽爾曲線成員變數(起始點,控制(操作點),終止點,3點座標)<br />private int startX, startY, controlX, controlY, endX, endY;<br />// Path<br />private Path path;<br />// 為了不影響主畫筆,這裡繪製貝賽爾曲線單獨用一個新畫筆<br />private Paint paintQ;<br />// 隨機庫(讓貝賽爾曲線更明顯)<br />private Random random;<br />/**<br /> * SurfaceView初始化函數<br /> */<br />public MySurfaceView(Context context) {<br />super(context);<br />sfh = this.getHolder();<br />sfh.addCallback(this);<br />paint = new Paint();<br />paint.setColor(Color.WHITE);<br />paint.setAntiAlias(true);<br />setFocusable(true);<br />// -----------以上是SurfaceView遊戲架構<br />//貝賽爾曲線相關初始化<br />path = new Path();<br />paintQ = new Paint();<br />paintQ.setAntiAlias(true);<br />paintQ.setStyle(Style.STROKE);<br />paintQ.setStrokeWidth(5);<br />paintQ.setColor(Color.WHITE);<br />random = new Random();<br />}<br />/**<br /> * SurfaceView視圖建立,響應此函數<br /> */<br />public void surfaceCreated(SurfaceHolder holder) {<br />screenW = this.getWidth();<br />screenH = this.getHeight();<br />flag = true;<br />// 執行個體線程<br />th = new Thread(this);<br />// 啟動線程<br />th.start();<br />// -----------以上是SurfaceView遊戲架構<br />}<br />/**<br /> * 遊戲繪圖<br /> */<br />public void myDraw() {<br />try {<br />canvas = sfh.lockCanvas();<br />if (canvas != null) {<br />canvas.drawColor(Color.BLACK);<br />// -----------以上是SurfaceView遊戲架構<br />drawQpath(canvas);<br />}<br />} catch (Exception e) {<br />// TODO: handle exception<br />} finally {<br />if (canvas != null)<br />sfh.unlockCanvasAndPost(canvas);<br />}<br />}<br />/**<br /> * 繪製貝賽爾曲線<br /> *<br /> * @param canvas 主畫布<br /> */<br />public void drawQpath(Canvas canvas) {<br />path.reset();// 重設path<br />// 貝賽爾曲線的起始點<br />path.moveTo(startX, startY);<br />// 設定貝賽爾曲線的操作點以及終止點<br />path.quadTo(controlX, controlY, endX, endY);<br />// 繪製貝賽爾曲線(Path)<br />canvas.drawPath(path, paintQ);<br />}<br />/**<br /> * 觸屏事件監聽<br /> */<br />@Override<br />public boolean onTouchEvent(MotionEvent event) {<br />endX = (int) event.getX();<br />endY = (int) event.getY();<br />return true;<br />}<br />/**<br /> * 遊戲邏輯<br /> */<br />private void logic() {<br />if (endX != 0 && endY != 0) {<br />// 設定作業點為線段x/y的一半<br />controlX = random.nextInt((endX - startX) / 2);<br />controlY = random.nextInt((endY - startY) / 2);<br />}<br />}<br />/**<br /> * 按鍵事件監聽<br /> */<br />@Override<br />public boolean onKeyDown(int keyCode, KeyEvent event) {<br />return super.onKeyDown(keyCode, event);<br />}<br />public void run() {<br />while (flag) {<br />long start = System.currentTimeMillis();<br />myDraw();<br />logic();<br />long end = System.currentTimeMillis();<br />try {<br />if (end - start < 50) {<br />Thread.sleep(50 - (end - start));<br />}<br />} catch (InterruptedException e) {<br />e.printStackTrace();<br />}<br />}<br />}<br />/**<br /> * SurfaceView檢視狀態發生改變,響應此函數<br /> */<br />public void surfaceChanged(SurfaceHolder holder, int format, int width,<br />int height) {<br />}<br />/**<br /> * SurfaceView視圖消亡時,響應此函數<br /> */<br />public void surfaceDestroyed(SurfaceHolder holder) {<br />flag = false;<br />}<br />}<br /> 

 

 本章源碼: http://www.himigame.com/android-game/386.html

 

 

.

 

.

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.