首先 我们看下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