Using core.async to capture and merge the events and translate them into game commands is a pretty cool way to go about this.
You can see an example in my snake game:
https://github.com/joakin/cnake/blob/master/src/cnake/ui.cljs#L140-L217
Once you have captured your input and transformed it into game events, you could pipe it to wherever you've got the game logic.
In my case, thats a go-loop that processes commands and contains the game state locally to that fn, and applies different functions to it and emits events for the UI to react to:
https://github.com/joakin/cnake/blob/master/src/cnake/ui.cljs#L140-L217
A more traditional approach would be to pass those commands to a function that would choose how to update an atom containing the game state.
There is a cool post about the core.async type of architecture on a game:
http://ragnard.github.io/2013/10/01/clojurecup-pong-async.html