#Testin杯#Mkey libgdx游戏引擎教程(八)libgdx中的用户手势识别(一)附源码

75
回复
869360
查看
  [复制链接]

30

主题

350

帖子

1089

安币

Android大神

Rank: 6Rank: 6

QQ达人

发表于 2012-7-13 18:14:30 | 显示全部楼层 |阅读模式
本帖最后由 耒佲請ぁ留埗 于 2012-8-3 11:33 编辑


以下系列教程按讲课顺序排列,也是推荐阅读的顺序

第一讲:libgdx游戏引擎教程(一)性能优良的游戏引擎—libgdx http://www.apkbus.com/android-57355-1-1.html

第二讲: libgdx游戏引擎教程(二) ApplicationListener,着手第一个程序http://www.apkbus.com/android-57372-1-1.html

第三讲:libgdx游戏引擎教程()libgdx粒子系统的使用 http://www.apkbus.com/android-57456-1-1.html

外篇一:libgdx游戏引擎教程外篇(一)优美的自定义进度条(附源码) http://www.apkbus.com/android-57523-1-1.html

第四讲:libgdx游戏引擎教程(四) 游戏正式开始,资源异步加载(附源码)http://www.apkbus.com/android-57716-1-1.html

第五讲 libgdx游戏引擎教程(五)多游戏界面的实现(一)附源码 http://www.apkbus.com/android-57936-1-1.html

第六讲 libgdx游戏引擎教程(六)多游戏界面的实现(二)附源码 http://www.apkbus.com/android-57991-1-1.html  

第七讲 libgdx游戏引擎教程(七) 在libgdx中拦截Android按键事件 http://www.apkbus.com/android-58030-1-1.html  

外篇二: libgdx游戏引擎教程外篇(二)libgdx移植俄罗斯方块(附源码) http://www.apkbus.com/android-58102-1-1.html   

实战一:libgdx游戏引擎教程实战篇(一)移植俄罗斯方块(附源码) http://www.apkbus.com/android-58404-1-1.html  

实战二:libgdx游戏引擎教程实战篇(二)移植俄罗斯方块(附源码) http://www.apkbus.com/android-58408-1-1.html  

实战三:libgdx游戏引擎教程实战篇(三)移植俄罗斯方块(附源码) http://www.apkbus.com/android-58414-1-1.html  

实战四:libgdx游戏引擎教程实战篇(四)移植俄罗斯方块(附源码) http://www.apkbus.com/android-58418-1-1.html  

实战五:libgdx游戏引擎教程实战篇(五)移植俄罗斯方块(附源码) http://www.apkbus.com/android-58419-1-1.html

实战六:libgdx游戏引擎教程实战篇(六)移植俄罗斯方块(附源码) http://www.apkbus.com/android-58760-1-1.html

第八讲 libgdx游戏引擎教程(八) libgdx中的用户手势识别(一)附源码 http://www.apkbus.com/android-58933-1-1.html

第九讲 libgdx游戏引擎教程(九) libgdx中的用户手势识别(二)附源码 http://www.apkbus.com/android-59152-1-1.html

外篇三: libgdx游戏引擎教程外篇(三) 优美的自定义对话框(附源码) http://www.apkbus.com/android-59654-1-1.html  

第十讲:  libgdx游戏引擎教程(十)演员类的复杂动画(一)(附源码) http://www.apkbus.com/android-59998-1-2.html

第十一讲:libgdx游戏引擎教程(十一)演员类的复杂动画(二)(附源码) http://www.apkbus.com/android-60053-1-1.html

第十二讲:libgdx游戏引擎教程(十二)演员类的复杂动画(三)(附源码) http://www.apkbus.com/android-60194-1-1.html   

第十三讲: libgdx游戏引擎教程(十三)演员类的用户交互功能详解(附源码)  http://www.apkbus.com/android-60457-1-1.html

第十四讲:libgdx游戏引擎教程(十四)libgdx中常用的控件(附源码) http://www.apkbus.com/android-60569-1-1.html

最新更新 第十五讲 :libgdx游戏引擎教程(十五)在Libgdx中仿微信帮助滑动效果(附源码) http://www.apkbus.com/android-60822-1-1.html


我们在第七讲的基础上做修改,第七讲源代码:



本讲源代码下载:


        按理今天应该是实战篇的第七讲,但是我昨天无意中想起了一个很有意思的东西,就是libgdx中的手势检测。游戏成功的很大一部分因素在于这个游戏能够激起用户持续玩的兴趣,并提供优异的交互体验。那么我们今天就来看一看Libgdx作为一个出色的游戏引擎,它是怎样实现手势识别的功能的。

Libgdx中提供了一个手势检测的类:GestureDetector
ClassGestureDetector

java.lang.Object
  |com.badlogic.gdx.InputAdapter
      |com.badlogic.gdx.input.GestureDetector

All ImplementedInterfaces:
InputProcessor


   可以看出GestureDetector实现了InputProcessor接口,为了更好地让大家理解其中的原理,这里我们先用一讲的篇幅首先介绍一下InputProcessor这个类,其实这个类我们一点也不陌生,只是在以往的教程中我并没有直接提出来罢了。先卖个关子,大家往下看就明白了。

