Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 27.09.2018, 13:40
Аспирант
Отправить личное сообщение для drakulawz Посмотреть профиль Найти все сообщения от drakulawz
 
Регистрация: 13.08.2018
Сообщений: 79

Как сделать одноразовое нажатие клавиш.
Здравствуйте!
(Это работа с канвасом.)
Есть скрипт для одновременного нажатия клавиш, всё работает, но мне нужно сделать чтобы при нажатии, например, стрелки в верх и влево, эти клавиши срабатывали лишь раз (аналогично и с одной клавишей), т.е. нужно прервать выполнение функции после того как условие выполнится, но такое ощущения, что то условие которое я написал вообще не проверяется - это я думаю, что так надо сделать - надеюсь меня наставят на путь истинный и помогут решить эту головоломку. Другими словами, мне нужно, чтобы "player" перемещался на "speed" или по оси "х", или по "у", или по оси "х - у" одновременно (по диагонали) - нажал клавишу и держи сколько хочешь, но "player" сдвинется только на "speed", нажмёшь ещё раз - сдвинется ещё раз.
Вот скрипты:

Для обработки клавишь:
var keys = {
    'W': 87,
    'S': 83,
    'A': 65,
    'D': 68,
    'LEFT': 37,
    'RIGHT': 39,
    'UP': 38,
    'DOWN': 40,
    'PAUSE': 32
};

var keyDown = {};

var setKey = function (keyCode) {
    keyDown[keyCode] = true;
    //    console.log(keyCode);
};

var clearKey = function (keyCode) {
    keyDown[keyCode] = false;
};

var isKeyDown = function (keyName) {
    return keyDown[keys[keyName]] == true;
};

var isAnyKeyDown = function () {
    for (var k in keyDown) {
        if (keyDown[k])
            return true;
    }
};

window.onkeydown = function (e) {
    setKey(e.keyCode);
};
window.onkeyup = function (e) {
    clearKey(e.keyCode);
};


То, что должно двигаться по нажатию:
var player = {
    level: 1,
    hp: 3,
    width: 50,
    height: 50,
    x: 320,
    y: 240,
    speed: 2,
    dx: 0,
    dy: 0,
    score: 0,
    color: randomColor(),

    draw: function () {
        drawRect(this.x, this.y, this.width, this.height, this.color);
    },

       // попытка сделать то что задумал:
        move: function () {
        if (this.x != this.x + this.width || 
            this.y != this.y + this.height || 
            this.x != this.x - this.width || 
            this.y != this.y - this.height) {
            if (isKeyDown('LEFT')) {
                this.x -= this.speed;
                this.dx = -1;
            } else if (isKeyDown('RIGHT')) {
                this.x += this.speed;
                this.dx = 1;
            } else {
                this.dx = 0
            }
            if (isKeyDown('DOWN')) {
                this.y += this.speed;
                this.dy = 1;
            } else if (isKeyDown('UP')) {
                this.y -= this.speed;
                this.dy = -1;
            } else {
                this.dy = 0;
            }
        } else {
            return;
        }
    },

    init: function (x, y) {
        this.x = x;
        this.y = y;
    }
};
Ответить с цитированием
  #2 (permalink)  
Старый 27.09.2018, 14:23
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 642

<html>

<head>
  <style>
    #hero {
      position: fixed;
      top: 100px;
      left: 100px;
      width: 100px;
      height: 100px;
      background-color: burlywood;
      border: 1px dashed #cccccc;
    }
  </style>
</head>

<body>
  <textarea id="keys"></textarea>
  <div id="hero"></div>
  <script>
    const keys = [37, 39, 38, 40]
    const speed = 5
    const keyPressed = {}
    const currentPosition = {
      x: 100,
      y: 100
    }

    const hero = document.getElementById('hero')

    document.addEventListener('keydown', function (e) {
      if (keys.includes(e.keyCode)) {
        keyPressed[e.keyCode] = true
      }
    })

    document.addEventListener('keyup', function (e) {
      if (keys.includes(e.keyCode)) {
        delete keyPressed[e.keyCode]
      }
    })

    setInterval(() => {
      document.getElementById('keys').value = JSON.stringify(keyPressed)
      update()
    }, 100)

    update = () => {
      if (38 in keyPressed) currentPosition.y -= speed
      if (40 in keyPressed) currentPosition.y += speed

      if (37 in keyPressed) currentPosition.x -= speed
      if (39 in keyPressed) currentPosition.x += speed

      hero.style.top = `${currentPosition.y}px`
      hero.style.left = `${currentPosition.x}px`
    }
  </script>
