REPENTOGON NightmareScene 全局类完全指南:操控过渡场景精灵与回调
游戏开发插件系统【免费下载链接】REPENTOGONScript extender for The Binding of Isaac: Repentance项目地址https://gitcode.com/gh_mirrors/re/REPENTOGON点击查看免费下载NightmareScene是 REPENTOGON 为《以撒的结合忏悔》The Binding of Isaac: Repentance注入的 Lua 全局类用于访问游戏在**关卡过渡场景stage transition / nightmare scene**中使用的全部精灵Sprite与状态数据。本文以官方文档 docs/docs/NightmareScene.md 为核心骨架结合仓库源码逐函数讲解 API 签名、返回值与底层实现并演示如何配合MC_POST_NIGHTMARE_SCENE_RENDER、MC_POST_NIGHTMARE_SCENE_SHOW回调在过渡动画中注入自定义视觉内容。读完本文你将能在 MOD 中自由替换过渡场景的背景、进度条、玩家肖像读取进度条映射表并判断当前是否处于 Dogma 噩梦场景。NightmareScene 是什么过渡场景的画布访问入口在《以撒》中每次进入新楼层时屏幕上会播放一段短暂的过渡动画背景是楼层剪影中间是带有楼层进度的进度条玩家的头像肖像从上一个楼层走到下一个楼层。这段动画在游戏内部由一个名为NightmareScene的类负责渲染。REPENTOGON 将其以全局表global table的形式暴露给 Lua 脚本。与 StageTransition 类形成明确分工——后者只负责配置过渡如何播放如GetSameStage/SetSameStage控制 Isaac 的头像是否移动而如果你想直接操控过渡画面里的内容背景、气泡、进度条、肖像就必须使用NightmareScene类。这两者一个管行为参数一个管视觉元素是设计上的一对互补接口。获取方式与调用约定依据文档 docs/docs/NightmareScene.md通过全局表NightmareScene直接访问无需实例化即可以用NightmareScene全局表获得这个类。调用这些函数必须使用.句点而不是:冒号因为它们是静态全局函数不接收 self 参数local sprite NightmareScene.GetBubbleSprite()警告在游戏完全初始化之前不要调用本类的函数请确保只在回调callback上下文中使用。这是因为该类的全部函数最终都通过g_Manager-GetNightmareScene()获取单例指针见 repentogon/LuaInterfaces/LuaNightmareScene.cpp在 Manager 尚未完成初始化时该指针不可用。从源码看这个全局表的注册发生在LuaEngine::RegisterClasses钩子中LuaNightmareScene.cpp共有 6 个函数被挂载到NightmareScene全局表Lua 函数返回类型说明GetBackgroundSprite()Sprite过渡场景背景精灵GetBubbleSprite()Sprite过渡场景气泡精灵GetPlayerExtraPortraitSprite()Sprite玩家的额外肖像精灵GetProgressBarSprite()Sprite进度条精灵GetProgressBarMap()int[]进度条楼层映射表14 个整数IsDogmaNightmare()boolean当前是否为 Dogma 噩梦场景函数详解1.GetBackgroundSprite()→ Spritelocal sprite NightmareScene.GetBackgroundSprite()返回过渡场景的背景精灵。底层实现直接返回NightmareScene结构体内偏移0x20处的_backgroundANM2成员见 libzhl/functions/NightmareScene.zhl并以 Sprite 元表压入 Lua 栈LuaNightmareScene.cpp。2.GetBubbleSprite()→ Spritelocal bubble NightmareScene.GetBubbleSprite()返回过渡场景的气泡精灵即包裹玩家肖像的泡泡/气罩元素。对应结构体偏移0x134处的_bubbleANM2NightmareScene.zhl。3.GetPlayerExtraPortraitSprite()→ Spritelocal portrait NightmareScene.GetPlayerExtraPortraitSprite()返回玩家的额外肖像精灵。注意它与背景、气泡、进度条不同该函数直接访问结构体偏移0x4d4处的_playerExtraPortraitANM2成员LuaNightmareScene.cpp。这个精灵与 REPENTOGON 的extrastageportrait玩家自定义标签直接相关当某位玩家的 XML 配置了extrastageportrait属性时过渡场景会额外加载一张肖像动画加载后正是存放在_playerExtraPortraitANM2中详见下文延伸REPENTOGON 对 NightmareScene 的扩展。4.GetProgressBarSprite()→ Spritelocal bar NightmareScene.GetProgressBarSprite()返回过渡场景中进度条精灵对应结构体偏移0x248处的_ProgressBarANM2。通过 Sprite 接口你可以控制其位置、颜色、透明度、播放动画帧等属性。5.GetProgressBarMap()→int[]local map NightmareScene.GetProgressBarMap() for i 1, #map do print(floor .. i .. - .. map[i]) end返回进度条楼层映射表一张包含 14 个整数的 Lua 数组描述了进度条上每个刻度对应的楼层编号。底层实现值得注意——它并非直接返回内部指针而是在 LuaNightmareScene.cpp 中逐个复制结构体偏移0x36c处的int*数据int* content nc-GetProgressBarMap(); for (int i 0; i 14; i) { lua_pushinteger(L, i 1); lua_pushinteger(L, *content); lua_rawset(L, -3); }也就是说Lua 侧拿到的是副本对其修改不会写回游戏内存若要改变进度条显示内容应通过精灵接口如切换ProgressBarANM2的动画帧来实现。6.IsDogmaNightmare()→booleanlocal isDogma NightmareScene.IsDogmaNightmare()返回当前过渡场景是否为Dogma 噩梦Dogma Nightmare即进入《忏悔》DLC 中 Dogma/Boss 战前那段特殊的黑白噩梦式过渡。底层读取结构体偏移0x5e8处的布尔标志NightmareScene.zhl并通过lua_pushboolean返回LuaNightmareScene.cpp。利用此标志可以在回调中区分普通楼层过渡与 Dogma 特殊场景从而决定是否叠加自定义特效。底层结构从源码看 NightmareScene 的内存布局ZHL 定义文件 libzhl/functions/NightmareScene.zhl 完整描述了该类的内部布局为上述函数提供了硬核佐证struct NightmareScene depends (ANM2) { inline ANM2* GetBackgroundSprite() { return this-_backgroundANM2; } inline ANM2* GetBubbleSprite() { return this-_bubbleANM2; } inline ANM2* GetProgressBarSprite() { return this-_ProgressBarANM2; } inline int* GetProgressBarMap() { return (int*)((char*)this 0x36c); } inline bool* IsDogmaNightmare() { return (bool*)((char*)this 0x5e8); } }; ANM2 _backgroundANM2 : 0x20; ANM2 _bubbleANM2 : 0x134; ANM2 _ProgressBarANM2 : 0x248; ANM2 _playerExtraPortraitANM2 : 0x4d4; // 结构体总大小 0x5ec从中可以归纳出几个实现事实前三个精灵函数背景、气泡、进度条返回的都是ANM2动画对象是NightmareScene的内嵌成员而非指针因此 Lua 绑定通过UserdataPtr::push包装后返回 Sprite 对象GetPlayerExtraPortraitSprite在 ZHL 中未声明为 inline 方法但 LuaNightmareScene.cpp 直接对_playerExtraPortraitANM2成员取址佐证了该成员在结构体中的存在GetProgressBarMap与IsDogmaNightmare返回的是裸指针/裸标志Lua 层做了按值复制的转换该类同时声明了三个原生方法LoadConfig(char* xmlpath)、Render()、Show(bool unk)NightmareScene.zhl它们虽未直接暴露给 Lua但被 REPENTOGON 用于挂钩回调见下节。配套回调MC_POST_NIGHTMARE_SCENE_RENDER 与 MC_POST_NIGHTMARE_SCENE_SHOWNightmareScene类与两个 REPENTOGON 自定义回调紧密配套见 docs/docs/enums/ModCallbacks.mdID回调名参数返回1102MC_POST_NIGHTMARE_SCENE_RENDERvoidvoid1103MC_POST_NIGHTMARE_SCENE_SHOW(boolean IsDogmaNightmare)void1102MC_POST_NIGHTMARE_SCENE_RENDER在NightmareScene::Render渲染之后触发是向过渡画面叠加自定义绘制/修改精灵属性的最佳时机。它的实现采用的是 ASM 补丁在 repentogon/Patches/ASMPatches/ASMCallbacks.cpp 中通过签名扫描定位NightmareScene::Render在函数入口插入调用RunPostNightmareSceneRender并把EDI寄存器中的NightmareScene*作为参数传入后触发回调 1102。1103MC_POST_NIGHTMARE_SCENE_SHOW在NightmareScene::Show执行之后触发并把Show的bool unk参数作为IsDogmaNightmare布尔值传给 LuaCustomCallbacks.cpp。由于Show负责在播放过渡前组装场景内容在此回调中修改精灵可以确保改动在动画开始前生效。实战示例在过渡场景中叠加自定义效果综合上述 API 与回调一个典型的 MOD 脚本可以这样使用NightmareScene-- 1) 在 Show 之后检查场景类型并记录状态 local nightmareMod { isDogma false, } function nightmareMod:onShow(isDogma) nightmareMod.isDogma isDogma -- 普通过渡把背景调成半透明 local bg NightmareScene.GetBackgroundSprite() bg.Color Color(1, 1, 1, 0.5) end nightmareMod:AddCallback(ModCallbacks.MC_POST_NIGHTMARE_SCENE_SHOW, nightmareMod.onShow) -- 2) 在 Render 之后逐帧驱动动画 function nightmareMod:onRender() local bar NightmareScene.GetProgressBarSprite() bar:Play(BarAnimation, true) -- 播放/循环指定动画 local bubble NightmareScene.GetBubbleSprite() bubble.Scale bubble.Scale * 1.01 -- 让气泡缓慢膨胀 if nightmareMod.isDogma then -- Dogma 噩梦场景给背景加一层红晕 NightmareScene.GetBackgroundSprite().Color Color(1, 0.3, 0.3, 1) end end nightmareMod:AddCallback(ModCallbacks.MC_POST_NIGHTMARE_SCENE_RENDER, nightmareMod.onRender)实战要点精灵操作全部走 Sprite 接口Color、Scale、Rotation、Play、Load等文档中所有返回值均为 Sprite 对象Sprite 类文档提供了完整的可用方法清单GetProgressBarMap()返回的是 14 元素副本若想自定义进度条显示应结合GetProgressBarSprite()的动画帧/精灵贴图来实现而不是修改返回值时机把控MC_POST_NIGHTMARE_SCENE_RENDER1102每帧渲染后触发适合逐帧动画MC_POST_NIGHTMARE_SCENE_SHOW1103只触发一次适合一次性初始化。延伸REPENTOGON 对 NightmareScene 的原生扩展除了 Lua APIREPENTOGON 内部还围绕NightmareScene做了三处值得了解的改动均可在源码中验证1.stageportrait/extrastageportrait玩家自定义标签PlayerTags.cpp通过 ASM 补丁挂钩NightmareScene::Show支持玩家 XML 配置两个新属性stageportrait指定过渡场景中玩家主肖像的文件名基于bigportraitroot拼接路径存在时替换默认肖像extrastageportrait额外加载一张肖像动画加载后存放在_playerExtraPortraitANM2中——这正是 Lua 侧GetPlayerExtraPortraitSprite()能读到它的原因。加载逻辑为_playerExtraPortraitANM2.Load(result, true)并调用Play播放默认动画PlayerTags.cpp。2.NoShake玩家标签PlayerTags.cpp同样通过 ASM 补丁挂钩NightmareScene::Show当玩家配置了noshake标签时过渡场景以及 Boss 入场动画将跳过屏幕震动效果。3.NightmareScene::LoadConfig的 MOD 路径支持XMLData.cppREPENTOGON 钩住了NightmareScene::LoadConfig(char* xmlpath)在加载过渡场景配置时同步处理 MOD 内容路径ProcessModEntry使得 MOD 能够为过渡场景注入/覆盖资源同时保证xmlsloaded标志下的重复加载不被重复处理。注意事项与最佳实践必须等待游戏初始化完成文档明确警告本类的函数在游戏完全初始化之前不应被调用所有函数内部都会访问g_Manager-GetNightmareScene()脱离回调调用会存在空指针风险。用.而非:NightmareScene是全局函数表而非实例元表误用:会因多传 self 导致参数错位或报错。区分两个类配置过渡行为用 StageTransition如SetSameStage控制头像是否移动操控过渡画面内容用NightmareScene二者互补而非替代。副本数据勿回写GetProgressBarMap()返回的是 Lua 侧新建的表修改它不会影响游戏内部状态。优先在回调内读取由于过渡场景生命周期短暂建议在 1102/1103 回调中获取并缓存所需精灵引用避免跨场景持有过期对象。精灵为共享引用返回的 Sprite 指向游戏内部ANM2对象修改会直接影响游戏渲染注意在过渡结束后恢复默认状态如颜色、透明度以免影响后续场景。总结NightmareScene全局类是 REPENTOGON 中操控关卡过渡场景视觉内容的唯一官方入口GetBackgroundSprite、GetBubbleSprite、GetProgressBarSprite、GetPlayerExtraPortraitSprite四个函数分别暴露背景、气泡、进度条与额外肖像四个ANM2精灵GetProgressBarMap提供 14 元素楼层映射表Lua 侧副本IsDogmaNightmare用于识别 Dogma 噩梦场景。配合MC_POST_NIGHTMARE_SCENE_RENDER1102与MC_POST_NIGHTMARE_SCENE_SHOW1103两个回调MOD 开发者可以在过渡动画的组装阶段与每帧渲染阶段自由叠加自定义效果实现完全个性化的楼层过渡体验。需要进一步查阅精灵可用方法时请参考 Sprite 类文档。赞分享游戏开发插件系统【免费下载链接】REPENTOGONScript extender for The Binding of Isaac: Repentance项目地址https://gitcode.com/gh_mirrors/re/REPENTOGON点击查看免费下载相关推荐电脑怎么用键鼠玩手游QtScrcpy 投屏与键鼠映射实践指南电脑怎么用键鼠玩手游QtScrcpy 投屏与键鼠映射实践指南 玩手游瞄准时手指常常遮住屏幕大半切换技能还要腾出拇指手上同时管几台手机时来回切窗口核对状游戏开发插件系统REPENTOGON BossPoolManager 全局类完全指南读取与操控 Boss 池REPENTOGON BossPoolManager 全局类完全指南读取与操控 Boss 池 BossPoolManager 是 REPENTOGON《以撒游戏开发插件系统Buzz 离线转录工具基于 Whisper 的免费本地语音转文字3 步搞定会议纪要与字幕Buzz 离线转录工具基于 Whisper 的免费本地语音转文字3 步搞定会议纪要与字幕 还在把 3 小时的会议录音上传到云端然后等 40 分钟出字幕更游戏开发插件系统上一篇RIOT 上的 NASA bplib DTN 实战基于 UDP Convergence Layer 的 BPv7 示例深入解析下一篇Fail2Ban 异常体系解析fail2ban.exceptions 模块与 Jail 异常处理机制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考