libgdx游戏引擎教程(九) libgdx中的用户手势识别(二)附源码

转自:http://www.apkbus.com/android-59152-1-1.html

 

本讲源代码:
edu.nju.wsj.libgdx.rar(3.57 MB, 下载次数: 155)

2012-7-15 11:54 上传
点击文件名下载附件
下载积分: 下载豆 -2



 

我们都知道,一款游戏的成功的很大一部分因素在于这个游戏能够激起用户持续玩的兴趣,并提供优异的交互体验。那么我们今天就来看一看 Libgdx作为一个出色的游戏引擎,它是怎样实现手势识别的功能的。


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

ClassGestureDetector


 

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



 

All ImplementedInterfaces:
InputProcessor

 

可以看出GestureDetector实现了InputProcessor接口,我们在上一讲中已经给大家全面介绍了InputProcessor这个接口的原理和使用方法,并实际操作了一下,将我们曾经使用的按键捕捉方法(在一个Screenrender()方法内不停调用Gdx.input.isKeyPressed() )替换成了一个回调函数:
  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接口,那么在系统接收到用户按键相应的时候系统就会自动调用这个函数,我们只要在这个函数中添加对应的处理代码就可以了,相比我们在render()函数中用代码去主动接收简单得多。



 

现在终于要进入正题了,我们尝试使用GestureDetector来对用户的手势做出相应的响应。除却自定义的手势,常见的手势有哪些呢?


我们来看看0.9.4API里面对GestureDetector.GestureListener的介绍:

1.jpg

2012-7-15 11:54 上传
下载附件(168.09 KB)



其中介绍了六个动作:
1.fliping中文的理解和划页很类似,API中告诉我们,这个函数当用户用手在屏幕上拖拽并且做出翻页动作时触发。


flipingpic.jpg

2012-7-15 11:54 上传
下载附件(7.34 KB)



2.longPressed这个很好理解,就是手指的长按动作,用户做出长按动作的时候触发。




 

3.pinch直接翻译过来的意思是收缩,其实就是一个多点触摸的手势,并且两个手指做出收缩的动作,为了解释方便,我画了一张图:


pinch.jpg

2012-7-15 11:54 上传
下载附件(8 KB)




4.tap 就是轻击了,和触摸有点类似,不过速度应该比触摸快一些


5.TouchDown也非常好理解,手指按下的一瞬间就触发,不管其后是什么其他的动作都会触发touchDown()方法,如果时间较短,在touchDown()后会触发tap()


6.zoompinch对应,也是是一个多点触摸的手势,并且两个手指做出放大的动作

zoom.jpg

2012-7-15 11:54 上传
下载附件(7.9 KB)


7.pan 和fliping比较类似,但是没有最后翻页的动作:

pan.jpg

2012-7-15 11:55 上传
下载附件(7.85 KB)



有了之前的介绍,相信大家已经大概明白了。我们实际尝试一下,代码在第八讲的基础上修改,让Progress.java实现GestureDetector.GestureListener:

  1. public class Progress implements Screen,InputProcessor,GestureListener
复制代码
并添加相应的方法, GestureDetector.GestureListener需要实现的方法有以下几个(我们这里在每一段里面添加一个Log,便于我们查看系统相应的过程)。
  1. @Override
  2. public boolean fling(float arg0, float arg1) {
  3. // TODO Auto-generated method stub
  4. Log.i("Testin-apkbus", "fling");
  5. return false;
  6. }

  7. @Override
  8. public boolean longPress(int arg0, int arg1) {
  9. // TODO Auto-generated method stub
  10. Log.i("Testin-apkbus", "longPress");
  11. return false;
  12. }

  13. @Override
  14. public boolean pan(int arg0, int arg1, int arg2, int arg3) {
  15. // TODO Auto-generated method stub
  16. Log.i("Testin-apkbus", "pan");
  17. return false;
  18. }

  19. @Override
  20. public boolean pinch(Vector2 arg0, Vector2 arg1, Vector2 arg2, Vector2 arg3) {
  21. // TODO Auto-generated method stub
  22. Log.i("Testin-apkbus", "pinch");
  23. return false;
  24. }

  25. @Override
  26. public boolean tap(int arg0, int arg1, int arg2) {
  27. // TODO Auto-generated method stub
  28. Log.i("Testin-apkbus", "tap");
  29. return false;
  30. }

  31. @Override
  32. public boolean touchDown(int arg0, int arg1, int arg2) {
  33. // TODO Auto-generated method stub
  34. Log.i("Testin-apkbus", "touchDown");
  35. return false;
  36. }

  37. @Override
  38. public boolean zoom(float arg0, float arg1) {
  39. // TODO Auto-generated method stub
  40. Log.i("Testin-apkbus", "zoom");
  41. return false;
  42. }
复制代码
最后还有一个工作一定不要忘了,我们要让系统能够监听手势动作,我们需要调用
  1. Gdx.input.setInputProcessor();
复制代码

这里还有一个问题,GestureDetector.GestureListener并不是一个InputProcessor,我们需要封装一个GestureDetector(它是一个InputProcessor)并加入系统监听列表
  1. Gdx.input.setInputProcessor(new GestureDetector(this));
