首頁 收藏 QQ群
 網(wǎng)站導(dǎo)航

ZNDS智能電視網(wǎng) 推薦當(dāng)貝市場(chǎng)

TV應(yīng)用下載 / 資源分享區(qū)

軟件下載 | 游戲 | 討論 | 電視計(jì)算器

綜合交流 / 評(píng)測(cè) / 活動(dòng)區(qū)

交流區(qū) | 測(cè)硬件 | 網(wǎng)站活動(dòng) | Z幣中心

新手入門 / 進(jìn)階 / 社區(qū)互助

新手 | 你問我答 | 免費(fèi)刷機(jī)救磚 | ROM固件

查看: 11225|回復(fù): 0
上一主題 下一主題
[教程]

Android游戲開發(fā)之觸摸軌跡曲線的實(shí)現(xiàn)處理(二十四)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2013-8-28 16:27 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
Android游戲開發(fā)之觸摸軌跡曲線的實(shí)現(xiàn)處理   
     
   
   
   
        在上一章的學(xué)習(xí)中我們已經(jīng)知道如何處理游戲中的觸摸事件,這一章將向同學(xué)們介紹繪制游戲觸摸軌跡的曲線圖,在onTouchEvent方法中我們可以拿到手指在屏幕中觸摸點(diǎn) X Y時(shí)時(shí)的坐標(biāo),這章我們研究的課題就是如何把這些點(diǎn)變成一種無規(guī)則軌跡并且將這條無規(guī)則曲線顯示在屏幕中。   
   
        Android提供了一個(gè)Path類 , 顧名思義這個(gè)類可以設(shè)置曲線路徑軌跡。任何無規(guī)則的曲線實(shí)際上都是由若干條線段組成,而線段的定義為兩點(diǎn)之間最短的一條線。path類就 可以記錄這兩點(diǎn)之間的軌跡,那么若干個(gè)Path 就是我們須要繪制的無規(guī)則曲線。   
   
下面介紹一下API 中path類設(shè)置軌跡路徑的方法   
public class   
Path   
extends Object   
java.lang.Object   
        android.graphics.Path   
quadTo(float x1, float y1, float x2, float y2)   
Add a quadratic bezier from the last point, approaching control point (x1,y1), and ending at (x2,y2).   
   
解釋:   
參數(shù)1 軌跡起始點(diǎn)X坐標(biāo)   
參數(shù)2 軌跡起始點(diǎn)Y坐標(biāo)   
參數(shù)3 軌跡結(jié)束點(diǎn)X坐標(biāo)   
參數(shù)4 軌跡結(jié)束點(diǎn)Y坐標(biāo)   
所以根據(jù)這個(gè)參數(shù)就可以設(shè)置一條線段軌跡。   
   
         同學(xué)們,我們先看一張效果圖。 為了設(shè)置一條比較圓滑好看的曲線我們需要對(duì)游戲畫筆進(jìn)行一些設(shè)置。注釋已經(jīng)在代碼中寫的很清楚了,在這里我詳細(xì)說一下 設(shè)置畫筆風(fēng)格  mPaint.setStyle(Paint.Style.STROKE); 意思是設(shè)置畫筆的風(fēng)格 android 畫筆一共提供了三種風(fēng)格Paint.Style.STROKE 、Paint.Style.FILL、Paint.Style.FILL_AND_STROKE 意思分別為 空心 、實(shí)心、實(shí)心與空心 。如果不設(shè)置的話默認(rèn)為 Paint.Style.FILL,在這里必需設(shè)置成空心 因?yàn)槿绻坏┰O(shè)置成實(shí)心或者實(shí)心與空心那么畫筆會(huì)把path路徑中間包住這樣就不是曲線線段了,所以同學(xué)們注意一下這里。   
  1.             /** 創(chuàng)建曲線畫筆 **/   
                mPaint = new Paint();   
                mPaint.setColor(Color.BLACK);   
                /**設(shè)置畫筆抗鋸齒**/   
                mPaint.setAntiAlias(true);   
                /**畫筆的類型**/   
                mPaint.setStyle(Paint.Style.STROKE);   
                /**設(shè)置畫筆變?yōu)閳A滑狀**/   
                mPaint.setStrokeCap(Paint.Cap.ROUND);   
                /**設(shè)置線的寬度**/   
                mPaint.setStrokeWidth(5);
