Slalom 64是顶视角的像素艺术滑雪游戏,我刚刚将它发 布在了iOS和Android平台上。这是游戏开发的故事。

https://preview.redd.it/8r6wz57zckzg1.png?width=1024&format=png&auto=webp&s=04291723a8a6f95b6a3971247a13aa60e0986bb5

奇特的技术选择

我不是游戏开发者。我是一名知道后端技术和React Native一些基本知识的软件工程师。因此,我没有学习Unity或Godot。相反,我想看看RN游戏平台有多远能让人走通。结果比你预想的还要远,边界却非常锋锐。

绘图栈:/react-native-skia绘制到一个离屏的180×320画布(C64的原生比例),然后使用FilterMode.Nearest将其扩展到设备分辨率。
没有抗锯齿 – 整个风格就是粗糙的像素。在高度不同的手机上,它使用黑边进行字母排列。

游戏循环问题

React Native并没有给你requestAnimationFrameUI线程。你得到了react-native-reanimateduseFrameCallback,它在工作员中运行 – JS类函数直接在UI线程中执行,绕过React和JS桥。

但是有个陷阱:工作员可以捕捉编译时值。如果在运行时需要改变状态(例如,速度加速度在检查点上),那么该值必须是一个SharedValue,而不是普通变量。获取它不正确会产生真正令人困惑的BUG – 变量在JS中更新,但工作员永远在用旧值。

无论实际帧时间如何,物理始终在16.67ms固定时距步上。这意味着在60HZ和120HZ设备上的行为完全相同,尤其是对于一个时间是关键的游戏来说。

声音

react-native-audio-api – React Native的Web音频API实现。单个AudioContext单例,decodeAudioData用于加载,AudioBufferSourceNode用于火灾效果音。很好。但是你需要在用户手势上初始化上下文,或者iOS会默默地拒绝播放任何内容。

过程式轨迹生成

每一个关卡都被传入一个固定的值(mountainIndex + 1 * 1000 + levelIndex),这样每一帧产生的是相同的关卡。无尽模式使用会话传入值和块索引来预生成20个块。门位排列是随机的,总是偏向外围wall。障碍物被排除在每个门外围1.5倍的安全区内。所有随机都是通过被传入值的循环伪随机函数来实现的,而不是使用Math.random来产生随机数。这是实现重复可复现的关键。