欢迎光临散文网 会员登陆 & 注册

音游制作杂谈(230409)

2023-04-10 00:44 作者:Fuxfantx  | 我要投稿

在xx时间,发生xx事件

  • 大多数情况下,Flag法是很够用的:


  • 对于Lua而言,Flag法可以做一个简单的升级:

    {

    {88888, "dosthA()"},

    {77777, "dosthB()"}

    }

    事前按时间倒序排序,每帧从最后一组开始遍历:当前时间>=发生时间,执行之,然后给对应的元素赋nil;当前时间<发生时间,退出遍历循环。

    执行上可以直接dofile(),执行完直接给对应项赋nil。

  • 时间敏感性:游戏引擎的生命周期函数很难均匀执行,“基本只能保证每秒执行的次数是对的”,因此如果涉及到时间敏感性很高的事件(比如有个Note要在下落纸带上来回跳)就应该转变思路、换用状态机来实现:

    时间敏感事件  ->  时间不敏感事件  +  状态机

异步输入

音游是一个相对小众的游戏品类,所以游戏引擎一般是不实现异步输入的。游戏引擎一般考虑一帧一轮的设计思路,输入检测往往局限于“若该帧有输入,就把输入信息发给回调函数”。

近两年的设备触控报告率往往两倍于甚至更多倍于屏幕刷新率,为了充分利用设备的触控报告,就需要摆脱引擎本身的“一帧一轮”制约。那么,首先必须能直接对接操作系统API,甚至硬件API,以拿到原始输入信息。其后考虑两种思路:

A. Fixed Update。每秒执行很多次“拿原始输入”+“进行输入有关的游戏逻辑”

B. 缓存近几次输入,然后走Update,还是每帧运行一次游戏逻辑。

关于脚本层面和怎么和系统层面通讯,不同引擎有不同的实现。就个人而言,个人计划使用Defold引擎,而Defold所有脚本组件运行在同一个Lua State下,这意味着可以把“原始输入”直接存在Lua State的一个全局变量中。通过C/C++修改Lua State里的某个Lua变量也是比较方便的。

最终,异步输入这么实现:

通过C/C++逻辑捕获系统的输入报告,经过一些包装之后把输入报告(输入情况+时间)缓存到Lua State里的一个全局表中。游戏逻辑可以直接访问存储输入报告全局表。

简单拟两个注意事项:

A. 如果考虑缓存法的话,脚本一次Update会处理复数个输入报告,就需要想个办法判断下缓存的输入报告是否属于当前帧的处理范畴。对于Defold的话,可以利用一下Update传入的dt参数,应该是没问题的;

B. 很难预测全局Lua表更新、脚本的执行等在时间上的先后,因此在脚本Update逻辑的开头,应该把输入报告表深拷贝一份,后续逻辑围绕这份深拷贝进行。


曲线的实现

很难回避直线拟合+插值。

对于不太想涉猎底层API的人,能理解到这一层应该够用了(指直接拿Sprite拼图):

平行四边形或梯形  =  矩形  +  一两个直角三角形  =  更多的直角三角形

愿意涉猎底层一些的API的话,就根据插值节点去生成顶点流,然后用顶点流去生成Mesh。拿到Mesh走材质贴图,甚至着色器,只要肯学都会有办法的。


音游制作杂谈(230409)的评论 (共 条)

分享到微博请遵守国家法律