【制作日志】phigros电脑移植制作过程

【制作日志】phigros电脑版制作过程

前言:如果你发现一个纸飞机飞的特别远,你也想做一个相同的,那么最简单的方法就是拿一张一样的纸,对着一样的折叠教程折一遍,这样虽然你还是不知道为什么这么折飞得远,但是研究起来就会方便很多。但是当你没有折叠教程的时候,就只能发挥自己的想象力了。最终可能你也不知道你的折法和他的折法是不是一样的,但是至少你的纸飞机飞的也蛮远的。
作者:一墨滢一 https://www.bilibili.com/read/cv8012350 出处:bilibili


零、日志的最近更新与一些通告

2021.8.14 16:26
删除了第二章“note方面”中的一个“谨慎添加”,添加了一段话
2021.8.15 15:37
修改了一系列标题的字号

这篇文章与这些程序不是由官方写的,以下内容仅供学习程序,请勿用于其他情况。
文章的程序虽然是用scratch写的,但是有全部语言的泛用性,在阅读时请注意。


一、愚か者の賢人論

————角色创建

note方面我这里采用的是我以前就画好过的素材,线随便整一条就好了
note的素材以后我兴许会改吧,但现在能用就行了
击打特效方面的话原本也是有画的,但想改改,现在就先不用吧


二、Moonlight Of Sand Castle

————note的行进引擎的搭建

