首頁(yè) 收藏 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ū)互助

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

查看: 11817|回復(fù): 0
[教程]

Android游戲開(kāi)發(fā)之單點(diǎn)觸摸與多點(diǎn)觸摸的響應(yīng)方式(二十三)

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

上一篇:Android讀取彩信附件
下一篇:Android 利用Java反射技術(shù)阻止通過(guò)按鈕關(guān)閉對(duì)話框

本版積分規(guī)則

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

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

GMT+8, 2024-10-21 11:32 , Processed in 0.063181 second(s), 13 queries , Redis On.

Powered by Discuz!

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

© 2007-2024 ZNDS.Com

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