Android游戏开发之单点触摸与多点触摸的响应方式(二十三)

Android游戏开发之单点触摸与多点触摸的响应方式
游戏开发中的触摸事件


         在游戏开发中监听屏幕触摸事件须要在View中重写父类onTouchEvent方法,在重写的方法中拦截用户触摸屏幕的一些信息,比如触摸屏幕的X 、 Y坐标 触摸屏幕发生的事件 触摸按下  触摸抬起  触摸移动,触摸屏幕发生的时间 等等, 我们先看看onTouchEvent的函数原型。
    
    函数中的Event 参数的意思为当前触摸事件的对象,这个对象中包含着当前触摸事件的一切信息。比如ecent.getAction()可以拿到当前触摸事件的名称,根据触摸事件的名称可以判断当前是触摸按下 还是 触摸移动 还是 触摸抬起。 event.getX()与 event.getY()可以拿到当前触摸屏幕的X Y坐标。event.getEventTime(); 可以拿到当前触发触摸事件的时间,等等所有的信息。
  1.         @Override
  2.         public boolean onTouchEvent(MotionEvent event) {
  3.             int action = event.getAction();
  4.             mPosX = (int) event.getX();
  5.             mPosY = (int) event.getY();
  6.             switch (action) {
  7.             // 触摸按下的事件
  8.             case MotionEvent.ACTION_DOWN:
  9.                 Log.v("test", "ACTION_DOWN");
  10.                 break;
  11.             // 触摸移动的事件
  12.             case MotionEvent.ACTION_MOVE:
  13.                 Log.v("test", "ACTION_MOVE");
  14.                 break;
  15.             // 触摸抬起的事件
  16.             case MotionEvent.ACTION_UP:
  17.                 Log.v("test", "ACTION_UP");
  18.                 break;
  19.             }
  20. //            return super.onTouchEvent(event);
  21.             return true;
  22.         }
复制代码
这个函数是具有有返回值的,须要返回一个布尔值。大家发现我将return super.onTouchEvent(event)注释掉了而是直接return ture。 我给同学们解释一下为什么要着么操作。onTouchEvent方法不是我们手动调用的而是系统调用的 它的返回值会直接通知系统是否回调方法。如果说在这里return false  onTouchEvent方法永远不会在被回调也就是说它只能响应触摸按下操作,触摸移动事件 和触摸抬起事件永远都不会在被响应 ,log只会打印出"ACTION_DOWN"。 如果这里return super.onTouchEvent(event); 调用父类的方法来得到返回值返回 ,这样也是有问题的因为调用父类的onTouchEvent方法可能也会返回false 这样一来依然会无法响应触摸移动事件和触摸抬起事件。所以为了正确的处理触摸事件在这里我们直接return ture 这样一来就万无一失了,Log中会将所有信息都打印出来。



