APP下载

3D街机游戏系统研究与应用

2017-03-27邓增强朱铮涛龙诗军

电脑知识与技术 2017年3期

邓增强++朱铮涛++龙诗军

摘要:针对当前国内街机游戏开发难度大、难以移植、开发周期长的问题,提出Unity3D引擎结合Android平台技术的街机开发方案。该项目用Unity3D引擎开发一款游戏,完成Android系统与Unity3D的数据交互、添加NGUI事件源,从而实现外部硬件设备控制游戏及游戏中的交互界面。针对厂家生产需求开发一个安卓系统桌面启动器并监听Android开机广播实现开机启动游戏,预装游戏软件实现系统集成。实践表明该系统完成度高,该开发方案开发效率高,在街机游戏开发和应用方面有一定的推广应用价值。

关键词:街机游戏;Unity3D;NGUI;Android; 安卓系统桌面启动器

中图分类号:TP317 文献标识码:A 文章编号:1009-3044(2017)03-0202-04

Research and Application of 3D Arcade Game System

DENG Zeng-qiang1, ZHU Zheng-tao1,LONG Shi-jun2

(1.Guangdong University of Technology, College of Information Engineering,Guangzhou 510006,China;2.Longsys Electronics Company Limited,Shenzhen 518057,China)

Abstract: Consider the difficult of development,transplant and the problem of long development cycle of the current arcade development in China,an arcade development plan by using Unity3D engine combined the technology of the Android platform was proposed.In order to realize external hardware equipment to control the game and the game's interface,data interaction between Android system and Unity3D was completed ,add NGUI event source.Consider the demand for the manufacturers,a launcher was developed to monitor Android broadcast,pre-installed game APK to realize system integration.The result shows that the system is highly completed,the development plan is efficiency,and it has certain value of popularization and application in arcade game development and application.

Key words:arcade games; unity3d; ngui; android; launcher

1 概述

街机是置于公共娱乐场所的经营性专用游戏机[1]。1971年麻省理工学院学生诺兰.布施内尔设计了世界上第一个业务用游戏机开始,街机这一名词开始出现[2]。20世纪80年代街机游戏开始蓬勃发展,到21世纪初,期间出现了众多优秀的街机游戏。随着计算机技术的发展,各种形式的游戏开始涌现,如:PC游戏、手游、电视游戏等,这些新兴的游戏方式冲击着街机游戏市场。然而,街机游戏的临场感、操控感和体验感是PC游戏和手游等无法比拟的[3]。由此,街机游戏还是拥有数量可观的玩家用户。但作为开发者和厂商来说,街机游戏并不欢迎,其原因主要是开发方式难、硬件成本高、一台机器只能运行一个游戏。

随着Android平台和Unity3D游戏开发引擎的出现,街机游戏的开发方式也出现了新的可能。Android平台是开源系统,其开放性和广泛的硬件支持的特点吸引众多的开发者进行游戏开发[4]。为简化游戏开发,选用Unity3D游戏引擎,该引擎有良好的跨平台特性、打包发布简单、良好的移植性的特点,开发者无需了解底层技术即可进行开发,大大缩短了开发时间周期[5]。Unity3D 中整合如地形创建工具、碰撞检测和灯光渲染组件、粒子系统、物理引擎、常用脚本等丰富的开发资源。同时,还在Mono Behavior这个类库中为开发者定义了各种实用的方法,从而为开发提供了更大的方便[6,7]。本项目以Unity3D技术为基础,实现一款街机游戏,以Android技术为辅助,实现游戏控制和系统集成。该系统为解决街机游戏开发困境提供一定的引导和参考。

2 设计内容概述

该项目为一款针对儿童用户的安卓平台游戏,采用三维游戏风格,最终将游戏集成到安卓源码,实现自定义安卓系统桌面启动器(launcher)和针对游戏软件的开机自启。系统主要模块包括两部分:客户端游戏软件模块和安卓系统集成模块。

2.1 游戏玩法介绍