</body>

</html>


у меня как-то так получилось )
Ответить с цитированием
  #3 (permalink)  
Старый 27.09.2018, 14:39
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

canvas одноразовое нажатие клавиш
drakulawz,
вариант Rise, добавлено
Сообщение от drakulawz
чтобы "player" перемещался на "speed" или по оси "х", или по "у", или по оси "х - у" одновременно (по диагонали) - нажал клавишу и держи сколько хочешь, но "player" сдвинется только на "speed", нажмёшь ещё раз - сдвинется ещё раз.
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <script>
    try {
  'code' in KeyboardEvent.prototype || Object.defineProperty(KeyboardEvent.prototype, 'code', {
    get: function () { return { 37: 'ArrowLeft', 38: 'ArrowUp', 39: 'ArrowRight', 40: 'ArrowDown' }[this.keyCode] }
  })
} catch (e) {}

  </script>
</head>

<body>
<canvas width="200" height="100" id="myCanvas" style="border: 1px solid red"></canvas>
<script>
var canvas  = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var rec = {};
  rec.x = 10;
  rec.y = 10;
  rec.width = 50;
  rec.height = 25;
  rec.step = 5;
  rec.color = 'red';
  rec.moveup = function () {
    this.y = Math.max(this.y - this.step, 0);
  };
  rec.movedown = function () {
    this.y = Math.min(this.y + this.step, canvas.height - this.height);
  };
  rec.moveleft = function () {
    this.x = Math.max(this.x - this.step, 0);
  };
  rec.moveright = function () {
    this.x = Math.min(this.x + this.step, canvas.width - this.width);
  };
  rec.draw = function () {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = this.color;
    ctx.fillRect(this.x, this.y, this.width, this.height);
  };
  rec.draw();
var move = {};
  document.onkeydown = function (e) {
e.preventDefault();//только для примера тут
    if(move[e.code]) return;
    if (e.code == 'ArrowUp')  {rec.moveup();move.ArrowUp = true }
    else if (e.code == 'ArrowDown') {rec.movedown();move.ArrowDown = true }
    else if (e.code == 'ArrowLeft')  {rec.moveleft();move.ArrowLeft = true}
    else if (e.code == 'ArrowRight') {rec.moveright();move.ArrowRight = true}
    else return;
    rec.draw();
  };
  document.onkeyup = function (e) {
    if (e.code == 'ArrowUp')    move.ArrowUp = false;
    else if (e.code == 'ArrowDown')  move.ArrowDown = false;
    else if (e.code == 'ArrowLeft')  move.ArrowLeft = false;
    else if (e.code == 'ArrowRight') move.ArrowRight = false;
  };

</script>


</body>
</html>

Последний раз редактировалось рони, 27.09.2018 в 14:42.
Ответить с цитированием
  #4 (permalink)  
Старый 27.09.2018, 14:43
Аспирант
Отправить личное сообщение для drakulawz Посмотреть профиль Найти все сообщения от drakulawz
 
Регистрация: 13.08.2018
Сообщений: 79

Сообщение от SuperZen
у меня как-то так получилось )
Перефразирую:
мне нужно, что бы после того как нажалась стрелка (любая или две для диагонали), ивент прекращался и плеер был перемещён на спид - всё, он не должен больше двигаться сколько бы клавиша не держалась. Нажал ещё раз - тот же эффект, ещё раз - аналогично. Вот такое решение мне нужно. Плеер не должен перемещаться когда держишь клавишу нажатой! Только один шаг - одно нажатие!
Ответить с цитированием
  #5 (permalink)  
Старый 27.09.2018, 14:46
Аспирант
Отправить личное сообщение для drakulawz Посмотреть профиль Найти все сообщения от drakulawz
 
Регистрация: 13.08.2018
Сообщений: 79

рони,
Круто! Благодарю!


#offtop Кстати, кто-нибудь может сталкивался, не работают всплывающие окна в браузере (UC Browser) - ничего не менял (не помню по крайней мере), вот когда плюсик возле "Карма" жму ничего не выпадает - как и с остальными диалогами на сайте (и на всех остальных). Может какая-то комбинация клавиш такое делает? Если кто не в курсе - это тот же гугл хром (на его основе спиляно).

Последний раз редактировалось drakulawz, 27.09.2018 в 14:51.
Ответить с цитированием
  #6 (permalink)  