1.单点触摸

        在下面这个DEMO中 用手触摸 移动 屏幕后 下面的icon图片会跟随这我的手势移动。 代码实现主要是在onTouchEvent方法中时时去计算手触摸屏幕各个状态的坐标 然后调用 postInvalidate(); 方法去通知UI刷新屏幕重新显示图片 文字的位置以及内容。 具体相关内容见Android游戏开发之构建游戏框架View与SurFaceView的区别(五)
  1. import android.app.Activity;
  2. import android.content.Context;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.graphics.Canvas;
  6. import android.graphics.Color;
  7. import android.graphics.Paint;
  8. import android.os.Bundle;
  9. import android.util.Log;
  10. import android.view.MotionEvent;
  11. import android.view.View;

  12. public class ViewActivity extends Activity {
  13.     @Override
  14.     public void onCreate(Bundle savedInstanceState) {
  15.         super.onCreate(savedInstanceState);
  16.         setContentView(new MyView(this));
  17.     }

  18.     public class MyView extends View {

  19.         /** 触摸后绘制的图片 **/
  20.         Bitmap mBitmap = null;

  21.         /** 游戏画笔 **/
  22.         Paint mPaint = null;

  23.         /** 触摸后在屏幕中显示的位置 **/
  24.         int mPosX = 0;
  25.         int mPosY = 0;
  26.         
  27.         /**事件触发时间**/
  28.         Long mActionTime = 0L;
  29.         
  30.         public MyView(Context context) {
  31.             super(context);
  32.             /** 设置当前View拥有控制焦点 **/
  33.             this.setFocusable(true);
  34.             /** 设置当前View拥有触摸事件 **/
  35.             this.setFocusableInTouchMode(true);
  36.             /** 加载图片 **/
  37.             mBitmap = BitmapFactory.decodeResource(getResources(),
  38.                     R.drawable.item);
  39.             mPaint = new Paint();
  40.             mPaint.setColor(Color.WHITE);
  41.         }

  42.         @Override
  43.         protected void onDraw(Canvas canvas) {
  44.             /** 绘制图片 **/
  45.             canvas.drawBitmap(mBitmap, mPosX, mPosY, mPaint);
  46.             canvas.drawText("当前X坐标:"+mPosX, 0, 20, mPaint);
  47.             canvas.drawText("当前Y坐标:"+mPosY, 0, 40, mPaint);
  48.             canvas.drawText("事件触发时间:"+mActionTime, 0, 60, mPaint);
  49.             super.onDraw(canvas);
  50.         }

  51.         @Override
  52.         public boolean onTouchEvent(MotionEvent event) {

  53.             int action = event.getAction();
  54.             mPosX = (int) event.getX();
  55.             mPosY = (int) event.getY();
  56.             switch (action) {
  57.             // 触摸按下的事件
  58.             case MotionEvent.ACTION_DOWN:
  59.                 Log.v("test", "ACTION_DOWN");
  60.                 break;
  61.             // 触摸移动的事件
  62.             case MotionEvent.ACTION_MOVE:
  63.                 Log.v("test", "ACTION_MOVE");
  64.                 break;
  65.             // 触摸抬起的事件
  66.             case MotionEvent.ACTION_UP:
  67.                 Log.v("test", "ACTION_UP");
  68.                 break;
  69.             }
  70.             /**得到事件触发时间**/
  71.             mActionTime = event.getEventTime();
  72.             /** 通知UI线程刷新屏幕 **/
  73.             postInvalidate();
  74.             // return super.onTouchEvent(event);
  75.             return true;
  76.         }
  77.     }
  78. }
