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

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

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

軟件下載 | 游戲 | 討論 | 電視計算器

綜合交流 / 評測 / 活動區(qū)

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

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

新手 | 你問我答 | 免費刷機救磚 | ROM固件

查看: 11990|回復: 0
上一主題 下一主題
[教程]

Android游戲開發(fā)之單點觸摸與多點觸摸的響應方式(二十三)

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2013-8-28 16:27 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
Android游戲開發(fā)之單點觸摸與多點觸摸的響應方式   
游戲開發(fā)中的觸摸事件   
   
     
         在游戲開發(fā)中監(jiān)聽屏幕觸摸事件須要在View中重寫父類onTouchEvent方法,在重寫的方法中攔截用戶觸摸屏幕的一些信息,比如觸摸屏幕的X 、 Y坐標 觸摸屏幕發(fā)生的事件 觸摸按下  觸摸抬起  觸摸移動,觸摸屏幕發(fā)生的時間 等等, 我們先看看onTouchEvent的函數(shù)原型。   
      
    函數(shù)中的Event 參數(shù)的意思為當前觸摸事件的對象,這個對象中包含著當前觸摸事件的一切信息。比如ecent.getAction()可以拿到當前觸摸事件的名稱,根據(jù)觸摸事件的名稱可以判斷當前是觸摸按下 還是 觸摸移動 還是 觸摸抬起。 event.getX()與 event.getY()可以拿到當前觸摸屏幕的X Y坐標。event.getEventTime(); 可以拿到當前觸發(fā)觸摸事件的時間,等等所有的信息。   
  1.         @Override   
            public boolean onTouchEvent(MotionEvent event) {   
                int action = event.getAction();   
                mPosX = (int) event.getX();   
                mPosY = (int) event.getY();   
                switch (action) {   
                // 觸摸按下的事件   
                case MotionEvent.ACTION_DOWN:   
                    Log.v("test", "ACTION_DOWN");   
                    break;   
                // 觸摸移動的事件   
                case MotionEvent.ACTION_MOVE:   
                    Log.v("test", "ACTION_MOVE");   
                    break;   
                // 觸摸抬起的事件   
                case MotionEvent.ACTION_UP:   
                    Log.v("test", "ACTION_UP");   
                    break;   
                }   
    //            return super.onTouchEvent(event);   
                return true;   
            }
復制代碼
這個函數(shù)是具有有返回值的,須要返回一個布爾值。大家發(fā)現(xiàn)我將return super.onTouchEvent(event)注釋掉了而是直接return ture。 我給同學們解釋一下為什么要著么操作。onTouchEvent方法不是我們手動調(diào)用的而是系統(tǒng)調(diào)用的 它的返回值會直接通知系統(tǒng)是否回調(diào)方法。如果說在這里return false  onTouchEvent方法永遠不會在被回調(diào)也就是說它只能響應觸摸按下操作,觸摸移動事件 和觸摸抬起事件永遠都不會在被響應 ,log只會打印出"ACTION_DOWN"。 如果這里return super.onTouchEvent(event); 調(diào)用父類的方法來得到返回值返回 ,這樣也是有問題的因為調(diào)用父類的onTouchEvent方法可能也會返回false 這樣一來依然會無法響應觸摸移動事件和觸摸抬起事件。所以為了正確的處理觸摸事件在這里我們直接return ture 這樣一來就萬無一失了,Log中會將所有信息都打印出來。   
   
   
   
