随着我国经济飞速发展, 人们的生活方式发生明显的变化. 体力活动减少, 高脂、高蛋白饮食, 环境污染, 使得人们身体的亚健康状态显得日益突出. 健身逐渐成为人们日常生活中必需的内容, 然而绝大多数城市人蜗居在高楼大厦的狭小的空间里, 想得到理想的户外活动空间比较困难, 加之空气污染和交通拥堵, 户外健身并非健康、安全, 在室内进行健身是一个经济的选择. 电子游戏作为一种现代娱乐方式已经深入人们生活, 传统的电子游戏用的键盘、鼠标、游戏手柄、手触屏作为输入设备, 控制游戏的进程, 玩家玩久了就会出现因久坐、姿势不当而产生的疾病(如颈椎病、腰椎间盘突出等). 一些把模拟器和健身器材与计算机结合而设计出来的电子游戏相继出现, 如跳舞毯、跑步机[1]、动感单车游戏[2]等, 还有近年来十分流行体感游戏, 如任天堂的Wii、索尼的PlayStation Move、微软的kinect[3]. 还有用kinect与跑步机相结合设计的游戏系统[4]. 以各种运动器材和体感设备作为计算机的输入设备, 设计出的电子游戏能克服上述弊病, 它们集健身和娱乐为一身, 符合现代人健身要求, 必将成为电子游戏发展的趋势. 踏步机是近年来较为流行的运动器械, 它结构小巧且造价低廉, 以它为游戏输入设备设计一款电子游戏将其运用到家庭健身具有重大现实意义和市场价值.
1 踏步机游戏的硬件设计方案 1.1 总体设计原理本文所设计的适用于踏步机电子游戏系统有三个部分组成: 踏步机、传感装置、计算机(如图1所示). 踏步机(7)供玩家按游戏要求完成踏步动作; 传感装置(2)由两个霍尔传感器、MAX232串口芯片和STC89C52单片机组成, 用来感应玩家踏步动作并计算左、右步频, 然后将左、右步频数据传给计算机(1); 计算机负责游戏软件的运行和显示. 霍尔传感器(5、6)安放在踏步机踏板的下方, 感应磁片放在踏板的外侧边, 当玩家踏下脚踏板时外侧边的磁片经过霍尔传感器, 传感器产生低电平信号, 霍尔传感器的信号线连接在STC89C52单片机数据端口. 单片机接收信号并计算步频, 步频即每分钟踏步的次数, 以右脚为例, 当右脚踏下时, 右踏板经过右侧传感器, 由单片机记下此时刻, 记为t1, 当右脚再次踏下时, 右踏板经过传感器, 再由单片机记下第二次时刻, 记为t2, 这样可由单片机计算右步频(R), R=60/(t2-t1), 即每分钟踏步多少次. 单片机的数据输出端口连接串口数据传输芯片MAX232, 并将步频数据送至MAX232, MAX232再将步频数据传到与计算机. 计算机接收到左右步频, 即可计算步频差, 利用步频和步频差来设计游戏软件, 让它们来驱动游戏主角运动. 具体方案是: 左、右步频的平均值可用来决定游戏主角的移动速度; 步频差(左步频减去右步频的数值)在预设正负阈值范围内时, 游戏主角运动方向不变; 如果步频差大于正阈值, 使游戏主角向左拐; 如果步频差小于负阈值, 使游戏主角向右拐; 步频差阈值可根据情况自主设定. 有这三种方向就可使得游戏主角实现在游戏中左、右、前、后运动, 向后运动可使用连续左拐或者右拐.
1.2 传感装置的设计方案与实现
本文的传感器装置主要由下列元件组成: 霍尔传感器为乐清市墨尔电气有限公司产品, M8系列NJK5001C. 单片机为STC89C52, STC公司产品, 属于MCS-51系列. 串口芯片MAX232为德州仪器公司生产. 根据总体设计方案和芯片说明书连接各芯片管脚, 用PROTEL99绘制PCB电路图, 如图2. (1) 霍尔传感器信号线输入, 霍尔传感器为NPN常闭型, 有3条外接线, VCC、OUT、GND. VCC接5 V电源, GND接地, VCC与OUT(信号输出线)之间接1 KΩ电阻, 两个OUT线分别接在单片机P2.1和P2.0端口上. (2) STC89C52单片机, 使其在最小系统下运行, VCC接入+5 V电源, GND接地, 18、19管脚接11.0592 M晶振, 晶振两端分别接两个30pF电容. (3) MAX232; (4) 串口(DB9). 关于单片机与MAX232的连接, MAX232的T1IN(11脚)接单片机串行发送端TXD(P3.1, 11脚), MAX232的R1OUT(12脚)接单片机串行接收端RXD(P3.0, 10脚). MAX232的T1OUT(14脚)接DB9的3脚. MAX232的R1IN(13脚)接DB9的2脚.
1.3 传感装置的程序编写
根据游戏的总体设计方案和单片机所起的作用, 即计算左右步频并发送步频数据, 单片机程序应有3个功能, 初始化单片机的设置、计算步频、发送数据. 初始化函数完成单片机的设置, 主要包括两个定时器的设置, 一个用于计时, 在timer0函数实现, 另一个用于设置波特率, 在initial函数实现. 计算步频函数包括计算步频和发送步频数据两个功能, 流程图如图3所示. 本文使用Keil Version3软件, 用C语言编写单片机程序[5].
void timer0() interrupt 1 //定时器50 ms, 11.0592 M晶振
{
//(65536-45872)/256 求模, 装入定时器TH0
TH0=76;
//(65536-45872)%256 求余, 装入定时器TL0
TL0=208;
num++;
//定时器中断一次为50毫秒, num为2时100毫秒
if(num==2)
{
num=0;
//当前的时刻, 以100毫秒为单位累加
now++;
}
}
void initial() //单片机初始化
{
//TMOD设定时器1位工作方式2,
//定时器0位工作方式1
TMOD=0x21;
//装入定时器TH0
//(65536-45872)/256 求模
TH0=76;
//(65536-45872)%256 求余
TL0=208;
//装入定时器TL0
EA=1; //开总中断, IE
ES=1; //开串口中断, IE
ET0=1; //开定时器0中断, IE
TR0=1; //启动定时器0, TCON
TH1=0xfd; //波特率为9600, 11.0592 M晶振
TL1=0xfd; //波特率为9600, 11.0592 M晶振
TR1=1; //启动定时器1, TCON
SM0=0; //设定串口工作方式1, SCON
SM1=1; //设定串口工作方式1, SCON
left=1; //左探测口设为没有探测到
right=1; //右探测口设为没有探测到
}
2 踏步机游戏软件的编写方案 2.1 游戏软件的策划
本文的游戏编写的目的主要是检验踏步机游戏系统的可行性、操控性, 在游戏中实现健身功能, 因此可以采用敏捷的开发方式和原型设计的思路进行游戏设计, 从已有的游戏选择一种, 将其内容进行扩展, 加入一些新的元素[6]. 踏步机游戏可定性为体育竞速类游戏, 鉴于本文踏步机游戏软件编写的目的, 本文改写了经典游戏“贪吃蛇”, 贪吃蛇游戏是人们熟悉的电子游戏, 玩家测试起来容易上手, 程序编写也较简单, 用它来测试整个游戏系统较为方便.
2.2 踏步机贪吃蛇游戏的设计本文用Visual Studio 6.0作为软件开发工具, VC6.0编写贪吃蛇游戏[7]. 游戏总体上分5个功能模块, 如图4所示. 根据以上所述的功能可将游戏分5个类进行设计. (1)主游戏类, 主要负责各类的调用和主界面的显示. 利用VC6.0中MFC的对话框模式建立一个CSnakeNew工程, VC6.0自动生成CSnakeNewDlg和CSnakeNewApp两个类. (2)游戏规则类, 在工程中定义为CRule类. (3)串口类, 主要负责串口设置、打开和步频的接收. 在工程中加入Microsoft Communication Control, 自动生成CMSComm串口类, 调用类中函数可实现串口通信. (4)帮助对话框类, 显示游戏的帮助文档. (5)蛇类, 主要实现蛇身移动、增加及移动方向, 蛇身、果实的更新和显示. 在工程中添加CSnake类, 它公有继承CWnd类. 各类的关系如图5所示, 贪吃蛇游戏中CSnake类继承CWnd类, 它们之间是泛化关系; 同时它与CRule类、CSnakeNewDlg类是依赖关系; CSnakeNewDlg类与CMSComm类也是依赖关系.
时序图6显示了各类对象之间在游戏运行阶段相互调用和信息传递关系. 玩家调用主对话框类CSnakeNewDlg的对象dlg的方法OnOpen()打开串口; 接着dlg调用CMSComm类对象m_ctrlComm一系列方法初始化串口, 包括SetCommPort()设置端口号, SetPortOpen()打开端口, SetSetting()设置端口参数, SetInputMode()取回传入数据的方式, SetRThreshold()设置接受缓冲区每接受到字符个数, SetInputLen()设置当前接收区数据长度, GetInput()先预读缓冲区以清除残留数据; 玩家再次调用dlg中的方法OnGame(), 调用CSnake类m_snk的GameStart(), 同时返回模式参数; 玩家做踏板运动, 传感器接收信号并计算步频频与计算机通信, 系统调用OnOnCommMscomm(), 此方法调用m_ctrlComm的方法GetCommEven()和GetInput(), 判断串口事件和读缓冲区数据, 桨频数据将被接收; 在OnOnCommMscomm()方法中调用m_snk中贪吃蛇游戏模式响应方法GameAction(), 这个方法分别调用GameMove(), 在游戏模式中控制蛇身移动; 在GameMove()中会调用ReDrawBody()重绘蛇身; ReDrawBody()发送系统消息进行窗口重绘, 调用CSnake类中的OnPaint()方法进行游戏画面的重绘.
2.3 踏步机贪吃蛇游戏主要类的设计 2.3.1 游戏规则类
游戏规则类的判断游戏状态模块主要算法设计如下:
(1)当蛇身每移动一步时, 就对蛇头部的坐标进行判断.
(2)如果已经与游戏界面的边界或者和蛇身向量中的坐标重合, 说明贪吃蛇已经碰到了墙壁或者自己身体, 提示游戏结束.
(3)设置游戏为结束状态.
2.3.2 串口类利用VC++6.0中所提供的串口控件, 在工程中加载CMSComm类, 调用类中函数可实现串口通信. 蛇身动作函数应放在OnOnCommMscomm1()中调用, 即可实现踏板动作与蛇身移动的一致. 显示平均步频、显示得分语句也可放在此函数中.
2.3.3 蛇类蛇类的设计是整个软件的关键环节, 蛇类具体包含数据、函数如下:
蛇类的头文件CSnake.h
#include "Afxtempl.h" //插入模板头文件
#include"Rule.h" //插入规则类头文件
class CSnake: public CWnd
{
public:
CSnake();
public:
int m_avgRate; //平均步频
int m_nDifRate; //步频差
int m_SnkRRate; //蛇的右步频
int m_SnkLRate; //蛇的左步频
bool flagR; //右步频标志
bool flagL; //左步频标志
int m_nPreDir; //前一次动作方向
int m_nScore; //分数
bool m_bIsOver; //游戏结束
public:
//游戏模式蛇身移动
void GameMove(CPoint pt1);
//游戏模式蛇身动作
void GameAction();
BOOL GameStart(); //游戏模式开始
void InitGame2(); //游戏模式初始化
void InitFoods(); //初始化果实
void ReDrawBody(CPoint pt); //重绘蛇身
private:
CArray<CPoint, CPoint>m_body; //蛇身向量
CArray<CPoint, CPoint>m_body1; //目标蛇身向量
CPoint m_psFood; //果实
CRule rule; //规则类对象
};
蛇类主要完成以下功能:
(1)果实的随机生成和显示
果实必须随机生成, 果实出现的范围不要在游戏窗口边缘, 这样可以降低游戏难度. 果实不能与蛇身重合, 即果实的坐标不能与蛇身的坐标相同. Snake.cpp中void CSnake::InitFoods() 初始化果实, 如图7.
(2)贪吃蛇游戏功能
游戏功能是让玩家感受到健身与游戏的结合, 从游戏中得到有效的锻炼. 先在游戏中探索到自己的有氧运动强度范围, 可记录下心率和体力感知度[8](对照RPE表获得)对应的上下限步频, 然后在游戏中设定上下限步频, 平均步频数值决定蛇身颜色的变化, 玩家低于下限步频踏板时, 蛇身变蓝, 高于上限步频, 蛇身变红, 在上下步频之间蛇身是绿色. 玩家在游戏中让蛇身保持绿色就是在一定步频范围内踏板, 也就是在做有氧踏板运动, 如图8所示. 当玩家经过一段时间的游戏, 如果感到踏板比较轻松, 而且比较容易得到高分, 就可以设定更高的上下限步频, 这样通过再一轮的踏步游戏, 便可以提高玩家的有氧运动能力.
蛇身的方向由左、右步频差来控制, 例如可以规定步频差等于右步频减去左步频:
$ m\_nDifRate = m\_SnkRRate - m\_SnkLRate $ |
步频差阈值可以自由设定, 数值小, 拐弯就容易. 例如可以规定阈值为10, 当步频差(m_nDifRate)大于10, 设定蛇身向左拐, m_nDifRate<–10时, 蛇身向右拐, –10 <=m_nDifRate<=10时蛇身保持原方向前进. 在编程时要增加一个变量保存先前蛇身移动方向. 蛇身移动的快慢由平均步频决定, 如式(1), 具体移动步数由式(2)计算得出, 蛇身每步即移动一个像素, 移动多少步数由平均步频、m、n决定, m和n可根据蛇身大小、游戏窗口的大小、游戏的节奏自主设定.
$ m\_avgRate{\rm{ = }}\left[ {\left( {m\_SnkRRate + m\_SnkLRate} \right)/2} \right] $ | (1) |
$ steps = \left[ {m\_avgRate/m} \right] + n $ | (2) |
Snake.cpp中void CSnake::GameAction() 是蛇身动作函数, 它控制游戏模式中蛇身移动, 详细设计过程如图9所示. 其中for循环语句为for(int i=0; i<移动步数公式所得出值; i++), 表示蛇身移动步数.
3 结语踏步机游戏设计是否成功关键在于它的交互性, 实现良好交互性关键是游戏的操控性, 这是从玩家操控踏步机器进而控制贪吃蛇的移动体现出来. 操控性是指游戏的易用性和操作的准确性, 准确性是指, 按照传感器以及游戏软件所设定的规格所能达到的操作结果与玩家实际操作游戏时所预判的结果, 在程度上的差异. 操控性能的好坏评价, 一方面在于设计, 另一方面在于玩家熟练掌握技巧所需要的时间以及他们的主观体验. 本游戏易用性方面主要表现在玩家在做拐弯动作时有点难度, 玩家必须一只脚踏板快, 另一只踏板慢, 这样才能产生步频差较大, 形成蛇的转向. 本文的建议是, 在做拐弯动作时把一只踏板停住, 快速踏另一只踏板, 这样就容易形成一个步频数值就会远大于另一个步频. 测试者要经过一些练习才能掌握好.
基于运动器材作为游戏的输入设备具有稳定性好、精确度高、成本低, 从而设计的电子游戏具有操作感、精准感较强, 模拟运动体验好等特点. 由于它们本身就是健身器材, 因此更容易设计出健身游戏软件与之配套. 基于体感游戏手柄设计体育类游戏, 或者基于Kinect摄像头, 通过深度识别和人体骨骼追踪技术, 实现人机交互, 设计的游戏, 易产生误差, 游戏操作起来有时会产生延迟和操作失败, 玩家的游戏体验与该体育项目的实际体验相差较大. 本文所用的踏步机为市场上普通款式, 传感器的安装并不需要改变对原踏步机结构, 具有设计简单, 安装方便, 成本低廉等优点, 有较好的市场前景. 就普适性而言, 本文的传感器装置的设计思想也可以运用在其他运动器械上, 例如具有双桨的划船机、椭圆机等, 只要有两个运动部件, 类似于踏步机, 都适用以上原理, 即计算左右运动频率, 利用左右频率差和平均频率来驱动游戏主角运动.
[1] |
耿彬. 跑步机体感游戏的设计与实现[硕士学位论文]. 长沙: 湖南大学, 2010.
|
[2] |
李波. 健身单车体感游戏设计与实现[硕士学位论文]. 长沙: 湖南大学, 2010.
|
[3] |
张诗潮, 钱冬明. 体感技术现状和发展研究. 华东师范大学学报(自然科学版), 2014(2): 41-49, 126. |
[4] |
黄静, 郎波, 张志稳, 等. 基于Kinect跑步机系统. 计算机系统应用, 2016, 25(9): 113-118. |
[5] |
郭天祥. 新概念51单片机C语言教程-入门、提高、开发拓展全攻略. 北京: 电子工业出版社, 2009. 74–76.
|
[6] |
何青. 游戏程序设计教程. 北京: 人民邮电出版社, 2011. 17–20.
|
[7] |
王浩. Visaul C++游戏开发经典案例详解. 北京: 清华大学出版社, 2010. 263–302.
|
[8] |
曲绵域, 于长隆. 实用运动医学. 北京: 北京大学医学出版社, 2003, 78. |