Android中类似于奇虎360手机卫士中摇一摇效果实现

来源:互联网 发布:淘宝固定背景 编辑:程序博客网 时间:2024/04/29 17:46

首先 我们看下360摇一摇的那个界面


(我去,这图片大了点~~,ubuntu找不到图像编辑工具)

因为目前有个蛋疼的需求,要做过类似与这样小球晃来晃去然后跳出个结果来的东西。

说的白点,其实我这边的一个功能是,彩票趣味选球的一个需求。

基本看了下市面上都是以生肖啊,星座啊来实现一个趣味玩法。

但是我们这边设计说不能太和市面上的重样了。

觉得360这样撞击挺好玩的,就先做个这样的玩玩。

当然,以幸运选号这个重点词来说,相对来说星座和生肖这样是比较符合常理,我们这个只是说一个机选的变种,

所以我们暂时叫他为趣味选号嘛,^_^。

其实我本来想是做个类似于电视上看到那种,一个开奖池哗啦啦滚出几个球。

或者简单点是做类似与这样一个幸运打球,撞击一下分出个小球来,直到小球满足一注。

然后发现这觉逼是个比较浩大的工程,可能可以用下box2d现成的框架,但是有时间慢慢看下文档,花点时间也会死可以,

然后目前我真在火力全开学IOS阶段,其他的都有点浮云,基本希望1-2天熟悉然后搞完,毕竟这只是附带小工能。

这次产品第二个版本,老大也就分了优先级不高的,只是产品润色而非核心的东西。


废话完毕。

下面我们简单的看下360这个是怎么实现。

我大概玩了下,基本内容其实不多

1.利用了加速度传感器

2.碰撞检测

3.游戏音频


第一点,传感器这个说起来简单,但是一开始还是有点云里雾里,到底手机怎么动,x,y,z的变化是什么

这个大伙自行百度吧,但是baidu出来了,没有很好空间感,还是会迷糊的,最好的做法是改变手机运动,打印除 x,y,z的值

比如:

[html] view plaincopy
  1. /**  
  2.      * 1.手机站立时:x = 0,01;y = 9.8,实际方向下微微偏左(0.01,9.8), 2.手机左高右低 x = -9.8; y = 0.01  
  3.   
  4.      */  
因为小球是在二维空间动,我这边没考虑z;


第二点:弄明白了后,你就基本知道如何老控制小球了,但是对于看360这个摇一摇来说,

我不知道它的物体运动是如何模拟的,我这边只是比较寒碜的用了下初中级别的物理知识来冒充下,当然,会有许多bug。

因为纯粹的以加速度来提供物体速度,我反正模拟不出那种死命摇晃后,变态的小球速度。因此我这边做了点小处理