游戏设置有三个场景:草原、雪地、海岛,每个场景跑道都设置有路障。玩家使用操纵拉绳操控马匹,在限定的时间内与电脑马匹竞赛,玩家可以操控马匹加速,限定時间倒计时结束判定玩家马匹在跑道上的位置进行排名。游戏流程如图1。

图1 游戏过程展示

游戏操控方式通过马匹上左右两条缰绳控制左右移动,同时拉两根缰绳表示主角跳起,而在交互界面场景中表示“确定”,马身一个按键控制主角加速,机箱处留有投币处和商家进入后台参数设置界面的按键。

2.2 主要模块及功能

客户端软件模块是软件的主要模块,是直接影响玩家用户体验的重要部分,该模块使用C#编写游戏逻辑和交互界面。在Unity3D游戏引擎中导入游戏需要的场景资源:图片素材、角色模型、场景模型、音乐资源、字体等,编写脚本代码控制游戏逻辑,例如:角色行为控制、AI寻路、UI等。

生产厂家在生产中有硬件制作、系统镜像烧录、游戏安装等过程。然而,这样每次机器运行需要选择游戏应用图标进入游戏,大大增加了操作复杂度,不符合街机生产需求。针对这一情况,笔者将游戏APK(Android Package)预装到Android系统中,并开发一个launcher替换系统原生launcher,由此launcher启动游戏。基于以上描述可得项目关键模块框架如图2。由于篇幅限制,本文对开发过程中模型导入、粒子系统、Android源码编译等不做描述。

图2 游戏总体框架图

3 系统关键模块技术及实现

3.1 控制功能模块

区别手机游戏触摸控制和PC游戏的键盘控制,本游戏依赖外部硬件设备,通过串口数据通信与Android平台进行数据交互。

Unity3D与Android数据传输的方式有多种。可以在Eclipse中编写所需的Android平台功能,以库文件的形式在Unity3D中使用;也可以将Unity项目导出为Android项目,然后编写Android程序,两种方式都可实现数据传输,只是实现过程有区别。本项目以Unity3D为主,将Eclipse的功能制作成插件集成到Unity3D中,其原理是使用Android NDK將C/C++编写的代码编译成.so文件后,在Unity3D中用C#代码进行相互调用,具体实现方法为:

1)使用Eclipse创建一个库文件工程;

2)在Eclipse中编写串口操作,遵循普遍串口操作规律,实现打开串口、读写串口、关闭串口,继承UnityPlayerActivity实现Activity与Unity对接,并封装一系列的方法来为Unity3D提供访问串口读写数据的接口,然后输出.jar格式库文件,代码片段:

public String getJumpPass()

{return jumpPass;}

public void setJumpPass(String jumpPass) {this.jumpPass = jumpPass;}

3)复制AndroidManifest.xml、.so文件、.jar文件到Unity3D目录Plugins/Android下,重新设置AndroidManifest.xml中activity名称,使之与Eclipse工程中activity一致;

4)Unity3D创建SerialPortData.cs脚本访问.jar库。在Start()函数中获取Android的activity,从而访问.jar库文件中传来的字符串数据,据此判断玩家或商家做出的操作;

void Start(){

AndroidJavaClass jc=new AndroidJava- Class("com.unity3d.player.UnityPlayer"); activity=jc.GetStatic("currentActivity");}

在Update()函数中每帧刷新一次,检测是否有新的操作,代码片段如下:

void Update(){

string coin=":020"; //投币信号

string jump=":290"; //上跳或者确认

string left=":210"; //左操作

string right=":220"; //右操作

string accelerate = ":230";//加速信号

string bkEnter = ":240"; //后台信号if(activity.Call(“getJumpPass")==jump)

{activity.Call("setJumpPass","");

isjump = true;}}

其中”:290\n”等是串口通信协议,利用AndroidJavaObject的Call()方法获取串口数据,通过比较字符串确定操作是否成功。

3.2 交互界面实现

