Как имитировать нажатие клавиш в JavaScript без jQuery

Создание симуляции клавиш для мобильной версии игры

Разрабатываю браузерную игру на чистом JavaScript с использованием processing.js. На компьютере все работает отлично, но нужно адаптировать под мобильные устройства.

Нашел код для определения свайпов:

function detectTouch(element, handler){
    var surface = element,
    direction,
    beginX,
    beginY,
    deltaX,
    deltaY,
    minDistance = 120,
    maxDeviation = 80,
    timeLimit = 250,
    duration,
    touchStart,
    processSwipe = handler || function(direction){}

    surface.addEventListener('touchstart', function(evt){
        var touch = evt.changedTouches[0]
        direction = 'none'
        beginX = touch.pageX
        beginY = touch.pageY
        touchStart = new Date().getTime()
        evt.preventDefault()
    }, false)

    surface.addEventListener('touchend', function(evt){
        var touch = evt.changedTouches[0]
        deltaX = touch.pageX - beginX
        deltaY = touch.pageY - beginY
        duration = new Date().getTime() - touchStart
        if (duration <= timeLimit){
            if (Math.abs(deltaX) >= minDistance && Math.abs(deltaY) <= maxDeviation){
                direction = (deltaX < 0)? 'left' : 'right'
            }
            else if (Math.abs(deltaY) >= minDistance && Math.abs(deltaX) <= maxDeviation){
                direction = (deltaY < 0)? 'up' : 'down'
            }
        }
        processSwipe(direction)
        evt.preventDefault()
    }, false)
}

Использую так:

detectTouch(gameElement, function(dir){
    if (dir == 'left')
        console.log('Свайп влево обнаружен!')
});

Функция движения персонажа выглядит так:

var controlCharacter = function(){
    if(currentKey === ARROW_LEFT){
        posX -= 4*gameScale;
    }
    if(currentKey === ARROW_RIGHT){
        posX += 4*gameScale;
    }
    if(currentKey === ARROW_UP){
        posY -= 4*gameScale;
    }  
    if(currentKey === ARROW_DOWN){
        posY += 4*gameScale;
    }
};
if(isKeyDown){
    controlCharacter();
}

Как заставить детектор свайпов симулировать нажатие клавиш для управления персонажем?

А почему не сделать универсальную функцию движения? Вместо привязки к currentKey создай moveCharacter(direction) и вызывай её и из обработчика клавиш, и из свайпов. Так код будет чище и не придется имитировать события. Какой движок processing.js используешь кстати?

Можешь использовать dispatchEvent для имитации реальных событий клавиатуры. Создаешь KeyboardEvent и отправляешь его:

detectTouch(gameElement, function(dir){
    let keyCode;
    if (dir == 'left') keyCode = 37; // ARROW_LEFT
    if (dir == 'right') keyCode = 39; // ARROW_RIGHT
    
    let event = new KeyboardEvent('keydown', {keyCode: keyCode});
    document.dispatchEvent(event);
});

Так твоя существующая система обработки клавиш будет работать без изменений, просто получит “поддельные” события от свайпов.

у меня была похожая задача когда делал арканоид для телефона. самый простой способ - это просто менять значение currentKey в обработчике свайпов. получается что-то типа:

detectTouch(gameElement, function(dir){
    if (dir == 'left') {
        currentKey = ARROW_LEFT;
        isKeyDown = true;
    }
    // аналогично для остальных направлений
});

только не забудь сбрасывать isKeyDown обратно в false через небольшую задержку, иначе персонаж будет двигатся бесконечно после одного свайпа.