为什么牛逼?——"Stonie is a KungFu monk"游戏精品功能介绍与详细规范,以及其中的挑战
是的,由于整体设计风格变动,我们游戏的名字变更了——不想被砖块砸的和尚不是一个好鼓手(这哪跟哪啊!!)。不扯远了,在Beta迭代阶段,由于有了Alpha阶段的代码库支撑,我们可以放开手脚来做一些真正面向用户的Feature。
1、改良的游戏引擎
看到这里有人也许会说,啊!又来了!技术向的User Story!不是的。这个User Story的原文描述如下:
As an average gamer, I want the game feel vivid and filled with eye-candies.
Those static pictures, single-pic-like menus will never satisfy me.
那么,要想达到上述效果,应该采取一些什么手段呢?别的几个组的同学也许会说,啊~我们多拖一点Silverlight控件到屏幕上,双击一下,加入一个Double animation不就可以了?很遗憾,XNA架构只认图片,没有控件一说……所以,为了增强对UI的描述能力,我们在Beta迭代开始的时候做出了一个重要的决定——改良游戏引擎。
不记得在哪本书上看过,说降低项目风险的一个好办法就是购买能够满足需求的成熟组件。但是我们一没有充裕的资金二不能使用开源框架,于是剩下唯一的解决方案就是自己写一个好的底层框架。
我们需要什么样的底层框架呢?先看看系统给我们提供了什么:
Update(GameTime gameTime);
SpriteBatch.Draw(....此处略去7个参数);
就这么些了……真的没别的了。设想我们直接使用这些接口来分别定义不同的显示部件,那么其一——整个团队将堕入“外科手术团队”的深渊——Draw有7个参数,GPU有多少种内存?茴字有多少种写法?——不是每个人都能掌控。其二——工作量将大大上升。每一次美工传入新的任务,整个团队都会叫苦不迭。
所以PM做了一个艰难的决定——Silverlight有控件,我们XNA也要有!我们要开发一个基于控件的高级引擎!
Ok,Specs.
南七引擎v1.0b 规范
1.架构
南七引擎架构分为三层。
底层为绘画与系统事件层,负责与系统SDK对接,实现所有内容的上屏功能。南七引
擎是面向显示对象的引擎,可以往底层动态添加/删除对象,上层的添加/删除事务会及
时反映在屏幕上。对象具有动画的特性,这些特性将由对象本身提供——绘画层不介入动
画的描述,但是要精确地将上层动画描述复制到屏幕上。另外上层的对象具有侦听系统
事件的能力,例如触摸事件,划动事件,程序退出,程序挂起等。
此外,绘画层提供了“层”的概念,用户可将显示对象添加到不同的层以获得分屏的特
性,最终实现游戏屏幕与菜单屏幕分离的效果,提高代码可维护性。绘画层为每个“层”
提供单独的背景动画支持(背景动画亦使用显示对象来表征),以及层间变换的动画支持,
其描述语言会在稍后章节提到。
中层为对象层,负责定义能被绘画层使用的显示单元。对象定义了一个显示单元的如下
属性:
1、类别。可以是一个图元,或者是一个字符串。如果是字符串,需要指定使用系统字体/
使用南七引擎自带图片字体(为了减小游戏体积,目前南七引擎自带图片字体仅支持0-9的
数字)
2、绝对坐标与绝对大小。自描述,不解释。
3、相对坐标与相对大小。这个属性会被叠加到坐标计算中,以实现“按照一个轨迹移动,
又能够以轨迹为中心偏移”的动画效果。
4、透明度
5、缩放比例
6、纹理区间。将纹理的一部分(而不是全部)映射到图元上。此项可以不指定。
7、蒙版颜色。指定此项可在图元上叠加一层半透明纯色蒙版。
8、图片动画向量。指定该项并开启图片动画后,系统将以给定速度匀速播放该向量中指定
的帧。
9、描述动画挂钩。这是一个函数挂钩,可以挂在上层定义的描述语言中。开启描述动画之
后,系统将以给定的速度播放整个描述动画。
这里详细说明一下描述动画的结构:
delegate void AnimationFunction(float progress);
挂钩接受来自底层的参数progress(0~1 之间),用于指定当前动画完成的百分比。
挂钩内可以自由更改显示对象中的任意public属性。
<实例>
public void rotateARound(float p)//旋转一圈
{
Angle = p * 360;
}
</实例>
注意,多个描述动画可以叠加,系统会同时处理这些描述脚本。最后的叠加效果由脚本
注册的顺序决定。
此外,对象可以侦听来自系统底层的事件。使用RegisterTouchHandler接口可侦听触摸
事件,使用RegisterEventProcessor(EventType,Processor)可处理其他事件。具体定义
参见详细文档。
上层为控件层。继承数个显示对象,组合成一个能够描述UI元素与游戏元素的单元。例如
继承DisplayComponent的Button对象,在屏幕上显示一个按钮,并且对外提供Clicked
事件。控件在实例化之后需要自动找到所在的显示层,并且注册好所有的底层事件。对于更
上层的逻辑,底层的繁琐细节不予暴露。
2.上层组件
南七引擎提供了丰富的上层组件,组成了一套完整GUI框架。
Canvas 提供基本的绘图组件
DraggableArea 提供有空间限制的组件,其中可放置其他组件
TextList 类似于各种GUI框架中的ListBox
Button 不解释,可继承Button实现自定义动画按钮。
ComboBox、SwitchBox 不解释
以及更多实用小部件……
3.性能
测试结果——~116Mpixels/second. -- 足够画任意多的飞机和子弹了吧,哈哈
Spec草稿出来之后我们发现,一旦实现了这样一个引擎,我们的图元描述能力将大大提高——达到Flash中ActionScript的水平(唯一美中不足的是没有外部编辑器来实现使用关键帧的插值动画,不过实在是资源有限,无法再往前走了)。在整个Beta迭代中,这套引擎也在不断地发展和改善,并对整个开发流程起到了提速的作用。
挑战:魔鬼在细节中,但是我们用少数写码能力强的同学(Thanks Rongcheng!)作为资源,吃掉了魔鬼,尔后一马平川,势如破竹。
于是,虽然这个Story的主要故事是引擎,但是最后我们得到了————
2、重制的游戏UI
由于大量使用动画效果,我们的游戏终于摆脱了“作坊小游戏”的阴影——游戏中甚至有40帧以上的“大制作”动画!游戏的整体画风是“中国山水画”,墨水的扩散,山水画的飘逸,在新引擎的支撑下都能够很好地表现出来。 最后我们得到了一个风格统一、做工精美的艺术品(Thanks Qifan and MIT!)~
3、可从网络扩充音乐库
这一个User Story其实是整个项目中风险最大的部分。PM现在想起来都还是觉得有些后怕。
Specs:
扩展包模块功能描述
扩展包模块分为三个部分
1、与选歌界面无缝结合。用户需要无差别地对待原厂曲目与扩充曲目,并在选歌界面可以
直接下载新的歌曲。
2、下载模块。正确处理WIFI与WAN环境下的下载行为,将下载好的曲目存放到手机,以便可以离线使用。
3、重制声音引擎。目前的声音引擎不支持播放存储空间中的媒体,需要重新设计与制作。
1、2都很顺利地按照进度实现了,但是第三条却让我们面临了严峻的挑战:由于XNA SDK的问题(我这里就必须吐槽一下,XNA开发团队你们到底在干什么!不能用就不要留接口!留了接口最后抛出NotImplementedException,这不是存心搞我们吗!!!有病啊!!!有病啊!!!有病啊!!!!!!),初期调查得出的方案最后不Work,于是我们启动了紧急方案,动用了更多的人力资源专注于解决这个问题。最后,在一个偏远的山村里,有一个网页……上面用一行话描述了解决方案——于是在略微Hack工程本身的XML文件之后,这个问题奇迹一般地解决了……
OK,就讲到这里了。具体游戏的感觉,等到发布之后大家就知道,敬 请 期 待~
Yadli