Session Planning
I see a potential problem in the controls if more than one controller button is needed simultaneously. The isFiring
returns a boolean on the FIRST button push it detects, and would ignore any additional entries in that list. This means if I press A
, it will do the action for A
, but then if I keep pressing A
, and also press B
, the action for A
+B
would not get executed; only the action for A
would.
I might be able to address this with using the keysDown
array, and adding a key like ‘controller’ + controllerIndex = true
.
Maybe I’m wrong, though, and the response time is fast enough that this isn’t a problem. I’ll just keep it on the back burner for when I need combination triggers.
This is also potentially already a problem for movement, as that requires two keys at once (to move up+left, etc), and key overrides. Hitting right
while already moving left
would ideally override the left
movement, and it does, but hitting left
while already moving right
does not, because left
gets added to the map later, and so the right
instance is found first. This is true regardless of which key gets hit first, as the map is constantly updated, and the sequence is upRight
, upLeft
, downRight
, downLeft
, up
, down
, right
, left
. The keys are then filtered for true cases and added to an Array of activeDirections
:
|
|
Then the first entry in activeDirections
is processed (it occurs to me that with this approach, activeDirections
could be changed to activeDirection
, and the above filter could be changed from filter
to find
to improve performance, if we only want the first entry, which is how it currently processes):
|
|
This is what causes the override cascading. Those combinations toward the top of the list have priority. I’m not sure I want to do anything about this, as this is actually how the original Centipede behaves when emulated on the web and controlled with keyboard arrows.
If instead all entries in the list are executed as follows, you get interesting behavior around the diagonal movement.
|
|
It moves really fast! This is because with up
/left
, the up
/left
is applying a speedY
and a speedX
, but left
is also applying speedX
, and it’s additive, so left
gets counted doubly. This could be mitigated somewhat by giving the movements half weight when perpendicularly applied, or by setting an upper limit on speedX
/speedY
. Also, the left
/right
and up
/down
combinations cancel each other out, which is desirable. Also, weird things happen when holding up
/down
and then hitting left
/right
. I think it’s best to avoid this approach without some serious reconsideration of how speeds are processed.
Some Refacoring: Low Hanging Fruit
Refactored to simplify the move
/getActiveDirection
logic:
|
|
becomes:
|
|
And getActiveDirection
replaces setActiveDirections
:
|
|
Some rework to clean this up a bit: e3d9a08
Controller Axes Analysis
|
|
The axes output array is: [leftStick.x, leftStick.y, rightStick.x, rightStick.y]
How do I get the D-pad values? A worry for later.
Up with the left stick looks like this: [-0.15259255468845367, -1, -0.11713004112243652, -0.0138248847797513]
Index 1 is a value of -1
.
Resting axes look like this (that’s a lot of deviation from 0 in the horizontals): [-0.11615344882011414, -0.01678518019616604, -0.12402722239494324, -0.003997924737632275]
Negative values are left
or up
, as expected. This should make it really simple to control movement, as the speeds can just be set to the target value. gamePiece.speedX = leftStick.x, gamePiece.speedY = leftStick.y
, if gamePad is active, while ignoring values less than, say, 0.5
, because it looks like there’s a lot of inherent drift at rest. This can take priority over WASD
, because CONTROLLERS, MAN!
Post Session
So far I’ve got it to a point where the controller works for movement, but I have not accounted for the edges of the play area, so the gamePiece
can move outside, which is obviously bad.
I’m going to have to make a decision on whether to use the axes inputs to determine the direction (this makes it easier to reuse the existing keyboard logic that handles edge collisions), or apply the axes inputs directly (which gives a more dynamic speed feel, as the speed changes based on stick pressure). In the latter case, I will need to update the gamePiece.getPositionModifiers
function to allow variance in the x
and y
values (currently they’re -1
, 0
, or 1
only.)
https://gitlab.com/taciturn-pachyderm/centipede/commit/f16d1a81c020bf421c3e5af0ecd0c8e161ef1dde