Closed deathcap closed 10 years ago
Event bindings for kb-controls
has been oft-requested, but when it comes up I am iffy on implementing it:
kb-controls
is designed to be a polling interface primarily so that inputs are recordable. A central point in voxel-engine
or other game engine could collect user input state along with the time-of-sample and use that to build replays / update frames for network games. It's a module designed for the collection of input events that affect the simulation.
Event listening is ideal for events that do not affect the simulation -- such as switching POV -- and so can be handled immediately. I've been avoiding adding event listening to kb-controls
for the following reasons:
R
would be solved by scoping the keydown
listener to the canvas itself instead of the window.kb-controls
, primarily to avoid inflicting a decision on the end user of the API -- "Should I poll for this action or listen for it?" Keeping kb-controls
to a polling interface mandates that any action that mutates the simulation is received in a polling fashion.The confounding bit in this, I think, is that kb-controls
does two things: presents a polling interface for input, and also allows key to action mapping, and so there's a desire for an event listening api that allows for key remapping.
(Sorry for the rambling reply. Great work on kb-bindings
+ kb-bindings-ui
!)
FWIW, I wanted to event based controls as well until @chrisdickinson so eloquently explained why a polling interface is superior at last nodeconf. My vote is to keep kb-controls and thus keeping it based on polling.
But I am +1 to pulling anything out of voxel-engine and into the user land, if possible.
Alright I'll close this for now, will see about another solution. I think a customizable keybindings object (exposable to a UI plugin) would go a long way, however. game-shell has its own key bindings mechanism, I'll need to see how to integrate with it (ref https://github.com/voxel/issues/issues/4)
Changes game.buttons to use kb-bindings - which is based on and compatible with @chrisdickinson's kb-controls, but takes it a step further than providing a polling interface, also adding events and reconfigurable bindings.
This functionality is very useful to add here since it allows the game to centrally control the keyboard handling, consistently enabling/disabling capturing as pointer lock is attained/released and providing a unified interface for managing bindings.
Previously, non-polling kb handling code would register its own event handlers on the DOM, for example from @maxogden's voxel-hello-world:
which works, but if you're typing 'R' in a text control (etc.), the event handler is still executed, so it needs to hook into attain/release interact itself.. which gets messy quickly, plus, the above handler still hardcoded the specific keybinding. With kb-bindings in voxel-engine, you can register a descriptive binding name (e.g. 'pov' — to optionally let the user rebind it with kb-bindings-ui), then listen for the appropriate events (which are only sent if enabled, so they don't interfere with modal widgets), and it it all works well.
There may be other solutions to these problems than changing
game.buttons
outright. I also experimented with adding akb_module
option to voxel-engine, allowing users to pass in their own kb module, but this was problematic since it cannot be JSON-serialized (similar problem to GH-95). If kb-controls itself https://github.com/chrisdickinson/kb-controls/issues/4 grows these features, that would be an option too, but I think events is probably out of the scope of kb-controls (hence a more expansive module, kb-bindings). Or if voxel- could be rearchitected somehow so that voxel-engine wouldn't depend on kb-, instead vice versa (or not at all?), allowing modules to be easily swapped in or out (similar to gl- vs three.js as @shama describes in https://github.com/voxel/issues/issues/4) with fewer interdependencies, but I'm not sure exactly how that would work (open to suggestions); though at least the change in this PR was sufficient for my purposes =) (currently using in ~8 voxel modules)