游戏中涉及的界面操作有玩家选择场景界面和商家后台参数设置界面,界面设计采用NGUI插件。NGUI[8]是专门针对unity引擎,用C#语言编写的一套插件,相比较unity3D原生引擎GUI和NewGUI系统功能更强大、操作更方便,它提供了强大的事件机制,通过UICamera监听UI事件并分发事件,事件覆盖此camera渲染的GameObject。游戏中玩家投币达到商家设定的数量后,游戏进入场景选择界面如图3。

图3 场景选择界面

UICamera监听的事件源有鼠标、键盘、触屏和手柄。而本游戏控制依赖外部硬件设备,通过串口输入与Android系统通信,UICamera事件源并不包括串口控制方式。因此,通过UICamera.cs中Update()添加事件源,Notify()分发事件处理函数的方式对NGUI做二次开发,左拉缰绳操作事件代码:

if(SerialPortData.leftpull)

{SerialPortData.leftpull = false;

currentScheme=ControlScheme.Controller; Notify(mCurrentSelection,"OnSignalLeft",null);Notify(editActiveValue,"OnSignalLeft",null);}

其中Notify封装SendMessage方法分发事件,参数一为接收消息的游戏对象,参数二为函数名。为了使操控效果美观,添加WrapContent脚本实现无限滑动效果,添加UIKeyNavigation定位UI。当监听到控制事件,立即转发到对应的处理函数,函数片段:

public class NewUIKeyNavigation : UIKey- Navigation {void OnSignalLeft()

{if (!NGUITools.GetActive(this)) return;

GameObject go = null;

go = GetLeft();

go.GetComponent().O-nClick ();if (go != null)

UICamera.selectedObject = go;}......}

街机游戏每局需要的投币数量是商家设定的,此时就需要定制一个后台参数设置界面如图4。参数包括:中英文切换、游戏时长、每次游戏需投币数目、背景音乐开关。

图4 后台设置界面

后台设置使用Unity3D提供的Player- Prefs類持久化保存和读取数据,该类以键值对的形式将数据保存在本地文件中,保存成功后通过“键”访问数据值。

3.3 寻路AI

游戏AI设计是评价一个游戏可玩性的一个重要指标,本游戏使用AI是寻路AI。Unity3D中常用的寻路AI算法有A*(A-Star)、导航网格(NavMeshAgent)、路点寻路。

A*算法是目前用来解决静态网格求最短路径问题最有效的算法[9]。普通搜索算法,如广度优先和深度优先算法,通过遍历所有解从而去寻找最优解,当解的数量过多,普通算法效率过低。A*算法使用启发式搜索算法,对每个搜索位置进行评估,提高搜索效率。A*算法适用地图类型为静态网格的游戏,所以必须是先设计好属性固定不变的地图,且必须已知起点和终点,本游戏角色在场景中起始位置确定,但终点位置不定,所以A*寻路不适用本游戏。

导航网格[10](NavMesh)寻路方法是Unity3D自3.5版本起增加的内置插件。其原理是通过烘焙将地形的信息记录起来, 游戏物体挂载NavMeshAgent组件,导航物体便会自行根据目标点来寻找最直接的路线,并沿着该线路到达目标点。角色会绕过或者跳跃过各种复杂的障碍,找到一条理论上“最短路径”。在本游戏中这种方式实现自动寻路会存在很多不定的因素,如场景道路边界存在拐点,自动寻路时移动角色会紧贴拐点移动,并不适合路径随机、移动平滑等需求,导致游戏可玩性不高。

路点寻路方式是在地图场景中设置一些节点并且构成连通的网络区域,每一个节点表示一个路点(WayPoint)[11],游戏角色沿连通的网络线移动,该路线由开发者设定,并不是最优路径,而且游戏角色每次穿过一个路点时产生一个随机小角度起始方向角度并沿该方向寻找下一路点。路点寻路方式适合用于大地图场景,而且对系统消耗更小,实现方法简单有效。综上,本游戏选用路点寻路AI,其具体实现流程为:

1)在场景地图上设置路点,为路点添加sphere碰撞体,并设置tag标签“playerways”,并将路点对象按顺序放进程序定义的public数组中;

