2014-10-01
demo 在 http://buaabt.cn/showtopic-377837.aspx
我在担心大神看到这帖子只会一笑置之啊……
这帖子是为了记录开发过程而写的。为什么放在漫版而不是软件版呢?个人觉得漫版更亲切一些,而且能过滤掉大多数小白……对不起最后这个半句有点冲,但是我的确认为那些只是纠结于软件的使用的人很麻烦……
GLaDOS:
At the Enrichment Center we promise never to value your safety above your unique ideas and creativity. However, do not destroy vital testing apparatus.
我大 Gatekeeper 镇楼。
开发引擎中,代号 Haru。
目前需求:
OS: Windows Vista 或以上(因为 MonoGame 使用的 SharpDX 强制加载 DirectX 11;我机器显卡不支持 OpenGL v3 因此也无法使用 Windows OpenGL 模板)。嗯跨平台最后肯定要解决 XP 这一块的问题的,实在不行就自己去修改源代码编译 SharpDX。
其他所需组件:
- OpenAL
- 如果要播放某种格式的视频,当然需要对应的解码器……
目标:
- 开源
- 跨平台
- 快速开发
- 开放接口
- 组件化
(目前的)终极目标:
- 成为兼容 KiriKiri 的跨平台引擎
有些组件授权为 GPL,所以引擎相关部分的开源是必须的。不过由于引擎组成仍然不完整,因此先不将代码公开。
有些组件来源于网络,我记录了相应来源。不过大多数没达到我的要求,所以我对其做了修改。
基于 MonoGame,所用语言为 C#、C++/CLI。由于目标是跨平台的,因此项目中用的大部分是可移植的代码;小部分平台相关的代码分离了出来作为某些抽象类/接口的实现。
这是我第一个涉及 C++/CLI 的项目,感觉确实挺好用的……
现在已经实现的功能(会持续改进):
- 基于事件的 GUI 支持
- 音频支持
- 多字节字符集的支持(*)
- 自适应坐标系统
- 外置调试器
部分实现的功能:
- 视频支持(现在还未实现直接读取视频中的音频帧&同步)
将加入的功能:
- 脚本(准确来说,现在为了引擎演示,做了一个小型的脚本分析器,不过最终肯定不会用这个)
- 类似 VPK 的资源管理
- 插件系统
- 自适应帧率调节
优势:
- 运行于 Mono/.NET 平台,充分利用符合 CLS 的语言的优势,不需要纠结于底层代码。以前我做的是直接基于 SDL 的,文本&视频先不说,单是对象生命周期的控制(以及 STL!)就很令人不好了。自从换了 MonoGame,腰不疼了,腿不酸了,吃嘛嘛香!
- 担心效率损失?嗯,确实会有一点,不过至少现在没明显缺陷,而且我也会尽量将其做好。例如现在的演示中,主界面背景就是 Strawberry Nauts(不要问我为什么又拿这个游戏开刀)的 OPMV 文件(视频),在我这渣本上照样能跑出 36 fps,资源占用也与 MPC-HC 播放同一个视频时相当,还别提视频上还有一个动态组件(用作简单特效演示)在跑着……前两天就在手工优化这个,头疼死了……游戏主内容的画面,一般是 50~60 fps(XNA/MonoGame 固定刷新频率模式时的封顶刷新频率)。{2014-09-07 16:15 CPU 占用率正常在2%~8%,播放视频大约在20%。这个占用率相比直接用 C++ 从底层操作 DirectX 来说确实高了一些,不过还是在可以接受的范围内的。}
- 该引擎支持多字节字符集,目前绘制效果也与 KiriKiri 相当。
- 可扩展性。现在的演示是一个小小的 AVG 引擎,不过就像 KiriKiri 一样,其能力不止于此。完全可以继承一些基础类(也可以选择自己实现接口 = =)之后做 RPG/STG……据说《魔法使之夜》很华丽(我个人没看过),假设某一天做好了,可以移植来试试。实现插件系统之后就可以在引擎的基础上写插件,而不用修改本身的代码了;甚至做成 foobar2000 的结构(需要好好准备)……(这个方面推荐看一下 SharpDevelop 的代码。)
Bugs & 改进:
- 视频播放组件有少量内存泄露,还没查出来在哪里……
- 文字绘制资源占用率稍微高了一点(满屏文字的话,帧率下降到30),不过可以再优化。
- 组件结构还有少量变动,我面向对象&组件化是渣渣(多看书!)……
另外,在已有的组件的基础上,今天写这个小小的 AVG 演示,连同简单脚本解析器一起,加起来也不超过一个小时……够快的……
完成这个阶段的目标的时候,就可以考虑将整个引擎脚本化了。不过在此之前,我要去学编译原理……(对,还有之前的弹幕君的事……)
脚本处理,综合所用环境,可以考虑用 Roslyn(类 C#),用 Jurassic(类 JavaScript),或者基于 TypeScript。为了更好地使用工具,应该先将原理弄清楚……
Q&A
Q:为什么不用 KiriKiri?
A:我讨厌无类型语言!(←知道我在说谁吧)而且 KiriKiri 主程序用了许多 Windows API 导致无法移植到其他平台。W. Dee 正在做 KiriKiri 3(目标是跨平台),不过总觉得吧,我们可以自己实现一个这个……而且不管对于希望写小游戏的人还是游戏公司还是希望研究这个的人,C# 明显比 C++ 好理解多了对吧,开发效率也高一些……(而且 KiriKiri 缺少中文或英文注释!连文档都是日文的!叫我这种日文渣怎么扫啊!)至于 KAG,那是见仁见智的事情……高级制作肯定不止要用 KAG,至少要深入 TJS 吧……这一段看以后脚本化了怎么设计吧。
Q:为什么不用 PyGame/Ren’Py?
A:我讨厌无类型语言!(←知道我在说谁吧)而且 Ren’Py 是基于 PyGame 的,PyGame 是基于 SDL 的,对多字节字符(例如,中文)的支持很蛋疼……好吧即使不蛋疼但是写起程序就那类型问题还是很蛋疼……
Q:为什么不用其他的,例如 ALICESOFT 的,或者 ONScripter?
A:不!用!就!是!不!用!
在最后,要感谢 MSTC 的成员。
我加入 MSTC 之后第一个参与的是 SpaceMoto(开发这个的同学我忘了你的名字,但是还是要吐槽你的拼写),一个用 XNA 开发的游戏。这个东西似乎没有流传到外面。(上一年大神开发的类似性质的 Ocean Scream 可是作为编程竞赛的平台的。后来微软策略改了,SpaceMoto 后面也没听到什么消息。)不过呢,其实主要是我和另外几位(另外几位是大神)在讨论设计之类的问题,不过后来我也没怎么参与了,这位同学一个人将 SpaceMoto 写了下来……
然后大二这一年,我在 MSTC 中非常非常不活跃,仅仅是负责了第一次招新……我都怀疑自己能否有能耐和那些大神们坐在一起选新人……
不管怎么样,Ocean Scream 的源代码我还保存了一份。一年前我看的时候,总是搞不清游戏的运行机制。当时思维主要还在 VB6 的阶段,VB .NET 也只是简单应用;代码里各种东西觉得乱七八糟的,看不懂。一年之后,我终于有足够的能力做 MonoGame 的开发了,能读懂为什么要这么写代码了,能做一点应用了。
说实话,我不知道这一年来我在技术方面积累了什么,好像没什么吧,但是这种感觉真的很神奇……
将我领进门的 MSTC 的成员们,感谢你们!特别是6系和21系的几位大牛。(在花园里点名表扬好么?好的话就点名了吧……)
(为什么弄得有点像“师父在天之灵”的样子……诶诶我不是这个意思……)
PS. 因为是无类型/弱类型语言,而同时被我讨厌的还有 MATLAB、BASIC(不是 VB)和 JavaScript。
PPS. 人家 W. Dee 早我14年做出一个应用广泛的引擎,作为后辈,追是不容易的,但是还得有人有这个志向吧。
PPPS. 看演示的同学表示演示内容很蛋疼。
PPPPS. 有人会说:“你做了引擎,没有好内容,照样没有好游戏。”没错,所以要做成品游戏,还得找美工&音乐。
PPPPPS. @紫晓暮雾 关于之前提到的那个制作类似手绘2D效果的玩意儿,这个假期看了一些动画设计理论的书,表示我原来提出的,我还没有能力实现。就是说,以我计划能达到的技术水平,做出来的东西还无法达到设计师需要的水准。所以暂时搁置吧。但是还是要考虑的,不留 loose end。(← General Sheperd)
PPPPPPS. 如果你们在想我是6系或者21系的,那就错了。 *2014-09-07 13:13 加入
2014-09-07 12:50
(此内容针对 AVG)
在脚本指令里多加一条,游戏页面中加入一个图像控件,一个简单的立绘系统就完成啦~由于每个元素都可以应用特效,所以拓展是非常方便的~
2014-09-08 (因花园暂时关闭而未发上来)
更改了字体渲染后端。现在可以脱离 System.Drawing
运行。(不过附加问题是排版上有时有 3 px 左右的偏离,以及字形的控制要自己写……好吧我得看看文档……)
另外一个重大改进是,解决了锯齿&字体颜色问题。这里给可能会遇到该问题的后人留解决关键吧:Microsoft.Xna.Framework.Color 的颜色格式其实是自乘(premultiplied)的。相关信息见链接。怪不得 PixelFormat/SurfaceFormat 里还有 PARGB(就是 Premultiplied ARGB 啦)的枚举值……
2014-09-09
修复了一个透明度bug。此外,AVG 子系统开始制作。
2014-09-11 *
Public demo 有希望了……不过马上就是国赛,然后立即开始上课,体力可能会不济,时间推迟一些……
嗯,附加一句,以现在的框架,写起来就和写 WinForm 程序一样。
2014-09-12 凌晨 (00:15)
给字体布局写了一个解决方案,多次测试暂时没发现问题。因为所用的东西和 TrueType 的文档有些地方不一样(或者是我的理解问题),所以还无法验证该方案是否真的没问题。
另外 MonoGame 的最小化-恢复问题真的要命啊……还没有一个好的方法解决这个问题……
今天早上就要开始国赛了我是不是在作死……
2014-09-12 凌晨 (02:40)
睡觉之前想还是解决一下窗口大小的问题吧……结果这么下去就继续作大死了。
刚刚解决(在 Windows 平台下,其余未测试)。结果表明不是 MonoGame 的问题,而是我原来处理方式有误。
上社区&调试了半天,发现最小化时会发送一次 ClientBounds = Rectangle.Empty
的消息。然后对其进行响应,保存并恢复状态啥的……两个多小时就这么过去了。
附加的提示:建议开启 IsFixedTimeStep
,这样 XNA/MonoGame 会自动帮你处理刷新速率问题。如果设置为 False
的话,在窗口大小为零时由于 Draw()
立即返回,导致 Update()
被几乎是死循环式地调用。
另外,如果在最小化(此时位置为 (-32000, -32000)
,大小为 (0, 0)
)时,如果不按照默认处理办法(直接按照新窗口大小为0进行自动调整),而将缓冲区大小强制设定为一个非零大小的值(例如 (160, 90)
)并绘制,会出现一个 CPU 占用率也不高但是所有操作都变得非常缓慢的问题,不知道是什么造成的。在这里记录下来。所以我才写了一段很别扭的代码用来检测和避免各种恶心的情况。找原因和解决,这两步都花了很长时间……
看社区里人们遇到的问题,例如早期 OpenTK v1.0 的 (1, 1)
问题(导致无法最小化;在 OpenTK v1.1 中修复为 (0, 0)
,就是现在的样子),会手工解决的人不多,所以哀鸿遍野,感觉我用的还是经过多次改进的东西,算轻松了……
看来是真作死了。
2014-09-12 凌晨 (03:57)
本来以为好了,谁知道在失焦和最小化的时候还是有卡顿的现象……于是琢磨了一个小时……现在算是可以了,但是代码里一堆“// HACK:”……
2014-09-23
开学之后果然很多事情就出现了。今天脚本系统(原型)才初步测试完毕……不过目前已经隐约有游戏的影子了……
2014-09-26 凌晨 (01:44)
卡顿的问题还没解决,只好限制重绘时机了。另外,有时居然发生音频值错误,而且根据调试结果,是多次多点偶然的……
一条线制作完成。嗯细节么……这是一个 technical preview 而已,所以八分相像即可。另外,还是拿SN开刀
2014-10-01 凌晨
找了第一只小白鼠试验运行了一下。这位小白鼠今天早上还要出队爬山,感谢啊感谢。被所采用的组件坑了不少。
先记下来吧。VCRT12(某个蛋疼的家伙居然拿 VS2013 来编译,在小白鼠的机子上直接就初始化失败了,幸亏我还是有点经验,去查看了导入表)/OpenAL,绝对绝对不能缺。
2014-10-10
更新了所有的集合操作逻辑,妈妈再也不用担心迭代器无效啦~(当然,也有限制,例如更新时机需要掐准。)