看一下官方文档中InputProcessor的说明:

InterfaceInputProcessor

All KnownImplementing Classes:
GestureDetector, InputAdapter, InputMultiplexer, RemoteSender, Stage


在这部分下面还有一句话:

“AnInputProcessor is used to receive input events from the keyboard and the touchscreen (mouse on the desktop). For this it has to be registered with the Input.setInputProcessor(InputProcessor) method. It will be called each frame before thecall to ApplicationListener.render(). The methods return a boolean in case you want to write amultiplexing InputProcessor that has a chain of child processors that signalwhether they processed the event. The InputMultiplexer offers you exactly this functionality.”

     简单地说,InputProcessor就是用来接收用户的键盘和屏幕的输入事件的,我们在使用InputProcessor之前,换句话就是我们要让系统自动接收用户的键盘和屏幕的输入事件并让其做出相应响应的话,我们必须要调用
  1. Gdx.input.setInputProcessor(InputProcessor);
复制代码
这一语句。还记得我们在libgdx中添加舞台stage,并让舞台中的控件,如按钮能够接收触摸事件的时候我们是怎么做的吗?我们在Screen的show()函数中添加了以下语句
  1. Gdx.input.setInputProcessor(stage);
复制代码
我们再看看上面给出的InputProcessor的介绍:


All KnownImplementing Classes:
GestureDetector, InputAdapter, InputMultiplexer, RemoteSender, Stage


这两句话告诉大家,
GestureDetector,InputAdapter,InputMultiplexer,RemoteSender,Stage
都直接实现了InputProcessor接口。


  这样大家就明白了吧?根据java的多态原则,舞台类Stage实现了InputProcessor接口,就可以把它看作InputProcessor实例,那么传入stage的引用就可以让stage接收用户触摸事件了。
  1. Gdx.input.setInputProcessor(InputProcessor);
复制代码

那如果我们要让多个实现了InputProcessor的实例都接收用户的键盘和屏幕的输入事件该怎么办呢?很显然
  1. Gdx.input.setInputProcessor(InputProcessor);
复制代码
    只将某一个实现了InputProcessor接口的实例传入,这样只有这一个实例可以接收用户的键盘和屏幕触摸事件,但我们有时候需要多个实例都同时接收到这些事件,比如我们有一个Screen(相信这个对于一直看我的教程的童鞋们应该不陌生吧),再之这个Screen里面有一个stage,两个都需要接收手势事件怎么办呢?我们首先可以让这个Screen实现InputProcessor接口,这样这个Screen就可以接收用户触摸和按键事件了,然后这里Libgdx提供了另外一个类:InputMutiPlexer,使用方法如下:
  1. InputMultiplexer multiplexer = new InputMultiplexer();
  2.         multiplexer.addProcessor(new InputProcessor1());
  3.         multiplexer.addProcessor(new InputProcessor2());
  4.         Gdx.input.setInputProcessor(multiplexer);
复制代码
      

     其中InputProcessor1,InputProcessor2是两个分别实现了InputProcessor的类,相信从上面的语句大家应该明白怎么做了,这里就不再赘述。



   其中我们第七讲中介绍了一种拦截按键事件的方法,就是在Screen的render()函数中不断调用Gdx.input.isKeyPressed()来判断按键事件,这个方法不是回调方法,因此从某种程度上来说是我们人为地接收了这个事件,这样比较麻烦,不够简便。这里我们将用InputProcessor拦截按钮事件,更重要的是,InputProcessor中的相应函数是回调函数,因此它会自动对按键和触摸事件做出相应,对我们开发者而言真是省心多了。这一讲的代码我们将第七讲中的代码做修改,改用InputProcessor来拦截按键事件。

我们打开第七讲结束后的工程。



修改Progress.java,让Progress实现Screen,InputProcessor两个接口
  1. public class Progress implements Screen,InputProcessor
复制代码
这里我们还可以做一个工作,添加一条语句
  1. Gdx.input.setCatchBackKey(true);
复制代码
     在官方网站上的wiki中我们可以看到对这段语句的解释:“You will still receive key events if you have registered an InputProcessor, but the operating system will not close your application.”
也就是说,这条语句添加之后,Android系统就不会拦截到Back键按下的事件了,按下BackActivity也就不会退出了

  还记得在第七讲中我是怎么实现同样的功能的吗?我重写了LibgdxActivity.java中的OnBackPressed(),使得Android系统本身不能接收到Back事件,那么在用了这个语句以后,我们就不用再重写OnBackPressed()了,为了证明这条语句的作用,我们将LibgdxActivity.java中的OnBackPressed()方法恢复成它本来的样子:
  1. @Override
  2.         public void onBackPressed() {
  3.                 // TODO Auto-generated method stub
  4.                 super.onBackPressed();
  5.         }
复制代码
我们再在MyGame.javashow()函数中添加
  1. Gdx.input.setCatchBackKey(true);
