Fix Character Jumping to Left Right Up Down
29th May 2022Fix Character Jumping
The character jumping around the page was caused by having to finish the animation to the next unit before going on to the next key. It is important to finish the animation. If we did not finish the animation before executing the next movement, then the character could be walking in-between units.
Example: the player could be holding down the right arrow key and the character would be traveling 32px right every 400ms (or whatever speed you designated for the "charSpeed" variable). If the player then changes their arrow key to down and we didn't finish the animation in the keyUp function with "$('#character').stop(true, true);" - then the character would start heading down before making it the full 32px.
It is important for us to stay within our established units as this will be used for object checking and border checking and determines if the player can move to the next direction or not.
To go about fixing the character jumping issue, we will need to detect if the character is already moving, if it is - do not move the next direction until the character movement has finished. To do this, we will remove the interval timer for character walking, we will use the character animation queue, and check if the character has any animations in its queue in the keyDown function.
First step is to remove "var TimerWalk;" from the global javascript variables as it will no longer be used.
Now, let's adjust our keyDown function to check if the character's queue has finished before allowing the character to move the next direction.
$(document).keydown(function(e) { if (!currentKey && $('#character').queue("fx").length == 0) { currentKey = e.keyCode; switch(e.keyCode) { case 38: moveChar('up'); break; case 39: moveChar('right'); break; case 40: moveChar('down'); break; case 37: moveChar('left'); break; } } });
If you noticed above, I no longer call the charWalk() function. Instead, I consolidated the charWalk() function and processWalk() function into one, moveChar(). I did this because we are no longer using the interval to move the character object, instead we will simply re-call the moveChar() function if the currentKey is still down. We are also going to have our character move at a "linear" rate as jQuery's "animate" function uses "easing" by default and we want our character to move at a constant speed. See the consolidated moveChar() function below. I will explain the character animation section below the new function.
function moveChar(dir) { //a player could switch key mid-animation //record the key that was down when animation started var currentKeyCheck = currentKey; //adjust from lang to code if (dir == 'up') dir = 'back'; if (dir == 'down') dir = 'front'; charStep++; if (charStep == 5) charStep = 1; //remove the current class $('#character').removeAttr('class'); //add the new class switch(charStep) { case 1: $('#character').addClass(dir+'-stand'); setTimeout(function() { charStep++; if (charStep == 5) charStep = 1; $('#character').removeAttr('class'); $('#character').addClass(dir+'-right'); }, (charSpeed/3)); setTimeout(function() { charStep++; if (charStep == 5) charStep = 1; $('#character').removeAttr('class'); $('#character').addClass(dir+'-stand'); }, ((charSpeed/3)*2)); break; case 2: $('#character').addClass(dir+'-right'); setTimeout(function() { charStep++; if (charStep == 5) charStep = 1; $('#character').removeAttr('class'); $('#character').addClass(dir+'-stand'); }, (charSpeed/3)); setTimeout(function() { charStep++; if (charStep == 5) charStep = 1; $('#character').removeAttr('class'); $('#character').addClass(dir+'-left'); }, ((charSpeed/3)*2)); break; case 3: $('#character').addClass(dir+'-stand'); setTimeout(function() { charStep++; if (charStep == 5) charStep = 1; $('#character').removeAttr('class'); $('#character').addClass(dir+'-left'); }, (charSpeed/3)); setTimeout(function() { charStep++; if (charStep == 5) charStep = 1; $('#character').removeAttr('class'); $('#character').addClass(dir+'-stand'); }, ((charSpeed/3)*2)); break; case 4: $('#character').addClass(dir+'-left'); setTimeout(function() { charStep++; if (charStep == 5) charStep = 1; $('#character').removeAttr('class'); $('#character').addClass(dir+'-stand'); }, (charSpeed/3)); setTimeout(function() { charStep++; if (charStep == 5) charStep = 1; $('#character').removeAttr('class'); $('#character').addClass(dir+'-right'); }, ((charSpeed/3)*2)); break; } //move the char switch(dir) { case'front': $('#character').animate({top: '+=32'}, charSpeed, "linear", function() { if (currentKey == currentKeyCheck) moveChar(dir); }); break; case'back': if ($('#character').position().top > 0) { $('#character').animate({top: '-=32'}, charSpeed, "linear", function() { if (currentKey == currentKeyCheck) moveChar(dir); }); } break; case'left': if ($('#character').position().left > 0) { $('#character').animate({left: '-=32'}, charSpeed, "linear", function() { if (currentKey == currentKeyCheck) moveChar(dir); }); } break; case'right': $('#character').animate({left: '+=32'}, charSpeed, "linear", function() { if (currentKey == currentKeyCheck) moveChar(dir); }); break; } }
Smoother Walk Cycle
The one step per movement did not look very smooth. To make our movement look smoother, I added two more steps to the walk cycle. When a player presses a directional key, the character will now take a step forward, bring its feet together, then take another step. This is handled by changing the character's class once the moveChar() function is initiated and then by two "setTimeout" functions executed 1/3 of the way and 2/3 of the way through the character's movement animation. See the excerpt from the moveChar() function below:
$('#character').addClass(dir+'-right'); setTimeout(function() { charStep++; if (charStep == 5) charStep = 1; $('#character').removeAttr('class'); $('#character').addClass(dir+'-stand'); }, (charSpeed/3));
Add new comment