Oneshot Gems
立即玩

游戏开发者指南

为监听器指定唯一的负责人和生命周期

如果重新启动后一次单击触发两次,则每次场景打开时都可能会注册一个侦听器,并且永远不会删除该侦听器。这种明显的重复动作症状与广泛的内存泄漏调查不同:首先计算注册并将它们与场景生命周期联系起来。每个侦听器都应该有一个明确的所有者、一个为该所有者运行一次的设置点,以及当场景停止接受输入时的拆卸路径。

本页内容

在有意的生命周期边界处注册

避免从渲染函数或每个帧附加窗口 keydown 处理程序。将场景特定的设置放入启动或安装函数中,并确保该函数在没有清理的情况下不能运行两次。使用removeEventListener时保留对回调的引用;重复创建的匿名回调以后很难匹配。或者,为一组相关处理程序提供一个 AbortController 并在侦听器选项中传递其信号,然后在场景结束时中止该组。

仔细选择活动目标。全局窗口侦听器可能适合游戏处于活动状态时的按键,但按钮的单击处理程序属于该按钮。不要为同一操作同时注册父委派处理程序和直接处理程序,除非事件传播是设计的故意一部分。

测试重复的场景输入作为症状检查

打开一个场景,按一次其动作,离开,然后再次打开它。一种输入仍应产生一种效果。重复该循环五次,并验证每次按下响应计数是否保持为 1;这是功能检查,而不是内存测量。还要确认旧场景的输入在退出后不再改变其分数或状态。 MDN 记录了 AbortSignal 对分组侦听器的支持,并指出匿名函数需要保留引用才能显式删除。

使拆卸与所有权保持一致

当场景被替换时,在处理它们引用的对象之前中止或删除其侦听器。如果某些侦听器属于整个应用程序 shell,请将它们保留在寿命较长的所有者中,而不是在每轮中删除它们。添加围绕重新启动、暂停和返回菜单流程的回归案例,因为每个转换可能会意外地安装同一场景两次或跳过其清理。

关于⁨防止重复的游戏事件监听器⁩的常见问题

为什么一键按下会产生多个游戏动作?

同一操作可能有多个已注册的处理程序,或者祖先和子级都可以处理该事件。在场景生命周期边界计算注册并检查事件传播。

AbortController 可以删除事件监听器吗?

是的。添加具有相同信号的相关侦听器,并在其所有者结束时调用中止。这为团队提供了清晰的拆卸路径;它不能取代决定由哪个所有者控制它们。

延伸阅读

发现信息过时了? 报告需要更正的内容

继续玩下去。

免费浏览器游戏,随时等你开玩。发现喜欢的游戏,让它成为你的下一个最爱。

跟随好奇心探索