Как сделать одноразовое нажатие клавиш.
Здравствуйте!
(Это работа с канвасом.) Есть скрипт для одновременного нажатия клавиш, всё работает, но мне нужно сделать чтобы при нажатии, например, стрелки в верх и влево, эти клавиши срабатывали лишь раз (аналогично и с одной клавишей), т.е. нужно прервать выполнение функции после того как условие выполнится, но такое ощущения, что то условие которое я написал вообще не проверяется - это я думаю, что так надо сделать - надеюсь меня наставят на путь истинный и помогут решить эту головоломку. Другими словами, мне нужно, чтобы "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; } }; |
<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> у меня как-то так получилось ) |
canvas одноразовое нажатие клавиш
drakulawz,
вариант Rise, добавлено Цитата:
<!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> |
Цитата:
мне нужно, что бы после того как нажалась стрелка (любая или две для диагонали), ивент прекращался и плеер был перемещён на спид - всё, он не должен больше двигаться сколько бы клавиша не держалась. Нажал ещё раз - тот же эффект, ещё раз - аналогично. Вот такое решение мне нужно. Плеер не должен перемещаться когда держишь клавишу нажатой! Только один шаг - одно нажатие! |
рони,
Круто!:write: Благодарю! #offtop Кстати, кто-нибудь может сталкивался, не работают всплывающие окна в браузере (UC Browser) - ничего не менял (не помню по крайней мере), вот когда плюсик возле "Карма" жму ничего не выпадает - как и с остальными диалогами на сайте (и на всех остальных). Может какая-то комбинация клавиш такое делает? Если кто не в курсе - это тот же гугл хром (на его основе спиляно). |
<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> |
рони, а почему нужно использовать именно Math.max и Math.min?
Разве не правильней будет Math.ceil ? |
Цитата:
Цитата:
|
SuperZen, не работает ведь.:) И я не понимаю, по большей части 50% вашего кода.:p Вариант рони, мне подходит.:yes:
|
Цитата:
А, не так выразился. Имею в виду, если взять вот так: в функции движения сделать так: this.x = this.x + this.step а уже в инициализации отрисовки: Math.ceil(canvas.width - player.width) |
Часовой пояс GMT +3, время: 10:20. |