这应该是我最想讲的一个模块,当年没怎么学习坐标系的我就在这瞎推公式,不过最终还真给我做出来了(
现在初中毕业,再来看看还能不能再现奇迹吧(大嘘)


判定线方面

创建\(LineQuantity\)变量,记录判定线的数量
创建\(LineAngle,LinePosX,LinePosY\)列表,实时记录判定线的坐标与角度
创建函数重置判定线信息,用来清除以上列表数据,同时根据\(LineQuantity\)的值为列表开辟新空间
创建函数记录判定线角度、坐标,用来上传信息至上列列表
image

note方面

因为note是跟着判定线动的嘛,所以肯定需要接收以上判定线给出的变量
创建\(BelongWhichLine\)列表,帮助note获取到对应判定线的信息
创建\(NoteQuantity\)变量,记录note数量

目前的调试阶段中,我们将非克隆体的本体的id设为1号
在之后实用时会改成0号,后面类推
Line方相同

创建函数移动,准备制作note在判定线在 无论任何方向任何位置任何时间任何音游 都能准确找到自己位置的移动啦(


我们规定,note在生成时离判定线的距离是600,为什么呢?
image

因为屏幕的最远距离是600,然后没有什么别的原因了,方便而已

在这篇日志的其中一个版本中,这一段被标上了“谨慎添加”,因为当时认为这个想法存在问题,会出bug。我写这段话的目的是提醒读者,看这篇日志的时候一定要保持思考,思考是否存在问题,是否能在自己的程序中用得上,是否存在改进的空间。毕竟这是在制作过程中边做边写的,难免会存在后来的想法推翻前面的想法的情况,望周知。我之后也会在日志前面打上关于之前段落的修改内容,请注意查看。


创建\(RemainingDistance\)变量记录note到判定线的距离
创建\(NotePos\)列表记录note在判定线上的x坐标
image

如图将会有两个note到达判定线上,红点为判定线中点。左边的note离中点20个单位长度,它的\(NotePos\)记为\(-20\),右边的即记为\(10\)

这个\(BelongeWhichLayer\)\(LayerSpeed\)不是现在写的,只是偶然间见一妙文,为记录,先创建下来

如下图,为任意时刻的note位置的推导过程。
其中O为判定线的中点,A为note位置,\(Lx\)\(Ly\)为判定线中点坐标,\(Nx\)\(Ny\)是写错了,都是记录下的\(NotePos\)

PS:字有点丑

image

在我实际运用的时候,由于scratch本身的方向设计和我的一些计算错误(我现在不知道是否真的有这个错误,麻烦有大佬帮我找找,谢谢了),会需要你在程序中调整一下正负号或者角度(比如加个减个90°之类的)
我最终使用的是这样的:

\(Ax=Lx+A''x+B'x\)
\(Ay=Ly+A''x-B'x\)
图中的90°-\(\alpha\)全部改为-\(\alpha\)

请自己根据自己的情况自行更改


二点五、间奏

前面讲的好像太罗嗦了,接下来会粗一点


三、AMAZING MIGHTYYYY!!!!

————Note与判定线的批量添加和Layer功能

note的生成

我们还没有做Note的生成呢,现在我们来完成这一点
并没有多难,拿\(RunTime\)\(NoteAppearTime\)比较就好了,到了就克隆出去
其中的一些克隆的技巧这里就不说了

如果你要制作制谱器的话,像我一样,你就得继续做点东西
在制谱器中,无论任意时刻我们都需要看到此时刻的情况。而如果你直接从第一个note开始比较的话,会出现这个时刻已经不该出现的note被克隆出来,这是我们不愿意看到的

你只要在整个\(RunTime\)\(NoteAppearTime\)比较前面多加一个找到一个\(NoteReachTime\)比目前\(RunTime\)大或等的,然后接下来的比较下标就从比\(RunTime\)大或等的这个note的下标开始就好了

至于为什么是\(NoteReachTime\)而不是\(NoteAppearTime\),你可以分类讨论自己看看情况,这里不多赘述


添加note

为了方便,让我们来包装一个可以批量添加note的方法吧!

一个note应当要有的信息:

信息 对应列表名
到达(击打)时间 \(NoteReachTime\)
种类 \(NoteType\)
所在判定线 \(BelongWhichLine\)
坐标(或是从哪一条轨道下落) \(NotePos\)
Layer(或是速度) \(BelongWhichLayer\)(或是\(NoteSpeed\))
生成时间 \(NoteAppearTime\)

前五个你肯定是要自己填的,最后一个我们需要通过到达时间与速度来生成

在我的程序中,我将生成时间定义为note最后一次到判定线的距离为600的时间,这一点可以根据自己需要更改。在我这里,因为是“最后一次到判定线的距离为600的时间”,所以会出现一些情况,在绝大部分情况中,这是无伤大雅的,因此我暂时不予修改。

记得要给列表按照NoteAppearTime从小到大的顺序进行排序


Layer

在讲解计算NoteAppearTime之前,我们需要实现“Layer”功能。

Layer是什么?我的理解是,layer是速度分组,这个功能可以让我们自由地操纵变速。

1.因此,只需要做不变速的读者可以跳过这一段。
2.在这里不写所有note一起变速的方法,但这只是我们的一种特殊情况,你可以理解成只有一层layer(如果没看懂,你就先继续看)
3.这是比较多坑的一个部分,制作时务必要小心,可以找qq2937278768问我

当然,我们还有一些问题没法解决,比如:当某个音符被反复击打时,我们只能让这一个音符出现在谱面上,无法实现“下面是正常的4K,上面有一个note在BGM的每个drop都被打一下弹起来”的效果。以及我们无法实现不同轨道不同速度的效果。
作者:一墨滢一 https://www.bilibili.com/read/cv8012350 出处:bilibili

我们可以把某一些note放入到一个新的layer中,而对于这些layer,我们可以对同一个范围的不同layer设置不同的速率因子。但是在演出时,这些layer看起来是不分离的,这有点像是Photoshop的图层的感觉
作者:一墨滢一 https://www.bilibili.com/read/cv8012350 出处:bilibili

不同轨道不同速度,不同note不同速度,还要变速,这就是我们制作Layer功能的初衷。

你需要有一些列表来存贮不同layer的信息,我准备了以下列表(打※号的不一定需要):

信息 对应列表名
当前的layer的速度 \(LayerSpeed\)
当前的layer的速度是由第几次变速而来的 \(LayerSpeedId\)
layer的速度要变成多少 \(LayerSpeedChangeTo\)
是哪个layer要变速 \(LayerSpeedChangeWhich\)
要在什么时候变速 \(LayerSpeedChangeTime\)
※下一次同一个layer变速的下标 \(LayerNext\)

一个layer在一个谱面中可能有好几个变速,一个谱面也可能会有好几个layer。这是layer和其变速的关系。新建一个layer和新建一个layer的一个变速是不一样的概念。

是个人都知道,我们应当按照时间顺序给layer变速。但是我懒得写排序,所以我在每次添加一个变速的时候都找到合适时间插入,这样也能保证是按照时间顺序排序的。

这样给layer变速的代码就很轻而易举地写出来了:从头开始遍历,等当前时间大于了\(LayerSpeedChangeTime\)的这一项(第i项),就更改\(LayerSpeed\)的第\(LayerSpeedChangeWhich\)的第i项项为\(LayerSpeedChangeTo\)的第i项,\(LayerSpeedId\)的第\(LayerSpeedChangeWhich\)的第i项项标记为i

新建一个layer的时候,可以添加两个“假变速”或者说“默认变速”,它们是在时间为0时的变速和在时间为曲子总时长时的变速。

我使用了\(LayerNext\)列表,因为我最开始做Layer功能的时候,我在\(LayerSpeedChangeTime\)列表中存的是此次变速结束的时间而非开始的时间,这样写麻烦多多,尤其是它很难进行变速,请不要这么写。我现在虽然想改这个,但代码量积重难返(懒),放他一马。


重新回到NoteAppearTime的计算

现在我们继续做NoteAppearTime,对于有变速的音游,你必须搭建好相关的Layer功能或是总体变速的功能才能做这个,至于为什么留作思考题。

这个程序的第一步:找到NoteReachTime\(LayerSpeedChangeTime\)的所在区间

这个程序的第二步:算出NoteReachTime到区间左端点的时间差乘上区间速度,用sum来记录

这个程序的第三步:从目前为止开始向前找同一Layer的区间,计算这一区间的右端点时间与左端点时间的差乘上区间速度,令sum加上它

这个程序的第四步:重复第三步,直到\(sum>=600\),此时减去这个区间刚刚加上的值,往回找一个时间点,使这个时间点与此区间右端点时间的差乘上区间速度加上现在的sum为600.显然此时间点就在使\(sum>=600\)的这个区间内

这个时间点就是NoteAppearTime

为什么layer功能这么麻烦?

你觉得分段函数求和麻烦不麻烦呢?

上面NoteAppearTime的计算本质上就是找这个layer变速图在NoteReachTime>=x>=NoteAppearTime区间内与x轴围成的面积。

或者就是我孤陋寡闻,不知道更方便的分段函数求和的方法了

Line

直接把note的copy过来改个变量就完成了


四、混沌を越えし我らが神聖なる調律主を讃えよ

————演出

列表准备与一些乱说...

说到phigros,怎么能少得了判定线的演出呢

此前我们在note的行进引擎上的努力就是为了这一刻
好似从贴吧老哥那里二次嫖了几个段子的你,就是为了在你的朋友或者同学面前口嗨下

和往常一样,我们需要一些列表来存贮这些演出...
我将演出类型分为移动、旋转、显示/消失三种,此外还要存储的是演出的起止时间与演出的是哪个line,和存储移动距离或是旋转距离。这样就一共有五个列表了!(实际上我还额外用了一个,用来存储移动演出中的y坐标移动)

我年少不懂事,将这些东西都存在同一个列表里,弄的列表十分臃肿,使起来特别难受。
类似于喝稀粥时把ABC三种榨菜全放进去了,但我只想吃榨菜A,从稀饭里面挑想要榨菜吃,就是很难受的事了...

所以啊,我的朋友萌,压榨列表的时候一定要慎重!


接收演出信息,出演!!!

演出是一个持续一段时间的东西,既然我们需要获取得到任意时刻的判定线的坐标等等,我们就要每分每刻地计算演出结果

以x坐标的演出为例,假设这个演出是让一个判定线的x坐标增加\(L\),开始时间与结束时间分别为\(t_{S}\)\(t_{E}\),若当前时刻的时间为\(t_{R}\),判定线原本的x坐标为B

那么显然当前时刻的x坐标应当是\(B+\dfrac{(t_{R}-t_{S})L}{t_{E}-t_{S}}\)

我所使用的接收演出信息的模式是这样的:

分成三个程序,分别同步地执行三个函数,每个函数都检测一种演出,类似于克隆note那样,到了演出开始的时候,就重复执行直到演出结束时间到达地执行当前演出,例如将判定线的x坐标变为\(B+\dfrac{(t_{R}-t_{S})L}{t_{E}-t_{S}}\)

能够重复执行的原因是,我现在做的版本只允许同一时间只能进行一个同一类型的Act(我想了想应该也不会出现要有两个演出的情况......吧)


五、The Cat Evolved Into The Microwave-proof Cat!

————击打特效和击打判定

击打判定

由于我是不善长画画的,所以我们先说击打判定,到时候击打特效可能会一笔带过

我的键位设计是这样的:

ASDJKL六个键位,击打其中之一就看作打了一个note,没有轨道之分。
同时,tap、drag、hold等同于phigros,flick看作抬起。


附录一、窓

————目前能获取到的错误

这些错误的发生原因都是玩家自己打开作品创作页不小心碰到什么东西,或者不小心删除了什么东西,也就是无法避免的bug。

如果有因为你没有打开作品创作页就出现的bug,那就是真正我该修的bug了,这种请报告给我,感谢!

1.Note没有与之对应的Layer
2.Layer的时间排序错误
3.同一类型的Act时间区间重复(现在的版本我们只做了同一时间只能进行一个同一类型的Act)
4.NoteReachTime小于0
5.

见到一个加一个

posted @ 2022-02-15 14:58  Nextlock  阅读(259)  评论(0)    收藏  举报