复制代码
2.多点触摸

         
         由于模拟器只能用鼠标点击一个点 无法模拟多点触摸,所以我用真机来调试多点触摸。下面这张图是我用豌豆荚在真机中截的图,此时我两只手指正在手机屏幕中触摸移动。界面中正确的根据我的手势来移动图片以及显示的内容。这里强调一下多点触摸并不是所有手机都支持 有些手机支持很多点有些手机可能只支持单点。就那我的手机来说只支持两点触摸。所以无论我用多少根手指头在我的手机屏幕上比划 也只会出现2个触摸点,如下图所示。






        下面我们详细的说一下代码的实现方式,多点触摸和单点触摸一样都是在onTouchEvent中去监听触摸事件。调用方法event.getPointerCount(); 可以拿到当前屏幕同时触摸点的数量 以我的手机为例因为只支持两点触摸所以在我的手机上调用该方法最多只会返回2。 拿到了触摸屏幕点的数量以后 可以使用for循环来遍历当前屏幕的所有触摸点,调用event.getX(i); 与 event.getY(i); 方法 将ID作为参数传入会得到每个点在屏幕中显示的X Y坐标值。最后根据坐标值将图片与内容绘制在手机屏幕中。
  1. import android.app.Activity;
  2. import android.content.Context;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.graphics.Canvas;
  6. import android.graphics.Color;
  7. import android.graphics.Paint;
  8. import android.os.Bundle;
  9. import android.util.Log;
  10. import android.view.MotionEvent;
  11. import android.view.SurfaceHolder;
  12. import android.view.SurfaceView;
  13. import android.view.Window;
  14. import android.view.WindowManager;
  15. import android.view.SurfaceHolder.Callback;


  16. public class SurfaceViewAcitvity extends Activity {

  17.     MyView mAnimView = null;

  18.     @Override
  19.     public void onCreate(Bundle savedInstanceState) {
  20.         super.onCreate(savedInstanceState);
  21.         // 全屏显示窗口
  22.         requestWindowFeature(Window.FEATURE_NO_TITLE);
  23.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  24.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);
  25.         // 显示自定义的游戏View
  26.         mAnimView = new MyView(this);
  27.         setContentView(mAnimView);
  28.     }

  29.     public class MyView extends SurfaceView implements Callback {

  30.         /** 触摸后绘制的图片 **/
  31.         Bitmap mBitmap = null;

  32.         /** 游戏画笔 **/
  33.         Paint mPaint = null;

  34.         SurfaceHolder mSurfaceHolder = null;

  35.         /** 控制游戏更新循环 **/
  36.         boolean mRunning = false;

  37.         /** 游戏画布 **/
  38.         Canvas mCanvas = null;

  39.         public MyView(Context context) {
  40.             super(context);
  41.             /** 设置当前View拥有控制焦点 **/
  42.             this.setFocusable(true);
  43.             /** 设置当前View拥有触摸事件 **/
  44.             this.setFocusableInTouchMode(true);
  45.             /** 加载图片 **/
  46.             mBitmap = BitmapFactory.decodeResource(getResources(),
  47.                     R.drawable.item);
  48.             /** 拿到SurfaceHolder对象 **/
  49.             mSurfaceHolder = this.getHolder();
  50.             /** 将mSurfaceHolder添加到Callback回调函数中 **/
  51.             mSurfaceHolder.addCallback(this);
  52.             /** 创建画布 **/
  53.             mCanvas = new Canvas();
  54.             /**创建画笔**/ 
  55.             mPaint = new Paint();
  56.             mPaint.setColor(Color.WHITE);
  57.         }

  58.         @Override
  59.         public boolean onTouchEvent(MotionEvent event) {
  60.             /** 拿到触摸的状态 **/
  61.             int action = event.getAction();
  62.             /** 控制当触摸抬起时清屏 **/
  63.             boolean reset = false;
  64.             switch (action) {
  65.             // 触摸按下的事件
  66.             case MotionEvent.ACTION_DOWN:
  67.                 Log.v("test", "ACTION_DOWN");
  68.                 break;
  69.             // 触摸移动的事件
  70.             case MotionEvent.ACTION_MOVE:
  71.                 Log.v("test", "ACTION_MOVE");
  72.                 break;
  73.             // 触摸抬起的事件
  74.             case MotionEvent.ACTION_UP:
  75.                 Log.v("test", "ACTION_UP");
  76.                 reset = true;
  77.                 break;
  78.             }

  79.             // 在这里加上线程安全锁
  80.             synchronized (mSurfaceHolder) {
  81.                 /** 拿到当前画布 然后锁定 **/
  82.                 mCanvas = mSurfaceHolder.lockCanvas();
  83.                 /** 清屏 **/
  84.                 mCanvas.drawColor(Color.BLACK);

  85.                 if (!reset) {
  86.                     /** 在屏幕中拿到同时触碰的点的数量 **/
  87.                     int pointCount = event.getPointerCount();

  88.                     
  89.                     /** 使用循环将每个触摸点图片都绘制出来 **/
  90.                     for (int i = 0; i < pointCount; i++) {
  91.                         /** 根据触摸点的ID 可以讲每个触摸点的X Y坐标拿出来 **/
  92.                         int x = (int) event.getX(i);
  93.                         int y = (int) event.getY(i);
  94.                         int showX = i * 150;
  95.                         mCanvas.drawBitmap(mBitmap, x, y, mPaint);
  96.                         mCanvas.drawText("当前X坐标:"+x, showX, 20, mPaint);
  97.                         mCanvas.drawText("当前Y坐标:"+y, showX, 40, mPaint);
  98.                         mCanvas.drawText("事件触发时间:"+event.getEventTime(), showX, 60, mPaint);
  99.                     }
  100.                 }else {
  101.                     mCanvas.drawText("请多点触摸当前手机屏幕" ,0, 20, mPaint);
  102.                 }
  103.                 /** 绘制结束后解锁显示在屏幕上 **/
  104.                 mSurfaceHolder.unlockCanvasAndPost(mCanvas);
  105.             }

  106.             // return super.onTouchEvent(event);
  107.             return true;
  108.         }
  109.         
  110.         @Override
  111.         public void surfaceChanged(SurfaceHolder holder, int format, int width,
  112.                 int height) {

  113.         }

  114.         @Override
  115.         public void surfaceCreated(SurfaceHolder holder) {

  116.         }

  117.         @Override
  118.         public void surfaceDestroyed(SurfaceHolder holder) {

  119.         }
  120.     }
  121. }
