Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 703|回复: 0

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

[复制链接]

该用户从未签到

发表于 2011-10-25 08:54:00 | 显示全部楼层 |阅读模式
Android游戏开发之单点触摸与多点触摸的响应方式
游戏开发中的触摸事件



         在游戏开发中监听屏幕触摸事件须要在View中重写父类onTouchEvent方法,在重写的方法中拦截用户触摸屏幕的一些信息,比如触摸屏幕的X 、 Y坐标 触摸屏幕发生的事件 触摸按下  触摸抬起  触摸移动,触摸屏幕发生的时间 等等, 我们先看看onTouchEvent的函数原型。
   
    函数中的Event 参数的意思为当前触摸事件的对象,这个对象中包含着当前触摸事件的一切信息。比如ecent.getAction()可以拿到当前触摸事件的名称,根据触摸事件的名称可以判断当前是触摸按下 还是 触摸移动 还是 触摸抬起。 event.getX()与 event.getY()可以拿到当前触摸屏幕的X Y坐标。event.getEventTime(); 可以拿到当前触发触摸事件的时间,等等所有的信息。         @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;

        }
复制代码这个函数是具有有返回值的,须要返回一个布尔值。大家发现我将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的区别(五)

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;

        

        /**事件触发时间**/

        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("事件触发时间:"+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;

            }

            /**得到事件触发时间**/

            mActionTime = event.getEventTime();

            /** 通知UI线程刷新屏幕 **/

            postInvalidate();

            // return super.onTouchEvent(event);

            return true;

        }

    }

}
复制代码2.多点触摸

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




        下面我们详细的说一下代码的实现方式,多点触摸和单点触摸一样都是在onTouchEvent中去监听触摸事件。调用方法event.getPointerCount(); 可以拿到当前屏幕同时触摸点的数量 以我的手机为例因为只支持两点触摸所以在我的手机上调用该方法最多只会返回2。 拿到了触摸屏幕点的数量以后 可以使用for循环来遍历当前屏幕的所有触摸点,调用event.getX(i); 与 event.getY(i); 方法 将ID作为参数传入会得到每个点在屏幕中显示的X Y坐标值。最后根据坐标值将图片与内容绘制在手机屏幕中。 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;



        /** 控制游戏更新循环 **/

        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回调函数中 **/

            mSurfaceHolder.addCallback(this);

            /** 创建画布 **/

            mCanvas = new Canvas();

            /**创建画笔**/

            mPaint = new Paint();

            mPaint.setColor(Color.WHITE);

        }



        @Override

        public boolean onTouchEvent(MotionEvent event) {

            /** 拿到触摸的状态 **/

            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) {

                    /** 在屏幕中拿到同时触碰的点的数量 **/

                    int pointCount = event.getPointerCount();



                    

                    /** 使用循环将每个触摸点图片都绘制出来 **/

                    for (int i = 0; i < pointCount; i++) {

                        /** 根据触摸点的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("事件触发时间:"+event.getEventTime(), showX, 60, mPaint);

                    }

                }else {

                    mCanvas.drawText("请多点触摸当前手机屏幕" ,0, 20, mPaint);

                }

                /** 绘制结束后解锁显示在屏幕上 **/

                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) {



        }

    }

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

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:54:07 | 显示全部楼层

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

Android游戏开发之单点触摸与多点触摸的响应方式(二十三)
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:54:10 | 显示全部楼层

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

好东西。学习了。
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:54:16 | 显示全部楼层

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

谢谢楼主分享
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:54:19 | 显示全部楼层

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

感谢楼主发布,谢谢。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-11 14:09 , Processed in 0.378272 second(s), 33 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表