2)通过OnTriggerExit(Collider other)函数判定当前路点索引值;

3)以一定的速度朝下一路点移动,如果到达最后一个路点并且游戏时间未结束,则将数组索引置零,方式如下:

if(NUM==waypoints.Length-1) transform.LookAt(waypoints[0]);else transform.LookAt(waypoints[NUM+1]);

图5 路点寻路示意图

3.4 系统集成关键技术

Android桌面就是一个应用软件,管理所有已安装的应用。实验中发现,通过系统原生launcher启动本游戏会在桌面停留,影响系统流畅性。由此,笔者自定义launcher,替换系统原生launcher,并屏蔽桌面界面。Android系统开机会发送一个开机广播,在自定义launcher的AndroidManifest.xml文件注册接收开机广播,并设置其为开机启动程序。编写脚本继承BroadcastReceiver,实现通过游戏APK包名启动游戏。

前文提到为厂家生产方便,需将游戏预装到安卓源码,并裁剪安卓源码,缩小系统镜像包体,加速镜像烧录,最终厂家只需要硬件平台和预装了游戏APK和launcher的镜像。预装中注意将游戏APK中的库文件放在device/softwinner/fiber-commom/prebuild/-apklib文件中,将游戏APK放入prebuild/ preinstall-apk目录下,并修改该目录下的Android.mk,对该apk进行申明。自定义launcher替换原生launcher时应删除原生launcher,并在当前文件夹下Android.mk文件中声明添加LOCAL_OVERRIDES_PACKA- GES := launcher2;否则第一次开机需要选择launcher启动器,系统不连贯。

4 系统展示

整个街机游戏系统从开启,如图6(a)到进入游戏,如图6(b),总共耗时35秒左右,系统运行流畅,无卡顿闪退等情况,投币、角色控制、后台控制等功能准确有效,交互界面简洁实用,整机如图6(c)。

图6 街机游戏整体效果图

5 结束语

本文就以往街機开发方式困难、开发成本高的问题,提出一种结合Unity3D游戏引擎和Android平台技术的街机开发方案,为突破以往街机开发方式,提出新的方案,具备一定的推广应用的价值。整个街机系统符合生产需求和游戏本身的设计需求,达到预期效果。当然,本游戏在游戏内容设计和优化方面稍显不足。目前,只有预装一个游戏。因此,后续可以开发更多游戏并开发一个安卓应用来管理这些游戏,丰富街机内容。

参考文献:

[1]刘卓.电子游戏的娱乐体验与交互设计[D].无锡:江南大学,2008.

[2]王峥.试论电子游戏与社会的互动[J].哈尔滨工业大学学报:社会科学版,2005,7(4):26-30.

[3]唐洁.VC++2008开发网络百家乐游戏[J].电脑编程技术与维护,2011,13(10):68-78.

[4]寿柏炎.基于Android平台软件开发方法的研究与应用[J].计算机光盘软件与应用,2013(01):244-245.

[5]袁田琛,胡新荣,赵俭辉.基于Leap Motion和Unity3D的体感游戏开发与集成[J].电脑知识与技术,2015,11(13):201-204.

[6]刘冬梅,宋平,邓英芝,等.基于Unity3D的"林大的松鼠”APP的设计与实现[J].智能计算机与应用,2015,5(2):80-85.

[7]谷敏,康雪丽.数据驱动的Unity3D场景约束框架的分析与设计[J].电脑知识与术,2015,11(30):180-183.

[8]相茂英,马纯永,韩勇,等.基于Unity3D的化工设备虚拟培训系统研究[J].计算机技术与发展,2014,24(07):196-200.

[9]周小镜.游戏地图中寻找路径的改进算法研究[J].信息技术,2010(12):125-127.

[10]Sturtevant N R,Buro M.Improving Collaborative Pathfinding Using Map Abstrac//AIIDE[C]. Marina del Rey, California: Proceedings of the Second Artificial Intelligence and Interactive Digital Entertainment Conference, 2006:80-85.

[11]臧晓强.手机游戏AI引擎设计[D].延吉:延边大学,2008.