Движение Javascript при удержании клавиши

Мне нужна помощь с функцией движения для игры на холсте.

Ниже то, что у меня есть, и происходит то, что игрок меняет направление только при нажатии левой/правой клавиши.

Было бы идеально, если бы игрок смотрел в соответствующем направлении, удерживая нажатой клавишу со стрелкой влево или вправо, чего в настоящее время не происходит.

Я понятия не имею, как это сделать, есть идеи?

Теперь у меня есть направление движения, работающее при удержании клавиши, обновленное ниже, но при первой загрузке страницы проигрыватель не отображается на экране, а затем отображается после нажатия клавиши. Что-то неправильно...

var trackRight = 0;
var trackLeft = 1;
var x = 570;
var y = 255; //no collision past here
var srcX;
var srcY;
var speed = 25;

var character = new Image();
character.src = "ptera_purple.png";

function updateFrame() {
    curFrame = ++curFrame % frameCount;
    srcX = curFrame * width;
    ctx.clearRect(0, 0, canvas.width, canvas.height, x, y, width, height);


    if (left && x > 0) {
        srcY = trackLeft * height; //important for sprite direction
        x -= speed;
    }

    if (right && x < canvasWidth - width) {
        srcY = trackRight * height;
        x += speed;
    }
}

var right = false;
var left = false;

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);

function keyDownHandler(e) {
    if (e.keyCode == 39) {
        right = true;
    } else if (e.keyCode == 37) {
        left = true;
    }
}

function keyUpHandler(e) {
    if (e.keyCode == 39) {
        right = false;
    } else if (e.keyCode == 37) {
        left = false;
    }
}

function moveLeft() { // keyboard controls
    left = true;
    right = false;
}

function moveRight() {
    left = false;
    right = true;
}


person LFJ__    schedule 10.10.2016    source источник
comment
Где остальная часть вашего кода? Мне кажется, что обработчики ключей здесь наименее важная часть проблемы; должна быть другая функция, которая проверяет переменные right и left, чтобы обновить состояние/скорость/направление/что-то еще у игрока?   -  person nnnnnn    schedule 10.10.2016
comment
@nnnnnn, добавил остальные. Есть и движение клавиатуры, и движение клавиши со стрелкой, вы думаете, что это будет конфликтовать?   -  person LFJ__    schedule 10.10.2016


Ответы (3)


Обесцененные keyEvent.keyCode не использую.

Обратите внимание, что keyEvent.keyCode устарела и не должна использоваться. Вы можете использовать keyEvent.key или keyEvent.code, где key — это то, что пользователь намеревается увидеть (удерживает сдвиг или заглавную букву для A или нет для a), а code — для ключевого положения, где код всегда «KeyA», независимо от того, заглавная это буква или нет.

событие клавиатуры MDN для получения полной информации.

Использовать объект keyState

Самый простой способ использовать клавиатуру в анимациях и играх — это иметь объект состояний клавиш. Добавьте одно и то же простое событие как вниз, так и вверх

document.addEventListener("keydown",keyhandler);
document.addEventListener("keyup",keyhandler);

Создать ключевой объект состояния

var keyState = {};

А затем просто отметьте ключ в зависимости от события ввода

function keyHandler(e){  // simple but powerful
   keyState[e.code] = e.type === "keydown";
}

Затем в основном цикле все, что вам нужно сделать, чтобы узнать, нажата ли клавиша

if(keyState.ArrowRight) { // right  is down }
if(keyState.LeftRight) { // left  is down }

Подробное состояние

Никогда не выполняйте какую-либо обработку ввода в событиях ввода-вывода, если у вас есть работающий цикл.

Вы можете получить больше информации. У меня обычно есть переключатель и изменение состояния

keyState = {
   down : {},   // True if key is down
   toggle : {},  // toggles on key up
   changed : {},  // True if key state changes. Does not set back false
                 // or you will lose a change
} 

function keyHandler(e){  // simple but powerful
   if(keyState.down[e.code] !== (e.type === "keydown")){
       keyState.changed = true;
   }
   keyState.down[e.code] = e.type === "keydown";
   if(e.type === "keyup"){
       keyState.toggle[e.code] = !keyState.toggle[e.code];
   }
}

Теперь, если вы хотите знать, была ли только что нажата клавиша

 if(keyState.down.LeftArrow && keyState.changed.LeftArrow){
      // key has been pushed down since last time we checked.
 }
 keyState.changed.LeftArrow = false; // Clear it  so we can detect next change
person Blindman67    schedule 10.10.2016
comment
Устарело, а не обесценено ;-( даже если на моем родном языке первое было бы более понято как нелюбимое больше, что все еще имеет смысл. - person Kaiido; 10.10.2016

вы можете добавить цикл while:

while(left == true) {
//code to execute
}

Я не уверен, что это сработает, но вы можете попробовать.

person nusje2000    schedule 10.10.2016
comment
Это не сработает и заблокирует страницу. Никакое событие не может сработать во время выполнения кода, и поэтому, когда оставлено значение true, цикл while будет зацикливаться вечно. - person Blindman67; 10.10.2016

Вам нужно прослушивать глобальное событие и отслеживать нажатие вниз, а затем сохранять движение где-нибудь. Посмотрите, что я сделал здесь https://github.com/panvourtsis/HTML5-canvas-game---POKEMON-/blob/master/canvas.pokemon.js

Также проверьте это

    document.onkeydown = function(e) {
        e = e || window.event;

        if(e.keyCode == "37") console.log("left");
        else if(e.keyCode == "38") console.log("up");
        else if(e.keyCode == "39") console.log("right");
        else if(e.keyCode == "40") console.log("down");
    };
person Panagiotis Vrs    schedule 10.10.2016
comment
Теперь у меня есть движение с удерживанием клавиши. Атм, плеер с начала загрузки страницы не показывает. Это фиксируется, когда игрок перемещается. Просто нужно разобраться сейчас, почему это происходит. - person LFJ__; 10.10.2016
comment
вы должны сначала нарисовать его с некоторыми x и y и начать перемещать его из этой начальной точки - person Panagiotis Vrs; 10.10.2016