復(fù)制代碼
     
   
        在觸摸按下事件中 通過moveTo() 方法設(shè)置觸摸屏幕點(diǎn)為軌跡的起始點(diǎn),這樣在觸摸移動(dòng)事件中設(shè)置曲線的軌跡 起始點(diǎn)為上次觸摸點(diǎn) 結(jié)束點(diǎn)為本次觸摸點(diǎn)。使用quadTo方法記錄每次移動(dòng)產(chǎn)生的一個(gè)曲線線段 然后將所有的曲線線段繪制在屏幕中,如果觸摸抬起將調(diào)用reset()方法重置曲線軌跡。   
  1.         @Override   
            public boolean onTouchEvent(MotionEvent event) {   
                /** 拿到觸摸的狀態(tài) **/   
                int action = event.getAction();   
                float x = event.getX();   
                float y = event.getY();   
                switch (action) {   
                // 觸摸按下的事件   
                case MotionEvent.ACTION_DOWN:   
                    /**設(shè)置曲線軌跡起點(diǎn) X Y坐標(biāo)**/   
                    mPath.moveTo(x, y);   
                    break;   
                // 觸摸移動(dòng)的事件   
                case MotionEvent.ACTION_MOVE:   
                    /**設(shè)置曲線軌跡**/   
                    //參數(shù)1 起始點(diǎn)X坐標(biāo)   
                    //參數(shù)2 起始點(diǎn)Y坐標(biāo)   
                    //參數(shù)3 結(jié)束點(diǎn)X坐標(biāo)   
                    //參數(shù)4 結(jié)束點(diǎn)Y坐標(biāo)   
                    mPath.quadTo(mposX, mposY, x, y);   
                    break;   
                // 觸摸抬起的事件   
                case MotionEvent.ACTION_UP:   
                    /**按鍵抬起后清空路徑軌跡**/   
                    mPath.reset();   
                    break;   
                }   
               //記錄當(dāng)前觸摸X Y坐標(biāo)   
                mposX = x;   
                mposY = y;   
                return true;   
            }
復(fù)制代碼
游戲繪制中調(diào)用drawPath方法將onTouchEvent中記錄的路徑曲線繪制在屏幕當(dāng)中。   
  1.         private void Draw() {   
                /**清空畫布**/   
                mCanvas.drawColor(Color.WHITE);   
                /**繪制曲線**/   
                mCanvas.drawPath(mPath, mPaint);   
               
                /**記錄當(dāng)前觸點(diǎn)位置**/   
                mCanvas.drawText("當(dāng)前觸筆 X:" + mposX, 0, 20,mTextPaint);   
                mCanvas.drawText("當(dāng)前觸筆 Y:" + mposY, 0, 40,mTextPaint);   
            }
復(fù)制代碼
     
給出整體代碼的實(shí)現(xiàn)   
   