复制代码
这一语句,保证在程序画面一显示的时候(因为程序默认启动界面就是一个MyGame,按下该界面上的按钮后才跳转到Progress就使得Android系统本身不能接收到Back事件


我们再修改Progress.java,把render()函数中的Back事件检测的代码删去,并将Back事件处理的代码放在Progress.javaOnKeyDown()函数内
  1. @Override
  2.         public boolean keyDown(int arg0) {
  3.                 // TODO Auto-generated method stub
  4. //这里还要检测一下按键的类型
  5.                 if(arg0==Input.Keys.BACK){
  6.                         System.out.println("Back Pressed");
  7.                         activity.ag.setScreen(activity.mg);
  8.                         stage.removeActor(animal);
  9.                 }
  10.                 return false;
  11.         }
复制代码
当然还有一个非常非常非常重要的工作我们要做!!就是将实现了InputProcessor接口的Progress.java也调用Gdx.input.setInputProcessor语句,让Progress也能监听用户的触摸的按键事件,在Progress.javashow()函数末尾修改,修改前的代码是这样的:


  1. Gdx.input.setInputProcessor(stage);
复制代码
我们修改成这样:
  1. InputMultiplexer multiplexer = new InputMultiplexer();
  2. multiplexer.addProcessor(this);
  3. multiplexer.addProcessor(stage);
  4. Gdx.input.setInputProcessor(multiplexer);
复制代码
即让两者都能接收用户触摸和按键事件。


这就算修改完成了,运行一下看看效果:



这个时候我们按下Back按钮,没有反映,程序不会退出,说明
  1. Gdx.input.setCatchBackKey(true);
复制代码
这一语句确实拦截了Back按钮事件。这里说一句题外话,libgdx也可以用同样的方法拦截Menu按下的事件,方法极其类似:

  1. Gdx.input.setCatchMenuKey(true);
复制代码
然后我们点击按钮进入游戏页面:




  再按下Back键,游戏界面退出,回到主页面,说明我们的代码是有效的。

    这样我们这一讲对InputProcessor这个Libgdx中非常重要的事件监听接口有了一个大概的介绍,更多的东西还是希望大家能在libgdx的实际开发中自己摸索自己总结,这样才能有长足的进步。下一讲我们将正式进入libgdx的GestureDetector,也就是用户手势检测部分的内容。



Testin ID:ilovemkey@gmail.com 总的而言这个平台真的非常好用!我正是用这个平台发现了现在写的这个应用的一些内存管理方面的问题。另外建议能够在测试报告中看到某一台机型在整个执行过程中的cpu和内存占用的变化情况,这样可以更快地锁定问题。感谢Itestin让测试变得轻松了太多太多!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
君见一叶舟,出没风波里

0

主题

46

帖子

171

安币

程序猿

Rank: 2

发表于 2012-7-14 11:56:32 | 显示全部楼层
作者好像讲评书,一到关键时刻就下次再讲

30

主题

350

帖子

1089

安币

Android大神

Rank: 6Rank: 6

QQ达人

 楼主| 发表于 2012-7-14 12:28:02 | 显示全部楼层
大窝瓜 发表于 2012-7-14 11:56
作者好像讲评书,一到关键时刻就下次再讲

实在抱歉啊...因为每一将看起来很短,其实要用很多时间准备,前前后后五六个小时,所以一天的时间就业能写一篇
君见一叶舟,出没风波里

0

主题

46

帖子

171

安币

程序猿

Rank: 2

发表于 2012-7-14 13:34:46 | 显示全部楼层
哈哈,我是开玩笑的,我学习消化这些知识也要时间,这样看着更过瘾,支持作者

30

主题

350

帖子

1089

安币

Android大神

Rank: 6Rank: 6

QQ达人

 楼主| 发表于 2012-7-14 13:36:46 | 显示全部楼层
大窝瓜 发表于 2012-7-14 13:34
哈哈,我是开玩笑的,我学习消化这些知识也要时间,这样看着更过瘾,支持作者 ...

有没有遇见什么问题?
君见一叶舟,出没风波里

0

主题

46

帖子

171

安币

程序猿

Rank: 2

发表于 2012-7-16 08:15:08 | 显示全部楼层
老师讲的不错,感觉受益匪浅,目前还没什么问题呢

0

主题

13

帖子

22

安币

初级码农

Rank: 1

发表于 2012-7-17 14:45:23 | 显示全部楼层
耒佲請ぁ留埗 发表于 2012-7-14 13:36
有没有遇见什么问题?

老师 您好,如果我想实现actor的拖动  怎么实现?

我好像找不到actor移动时候的坐标  谢谢

30

主题

350

帖子

1089

安币

Android大神

Rank: 6Rank: 6

QQ达人

 楼主| 发表于 2012-7-17 14:52:41 | 显示全部楼层
stefchang 发表于 2012-7-17 14:45
老师 您好,如果我想实现actor的拖动  怎么实现?

我好像找不到actor移动时候的坐标  谢谢 ...

为什么取不到坐标?里面不是有x,y两个参数可以直接拿出来用吗?
君见一叶舟,出没风波里
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )