defisym

lofter是啥,能吃吗?
这里主要是不务正业的东西。
啥,你问正经的去哪儿看?我也想知道哎~
╮(╯▽╰)╭
或许微博和知乎上稍微正经点吧(并不
真的要叫Decade Studio的话,LOGO请务必设计成鸽子形状的,咕咕咕~

AVG-链式结构/加载优化/半透明/剧情线跳转

文本块的组成结构:

在开始新游戏时,系统会指定一个文本块值,默认为100000,并且对该文本块进行解析操作,依照其导演代码进行演出

在文本结束时,需要指定跳转值,可以为章节(直接更新文本块值并继续对白),也可以为场景

当然使用后者不会更新文本块值,如果返回AVG界面依旧会重复上一个文本块,需要在目标场景中更新文本块值来不破坏链式结构

文本块的加载优化:

在文本块内,由;开始的行会被认为是注释,同时还承担着作为跳转标签的任务,所有文本块内跳转指令(如jmp,switch等)均需要定义标签值,系统会跳转到该标签所在的位置并继续执行导演代码,而标签并不可直接跳转,在加载文本时会对文本进行遍历,计算出标签所对应的行号,就像汇编计算标签的地址一样

本来,我的意思是本来,这应该由编译器做好了系统直接读,但文本这东西是要经常改的……我可不想和上次一样搞出来N多个轮子,做一个文本块需要来回来去捯扯,于是编译的事情是在加载的同时进行的

在测试各个指令的时候,这样做是没有问题的,毕竟就十几句测试文本,但实际使用中文本量是会很大的,一个块内1~2万字都很正常,所以需要对加载进行优化,而优化的重点就放在了存档与跳转界面(其实打开各个页面已经调用了存档功能,返回AVG界面则是调用读档功能,背景其实是在打开界面的瞬间进行的截图)

经过测试可知,当文本量小于1万字,即500行左右,30KB上下时,可以在一秒之内完成加载,用户很难体会到

在每次完成编译后,都会保留一个缓存文件,每次需要编译时,会验证该文件是否与当前文本块值一致,若一致则跳过编译过程;若不一致,则判读文件大小,大于25KB则进入loading界面,小于则在点击的瞬间完成加载与编译过程



引擎运行的机制是完成一帧内所有的指令后刷新画面,如果还是像之前那样将加载与编译放在一帧内完成而非并行处理,那么loading界面的意义并不大,还很有可能会失去响应……所以需要稍作修改为并行处理,也就是将整体的任务平均分配至每一帧内完成

所以说loading终于是真loading了_(:з」∠)_

借着这个契机修掉了一个存在了两年的超经典bug,即可以保存一个毫无意义的标题画面的存档(这个与存档的实现原理有关,存档模块会记录跳转之前的场景编号,也就是标题画面的编号,存档的截图也是在这个时候保存模糊并作为底板,保存就是复制临时存档,所以就能存上标题画面这个毫无意义的东西……)

立绘的不透明度:

简单但是很有趣的功能,可以做背后灵或者嘴上笑嘻嘻心里MMP的戏剧场景



跳过章节:

之前一直在纠结跳过章节的问题……因为存在有跳转指令和选项的问题

本来想的是跳转时遍历文本,然后进行跳转判断(真麻烦,我真蠢),后来决定采用投机取巧的方法

由于会查表转译标签,在这个过程中把所有可能造成跳转的指令扫描出来并且存储,跳转时查表,找到大于当前对话进度的进行跳转

这样处理,可以实现:跳转到下一次存档/跳转到下一次跳转标签/跳转到下一次跳转场景/跳转到下一次跳转章节/跳转到下一次剧情线操作

对话历史没有跟随更新,考虑到存在一个文本块内有大量文本的情形,如果通过循环来在一帧之内更新历史文本的话,会卡……

也算是取舍吧

剧情线操作:

嗯,给人一种很熟悉的感觉

我们的老朋友8086汇编……



changeline指令可以更新剧情线值,而cmpline这是将当前剧情线值与目标剧情线值进行比较,得出标记值

再通过je/ja/jb/jne指令,故事线当前值等于/大于/小于/不等于比较值,即即标志位为0/1/-1/≠0时,跳转到指定标签

其实归根结底不过是解析文本并顺序执行程度的能力,离现代编译器差着十万八千里

顶多类似于翻译机器码,不需要考虑词法分析句法分析

比如创建标签,需要在creatswitch指令后附加参数来指定创建的标签数量,但如果是高级语言,格式就会是这样的:

creatswitch

switch1

switch2

switch3

……

end

不过已经比去年和前年那个大数组好的太多了……

------------

AVG系统的重构已经基本完成,接下来一直到月底的时间会把更多的精力放在考试的准备上

不过;类似这种话一般都是flag……想想一百多年前,说物理学只剩下两朵乌云,经过许多物理学家们不懈的努力,现在满天都是乌云

这大约也是我上次下定决心重构的原因吧……


评论(3)

© defisym | Powered by LOFTER