Старый 27.09.2018, 15:09
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 642

<html>

<head>
  <style>
    #hero {
      position: fixed;
      top: 100px;
      left: 100px;
      width: 100px;
      height: 100px;
      background-color: burlywood;
      border: 1px dashed #cccccc;
    }
  </style>
</head>

<body>
  <textarea id="keys"></textarea>
  <textarea id="previous_keys"></textarea>
  <div id="hero"></div>
  <script>
    const keys = [37, 39, 38, 40]
    const speed = 5
    const keyPressed = {}
    let previousKeyPressed = {}
    const currentPosition = {
      x: 100,
      y: 100
    }

    const hero = document.getElementById('hero')

    document.addEventListener('keydown', function (e) {
      e.preventDefault()
      if (keys.includes(e.keyCode)) {
        keyPressed[e.keyCode] = true
      }
    })

    document.addEventListener('keyup', function (e) {
      e.preventDefault()
      if (keys.includes(e.keyCode)) {
        delete keyPressed[e.keyCode]
      }
    })

    setInterval(() => {
      document.getElementById('keys').value = JSON.stringify(keyPressed)
      document.getElementById('previous_keys').value = JSON.stringify(previousKeyPressed)
      update()
    }, 100)

    update = () => {
      if (38 in keyPressed && !(38 in previousKeyPressed)) currentPosition.y -= speed
      if (40 in keyPressed && !(40 in previousKeyPressed)) currentPosition.y += speed

      if (37 in keyPressed && !(37 in previousKeyPressed)) currentPosition.x -= speed
      if (39 in keyPressed && !(39 in previousKeyPressed)) currentPosition.x += speed

      hero.style.top = `${currentPosition.y}px`
      hero.style.left = `${currentPosition.x}px`

      previousKeyPressed = { ...keyPressed }
    }
  </script>
</body>

</html>
Ответить с цитированием
  #7 (permalink)  
Старый 27.09.2018, 15:20
Аспирант
Отправить личное сообщение для drakulawz Посмотреть профиль Найти все сообщения от drakulawz
 
Регистрация: 13.08.2018
Сообщений: 79

рони, а почему нужно использовать именно Math.max и Math.min?
Разве не правильней будет Math.ceil ?
Ответить с цитированием
  #8 (permalink)  
Старый 27.09.2018, 15:26
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

Сообщение от drakulawz
а почему нужно использовать именно Math.max и Math.min?
так проще всего получить ограничение диапазона, без всяких if.
Сообщение от drakulawz
Math.ceil
не знаю каким образом это применить.
Ответить с цитированием
  #9 (permalink)  
Старый 27.09.2018, 15:27
Аспирант
Отправить личное сообщение для drakulawz Посмотреть профиль Найти все сообщения от drakulawz
 
Регистрация: 13.08.2018
Сообщений: 79

SuperZen, не работает ведь. И я не понимаю, по большей части 50% вашего кода. Вариант рони, мне подходит.
Ответить с цитированием
  #10 (permalink)  
Старый 27.09.2018, 15:28
Аспирант
Отправить личное сообщение для drakulawz Посмотреть профиль Найти все сообщения от drakulawz
 
Регистрация: 13.08.2018
Сообщений: 79

Сообщение от рони
не знаю каким образом это применить.
Так если у меня координаты дробными получаются, разве не лучше применить Math.ceil ? Или в канвасе лучше так не делать?
А, не так выразился. Имею в виду, если взять вот так:
в функции движения сделать так:
this.x = this.x + this.step
а уже в инициализации отрисовки:
Math.ceil(canvas.width - player.width)

Последний раз редактировалось drakulawz, 27.09.2018 в 15:37.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Акардион меню из чекбоксов и списка, как сделать подсветку текущего элемента OliLoi jQuery 0 08.11.2016 08:15
Как сделать чтобы кнопка «Назад» работала бы в пределах определенного сайта? Askeer Общие вопросы Javascript 7 14.10.2016 12:23
Как сделать чтобы кнопка «Назад» работала бы в пределах определенного сайта? Askeer Общие вопросы Javascript 0 12.10.2016 18:58
как сделать чтобы в popup окне показывалось картинка? sarik Общие вопросы Javascript 31 15.03.2013 13:12
Как отследить нажатие клавиш <Alt>+<N> в Opera? alex77 Opera, Safari и др. 8 02.10.2010 16:08