2015-05-21 1 views
0

У меня возникла проблема с easelJS. У меня есть функция, которая прослушивает ввод с клавиатуры, но не обновляет переменные в соответствии с ключами, которые я ударил. Я поместил console.log в разные случаи, и он работает нормально, но по какой-то причине он обновляет переменные. Думаю, я не понимаю, как это работает. Вот мой кодПроблема с клавиатурой для клавиатуры EaselJS

  function handleKeyDown(event) { 
       switch(event.keyCode) { 
        case 16: 
         sonicSpeed = 15; 
         sonicState = 2; 
         console.log("Shift Key Pressed"); 
         break; 
        case 65: 
         sonicState = 1; 
         sonicDirectionXN = true; 
         break; 
        case 68: 
         sonicState = 1; 
         sonicDirectionXP = true; 
         break; 
        case 87: 
         sonicState = 1; 
         sonicDirectionYN = true; 
         break; 
        case 83: 
         sonicState = 1; 
         sonicDirectionYP = true; 
         break; 
       } 
      } 

      if (sonicState == 0) { 
       var sonic1 = new createjs.Sprite(spriteSheet1); 
      } 
      else if (sonicState == 1) { 
       var sonic1 = new createjs.Sprite(spriteSheet2); 
      } 
      else if (sonicState == 2) { 
       var sonic1 = new createjs.Sprite(spriteSheet3); 
      } 
+1

Есть ли причина, по которой ваше условие 'if (sonicState == 0)' находится за пределами функции? –

+0

Да, это только начало кода, и я хочу, чтобы он обновлял будущее движение только с помощью тикера, иначе я бы разместил его внутри функции – Jeff

+0

Хорошо. Похоже, у вас есть какая-то проблема с областью, хотя мне нужно больше узнать о вашем коде, прежде чем я смогу предложить правильное решение. –

ответ

1

Почему это не работает

Проблема заключается в том, что код не выполняется в порядке, вы думаете, что это. Как указал Феликс Клинг в вашем other question, код внутри вашей функции handleKeyDown не выполняется немедленно; он выполняется при нажатии клавиши. Вот фактический порядок выполнения (при отсутствии оптимизации браузером):

  1. handleKeyDown Функция создана (но НЕ выполнена).
  2. sonic1 sprite создается на основе значения sonicState (что является ВСЕГДА 0 на данный момент, так как handleKeyDown не запущен).
  3. Пользователь нажимает клавишу.
  4. handleKeyDown выполняет и изменяет sonicState. Ничего другого не происходит, потому что функция заканчивается после инструкции switch. Выполнение останавливается в конце функции.

Один из способов исправить это

Похоже, что вы пытаетесь изменить последовательность анимации на основе ключа, которая была нажата. Вы должны сделать это с помощью одного SpriteSheet; Somthing так:

var sonicSpriteSheet = new SpriteSheet({ 
    images: [myImage],    // You can also use multiple images. 
    frames: {width:50, height:50}, // Substitue 50 with your actual frame size. 
    animations: { 
     sonicState0: [0, 9],  // These are the start and end frame numbers. 
     sonicState1: [10, 19],  // Substitute with the actual frame numbers 
     sonicState2: [20, 29]  // for your images. 
    } 
}); 

Затем вы можете использовать gotoAndPlay, чтобы установить, какой проигрывается анимация. Это позволяет повторно использовать один и тот же спрайт вместо создания нового спрайта каждый раз.

var sonic1 = new createjs.Sprite(sonicSpriteSheet); 

function handleKeyDown(event) { 
    var sonicState = sonic1.currentAnimation; 
    switch(event.keyCode) { 
     case 16: 
      sonicSpeed = 15; 
      sonicState = "sonicState2"; 
      console.log("Shift Key Pressed"); 
      break; 
     case 65: 
      sonicState = "sonicState1"; 
      sonicDirectionXN = true; 
      break; 
     case 68: 
      sonicState = "sonicState1"; 
      sonicDirectionXP = true; 
      break; 
     case 87: 
      sonicState = "sonicState1"; 
      sonicDirectionYN = true; 
      break; 
     case 83: 
      sonicState = "sonicState1"; 
      sonicDirectionYP = true; 
      break; 
    } 
    if (sonicState != sonic1.currentAnimation) { 
     sonic1.gotoAndPlay(sonicState); 
    } 
} 

Поскольку gotoAndPlay является внутри функция handleKeyDown, он будет выполняться после того, как вы измените sonicState.

Edit - Другой способ это исправить

Если вы хотите использовать отдельные спрайты для каждой анимации, то вам нужно удалить старый спрайт и добавить новый, когда вы изменяете анимацию.

var sonic0 = new createjs.Sprite(spriteSheet0); 
var sonic1 = new createjs.Sprite(spriteSheet1); 
var sonic2 = new createjs.Sprite(spriteSheet2); 
var sonicState = 0; 
stage.addChild(sonic0); 

function handleKeyDown(event) { 
    var newSonicState = sonicState; 
    switch(event.keyCode) { 
     case 16: 
      sonicSpeed = 15; 
      newSonicState = 2; 
      break; 
     case 65: 
      newSonicState = 1; 
      sonicDirectionXN = true; 
      break; 
     case 68: 
      newSonicState = 1; 
      sonicDirectionXP = true; 
      break; 
     case 87: 
      newSonicState = 1; 
      sonicDirectionYN = true; 
      break; 
     case 83: 
      newSonicState = 1; 
      sonicDirectionYP = true; 
      break; 
    } 

    if (newSonicState != sonicState) { 
     // Remove the old sprite 
     stage.removeChild(sonic0, sonic1, sonic2); 

     // Add the new sprite 
     switch (newSonicState) { 
      case 0: 
       stage.addChild(sonic0); 
       break; 
      case 1: 
       stage.addChild(sonic1); 
       break; 
      case 2: 
       stage.addChild(sonic2); 
       break; 
     } 
    } 
} 
+0

, ваше решение является самым близким, с которым я получил работу, но у меня все еще есть несколько проблем. 1 - Я хочу, чтобы тикер был основным, контролирующим мои анимации, и 2 - я не могу контролировать частоту кадров различных анимаций с помощью вашего метода. , , или я могу? – Jeff

+0

Вы можете указать относительную скорость для каждой последовательности анимации, если хотите - см. Документацию [SpriteSheet documentation] (http://createjs.com/Docs/EaselJS/classes/SpriteSheet.html). Я не уверен, что вы имеете в виду, контролируя свои анимации с помощью тикера - если вы используете спрайты, они будут контролироваться сами по себе. –

1

Я не вижу весь свой код, но, судя по всему, у вас возникли проблемы с яваскрипта асинхронной природы. В вашей логике handleKeyDown нет времени для завершения, прежде чем запускать ваши операторы if, следовательно, вы не получите правильных результатов. Попытайтесь создать свои объекты Sprite прямо внутри слушателя handleKeyDown, чтобы сделать его синхронным;

function handleKeyDown(event) { 
    switch(event.keyCode) { 
     case 16: 
      sonicSpeed = 15; 
      sonic1 = new createjs.Sprite(spriteSheet3); 
      break; 
     case 65: 
      sonic1 = new createjs.Sprite(spriteSheet2); 
      sonicDirectionXN = true; 
      break; 
     case 68: 
      sonic1 = new createjs.Sprite(spriteSheet2); 
      sonicDirectionXP = true; 
      break; 
     case 87: 
      sonic1 = new createjs.Sprite(spriteSheet2); 
      sonicDirectionYN = true; 
      break; 
     case 83: 
      sonic1 = new createjs.Sprite(spriteSheet2); 
      sonicDirectionYP = true; 
      break; 
     default: // This is my quess for your sonicstate === 0 
      sonic1 = new createjs.Sprite(spriteSheet1); 
    } 
} 
+0

нет другого пути вокруг этого? потому что я планирую добавить код движения в операторы if, и если я это сделаю, он будет обновляться каждый раз, когда keyDown активируется, а не каждый раз, когда тикер галочки – Jeff

+0

просто пробовал это, он тоже не работает. Он все еще записывает нажатие клавиши, хотя, когда я помещаю в него console.log – Jeff