詳細(xì)的注釋已經(jīng)在代碼中寫出 歡迎大家閱讀   
  1. import android.app.Activity;   
    import android.content.Context;   
    import android.graphics.Canvas;   
    import android.graphics.Color;   
    import android.graphics.Paint;   
    import android.graphics.Path;   
    import android.os.Bundle;   
    import android.view.MotionEvent;   
    import android.view.SurfaceHolder;   
    import android.view.SurfaceView;   
    import android.view.Window;   
    import android.view.WindowManager;   
    import android.view.SurfaceHolder.Callback;   
       
       
    public class SurfaceViewAcitvity extends Activity {   
       
        MyView mAnimView = null;   
       
        @Override   
        public void onCreate(Bundle savedInstanceState) {   
            super.onCreate(savedInstanceState);   
            // 全屏顯示窗口   
            requestWindowFeature(Window.FEATURE_NO_TITLE);   
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);   
            // 顯示自定義的游戲View   
            mAnimView = new MyView(this);   
            setContentView(mAnimView);   
        }   
       
        public class MyView extends SurfaceView implements Callback,Runnable {   
       
             /**每50幀刷新一次屏幕**/     
            public static final int TIME_IN_FRAME = 50;   
       
            /** 游戲畫筆 **/   
            Paint mPaint = null;   
            Paint mTextPaint = null;   
            SurfaceHolder mSurfaceHolder = null;   
       
            /** 控制游戲更新循環(huán) **/   
            boolean mRunning = false;   
       
            /** 游戲畫布 **/   
            Canvas mCanvas = null;   
       
            /**控制游戲循環(huán)**/   
            boolean mIsRunning = false;   
               
            /**曲線方向**/   
            private Path mPath;   
               
            private float mposX, mposY;   
               
            public MyView(Context context) {   
                super(context);   
                /** 設(shè)置當(dāng)前View擁有控制焦點(diǎn) **/   
                this.setFocusable(true);   
                /** 設(shè)置當(dāng)前View擁有觸摸事件 **/   
                this.setFocusableInTouchMode(true);   
                /** 拿到SurfaceHolder對(duì)象 **/   
                mSurfaceHolder = this.getHolder();   
                /** 將mSurfaceHolder添加到Callback回調(diào)函數(shù)中 **/   
                mSurfaceHolder.addCallback(this);   
                /** 創(chuàng)建畫布 **/   
                mCanvas = new Canvas();   
                /** 創(chuàng)建曲線畫筆 **/   
                mPaint = new Paint();   
                mPaint.setColor(Color.BLACK);   
                /**設(shè)置畫筆抗鋸齒**/   
                mPaint.setAntiAlias(true);   
                /**畫筆的類型**/   
                mPaint.setStyle(Paint.Style.STROKE);   
                /**設(shè)置畫筆變?yōu)閳A滑狀**/   
                mPaint.setStrokeCap(Paint.Cap.ROUND);   
                /**設(shè)置線的寬度**/   
                mPaint.setStrokeWidth(5);   
                /**創(chuàng)建路徑對(duì)象**/   
                mPath = new Path();   
                /** 創(chuàng)建文字畫筆 **/   
                mTextPaint = new Paint();   
                /**設(shè)置顏色**/   
                mTextPaint.setColor(Color.BLACK);   
                /**設(shè)置文字大小**/   
                mTextPaint.setTextSize(15);   
            }   
       
            @Override   
            public boolean onTouchEvent(MotionEvent event) {   
                /** 拿到觸摸的狀態(tài) **/   
                int action = event.getAction();   
                float x = event.getX();   
                float y = event.getY();   
                switch (action) {   
                // 觸摸按下的事件   
                case MotionEvent.ACTION_DOWN:   
                    /**設(shè)置曲線軌跡起點(diǎn) X Y坐標(biāo)**/   
                    mPath.moveTo(x, y);   
                    break;   
                // 觸摸移動(dòng)的事件   
                case MotionEvent.ACTION_MOVE:   
                    /**設(shè)置曲線軌跡**/   
                    //參數(shù)1 起始點(diǎn)X坐標(biāo)   
                    //參數(shù)2 起始點(diǎn)Y坐標(biāo)   
                    //參數(shù)3 結(jié)束點(diǎn)X坐標(biāo)   
                    //參數(shù)4 結(jié)束點(diǎn)Y坐標(biāo)   
                    mPath.quadTo(mposX, mposY, x, y);   
                    break;   
                // 觸摸抬起的事件   
                case MotionEvent.ACTION_UP:   
                    /**按鍵抬起后清空路徑軌跡**/   
                    mPath.reset();   
                    break;   
                }   
               //記錄當(dāng)前觸摸X Y坐標(biāo)   
                mposX = x;   
                mposY = y;   
                return true;   
            }   
               
            private void Draw() {   
                /**清空畫布**/   
                mCanvas.drawColor(Color.WHITE);   
                /**繪制曲線**/   
                mCanvas.drawPath(mPath, mPaint);   
               
                /**記錄當(dāng)前觸點(diǎn)位置**/   
                mCanvas.drawText("當(dāng)前觸筆 X:" + mposX, 0, 20,mTextPaint);   
                mCanvas.drawText("當(dāng)前觸筆 Y:" + mposY, 0, 40,mTextPaint);   
            }   
               
            @Override   
            public void surfaceChanged(SurfaceHolder holder, int format, int width,   
                    int height) {   
       
            }   
       
            @Override   
            public void surfaceCreated(SurfaceHolder holder) {   
                /**開始游戲主循環(huán)線程**/   
                mIsRunning = true;   
                new Thread(this).start();   
            }   
       
            @Override   
            public void surfaceDestroyed(SurfaceHolder holder) {   
                mIsRunning = false;   
            }   
       
            @Override   
            public void run() {   
                while (mIsRunning) {   
       
                    /** 取得更新游戲之前的時(shí)間 **/   
                    long startTime = System.currentTimeMillis();   
       
                    /** 在這里加上線程安全鎖 **/   
                    synchronized (mSurfaceHolder) {   
                        /** 拿到當(dāng)前畫布 然后鎖定 **/   
                        mCanvas = mSurfaceHolder.lockCanvas();   
                        Draw();   
                        /** 繪制結(jié)束后解鎖顯示在屏幕上 **/   
                        mSurfaceHolder.unlockCanvasAndPost(mCanvas);   
                    }   
       
                    /** 取得更新游戲結(jié)束的時(shí)間 **/   
                    long endTime = System.currentTimeMillis();   
       
                    /** 計(jì)算出游戲一次更新的毫秒數(shù) **/   
                    int diffTime = (int) (endTime - startTime);   
       
                    /** 確保每次更新時(shí)間為50幀 **/   
                    while (diffTime <= TIME_IN_FRAME) {   
                        diffTime = (int) (System.currentTimeMillis() - startTime);   
                        /** 線程等待 **/   
                        Thread.yield();   
                    }   
       
                }   
       
            }   
        }   
    }
