Closed J-Puls closed 4 years ago
Agree the keyboard and touch controls should act and feel the same to the player. You observation about multiple keydown events firing in rapid succession is important. I would like to get away from any reliance on the keyboard sending events to autorepeat keystrokes. So changes are needed.
Let me focus in on the desired behavior as opposed to the "as built" behavior. Then a bit about a strategy for getting there.
Desired Behavior:
So long as the rotate key/touch button is held down the ship rotates smoothly at a constant angular velocity until key/touch button is released.
Burn should behave similarly. The burn continues so long as the key is held down and stops when the key is released.
If rotate and burn are held down at the same time, the ship both rotates and burns.
if the two rotate command keys/buttons are held down at the same time then for so long as they are both down, the ship does not rotate. They cancel each other out.
Fire just one missile per transition to keydown. (These are missiles, not a rail gun).
Proposed approach
Track the state of key, is it up or down, and drive behavior to the change in state, not arrival of new keydown events. The arrival of a keydown event when the key state is recorded as already down should be ignored. So, in the case of a burn, the burn starts at the keydown event for say KeyI and the burn ends at the keyup event for KeyI. That way the keyboard ought to be acting the same as the touch controls.
I don't know if this stream of repeated keypress events also has keyrelease events generated as well. Can experiment to find out. But if we we get lucky and there are no keyrelease events being synthesized implementing this new strategy should be straightforward.
Make sense?
Yep, makes sense. Tracking key state sounds like the way to go for sure.
In addition to this, I just noticed the reliance on continuous keydown events also introduces the issue that in a multiplayer game, both players will not be able to perform complex maneuvers at the same time if more than 3 keys are pressed (n-key rollover issue, I assume). For instance, if both ships are burning, and one is rotating, rotating the second ship will cancel the rotation of the first.
I agree.
Just did a quick experiment and confirmed that while you get a stream of repeated keydown events, they don't synthesize the corresponding keyup events. You can believe a keyup is a key release. That is good news.
Need to take some time to watch a movie with my wife, this evening. Otherwise I'd be right on it.
My thinking is that in spacewar.js use commandKeyDown and commandKeyUp to set flags (e.g. ship1.rotateRight = true, or ship1.burn = true) and not call the rotate or burn functions directly. Instead we call them from within the animate() function, perhaps as a separate inner loop devoted to controls.
I think if the mobile controls follow the same strategy (just setting flags) an let the animate loop execute the operations we will get the behavior we are after.
I went ahead and tagged this as a bug. It represents a gap between the desired behavior (as specified above) and the actual behavior. It should get priority over new features and enhancements.
Implemented the changes as outlined above. Tested on iPad and the need for tapping rotate and burn is eliminated. Still repeating the missile fire, but this is progress enough to close out this issue. Will file a separate issue for repeated missile fire. iPad play will be much enhanced when we get the AI for player 2 working; or get remote multiplayer functioning.
Just tested this on my devices, controls work much smoother now. Excellent.
Touch controls behave differently from keyboard controls. While a physical key is held down, multiple "keydown" events fire in rapid succession. While holding a touch button, only one "ontouchstart" event is fired, thus requiring the button to be tapped rapidly for the same result. Consider implementing a "burn-duration" parameter that cancels once "ontouchend" fires. This could also eliminate the lag in rotation after the initial keydown event, smoothing the animation