Fix Character Jumping to Left Right Up Down

29th May 2022
Table of contents

Fix 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));
Bạn thấy bài viết này như thế nào?
0 reactions

Add new comment

Image CAPTCHA
Enter the characters shown in the image.
Câu nói tâm đắc: “Điều tuyệt với nhất trong cuộc sống là làm được những việc mà người khác tin là không thể!”

Related Articles

String là một kiểu dữ liệu thông dụng trong nhiều ngôn ngữ lập trình, nó mạnh vì nó có thể dùng vào nhiều trường hợp để giải quyết các vấn đề

Nếu bạn muốn người dùng cung cấp tên, tuổi, email… ta cần một hàm Javascript  để đảm bảo rằng họ đã nhập với các thông tin này

Gọi phương thức postMessage của phần tử window / iframe mà bạn muốn gửi thông tin tới.

Ví dụ sau minh họa một biểu mẫu HTML5 truy cập dữ liệu thông qua lệnh gọi API Ajax bằng cách sử dụng phương thức POST.