復(fù)制代碼
總體來說這章內(nèi)容還是比較簡(jiǎn)單的,老規(guī)矩每篇文章都會(huì)附帶源代碼,最后如果你還是覺得我寫的不夠詳細(xì) 看的不夠爽 不要緊我把源代碼的下載地址貼出來 歡迎大家一起討論學(xué)習(xí)   
第十四講觸摸軌跡曲線.rar(125.29 KB, 下載次數(shù): 619)[/I]2011-9-3 00:54 上傳點(diǎn)擊文件名   下載積分: 下載豆 -2

上一篇:Android完全退出應(yīng)用程序
下一篇:Data Storage +AMS 課件共享

本版積分規(guī)則

Archiver|新帖|標(biāo)簽|軟件|Sitemap|ZNDS智能電視網(wǎng) ( 蘇ICP備2023012627號(hào) )

網(wǎng)絡(luò)信息服務(wù)信用承諾書 | 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證:蘇B2-20221768 丨 蘇公網(wǎng)安備 32011402011373號(hào)

GMT+8, 2024-12-22 16:51 , Processed in 0.069028 second(s), 17 queries , Redis On.

Powered by Discuz!

監(jiān)督舉報(bào):report#znds.com (請(qǐng)將#替換為@)

© 2007-2024 ZNDS.Com

快速回復(fù) 返回頂部 返回列表