中国大学排名前十名
【制作⽇志】phigros电脑移植制作过程
【制作⽇志】phigros电脑版制作过程
零、⽇志的最近更新与⼀些通告
2021.8.14 16:26
删除了第⼆章“note⽅⾯”中的⼀个“谨慎添加”,添加了⼀段话
2021.8.15 15:37
修改了⼀系列标题的字号
这篇⽂章与这些程序不是由官⽅写的,以下内容仅供学习程序,请勿⽤于其他情况。
⽂章的程序虽然是⽤scratch写的,但是有全部语⾔的泛⽤性,在阅读时请注意。
⼀、愚か者の賢⼈論
————⾓⾊创建
note⽅⾯我这⾥采⽤的是我以前就画好过的素材,线随便整⼀条就好了
note的素材以后我兴许会改吧,但现在能⽤就⾏了
击打特效⽅⾯的话原本也是有画的,但想改改,现在就先不⽤吧
⼆、Moonlight Of Sand Castle
————note的⾏进引擎的搭建
这应该是我最想讲的⼀个模块,当年没怎么学习坐标系的我就在这瞎推公式,不过最终还真给我做出来了(
现在初中毕业,再来看看还能不能再现奇迹吧(⼤嘘)
判定线⽅⾯
创建LineQuantity变量,记录判定线的数量
创建LineAngle,LinePosX,LinePosY列表,实时记录判定线的坐标与⾓度
创建函数重置判定线信息,⽤来清除以上列表数据,同时根据LineQuantity的值为列表开辟新空间
创建函数记录判定线⾓度、坐标,⽤来上传信息⾄上列列表
note⽅⾯
因为note是跟着判定线动的嘛,所以肯定需要接收以上判定线给出的变量
创建BelongWhichLine列表,帮助note获取到对应判定线的信息
创建NoteQuantity变量,记录note数量
⽬前的调试阶段中,我们将⾮克隆体的本体的id设为1号
在之后实⽤时会改成0号,后⾯类推
Line⽅相同
创建函数移动,准备制作note在判定线在⽆论任何⽅向任何位置任何时间任何⾳游都能准确找到⾃⼰位置的移动啦(
我们规定,note在⽣成时离判定线的距离是600,为什么呢?
因为屏幕的最远距离是600,然后没有什么别的原因了,⽅便⽽已
在这篇⽇志的其中⼀个版本中,这⼀段被标上了“谨慎添加”,因为当时认为这个想法存在问题,会出bug。我写这段话的⽬的是提醒读者,看这篇⽇志的时候⼀定要保持思考,思考是否存在问题,是否能在⾃⼰的程序中⽤得上,是否存在改进的空间。毕竟这是在制作过程中边做边写的,难免会存在后来的想法推翻前⾯的想法的情况,望周知。我之后也会在⽇志前⾯打上关于之前段落的修改内容,请注意查看。
创建RemainingDistance变量记录note到判定线的距离
创建NotePos列表记录note在判定线上的x坐标
如图将会有两个note到达判定线上,红点为判定线中点。左边的note离中点20个单位长度,它的NotePos记为-20,右边的即记为10。
这个BelongeWhichLayer与LayerSpeed不是现在写的,只是偶然间见⼀妙⽂,为记录,先创建下来
如下图,为任意时刻的note位置的推导过程。
其中O为判定线的中点,A为note位置,Lx、Ly为判定线中点坐标,Nx、Ny是写错了,都是记录下的NotePos
PS:字有点丑
在我实际运⽤的时候,由于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问我
不同轨道不同速度,不同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.
见到⼀个加⼀个
Processing math: 0%
打电话谁先挂