复制代码
总体来说这章内容还是比较简单的,老规矩每篇文章都会附带源代码,最后如果你还是觉得我写的不够详细 看的不够爽 不要紧我把源代码的下载地址贴出来 欢迎大家一起讨论学习
 第十三讲-单点与多点触摸.rar (125.29 KB, 下载次数: 390)




        下面我们详细的说一下代码的实现方式,多点触摸和单点触摸一样都是在onTouchEvent中去监听触摸事件。调用方法event.getPointerCount(); 可以拿到当前屏幕同时触摸点的数量 以我的手机为例因为只支持两点触摸所以在我的手机上调用该方法最多只会返回2。 拿到了触摸屏幕点的数量以后 可以使用for循环来遍历当前屏幕的所有触摸点,调用event.getX(i); 与 event.getY(i); 方法 将ID作为参数传入会得到每个点在屏幕中显示的X Y坐标值。最后根据坐标值将图片与内容绘制在手机屏幕中。
  1. import android.app.Activity;
  2. import android.content.Context;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.graphics.Canvas;
  6. import android.graphics.Color;
  7. import android.graphics.Paint;
  8. import android.os.Bundle;
  9. import android.util.Log;
  10. import android.view.MotionEvent;
  11. import android.view.SurfaceHolder;
  12. import android.view.SurfaceView;
  13. import android.view.Window;
  14. import android.view.WindowManager;
  15. import android.view.SurfaceHolder.Callback;


  16. public class SurfaceViewAcitvity extends Activity {

  17.     MyView mAnimView = null;

  18.     @Override
  19.     public void onCreate(Bundle savedInstanceState) {
  20.         super.onCreate(savedInstanceState);
  21.         // 全屏显示窗口
  22.         requestWindowFeature(Window.FEATURE_NO_TITLE);
  23.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  24.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);
  25.         // 显示自定义的游戏View
  26.         mAnimView = new MyView(this);
  27.         setContentView(mAnimView);
  28.     }

  29.     public class MyView extends SurfaceView implements Callback {

  30.         /** 触摸后绘制的图片 **/
  31.         Bitmap mBitmap = null;

  32.         /** 游戏画笔 **/
  33.         Paint mPaint = null;

  34.         SurfaceHolder mSurfaceHolder = null;

  35.         /** 控制游戏更新循环 **/
  36.         boolean mRunning = false;

  37.         /** 游戏画布 **/
  38.         Canvas mCanvas = null;

  39.         public MyView(Context context) {
  40.             super(context);
  41.             /** 设置当前View拥有控制焦点 **/
  42.             this.setFocusable(true);
  43.             /** 设置当前View拥有触摸事件 **/
  44.             this.setFocusableInTouchMode(true);
  45.             /** 加载图片 **/
  46.             mBitmap = BitmapFactory.decodeResource(getResources(),
  47.                     R.drawable.item);
  48.             /** 拿到SurfaceHolder对象 **/
  49.             mSurfaceHolder = this.getHolder();
  50.             /** 将mSurfaceHolder添加到Callback回调函数中 **/
  51.             mSurfaceHolder.addCallback(this);
  52.             /** 创建画布 **/
  53.             mCanvas = new Canvas();
  54.             /**创建画笔**/ 
  55.             mPaint = new Paint();
  56.             mPaint.setColor(Color.WHITE);
  57.         }

  58.         @Override
  59.         public boolean onTouchEvent(MotionEvent event) {
  60.             /** 拿到触摸的状态 **/
  61.             int action = event.getAction();
  62.             /** 控制当触摸抬起时清屏 **/
  63.             boolean reset = false;
  64.             switch (action) {
  65.             // 触摸按下的事件
  66.             case MotionEvent.ACTION_DOWN:
  67.                 Log.v("test", "ACTION_DOWN");
  68.                 break;
  69.             // 触摸移动的事件
  70.             case MotionEvent.ACTION_MOVE:
  71.                 Log.v("test", "ACTION_MOVE");
  72.                 break;
  73.             // 触摸抬起的事件
  74.             case MotionEvent.ACTION_UP:
  75.                 Log.v("test", "ACTION_UP");
  76.                 reset = true;
  77.                 break;
  78.             }

  79.             // 在这里加上线程安全锁
  80.             synchronized (mSurfaceHolder) {
  81.                 /** 拿到当前画布 然后锁定 **/
  82.                 mCanvas = mSurfaceHolder.lockCanvas();
  83.                 /** 清屏 **/
  84.                 mCanvas.drawColor(Color.BLACK);

  85.                 if (!reset) {
  86.                     /** 在屏幕中拿到同时触碰的点的数量 **/
  87.                     int pointCount = event.getPointerCount();

  88.                     
  89.                     /** 使用循环将每个触摸点图片都绘制出来 **/
  90.                     for (int i = 0; i < pointCount; i++) {
  91.                         /** 根据触摸点的ID 可以讲每个触摸点的X Y坐标拿出来 **/
  92.                         int x = (int) event.getX(i);
  93.                         int y = (int) event.getY(i);
  94.                         int showX = i * 150;
  95.                         mCanvas.drawBitmap(mBitmap, x, y, mPaint);
  96.                         mCanvas.drawText("当前X坐标:"+x, showX, 20, mPaint);
  97.                         mCanvas.drawText("当前Y坐标:"+y, showX, 40, mPaint);
  98.                         mCanvas.drawText("事件触发时间:"+event.getEventTime(), showX, 60, mPaint);
  99.                     }
  100.                 }else {
  101.                     mCanvas.drawText("请多点触摸当前手机屏幕" ,0, 20, mPaint);
  102.                 }
  103.                 /** 绘制结束后解锁显示在屏幕上 **/
  104.                 mSurfaceHolder.unlockCanvasAndPost(mCanvas);
  105.             }

  106.             // return super.onTouchEvent(event);
  107.             return true;
  108.         }
  109.         
  110.         @Override
  111.         public void surfaceChanged(SurfaceHolder holder, int format, int width,
  112.                 int height) {

  113.         }

  114.         @Override
  115.         public void surfaceCreated(SurfaceHolder holder) {

  116.         }

  117.         @Override
  118.         public void surfaceDestroyed(SurfaceHolder holder) {

  119.         }
  120.     }
  121. }
