我目前正在尝试使用 Vanilla javascript编写 Canvas 的小型游戏引擎,在我目前的工作原理心理模型中,用户将实例化一个Scene类,该类将包含所有要渲染的对象及其行为。每个 Canvas 一次只能有一个 Activity 场景,因此当前未加载的场景是非 Activity 的。这样,我希望能够将调度到 Canvas 的所有事件重定向到当前 Activity 的场景。它看起来像这样:

canvas.addEventListener(/* all */, (e) => activeScene.dispatchEvent(e));

但显然这是行不通的。

这里有一个类似问题的有趣答案:Listen for all events in JavaScript

这沿迭代所有窗口属性并为以“on”开头的所有属性注册事件侦听器的路线进行。

问题是,这不会捕获自定义事件,并且我想使用户能够使用从其他位置发送的自定义事件与他们的场景进行交互(例如, Canvas 上方的用于重置当前关卡的按钮可以发送“重置” '事件)。

替代方案是:
  • 用户在 Canvas 上调用自定义函数,然后在当前 Activity 场景上调用相应的函数
  • 用户按照我的想法调度了一个自定义事件,但是还必须为该事件类型添加一个事件侦听器,然后手动将该事件重定向到 Activity 场景(或者我提供了一个函数来注册该自定义事件并将该类型的事件重定向到 Activity 场景)

  • 在所有这些情况下,这都是用户的两步过程。我猜想在程序开始时注册一次所有自定义事件并没有那么糟糕,但是我想知道是否存在一个更优雅的解决方案。

    最佳答案

    好吧,经过一番修补后,我想到了解决方案:

    我使用此代码使用eventListeners重定向所有标准事件

    for(let key in myObj){
        if(key.startsWith('on')) {
           myObj.addEventListener(key.slice(2), (e) => {otherObj.dispatchEvent(e)});
        }
    }
    

    并且我覆盖了默认的dispatchEvent()方法,以便所有手动触发的事件都被重定向,无论它们的类型如何:
    myObj.dispatchEvent = (e) => {otherObj.dispatchEvent(e)};
    

    不幸的是,第一部分是必需的,因为标准事件不会通过dispatchEvent()方法触发。从理论上讲,这应该将在对象(在我的情况下将是 Canvas )上触发的所有事件重定向到另一个( Activity 场景)。

    10-04 16:02
    查看更多