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

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


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

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

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

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

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

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

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

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

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

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

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

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

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


废话完毕。

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

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

1.利用了加速度传感器

2.碰撞检测

3.游戏音频


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

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

比如:

/**
	 * 1.手机站立时:x = 0,01;y = 9.8,实际方向下微微偏左(0.01,9.8), 2.手机左高右低 x = -9.8; y = 0.01

	 */
因为小球是在二维空间动,我这边没考虑z;


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

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

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

	@Override
	public void onSensorChanged(SensorEvent event) {
		//主要是为了清除爆发模式时我们人为因素增大的加速度
		accelerationX = 0;
		accelerationY = 0;
		//方法一:爆发式的,即晃动频率达到一个级别后,调用。
		
		long curTime = java.lang.System.currentTimeMillis();
		if ((curTime - lastTime) > 10) {
			long diffTime = (curTime - lastTime);
			lastTime = curTime;
			float x = event.values[0];
			float	y = event.values[1];
			float z = event.values[2];
			float speed = Math.abs(x + y + z - lastX - lastY - lastZ)
					/ diffTime * 10000;
			Log.i(TAG, "speed是:::"+speed);
			if (speed > 400d) {
				//剧烈晃动,进入疯狂模式~~~
				accelerationX = x*10;
				accelerationY = y*10;
				preTime = curTime;
				//}
			}
//			else if(speed < 50d){
//				accelerationX = 0;
//				accelerationX = 0;
//			}
//			else{//此代码是基本时刻赋予了物体一个加速度,在开启碰撞音效下慎用~~
//				accelerationX = x * 0.5f;
//				accelerationY = y *0.5f;
//			}
			lastX = x;
			lastY = y;
			lastZ = z;
		}
』

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

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

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


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

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

/**
	 * 与边界检测碰撞
	 * 
	 * @param x
	 * @param y
	 * @param w
	 * @param h
	 * @return
	 */
	public boolean isCollision(float x, float y, float w, float h) {

		if (y >= this.y || this.y + r >= h) {
//			if(Math.abs(speed.y) > 80f ){
			Log.i("LILITH", "was Collision");
			rebound(COLLISION_X);
			return true;
//			}
		} else if (this.x <= x || this.x >= w - r) {
//			if(Math.abs(speed.x) > 80f){
			Log.i("LILITH", "was Collision");
			rebound(COLLISION_Y);
			return true;
//			}
		} 
		//	Log.i("LILITH", "was Collision");
			return false;
	}

然后是碰撞后物体反弹效果,我这么只是简单做了角度反射,画下图就知道,因为我定义的小球速度是类似以向量定义的(Vx,Vy);
因为真正意义上我们不同绘制小球其实就是绘制一个(x,y)的坐标,那速度其实就是针对与在x,y上的加减咯。

/**
	 * 碰撞后反弹
	 */
	public void rebound(int tag) {

		if (tag == COLLISION_X) {
			speed.x = (speed.x * 0.9f);
			speed.y = -(speed.y * 0.9f);
		} else if (tag == COLLISION_Y) {
			speed.x = -(speed.x * 0.9f);
			speed.y = (speed.y * 0.9f);
		}
	}

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


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


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


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

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

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

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

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

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

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


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

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





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值