This past week, there was a first for me. I did something I've never done before: I ran a workshop as part of a conference. The CodeLand:Distributed conference.
I had different game controllers that I could use during the presentation, but what happened if the people attending the workshop didn't have one? What if they couldn't complete the tasks because they missed a gamepad?
- It triggers the
- It generates a gamepad object with all the standard properties.
- It updates the values of the gamepad object when the user interacts with the virtual gamepad.
Here is a demo of the Gamepad Simulator at work:
It may be a basic thing at the moment, but it could be helpful for people that want to try and develop with the Gamepad API but don't have a physical gamepad available for any reason.
...which was the case in the presentation.
How it works
The initial code is fairly simple. It can be found on this Codepen –although this demo maybe better to appreciate the behavior–, and the project continues on GitHub.
The module creates an object named
gamepadSimulator that has 4 methods:
This method sets the whole environment in place to use the gamepad:
- It generates an SVG picture of a generic-looking gamepad and places it on the screen.
- It adds an id to the image so it can be styled and customized.
- It generates fake information for a standard 17-button gamepad.
- It associates all the events to the buttons and axes, so the information of the gamepad is updated upon user action.
- It replaces the
navigator.getGamepad()with its own method that will return the fake gamepad.
It is necessary to call this function at first... which may seem unnecessary; why not directly run all these actions when importing the module?
We could do that, but the idea is to expand the module in the future and allow for some customization of the gamepad (which would require this
This method will trigger the
gamepadconnected event with the gamepad information generated in the
To do so, we make use of the Event interface to create a custom event of the type
gamepadconnected, and then we dispatch it with
const event = new Event("gamepadconnected"); // update fakecontroller initial information event.gamepad = gamepadSimulator.fakeController; window.dispatchEvent(event);
The dispatched event will be treated as the regular event triggered after connecting a gamepad to the browser.
This method will trigger the
gamepaddisconnected event with the current information from the gamepad generated in the
create() function. It is created and dispatched/triggered in the same way as the
gamepadconnected event described in the previous section.
It is important to call this function after completing the tests. Otherwise, the gamepad won't be disconnected and the app –not the module– may keep running affecting performance.
This method performs necessary clean-up after the gamepad has been used:
- Calls the
disconnect()method (just in case).
- Removes the gamepad image from the screen.
- Reinstantiates the original
As of right now, the code and functionality are fairly basic. They get the job done, but they lack many options and customizations.
I would like to improve some things like:
- Allowing for diagonal moves of the axes (and different intensities).
- Adding options to generate non-standard gamepads.
- Adding customization so users could create a gamepad that fits their needs (e.g. number of buttons, number of axes, etc.)
- Having different gamepad faces and not just the generic one.
- Making it easier to export/import the project.
As I mentioned above, the project is on GitHub (and at a really early stage), so any suggestion/recommendation/help will be welcomed.