时间:2022-10-12 05:28:11
摘要:该文介绍了M3G(移动3D图形标准,Mobile 3D Graphics)和JABWT(Java蓝牙无线规范,Java APIs for Bluetooth Wireless Technology)的功能及优点,并且以多人赛车游戏为例,给出一个基于蓝牙技术的3d多人手机游戏的设计与实现。
关键词:M3G;JABWT;手机游戏
中图分类号:TN929文献标识码:A文章编号:1009-3044(2009)33-9522-03
Design and Implementation of 3D Multi-player Mobile Game Supported by Bluetooth Wireless Technology
WANG Tian-shun, SHENG Guang-lei
(Shengda College of Economics & TradeManagement, Zhengzhou University, Zhengzhou 451191, China)
Abstract: This paper introduces the functions and advantages of M3G (Mobile 3D Graphics API) and JABWT (Java APIs for Bluetooth Wireless Technology) and gives an example of multi-player car racing game for describing the design and implementation of 3D multi-player mobile games supported by Bluetooth wireless technology.
Key words: M3G; JABWT; mobile game
1 概述
随着手机相关硬件性能的不断提高,如处理器速度的加快、存储容量的增加、3D图形显示和渲染技术在手机上的成熟,以及手机应用程序开发包和操作系统平台功能的不断增强,使得手机移动类游戏成了开发热点,一个极具吸引力且快速发展的产业。该文首先介绍了M3G(JSR 184[1])和JABWT(JSR82[2])协议,之后给出了一个基于蓝牙的3D多人赛车游戏的实现。
2 相关规范
2.1 M3G概述
JCP(Java Community Process,Java社区过程)于2003年11月了M3G(JSR184),同时SuperScape和Hibrid公司实现了M3G规范协议,并且基于该规范的3D引擎以及程序开发包也分别投入市场。这一系列的事件标志着开发基于J2ME的手机3D程序成为一个新兴产业,手机上的3D应用将会是一个非常大的发展方向,比如3D游戏、3D虚拟现实技术,用户界面,3D屏保等。
2.2 JABWT概述
JABWT(Java APIs for Bluetooth Wireless Technology,JSR82)规定了一个标准的J2ME蓝牙开发平台,保证开发出来的程序可以在任何J2ME设备上运行,而不必考虑由于硬件平台和协议栈的不同对应用程序产生的影响[3]。基于JABWT的J2ME蓝牙开发模式不仅提高了开发效率,同时由于JABWT规范通过统一的Java语言平台和标准的蓝牙开发平台,使得J2ME蓝牙设备可以根据环境动态的下载并执行第三方开发的蓝牙应用代码。
3 蓝牙3D多人手机游戏的设计与实现
基于M3G和JABWT规范的蓝牙3D多人手机游戏的程序流程图如图1所示。
游戏开始首先要输入玩家的名称,然后Slave端服务,Master根据发现的玩家信息,选择哪几个玩家参与游戏。
根据游戏的要求,定义了四种传输数据类型:
PlayerAction:对游戏中的键盘事件进行的穷举,根据事件决定玩家角色如何运动;
PlayerState:定义了玩家控制的角色所需参数,用来进行坐标校正;
MasterCommand:Master端的命令,Slave根据Master端发送命令的不同进行不同的响应;
SlaveCommand:Slave端的命令,Master根据Slave端命令的不同进行不同的响应;
这些命令信息的发送需要在本地进行序列化,在远端进行反序列化,故定义了EM3DSerialization接口,所有以上四类需要传输数据的类都必须继承自这个接口。
接口定义如下:
public interface EM3DSerialization {
public byte[] serialize() throws IOException;
public void deserialize( byte[] data ) throws IOException;
}
一个Slave端发送信息的需要通过Master转发到其它Slave端,而Master端发送的信息则不必转发,信息的发送与接收如图2所示。
建立连接后,手机屏幕上的当前显示对象为BluetoothCanvas类的一个实例,它派生自Canvas类,内部生成2类线程:
重绘线程,用于屏幕重绘(每个实例仅有一个);
通讯线程,用于和远端用户进行信息的接收(Master端根据连接的Slave数量创建相应数目的线程,Slave端仅一个和Master端的连接);
因为生成的通讯线程是BluetoothCanvas类的内部对象,故所有信息的发送需要统一调用BluetoothCanvas类中的方法:transportCommand()和serialize()。transportCommand()方法根据事先定义的通讯规则(根据命令的来源与功能的不同,如屏幕按键事件,Master转发事件,计算网络延迟事件,坐标校正事件)封装、发送数据。欲发送的命令信息经过序列化后返回一个字节数组。
发送来的数据在接收线程的run()方法中进行命令解析,根据事先定义的通讯规则,由keyParseCommand()、 masterParseCommand()和 slaveParseCommand()分别调用deserialize()方法对读入的字节数组进行反序列化。
transportCommand()方法主要代码如下所示:
//command是传递的按键、命令等信息
//_transmitMsg判断是否需要转发
//index可以指定转发向哪个连接
//keyPressed值在解析按键信息时有用,默认为false,仅在keyPressed事件中赋值为true
//canvasEvent用来区别是按键还是系统产生的消息
public synchronized void transportCommand( int command , boolean _transmitMsg, int index ,
boolean keyPressed , boolean canvasEvent)
{ //计算网络延迟用
if( MasterCommand.MASTER_RE_NETSYNCHRONIZE == command ) {……}
if( SlaveCommand.SLAVE_NETSYNCHRONIZE == command ) {……}
if( SlaveCommand.SLAVE_NETSYNCHRONIZE2 == command ) {……}
//对PlayerAction对象进行参数设定,准备传输
if(Role.ROLE_MASTER == role) {……}
else if (Role.ROLE_SLAVE == role) {……}
//Master端要将该消息转发给其它Slave端
if(MasterCommand.MASTER_RETRANSMITMSG == command) {……}
//发送消息
//Master向所有的Slave广播本地产生的事件
//Slave向Master发送本地产生的事件,故Master需要转发该信息到其它Slave端
for( int i=0; i
}
serialize()方法主要代码如下所示:
public void serialize(EM3DSerialization em3dSerialization, BluetoothConnection bluetoothConnection)
{OutputStream os = bluetoothConnection.getOutputStream();
em3d_data = em3dSerialization.serialize();
//数据传输:
//1、把数据序列化后的长度传出
//2、byte数组传出
bluetoothConnection.writeInt(em3d_data.length);
os.write(em3d_data);
os.flush();
em3d_data = null;
}}
deserialize()方法主要代码如下所示:
public void deserialize(EM3DSerialization em3dSerialization, BluetoothConnection bluetoothConnection)
{InputStream is = bluetoothConnection.getInputStream();
int length = bluetoothConnection.readInt();
em3d_data = new byte[length];
is.read(em3d_data);
em3dSerialization.deserialize(em3d_data);
}
在BluetoothCanvas类的重绘方法中一个Graphics3D类的实例对该Canvas的Graphics对象进行绑定,来绘制3D世界。进行场景绘制的代码如下所示:
public void paint( Graphics g )
{
iG3D = iG3D.getInstance();
iG3D.bindTarget(g, true, 0);
try{
iG3D.render(scene);
}catch(Exception e){}
finally { iG3D.releaseTarget(); }
}
3D世界和汽车均是通过3DMax建模产生,首先建立模型,模型构造完毕后,通过3DMax自带的导出工具生成m3g格式的文件,通过JSR184的Loader类读入,并通过Canvas渲染到屏幕表面上。联机游戏的效果如图3所示:
图3 联机效果图
4 结束语
根据调查显示,69%的调查者表示比起一起玩手机上的网络游戏,他们更愿意和朋友一起玩通过蓝牙联接的局域网游戏。而3D游戏也己经成为一个不可逆转的大趋势,各手机制造商都把支持3D游戏作为一个新的卖点。在手机等移动设备飞速发展的今天,相信J2ME必定会在无线设备嵌入式系统开发中应有更广阔的应用前景。
参考文献:
[1] Sun Microsystems.JSR184: Mobile 3D Graphics API for J2ME[S].
[2] Sun Microsystems.JSR82:JavaTM APIs for Bluetooth[S].
[3] Nokia.Game Over Bluetooth:Recommdations to Game Developers[S].