Натискането на клавиш дава неочакван резултат. HTML5 игра

Така че аз съм в най-началния етап на създаване на моята първа игра в платформен стил в html5. Досега съм внедрил само движение наляво и надясно и няма "гравитация" или откриване на сблъсък.

Обаче вече срещнах проблем.

Ако отидете наляво или надясно за кратък период от време, „характерът“ действа по предназначение (използвам символ свободно, тъй като картата всъщност се движи). Ако обаче задържите клавиша натиснат, картата се движи твърде бързо.

Предполагам, че проблемът е, че слушателят на събития на натискане на клавиши слуша през цялото време, там за преместване на картата се движи преди всеки тик или кадър на играта.

Така че въпросът ми е как мога да накарам натискането на клавиша да увеличава отместването на картата само при всеки тик на играта (20 милисекунди).

Ето моя JSFiddle: ЩРАКНЕТЕ ТУК

document.addEventListener('keydown',function(event){
    var dir = event.which;

    if(dir == directions.LEFT){
        mapOffsetX += mapOffsetDistanceX;
        event.preventDefault();
    };

    if(dir == directions.RIGHT){
        mapOffsetX -= mapOffsetDistanceX;
        event.preventDefault();
    };
});

document.addEventListener('keyup',function(event){
    var dir = event.which;

    if(dir == directions.LEFT){
        mapOffsetX -= mapOffsetDistanceX;
    };

    if(dir == directions.RIGHT){
        mapOffsetX += mapOffsetDistanceX;
    };
});

initFloorObject(100,c.height/2,300,20,0,0,0,1);

var myInt = setInterval(function(){

clearScreen();

for(var i=0;i<floorObject.length;i++){
    floorObject[i][0] = parseInt(floorObject[i][0])+mapOffsetX;
};

drawChar();
drawFloorObjects();

},20);

person Dominic Sore    schedule 03.12.2013    source източник


Отговори (2)


Задайте променливата на false всеки път, когато keydown и я задайте обратно на true на всеки 20 милисекунди.

var isKeydownAvailable = true;
document.addEventListener('keydown', function (event) {
    var dir = event.which;
    if(isKeydownAvailable){
        if (dir == directions.LEFT) {
            mapOffsetX += mapOffsetDistanceX;
            event.preventDefault();
        };

        if (dir == directions.RIGHT) {
            mapOffsetX -= mapOffsetDistanceX;
            event.preventDefault();
        };
        isKeydownAvailable = false;
    };
});

В интервала нулирайте isKeydownAvailable до true.

var myInt = setInterval(function () {

    clearScreen();

    for (var i = 0; i < floorObject.length; i++) {
        floorObject[i][0] = parseInt(floorObject[i][0]) + mapOffsetX;
    };

    drawChar();
    drawFloorObjects();
    isKeydownAvailable = true;

}, 20);
person sPaz    schedule 03.12.2013
comment
Няма ли да използвам intervalTime като втори аргумент, когато задавам myInt в слушателя на събития? - person Dominic Sore; 03.12.2013
comment
Ааа, да, бихте го направили. Мисля, че прочетох въпроса погрешно. Чрез това как мога да накарам натискането на клавиша да увеличава отместването на картата само при всеки тик на играта (20 милисекунди), искате ли да извикате слушател на събития на всеки 20 милисекунди, когато играчът държи натиснат клавиша? - person sPaz; 03.12.2013
comment
Да, точно това имам предвид. Ще бъде ли приложимо вашето решение? - person Dominic Sore; 04.12.2013
comment
Редактирах отговора. Трябва да е приложимо. Ето един JSFiddle: jsfiddle.net/aU7ta/5. Промених интервала на 1 секунда, така че е по-ясно да се види промяната. - person sPaz; 04.12.2013

Използвайте булеви стойности за действия и проверете за тях във вашия интервал.
При натискане на клавиша задавате булевото isMovingLeft на true, след което добавяте отместването само във вашата интервална функция if(isMovingLeft). Направете това за другите действия и сте готови.

person SparK    schedule 03.12.2013