复制代码
同样的,对于这里有多个对象需要捕捉用户触摸事件的情况(如Progress既实现了InputProcessor接口也实现了GestureDetecotor.Listener),我们实际中的语句如下:
  1. multiplexer.addProcessor(this);
  2. multiplexer.addProcessor(stage);
  3. multiplexer.addProcessor(new GestureDetector(this));
  4. Gdx.input.setInputProcessor(multiplexer);
复制代码
这就算是加入了手势捕捉的代码,具体的手势识别是由系统来识别的,我们只需要在识别后做处理就可以,是不是很方便?

编译一下,运行,进入游戏界面(在代码层次是Progress.java),我们用手来做出各种手势,观察输出。


8.png
2012-7-15 11:54 上传
下载附件(36.02 KB)


进入该界面后,用手做出各种手势。


我们一个个来,先做轻击Tap的动作,即速度较快的敲击一下,输出:
taplog.jpg
2012-7-15 11:54 上传
下载附件(118.33 KB)



 

我轻击的速度比较快,因此我们可以看到两条输出,一条是标记触摸下TouchDown事件,另一条就是我们的Tap事件了。



 

其次我们来看看fliping,即划动翻页的动作。



fliping.jpg

2012-7-15 11:54 上传
下载附件(168.72 KB)



我们可以看到,除了一定会有的TouchDown()动作,还有几个pan动作也被识别到了,这也是很好理解的,我们一个flip的动作时间比较长,除了动作的最后一瞬间手做出了一个翻页的动作以外,我们的手都是在屏幕上进行拖拽,也就是pan动作了,因此如果我们要识别翻页的动作,我们要人为做进一步的处理,才能去除一些干扰。


 

剩下就是zoom和pinch这一对动作了,我们再来看看这两个动作时的输出,这一次的输出比较多,大家要注意看我下面的分析了


zoomlog.jpg

2012-7-15 11:54 上传
下载附件(389.12 KB)



首先是两个ToucDown的动作,因为我们用两个手指才能做出缩放的手势。那为什么会有那么多的输出呢?想一想也能明白,我们的缩放过程是一个持续的过程,时间比较长,而且我们需要实时捕捉两个手指的位置获取它们之间的距离才能在代码中绘图并做出缩放的效果,所以系统才会不停地触发这两个事件而不是像其他动作那样只触发少数的几次。


 

其他的手势都很好处理,这里我们主要实践并演示一下缩放手势zoom和pinch的处理,这也是我们在游戏中经常用到的一个手势。


 

我们来看看这两个回调函数:
  1. boolean pinch(Vector2 initialFirstPointer, Vector2 initialSecondPointer, Vector2 firstPointer, Vector2 secondPointer)

  2. boolean zoom(float originalDistance, float currentDistance)
复制代码

其中pinch()方法中用到了一个类,Vector2,我们从名字就可以看出来,这个类代表了一个二维矢量,不过我们可以更简单的理解为Vector2就是一个点,里面有x,y两个坐标。回调函数pinch()里有四个Vector2对象,分别代表动作开始时的两个手指的位置和当前两个手指的位置

同理对于zoom()方法也是一样,回调函数里面传入了两个参数,一个是动作开始时两个手指的距离,第二个参数就是当前两个手指之间的距离。

其实我们可以看出,pinch()方法比zoom()方法更全面,因为我们在pinch()方法中得到的是点的坐标,也可以转化成zoom()中的距离。

既然pinch()zoom()成对出现,那么我们在两个函数中任意一个做处理都是可以的。接下来我们做一个简单的功能,用手指实现舞台stage上的Animal的大小的缩放。我们在AnimalActor.java中添加一个float变量power,标记缩放的倍数,初始值为1.0

  1. //标记AnimalActor的缩放倍数
  2. float power=1;
复制代码


然后我们将AnimalActordraw()函数中绘图部分的参数乘以power:

  1. public void draw(SpriteBatch arg0, float arg1) {
  2. // TODO Auto-generated method stub
  3. stateTime += Gdx.graphics.getDeltaTime();
  4. //得到下一帧
  5. currentFrame = animation.getKeyFrame(stateTime, true);
  6. //以(0,0)绘制为起点(左下角为0,0)画出动画,大小128*128
  7. arg0.draw(currentFrame,0, 0,128*power,128*power);
  8. }
复制代码


然后我们在Progress.javazoom()函数中实时修改AnimalActor的power值

  1. @Override
  2. public boolean zoom(float arg0, float arg1) {
  3. // TODO Auto-generated method stub
  4. Log.i("Testin-apkbus", "zoom");
  5. animal.power=arg1/arg0;
  6. return false;
  7. }
复制代码

运行看一下效果,我们用两个手指做一个放大的动作,看看效果吧:

zoompic.png

2012-7-15 11:54 上传
下载附件(91.34 KB)


放大的效果


pinchpic.png

2012-7-15 11:54 上传
下载附件(40 KB)



我们再将它缩小



我们借助GestureDector还可以做出更复杂的手势识别,这里只是简单地演示一下,还要大家在平时的使用中多多尝试,就能开发出优秀的手势识别的游戏,提高游戏与用户之间的交互能力。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值