1.單點觸摸   
   
        在下面這個DEMO中 用手觸摸 移動 屏幕后 下面的icon圖片會跟隨這我的手勢移動。 代碼實現(xiàn)主要是在onTouchEvent方法中時時去計算手觸摸屏幕各個狀態(tài)的坐標 然后調(diào)用 postInvalidate(); 方法去通知UI刷新屏幕重新顯示圖片 文字的位置以及內(nèi)容。 具體相關(guān)內(nèi)容見Android游戲開發(fā)之構(gòu)建游戲框架View與SurFaceView的區(qū)別(五)   
     
  1. import android.app.Activity;   
    import android.content.Context;   
    import android.graphics.Bitmap;   
    import android.graphics.BitmapFactory;   
    import android.graphics.Canvas;   
    import android.graphics.Color;   
    import android.graphics.Paint;   
    import android.os.Bundle;   
    import android.util.Log;   
    import android.view.MotionEvent;   
    import android.view.View;   
       
    public class ViewActivity extends Activity {   
        @Override   
        public void onCreate(Bundle savedInstanceState) {   
            super.onCreate(savedInstanceState);   
            setContentView(new MyView(this));   
        }   
       
        public class MyView extends View {   
       
            /** 觸摸后繪制的圖片 **/   
            Bitmap mBitmap = null;   
       
            /** 游戲畫筆 **/   
            Paint mPaint = null;   
       
            /** 觸摸后在屏幕中顯示的位置 **/   
            int mPosX = 0;   
            int mPosY = 0;   
               
            /**事件觸發(fā)時間**/   
            Long mActionTime = 0L;   
               
            public MyView(Context context) {   
                super(context);   
                /** 設置當前View擁有控制焦點 **/   
                this.setFocusable(true);   
                /** 設置當前View擁有觸摸事件 **/   
                this.setFocusableInTouchMode(true);   
                /** 加載圖片 **/   
                mBitmap = BitmapFactory.decodeResource(getResources(),   
                        R.drawable.item);   
                mPaint = new Paint();   
                mPaint.setColor(Color.WHITE);   
            }   
       
            @Override   
            protected void onDraw(Canvas canvas) {   
                /** 繪制圖片 **/   
                canvas.drawBitmap(mBitmap, mPosX, mPosY, mPaint);   
                canvas.drawText("當前X坐標:"+mPosX, 0, 20, mPaint);   
                canvas.drawText("當前Y坐標:"+mPosY, 0, 40, mPaint);   
                canvas.drawText("事件觸發(fā)時間:"+mActionTime, 0, 60, mPaint);   
                super.onDraw(canvas);   
            }   
       
            @Override   
            public boolean onTouchEvent(MotionEvent event) {   
       
                int action = event.getAction();   
                mPosX = (int) event.getX();   
                mPosY = (int) event.getY();   
                switch (action) {   
                // 觸摸按下的事件   
                case MotionEvent.ACTION_DOWN:   
                    Log.v("test", "ACTION_DOWN");   
                    break;   
                // 觸摸移動的事件   
                case MotionEvent.ACTION_MOVE:   
                    Log.v("test", "ACTION_MOVE");   
                    break;   
                // 觸摸抬起的事件   
                case MotionEvent.ACTION_UP:   
                    Log.v("test", "ACTION_UP");   
                    break;   
                }   
                /**得到事件觸發(fā)時間**/   
                mActionTime = event.getEventTime();   
                /** 通知UI線程刷新屏幕 **/   
                postInvalidate();   
                // return super.onTouchEvent(event);   
                return true;   
            }   
        }   
    }
