ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Pyrite64节点图变量与图时钟:协程、变量持久化与Wave节点相位原理

Pyrite64节点图变量与图时钟:协程、变量持久化与Wave节点相位原理 Pyrite64节点图变量与图时钟协程、变量持久化与Wave节点相位原理【免费下载链接】pyrite64N64 Game-Engine and Editor using libdragon tiny3d项目地址: https://gitcode.com/GitHub_Trending/py/pyrite64Pyrite64 是一个基于 libdragon 与 tiny3d 的 N64 游戏引擎和编辑器。它的节点图Node Graph让你不用写 C 就能用拖线的方式编排游戏逻辑图被编译成游戏运行时执行的 C 代码并作为协程逐帧推进。本文讲透三件事变量如何持久化、图时钟graph clock如何走动以及Wave 节点的相位原理。一、节点图为什么是协程从连线到可暂停的代码在 Pyrite64 中节点图不是运行时解释的——编辑器在构建时把连线关系直接生成 C 源码每个Wait Frame变成一个coro_yield()游戏引擎每帧用coro_resume()唤醒它。核心实现在 nodeGraph.cppInstance::load()调用coro_create()为每个对象创建一个协程实例Instance::update()每帧coro_resume(corot)跑完即coro_destroy。这解释了节点图最重要的直觉图是可以睡的。执行流走到Wait就停在半路帧与帧之间的状态由两类东西保存变量Variables——用户声明的命名存储图时钟inst-time——记录图实际在跑的秒数。理解这两者就理解了 Pyrite64 节点图的全部时间语义。二、变量持久化声明一次跨帧、跨等待都记得值声明与读写在编辑器左侧的Variables 面板声明变量名称 类型Int、UInt、Float、Vec3、Quat 或 Object然后用两个节点访问节点清单见 nodeGraph.md节点作用Get Var读取变量引脚自动匹配变量类型Set Var写入变量支持 OpSet / Add / Subtract并输出结果值Set Var输出结果值是个小设计亮点一个节点既是赋值又是取值天然适合做每帧累加的计数器配合Wait Frame回环就是一帧 1 的节拍器。持久化在内存里怎么落地编译时所有变量被打包成一个按类型对齐的字节块var blob随实例存活整个运行期运行时结构体里有一块void* vars见 nodeGraph.hInstance类注释明确写着变量跨Wait保留每个变量的读写被生成成在固定偏移处的类型化 lvalue即inst-vars上的偏移访问代码生成逻辑在 graph.cppvarBlobBytes/ 变量偏移烘焙。所以变量持久化的本质是协程暂停时栈被冻结但变量不在协程栈里而在实例结构体中——这就是为什么计数、状态机、上次方向这类数据能在Wait之后原封不动。每对象默认值同一张图不同初始状态同一张图资产可以挂到任意多个对象上。每个声明的变量都会出现在每个对象Node Graph 组件上让你逐对象设置起始值Object 类型变量更是直接变成对象选择器——同一张图不同实例可以指向场景里不同的目标对象。三、图时钟只在跑的时候走每个图实例自持一个time字段nodeGraph.h 中注释Advances per active frame, but is frozen while the graph waits/sleeps。它的推进规则非常讲究场景inst-time行为执行到Wait Framecoro_yield()让出 加上本帧 deltaTime执行到Wait睡眠 N 秒冻结醒来后不追加勾选Repeat回环回到 Start 的路径上同样累加 deltaTime生成代码的对照来自 flow.js// Wait Frame 节点生成的两条语句 coro_yield(); // 下一帧再唤醒 inst-time P64::VI::SwapChain::getDeltaTime(); // 本地时钟前进而Wait节点只生成coro_sleep(...)——时钟不动。为什么要冻结一句话让波形跨暂停保持连续而不是跳变。假设你用一个 Sin Wave 驱动上下浮动的平台中途图睡了 3 秒若时钟照真实时间走醒来瞬间相位前移 3 秒平台瞬移到另一个位置视觉上是跳变时钟冻结醒来后波形从暂停前平滑续播。这个设计让协程暂停对时间驱动节点透明是 Wave 类节点可用的基础。四、Wave 节点相位原理一个公式看懂全部Pyrite64 内置 5 个振荡器Sin Wave / Cos Wave / Square Wave / Saw Wave / Triangle Wave定义在 value.js。它们共享同一个相位公式输出 Amplitude × wave( time × Speed Offset )其中p time × Speed Offset的单位是周期数cycles。五个波形对p的映射源码原式波形表达式p 为周期数特性Sinfm_sinf(p × 2π)平滑振荡Cosfm_cosf(p × 2π)比 Sin 领先 1/4 周期Square(p − ⌊p⌋) 0.5 ? 1 : −1方波Saw2 × (p − ⌊p⌋) − 1锯齿Triangle1 − 4×| (p0.25) − ⌊p0.25⌋ − 0.5 |三角波三个输入引脚 一个 Range 选项各管一件事Speed每秒周期数。p每秒前进Speed个周期所以 Speed2 就是 2HzAmplitude整体缩放作用于最终输出Offset相位偏移单位是周期数。Offset0.5 就是把整条波形向右平移半拍Range-1..1双极性或0..1单极性即先把波形(w×0.50.5)重映射。Offset 的妙用多个共享同一时钟的 Wave 节点默认起点相同、完全同步。给每个节点设不同 Offset如 0、1/3、2/3就能得到互相错开的三相波形——做环绕旋转、轮流闪烁、三通道颜色振荡都靠它不需要任何额外状态。⏱️ 注意因为p由图时钟驱动Wave 输出只在图活跃推进时变化。想让波形每帧都刷新图必须每帧醒着例如用Wait Frame回环或勾选 Repeat否则时钟冻结波形也冻结。五、实战速查搭一个浮动平台给对象添加Node Graph组件并创建图组件文档Variables 面板声明Float y 0可选用于记录高度主线Start → Get Position → Set Position → Wait Frame →回到Get Position给 Set Position 的 Y 输入接一个Sin WaveSpeed0.5、Amplitude0.5、Range0..1 再经 Map Range 缩放到想要的幅度中途加Wait比如玩家靠近才启动醒来后浮动物从暂停处继续不会跳位。六、关键路径速查内容路径节点图官方手册docs/docs/manual/script/nodeGraph.md自定义节点开发docs/docs/manual/script/nodeGraphCustom.md协程运行时n64/engine/src/script/nodeGraph.cpp实例结构体与time字段n64/engine/include/script/nodeGraph.hWait / Wait Frame 代码生成data/nodes/builtin/flow.jsWave 节点定义data/nodes/builtin/value.js变量偏移烘焙与生成src/project/graph/graph.cpp核心要点回顾Pyrite64 节点图 编译期生成 C 运行期协程变量存在实例的 var blob 里所以能跨Wait存活inst-time只在实际执行的帧上累加保证波形跨暂停连续Wave 的一切行为都由Amplitude × wave(time × Speed Offset)一个公式决定Offset 就是免费的相位调节器。【免费下载链接】pyrite64N64 Game-Engine and Editor using libdragon tiny3d项目地址: https://gitcode.com/GitHub_Trending/py/pyrite64创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表