How to mix vuex / vue with HTML5 games
Do you want a vue ui mixed with Babylon.js, Three.js, PIXI.js, canvas, Webgl, etc? Or maybe just to store some variables... or make reactive changes? Here's how it works in a few of my games... There are 3 main points of integration. These are mutating state in the store (writing to a variable in the store), reading state from the store (accessing the store variables from other places), and reacting to changes in state (triggering a function when a value in the store changes).
First, how do you expose the store? Well you can literally just export it and then import it. Or be lazy and stick it on window.store. You'll want to have a sensible order of initialization when your game starts up so that you don't try to access the store before it exists. But games already use loaders etc to load up their images and sounds, so there's a place for that. Load up the store first, probably.
For reading state from the store you can use a syntax like store.getters['setttings/graphicsMode']. It can be a little simpler than that, but this shows the synatx for a store nested within a store. In my game for example, I have a gameStore and a settingsStore just because I didn't feel like putting *all* of the properties into one giant vuex config. One can also access the state via store.state.settingsStore.someProperty but this is reading it directly instead of uses the getter. You probably want to use the getter, because then you can have a computed property, but either will work. For writing state to the store, the key is store.dispatch. Syntax is like store.dispatch('devStore/toggleDeveloperMenu', optionalPayload). This is invoking the *action* which means you need to create actions instead of just using a setter with this particular syntax.
So that's reading and writing! But what about reactivity? Well lets say your game logic dispatches some state which enters the store, you'll find that if that state is displayed in your vue ui it is already reactive and working. For example if you store.dispatch('game/updateHitpoints', { hp: 50 }) and there's already ui to draw the hitpoint bar on the hud that is going to change automagically. But what if you're pressing buttons in your vue-based settings menu or game ui? How does one get the game itself to react to that? Well there are two some what easy ways (among a million homegrown options). The first is to use the window to dispatch an event from the same action that you use to update the state, and be sure that you always use the action instead of directly accessing the setter. This will work fine, and I did it at first, but there is a more elegant and integrated way. That is to use store.watch.
The store.watch(selector, callback) will invoke your callback when the state defined by the selector you provide changes. For example this is how to setup your game to change the rendering settings in bablyon js (pseudocode) whenever someone changes the graphics level from low | medium | high | ultra. store.watch(state => state.settings.graphicsMode, () => changeGraphics(store.getters['settings/graphicsMode']));; The first arg is the selector function, which in this case specifies that we're watching graphicsMode for changes. The second function is what gets invoked when it does change. The actual body of my changeGraphics function is skipped b/c it doesn't really matter.. for me it might turn off shadows and downscale the resolution or something like that. Personally I create a function called bindToStore(stateSelector, callback) which sets up the watcher and invokes it once for good measure. This way when my game is starting it up, as all the watchers get setup listening for changes, that first first invocation also puts the ui into the correct state. So that's writing, reading, and reacting to state changes across the border between vuex/vue and any html5 app or game engine by integrating with getters, actions via dispatch, and watchers. Good luck and have fun!














