简体   繁体   中英

Redirect all events from one object to another

I'm currently trying to write a small game engine for the canvas in vanilla javascript, in my current mental model of how it would work, the user would instantiate a Scene class that would contain all objects to be rendered as well as their behavior. There would only be one active scene at a time per canvas, so that scenes that are not currently loaded are inactive. As such, I'd like to be able to redirect all events that are dispatched to the canvas to the currently active scene. It would look something like this:

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

but obviously this does not work.

There is an interesting answer to a similar question here: Listen for all events in JavaScript

that goes something along the lines of iterating over all window properties and registering an event listener for all properties that start with "on".

Problem is, this won't catch custom events, and I'd like to enable the user to interact with their scenes using custom events dispatched from other places (for example a button above the canvas to reset the current level could send a 'reset' event).

The alternatives would be:

  1. the user calls a custom function on the canvas that then calls the appropriate function on the currently active scene
  2. The user dispatches a custom event as I was thinking but also has to add an event listener for that event type and redirect the event to the active scene manually (or I provide a function to register the custom event and redirect events of this type to the active scene)

In all those cases it's a 2 step process for the user. I guess registering all custom events once at the start of the program wouldn't be that bad but I was wondering if there existed a more elegant solution.

Alright, after some tinkering here is the solution I came up with:

I redirect all standard events using eventListeners with this code

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

and I overwrite the default dispatchEvent() method so that all manually fired events are redirected regardless of their type:

myObj.dispatchEvent = (e) => {otherObj.dispatchEvent(e)};

Unfortunately the first part is necessary because standard events are not fired through the dispatchEvent() method. In theory this should redirect all events fired on the object (which in my case would be the canvas) to the other (the active scene).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM