Keyboard.GetState().IskeyDown() не работает должным образом

Вот метод обновления моего класса Player:

timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
KeyboardState state = Keyboard.GetState();
if (state.IsKeyDown(Keys.Up)) {
    if (currentFrame < 7) currentFrame = 7;
    if (timer >= delay) {
        if (currentFrame < 13) {
            currentFrame++;
        }
        else if (currentFrame == 13) {
            currentFrame = 7;
        }
        timer = 0;
    }
}
else {
    if (currentFrame > 7) currentFrame = 1;
    if (timer >= delay) {
        if (currentFrame < 6) {
            currentFrame++;
        }
        else if (currentFrame == 6) {
            currentFrame = 1;
        }
        timer = 0;
    }
}
sourceRect.X = currentFrame * 48 - 48; //I subtract 48 here to make the first frame 1 not 0.

А вот метод рисования:

spriteBatch.Draw(texture, position, sourceRect, Color.White);

Я пытаюсь сделать так, чтобы при нажатии клавиши вверх отображалась анимация с 7 по 13 кадр (из листа спрайтов). Когда клавиша «вверх» не нажата, рисуется анимация с 1 по 6 кадр.
Проблема: когда я продолжаю нажимать клавишу «вверх», она работает нормально, но когда я нажимаю клавишу «вверх» только один раз , анимация зависает на 7-м кадре.


person wingerse    schedule 14.02.2015    source источник
comment
Значение переменной timer искажено, оно всегда имеет большое значение. Всегда больше, чем delay.   -  person Hans Passant    schedule 14.02.2015
comment
@HansPassant Почему это? Я устанавливаю значение таймера на 0, если оно больше, чем задержка   -  person wingerse    schedule 14.02.2015
comment
0 — это время, когда пользователь начал игру, а не когда он нажал клавишу.   -  person Hans Passant    schedule 14.02.2015
comment
Я думал, что это время с момента последнего кадра.   -  person wingerse    schedule 14.02.2015


Ответы (2)


if (currentFrame > 7) currentFrame = 1;

попробуй изменить на

if (currentFrame >= 7) currentFrame = 1;
person Community    schedule 14.02.2015

Чтобы уточнить ответ @Silveor: в первый раз в цикле предположим, что currentFrame равно 1, а timer меньше delay.

  1. Вы нажали клавишу вверх, Keys.Up это клавиша вниз.
  2. currentFrame меньше 7 (это 1), поэтому установите его на 7.
  3. timer меньше delay, поэтому пропустите код, увеличивающий currentFrame
  4. В следующий раз через этот код: вы только нажали клавишу вверх (не удерживали ее), поэтому Keys.Up не является клавишей вниз.
  5. currentFrame не меньше 7 (это 7), поэтому не устанавливайте его равным 1
  6. Предположим, что timer больше, чем delay. Тем не менее currentFrame не будет увеличиваться или устанавливаться в 1, потому что currentFrame не меньше 6 или равно 6
  7. Нет кода для замены currentFrame на что-либо другое, поэтому он застревает на 7-м кадре.

Поэтому, если вы проверите значение 7 на шаге (5) выше, вы можете установить его равным 1. Вот почему ответ @Silveor правильный. :)

person ama1111    schedule 14.02.2015
comment
Можете ли вы объяснить 3? Если таймер меньше задержки, зачем пропускать эту часть? вместо этого он должен выполняться. - person wingerse; 14.02.2015
comment
Конечно: допустим, вы очень быстро нажимаете и отпускаете клавишу «вверх». Прошедшее время (т. е. timer) будет очень небольшим числом. В пути кода, который я описал выше, я предполагаю, что значение delay больше, чем это маленькое значение timer. - person ama1111; 14.02.2015
comment
таймер не является временем, прошедшим с момента нажатия клавиши вверх. Это время, прошедшее с момента последнего кадра. P.S. Можете ли вы проверить этот вопрос? У меня с этим проблемы: stackoverflow.com/questions/28517999 /не удается загрузить музыкальный файл - person wingerse; 14.02.2015
comment
Хорошо, я могу сказать это, не делая никаких заявлений о том, что timer измеряет: вы могли испытать симптом в своем вопросе (застрял на 7-м кадре) в сценарии, который я описал выше. Вероятно, это поможет вам визуализировать это, если вы добавите вызовы Debug.WriteLine() для регистрации значений timer, delay и currentFrame в различных частях этого метода. - person ama1111; 14.02.2015