[java] view plaincopy
  1.     @Override  
  2.     public void onSensorChanged(SensorEvent event) {  
  3.         //主要是为了清除爆发模式时我们人为因素增大的加速度  
  4.         accelerationX = 0;  
  5.         accelerationY = 0;  
  6.         //方法一:爆发式的,即晃动频率达到一个级别后,调用。  
  7.           
  8.         long curTime = java.lang.System.currentTimeMillis();  
  9.         if ((curTime - lastTime) > 10) {  
  10.             long diffTime = (curTime - lastTime);  
  11.             lastTime = curTime;  
  12.             float x = event.values[0];  
  13.             float   y = event.values[1];  
  14.             float z = event.values[2];  
  15.             float speed = Math.abs(x + y + z - lastX - lastY - lastZ)  
  16.                     / diffTime * 10000;  
  17.             Log.i(TAG, "speed是:::"+speed);  
  18.             if (speed > 400d) {  
  19.                 //剧烈晃动,进入疯狂模式~~~  
  20.                 accelerationX = x*10;  
  21.                 accelerationY = y*10;  
  22.                 preTime = curTime;  
  23.                 //}  
  24.             }  
  25. //          else if(speed < 50d){  
  26. //              accelerationX = 0;  
  27. //              accelerationX = 0;  
  28. //          }  
  29. //          else{//此代码是基本时刻赋予了物体一个加速度,在开启碰撞音效下慎用~~  
  30. //              accelerationX = x * 0.5f;  
  31. //              accelerationY = y *0.5f;  
  32. //          }  
  33.             lastX = x;  
  34.             lastY = y;  
  35.             lastZ = z;  
  36.         }  
  37. 』  

因此看上面代码,我提供了两种模式,一种是爆发模式。其实就一个检测晃动速率的东西,然后赋予一个加速度我顺便 *10,目前来看,有点快~

检测的灵敏度也高了点 50d,这个反正都是慢慢格局设备自己测试获取一个最好值

正常模式下则呢没看注释掉的那段。


第三点:对于传感器和小球控制基本解决了,下面是碰撞检测。

这个其实很简单,就是一个边界检测

[java] view plaincopy
  1. /** 
  2.      * 与边界检测碰撞 
  3.      *  
  4.      * @param x 
  5.      * @param y 
  6.      * @param w 
  7.      * @param h 
  8.      * @return 
  9.      */  
  10.     public boolean isCollision(float x, float y, float w, float h) {  
  11.   
  12.         if (y >= this.y || this.y + r >= h) {  
  13. //          if(Math.abs(speed.y) > 80f ){  
  14.             Log.i("LILITH""was Collision");  
  15.             rebound(COLLISION_X);  
  16.             return true;  
  17. //          }  
  18.         } else if (this.x <= x || this.x >= w - r) {  
  19. //          if(Math.abs(speed.x) > 80f){  
  20.             Log.i("LILITH""was Collision");  
  21.             rebound(COLLISION_Y);  
  22.             return true;  
  23. //          }  
  24.         }   
  25.         //  Log.i("LILITH", "was Collision");  
  26.             return false;  
  27.     }  

然后是碰撞后物体反弹效果,我这么只是简单做了角度反射,画下图就知道,因为我定义的小球速度是类似以向量定义的(Vx,Vy);
因为真正意义上我们不同绘制小球其实就是绘制一个(x,y)的坐标,那速度其实就是针对与在x,y上的加减咯。
[java] view plaincopy
  1. /** 
  2.      * 碰撞后反弹 
  3.      */  
  4.     public void rebound(int tag) {  
  5.   
  6.         if (tag == COLLISION_X) {  
  7.             speed.x = (speed.x * 0.9f);  
  8.             speed.y = -(speed.y * 0.9f);  
  9.         } else if (tag == COLLISION_Y) {  
  10.             speed.x = -(speed.x * 0.9f);  
  11.             speed.y = (speed.y * 0.9f);  
  12.         }  
  13.     }  

小球的反弹我是这么定义了,就是一个x,或是y速度的反过来(什么,为什么不是两个都反过来?画下图你就知道了~)
然后对于能耗,我随意设置了一个 0.9,即每次碰撞,速度变为 原来的0.9;这个你设置个变量,类似与和box2d那样的动态设置。


第四点:碰撞的音频检测,这个基本没什么说的,看下代码就懂了。
主要是要处理一个bug,小球看似静止在边界了,就是一个无限撞击过程,如果你设置了撞击声音,你懂的~
但是有人会很所以然的说,判断下啊,速度为0,不算碰撞好了。
但是,别忘了。你设置了一个加速度传感器,默认会有一个地球的重力加速度。
因此我简单两种做法:如果不设置音频,没问题的。
                                       要音频的画,我这边是舍弃了时刻检测赋值一个加速度。
当然,也许还有更好的办法,大伙可以自行解决,比如神马受力啊,能量啊。。。


然后我们看下我们的效果。。其实没啥看得,因为截图它不会动~


忽略上面那个。。那是测试绘制重叠测试绘制上去的。

下面我把我混乱的代码,里面会有好几个类,几个接口什么的基本没用,这是写习惯,刚开始琢磨要写个比较庞大的项目,

(因为想顺便写个传感器小游戏),后来当你慢慢想设计一个好的模拟世界时,你会发现,怎么跟 box2d框架好像。

比如设置一个运行空间,碰撞监听,加速度啊,恢复力啊什么的。

前人设计的轮子,其实还是蛮好使的。

然后不知到为什么,我直接碰撞操作检测放在物体 go的代码里,运行后模拟有bug。

比较赶时间,又发现模拟时有bug~~


以下是打包代码,代码比较随意,不好意思。有不足处,大家可以完善下

http://download.csdn.net/detail/nono_love_lilith/4291838