Lot's of progress, lots of input.
Long time no update. Project has been progressing well in several areas but this update will focus on improvements to the input. That is player input using various control methods to play the game.
The original release had mouse/keyboard and touch support.
It's been bugging me a bit with the touch controls that you often have your finger in the way of what you need to see. If you have the Zap power-up you have to position your finger above the player to stay in place while rotating and shooting, not very good! If you have the Munch power-up you often have your finger above the target as you are chasing it trying to eat it. Not good at all!
Realized that a virtual joystick would probably fix most of this. The user could put the finger anywhere on screen and a virtual joystick would appear so that the user can use it to control the player.
nippleJS is an excellent solution for this. Precise, well documented and specific. Not much more to say. Added to the project with ease, a half-hack to connect the data from it to the control system in place for the mouse/touch and it was good to go. It took more time to write new documentation and to update the tutorial to support the virtual joystick.
With a virtual joystick in the game, it only made sense to continue and add support for hardware versions as well. More precisely the HTML5 Gamepad API.
Gamepads.js is almost as great as nippleJS. The only minor issue with it, is that it lacks TypeScript definitions. Without the in-editor documentation you have to go back and forth between reading the documentation and writing your code.
The first draft of the gamepad controls were fairly straight forward, but did not feel great. Hard to get precision correct while having enough deadzone to make sure the gamepad did not send any data when not meant to. It took quite a bit of testing and re-thinking to get it to feel good.
Main steps to get the analog sticks to produce a result that feels good:
- Ever so slightly tweak the incoming data to make sure it goes up to 1. Values are 0 for center and 1 for full stick direction, but with some gamepads due to lack of calibration and/or wear they might not actually give you a full 1.
- Deadzone has to be configurable. A deadzone is the zone around center that will be considered 0 and gamepads are very different in how good they are at returning to 0 when releasing the stick. My old XBOX 360 gamepad stopped at anything from 0.25 to 0.05 (calibrating it got it down to 0.15).
- Recalculate the values to take into account the deadzone. Meaning if deadzone is 0.2, then 0.2 input value has to be recalculated to 0 so that you always have 0 to 1 values coming to the player controls.
- The most important step. Interpolate the values to smooth out the stick movement. I do it in three zones, so that little stick direction has higher interpolation, while full stick has less interpolation.
- Iterate the interpolation per frame towards the actual destination and stop when values are more or less the same, or abort if new input comes in. Most gamepads (but not all) stop sending data if the values do not change, if the user has moved the stick into a direction and holds it there, this makes sure that the player keeps on moving until facing the intended direction.
It's in the details
When the gamepad felt good to control the game it was a must to make the game fully gamepad compatible. Meaning adding support to navigate the menus with the gamepad, toggle options with the gamepad, adding a virtual keyboard (simple-keyboard) to allow high score name entry with the gamepad and update the documentation and the tutorial to support the gamepad. Phew!
Took more time than anticipated, but now that it is done, it does feel pleasing to say the least. For the next game the good news is that most of this can be re-used making it all in all time well spent.
If you are up for it, try the game. You can seamlessly switch between mouse, touch, virtual and gamepad as you play!
Hive P v. S is a mashup of classic arcade games. You fly around collecting stars, each star collected spawn an entity that forms a tail that gets longer and longer. Avoid the tail for as long as possible until you get a power up that gives you a limited time to destroy the tail. If successful you'll get bonus points and new stars are spawned. Rinse and repeat.
When the final score is high enough, you'll get the opportunity to submit the score to the high score table. The high score table is saved on Hive and is viewable on Hive as well as in-game for all users.
Game will be released for browsers, as a PWA and as native builds for mobile and computer platforms.
Check out the following links to get a closer look at the progress!
Game development using web technologies.