復制代碼
2.多點觸摸   
   
            
         由于模擬器只能用鼠標點擊一個點 無法模擬多點觸摸,所以我用真機來調(diào)試多點觸摸。下面這張圖是我用豌豆莢在真機中截的圖,此時我兩只手指正在手機屏幕中觸摸移動。界面中正確的根據(jù)我的手勢來移動圖片以及顯示的內(nèi)容。這里強調(diào)一下多點觸摸并不是所有手機都支持 有些手機支持很多點有些手機可能只支持單點。就那我的手機來說只支持兩點觸摸。所以無論我用多少根手指頭在我的手機屏幕上比劃 也只會出現(xiàn)2個觸摸點,如下圖所示。   
     
   
   
        下面我們詳細的說一下代碼的實現(xiàn)方式,多點觸摸和單點觸摸一樣都是在onTouchEvent中去監(jiān)聽觸摸事件。調(diào)用方法event.getPointerCount(); 可以拿到當前屏幕同時觸摸點的數(shù)量 以我的手機為例因為只支持兩點觸摸所以在我的手機上調(diào)用該方法最多只會返回2。 拿到了觸摸屏幕點的數(shù)量以后 可以使用for循環(huán)來遍歷當前屏幕的所有觸摸點,調(diào)用event.getX(i); 與 event.getY(i); 方法 將ID作為參數(shù)傳入會得到每個點在屏幕中顯示的X Y坐標值。最后根據(jù)坐標值將圖片與內(nèi)容繪制在手機屏幕中。   
  1. import android.app.Activity;   
    import android.content.Context;   
    import android.graphics.Bitmap;   
    import android.graphics.BitmapFactory;   
    import android.graphics.Canvas;   
    import android.graphics.Color;   
    import android.graphics.Paint;   
    import android.os.Bundle;   
    import android.util.Log;   
    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 {   
       
            /** 觸摸后繪制的圖片 **/   
            Bitmap mBitmap = null;   
       
            /** 游戲畫筆 **/   
            Paint mPaint = null;   
       
            SurfaceHolder mSurfaceHolder = null;   
       
            /** 控制游戲更新循環(huán) **/   
            boolean mRunning = false;   
       
            /** 游戲畫布 **/   
            Canvas mCanvas = null;   
       
            public MyView(Context context) {   
                super(context);   
                /** 設置當前View擁有控制焦點 **/   
                this.setFocusable(true);   
                /** 設置當前View擁有觸摸事件 **/   
                this.setFocusableInTouchMode(true);   
                /** 加載圖片 **/   
                mBitmap = BitmapFactory.decodeResource(getResources(),   
                        R.drawable.item);   
                /** 拿到SurfaceHolder對象 **/   
                mSurfaceHolder = this.getHolder();   
                /** 將mSurfaceHolder添加到Callback回調(diào)函數(shù)中 **/   
                mSurfaceHolder.addCallback(this);   
                /** 創(chuàng)建畫布 **/   
                mCanvas = new Canvas();   
                /**創(chuàng)建畫筆**/   
                mPaint = new Paint();   
                mPaint.setColor(Color.WHITE);   
            }   
       
            @Override   
            public boolean onTouchEvent(MotionEvent event) {   
                /** 拿到觸摸的狀態(tài) **/   
                int action = event.getAction();   
                /** 控制當觸摸抬起時清屏 **/   
                boolean reset = false;   
                switch (action) {   
                // 觸摸按下的事件   
                case MotionEvent.ACTION_DOWN:   
                    Log.v("test", "ACTION_DOWN");   
                    break;   
                // 觸摸移動的事件   
                case MotionEvent.ACTION_MOVE:   
                    Log.v("test", "ACTION_MOVE");   
                    break;   
                // 觸摸抬起的事件   
                case MotionEvent.ACTION_UP:   
                    Log.v("test", "ACTION_UP");   
                    reset = true;   
                    break;   
                }   
       
                // 在這里加上線程安全鎖   
                synchronized (mSurfaceHolder) {   
                    /** 拿到當前畫布 然后鎖定 **/   
                    mCanvas = mSurfaceHolder.lockCanvas();   
                    /** 清屏 **/   
                    mCanvas.drawColor(Color.BLACK);   
       
                    if (!reset) {   
                        /** 在屏幕中拿到同時觸碰的點的數(shù)量 **/   
                        int pointCount = event.getPointerCount();   
       
                           
                        /** 使用循環(huán)將每個觸摸點圖片都繪制出來 **/   
                        for (int i = 0; i < pointCount; i++) {   
                            /** 根據(jù)觸摸點的ID 可以講每個觸摸點的X Y坐標拿出來 **/   
                            int x = (int) event.getX(i);   
                            int y = (int) event.getY(i);   
                            int showX = i * 150;   
                            mCanvas.drawBitmap(mBitmap, x, y, mPaint);   
                            mCanvas.drawText("當前X坐標:"+x, showX, 20, mPaint);   
                            mCanvas.drawText("當前Y坐標:"+y, showX, 40, mPaint);   
                            mCanvas.drawText("事件觸發(fā)時間:"+event.getEventTime(), showX, 60, mPaint);   
                        }   
                    }else {   
                        mCanvas.drawText("請多點觸摸當前手機屏幕" ,0, 20, mPaint);   
                    }   
                    /** 繪制結(jié)束后解鎖顯示在屏幕上 **/   
                    mSurfaceHolder.unlockCanvasAndPost(mCanvas);   
                }   
       
                // return super.onTouchEvent(event);   
                return true;   
            }   
               
            @Override   
            public void surfaceChanged(SurfaceHolder holder, int format, int width,   
                    int height) {   
       
            }   
       
            @Override   
            public void surfaceCreated(SurfaceHolder holder) {   
       
            }   
       
            @Override   
            public void surfaceDestroyed(SurfaceHolder holder) {   
       
            }   
        }   
    }
復制代碼
總體來說這章內(nèi)容還是比較簡單的,老規(guī)矩每篇文章都會附帶源代碼,最后如果你還是覺得我寫的不夠詳細 看的不夠爽 不要緊我把源代碼的下載地址貼出來 歡迎大家一起討論學習   
第十三講-單點與多點觸摸.rar(125.29 KB, 下載次數(shù): 387)[/I]2011-9-3 00:51 上傳點擊文件名   下載積分: 下載豆 -2

上一篇:Android讀取彩信附件
下一篇:Android 利用Java反射技術(shù)阻止通過按鈕關(guān)閉對話框
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

GMT+8, 2024-11-20 18:28 , Processed in 0.059599 second(s), 16 queries , Redis On.

Powered by Discuz!

監(jiān)督舉報:report#znds.com (請將#替換為@)

© 2007-2024 ZNDS.Com

快速回復 返回頂部 返回列表