体感游戏时一种通过肢体动作变化来进行操作的新型电子游戏。Android移动体感包括体感游戏功能但不局限于游戏,而是将体感应用到大部分的应用 程序中,对PC上的普通程序也能进行体感控制。
该应用程序包含一个移动端(Android)程序和一个windows平台下的应用程序,它以Android平台的设备作为输入设备,利用手机内的传感器 采集数据,经Wi-Fi发送到PC端应用程序,有PC端程序接收并进行操作映射,遥控计算机的移动应用软件。在本项目中,只介绍Android端的开 发,PC端程序使用现成的程序。
二: 功能设计(设计流程)
介绍一下本软件整体架构、设计流程等
搭建程序框架
MainView
主界面
实现控制和通信
传感器开发
远程控制 三: UI设计 MainView主界面 点击左上方的设置按钮,进行目标主机的IP地址的设置,出现以下界面 Setting 设置界面 点击MainView主界面上的动感式按钮,跳转至动感式界面,如下图 SensingMode动感式界面 点击MainView主界面上的竞技式按钮,跳转至以下界面
四:核心代码
点击setting按钮,在进行IP地址的设置时,通过类Properties把配置信息保存到配置文件中或从配置文件中读龋
Properties properties = new Properties();//配置信息的保存或读取工具对象
try {
FileInputStream stream = context.openFileInput("configuration.cfg");// configuration.cfg配置文件
properties.load(stream);
ip = properties.getProperty("ip").toString();
language = properties.getProperty("language").toString();
} catch (Exception e) {
// 默认值
saveIp(DEFAULT_IP);// DEFAULT_IP = "172.16.145.48"
saveLanguage(DEFAULT_LANGUAGE);// DEFAULT_LANGUAGE = "chinese"
}
private boolean saveIp(String ip) {
Properties properties = new Properties();
properties.put("ip", ip);
properties.put("language", this.language);
try {
FileOutputStream stream = context.openFileOutput(
"configuration.cfg", Context.MODE_WORLD_WRITEABLE);
properties.store(stream, "");
return true;
} catch (Exception e) {
return false;
}
}
private boolean saveLanguage(String language) {
Properties properties = new Properties();
properties.put("ip", this.ip);
properties.put("language", language);
try {
FileOutputStream stream = context.openFileOutput(
"configuration.cfg", Context.MODE_WORLD_WRITEABLE);
properties.store(stream, "");
return true;
} catch (Exception e) {
return false;
}
}
在实现IP地址的设置后,通过UDP实现Android和PC端的通信,创建一个通信基类Transmission
public Transmission(String ip) throws SocketException, UnknownHostException {
ipAddress = InetAddress.getByName(ip);
socket = new DatagramSocket();
}
传感器的开发源程序:
manager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
sensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// 初始化加速度变化事件监听器
listener = new SensorEventListener() {
public void onSensorChanged(SensorEvent e) {//用于响应传感器数值变化
// 立体坐标系的加速度
int x = (int) e.values[SensorManager.DATA_X];
int y = (int) e.values[SensorManager.DATA_Y];
int z = (int) e.values[SensorManager.DATA_Z];
// 修改屏幕显示字符串
text.setText("摇摆手机,观察传感器数值变化(m/s^2)nx="
+ x + ", y=" + y + ", z=" + z);
}
public void onAccuracyChanged(Sensor s, int accuracy) {
//该函数用于传感器精度改变时执行相应的操作
}
};
遥控PPT原理
可以通过用户正面左右甩动手机,遥控PPT翻页,也可以使用音量键遥控PPT翻页。加速度传感器可以捕获x,y,z方向的加速度,那么怎样利用这些数据来 遥控PPT呢?PPT的操作有两个:向上翻页和向下翻页。需要考虑以下几点:
第一:一个挥动手势,会产生怎样的加速度数据?
第二:如何利用这些数据?
第三:如何屏蔽误操作?
在一次挥动中,手机的运动状态是:静止,加速,减速,静止。所以,在一次挥动中,产生了两个相反方向的加速度,再加上UDP数据包的传输的无序性,这加大 了开发的难度,所以,仅仅使用一个坐标轴方向的加速度作为判断依据是不够的。可以给程序添加一个约束条件:当手机屏幕朝上时,表示向下翻页,当手机屏幕朝 下时,表示向上翻页。
处理数据的源代码:
/**注册监听器*/
Private void registerListener(){
listener = new SensorEventListener() {
public void onSensorChanged(SensorEvent e) {//用于响应传感器数值变化
float x = (int) e.values[SensorManager.DATA_X];
float z = (int) e.values[SensorManager.DATA_Z];
//加速度大于15,判断手机被甩动了
if(x>15||x<-15){
//屏幕朝上:下一页 屏幕朝下:上一页
If(z>0)
NextPage();
Else
lastPage();
makeSensorDelay();//制造延时,只判断为一次操作,屏蔽多余操作
}
}
public void onAccuracyChanged(Sensor s, int accuracy) {
//该函数用于传感器精度改变时执行相应的操作
}
};
在分析得到操作信息后,接下来利用通信类PPTTransmission发送通知,控制PPT。控制PPT的代码如下:
try {
transmission = new PPTTransmission(ip);
transmission.changePage(PPTTransmission.NEXT_PAGE);
transmission.changePage(PPTTransmission.LAST_PAGE);
1
2
3
4
} catch (Exception e) {
e.printStackTrace();
showConnectFailDialog();//网络连接出现异常
}
使用音量键来控制PPT上下翻页
/** 音量键控制PPT */
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
nextPage();
return true;
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
lastPage();
return true;
}
// 其余的按钮,交给系统处理
return super.onKeyDown(keyCode, event);
}
遥控赛车实现
处理数据:赛车模式的数据处理规则相对于PPT控制来说比较复杂,为了减轻手机的运算负担,赛车遥控原理的实现在PC端实现。而Android端只要将传 感器的数据发送给PC端就可以了。获取传感器数据代码如下:
/** 为显示组件注册监听器 */
private void registerListeners() {
listener = new SensorEventListener() {
public void onAccuracyChanged(Sensor s, int accuracy) {
}
public void onSensorChanged(SensorEvent se) {
int z = (int) se.values[SensorManager.DATA_Z];
int y = (int) se.values[SensorManager.DATA_Y];
if (isIntValueChanged(z, y)) {
last_Z = z;
last_Y = y;
try {
transmission.zyChanged(z, y);
} catch (Exception e) {
e.printStackTrace();
manager.unregisterListener(listener); // 注销传感器
showConnectFailDialog();
}
}
}
发送数据:
按钮的操作消息的发送方法如下:
try {
transmission = new RacingTransmission(ip);
} catch (Exception e) {
e.printStackTrace();
showConnectFailDialog();
}
服务器设置:
Android移动体感客户端PC程序使用C#语言开发,该程序的主要功能是使用Socket接收Android端发送的数据,进而分析,处理相应 的动作。
程序分三个主要功能模块:
数据接收
数据解析
操作映射,将动作发送到系统消息队列,映射为鼠标,键盘动作
服务器运行截图:
总结:
优势在于利用移动终端设备来操作PC端,有很广泛的应用前景,本项目的缺点在于当身体处于不同姿态时在控制灵敏度方面,在后期可以设计更多的功能,让其达 到更加广泛的应用。