复制代码
总体来说这章内容还是比较简单的,老规矩每篇文章都会附带源代码,最后如果你还是觉得我写的不够详细 看的不够爽 不要紧我把源代码的下载地址贴出来 欢迎大家一起讨论学习
 第十三讲-单点与多点触摸.rar (125.29 KB, 下载次数: 390)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VR(Virtual Reality)即虚拟现实,是一种可以创建和体验虚拟世界的计算机技术。它利用计算机生成一种模拟环境,是一种多源信息融合的、交互式的三维动态视景和实体行为的系统仿真,使用户沉浸到该环境中。VR技术通过模拟人的视觉、听觉、触觉等感觉器官功能,使人能够沉浸在计算机生成的虚拟境界中,并能够通过语言、手势等自然的方式与之进行实时交互,创建了一种适人化的多维信息空间。 VR技术具有以下主要特点: 沉浸感:用户感到作为主角存在于模拟环境中的真实程度。理想的模拟环境应该使用户难以分辨真假,使用户全身心地投入到计算机创建的三维虚拟环境中,该环境中的一切看上去是真的,听上去是真的,动起来是真的,甚至闻起来、尝起来等一切感觉都是真的,如同在现实世界中的感觉一样。 交互性:用户对模拟环境内物体的可操作程度和从环境得到反馈的自然程度(包括实时性)。例如,用户可以用手去直接抓取模拟环境中虚拟的物体,这时手有握着东西的感觉,并可以感觉物体的重量,视野中被抓的物体也能立刻随着手的移动而移动。 构想性:也称想象性,指用户沉浸在多维信息空间中,依靠自己的感知和认知能力获取知识,发挥主观能动性,寻求解答,形成新的概念。此概念不仅是指观念上或语言上的创意,而且可以是指对某些客观存在事物的创造性设想和安排。 VR技术可以应用于各个领域,如游戏、娱乐、教育、医疗、军事、房地产、工业仿真等。随着VR技术的不断发展,它正在改变人们的生活和工作方式,为人们带来全新的体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值