![Старый](/forum/images/ca_serenity/statusicon/post_old.gif)
01.08.2019, 23:09
|
Новичок на форуме
|
|
Регистрация: 13.02.2018
Сообщений: 9
|
|
Обработка нажатия двух клавиш одновременно.
Всем привет! Помогите разобраться, как изменить код, чтобы обрабатывались две нажатые клавиши одновременно. Чтобы две кнопки были независимы друг от друга.
Я так понимаю тут причина в keyCode, которая принимает только какое то одно значение. т.е при получении второго значения(скажем D) значение W удаляется. Нужен массив? пробовал по разному, не понимаю.
var mas = {
'W':87,
'D':68
};
window.onkeydown=function(e){
if(e.keyCode == mas.W){
console.log('Кнопка W нажата');
}
if(e.keyCode == mas.D){
console.log('Кнопка D нажата');
}
window.onkeyup=function(e){
if(e.keyCode == mas.W){
console.log('Отжата кнопка W');
}
else if(e.keyCode == mas.D){
console.log('Отжата кнопка D');
}
}
}
В консоле при нажатии к примеру клавиши W вижу, как она обрабатывается, но как только нажимаю D обработка W прерывается.
В дальнейшем хочу чтобы объект в canvas мог двигаться не только по вертикали и горизонтали, но и по диагонали.
|
|
![Старый](/forum/images/ca_serenity/statusicon/post_old.gif)
02.08.2019, 00:44
|
![Аватар для j0hnik](https://javascript.ru/forum/image.php?u=50436&dateline=1483015396) |
Профессор
|
|
Регистрация: 01.12.2016
Сообщений: 3,650
|
|
у вас же есть событие keyup, очевидно ведь, что если клавиша была нажата, пока не сработало событие keyup она нажата.
|
|
![Старый](/forum/images/ca_serenity/statusicon/post_old.gif)
02.08.2019, 01:57
|
![Аватар для Malleys](https://javascript.ru/forum/image.php?u=4857&dateline=1261338679) |
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Зачем на каждом нажатии клавиши переопределяется обработчик отжимания клавиши?
Сообщение от Temcher
|
e.keyCode
|
Это не рекомендуемое к использованию свойство, используйте вместо него KeyboardEvent.prototype.key или KeyboardEvent.prototype.code
Исправленный вариант, в объекте pressedKeys хранятся нажатые клавишы...
var pressedKeys = {};
onkeydown = function(e) {
if(pressedKeys[e.code]) return;
pressedKeys[e.code] = true;
if(e.code === "KeyW") {
console.log('Кнопка W нажата');
} else if(e.code === "KeyD") {
console.log('Кнопка D нажата');
}
}
onkeyup = function(e) {
delete pressedKeys[e.code];
if(e.code === "KeyW") {
console.log('Отжата кнопка W');
} else if(e.code === "KeyD") {
console.log('Отжата кнопка D');
}
}
Можно упростить до...
var pressedKeys = {};
onkeydown = function(e) {
if(e.code in pressedKeys) return;
pressedKeys[e.code] = true;
}
onkeyup = function(e) {
delete pressedKeys[e.code];
}
В pressedKeys находятся зажатые клавиши.
Вот улучшенный вариант... Класс PressedKeysRegistry позволяет включать/выключать отслеживание нажатых клавиш, также используется метод addEventListener, чтобы вы могли добавить и другие обработчики событии keydown и keyup.
<canvas id="app" width="300" height="300" style="border: solid;"></canvas>
<script>
function PressedKeysRegistry() {
this.handler = this.handler.bind(this);
}
PressedKeysRegistry.prototype = {
constructor: PressedKeysRegistry,
start: function() {
addEventListener("keydown", this.handler);
addEventListener("keyup", this.handler);
},
stop: function() {
removeEventListener("keydown", this.handler);
removeEventListener("keyup", this.handler);
},
handler: function(event) {
if(event.type === "keydown") {
if(this[event.code]) return;
this[event.code] = true;
} else if(event.type === "keyup") {
delete this[event.code];
}
}
};
// пример
var pressedKeys = new PressedKeysRegistry();
pressedKeys.start();
var player = { x: 50, y: 50 };
var field = { width: 100, height: 100 };
var ctx = app.getContext("2d");
(function loop() {
ctx.clearRect(0, 0, app.width, app.height);
ctx.fillRect(player.x / field.width * app.width, player.y / field.height * app.height, 20, 20);
if("KeyD" in pressedKeys) player.x++;
if("KeyA" in pressedKeys) player.x--;
if("KeyS" in pressedKeys) player.y++;
if("KeyW" in pressedKeys) player.y--;
setTimeout(loop, 50);
})();
</script>
Последний раз редактировалось Malleys, 02.08.2019 в 13:32.
|
|
![Старый](/forum/images/ca_serenity/statusicon/post_old.gif)
02.08.2019, 06:03
|
![Аватар для j0hnik](https://javascript.ru/forum/image.php?u=50436&dateline=1483015396) |
Профессор
|
|
Регистрация: 01.12.2016
Сообщений: 3,650
|
|
Ставим влаги нажатым клавишам,вся соль в верхушке, остальное мишура (пример для простоты понимания, !не боевой код)
<div id="obj" style="width: 20px; height:20px; background-color:red; position:absolute; "></div>
<script>
var key = {
87: 0,
68: 0,
83: 0,
65: 0,
};
window.onkeydown = e => key[e.keyCode] = 1;
window.onkeyup = e => key[e.keyCode] = 0;
//остальное мишура
var rct = obj.getBoundingClientRect();
pos = [['top',rct.top],['left',rct.left]];
(run =_=> {
[[87,83],[65,68]].forEach((tl, x)=> tl.forEach((el, i)=> {
if(key[el]) {
pos[x][1] += i ? 1 : -1;
obj.style[pos[x][0]] = pos[x][1]+'px';
}
}));
setTimeout(run, 50);
})();
</script>
|
|
![Старый](/forum/images/ca_serenity/statusicon/post_old.gif)
02.08.2019, 07:50
|
![Аватар для рони](https://javascript.ru/forum/image.php?u=7416&dateline=1372796129) |
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,134
|
|
Сообщение от Malleys
|
var field = { width: 100, height: 100 };
|
для чего это?
|
|
![Старый](/forum/images/ca_serenity/statusicon/post_old.gif)
02.08.2019, 13:52
|
![Аватар для Malleys](https://javascript.ru/forum/image.php?u=4857&dateline=1261338679) |
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от j0hnik
|
Ставим влаги нажатым клавишам,вся соль в верхушке, остальное мишура (пример для простоты понимания, !не боевой код)
|
А в примере выше не тоже самое? И как 87, 68, 83, 65 может быть лёгким для понимания? У вас получается, что правый и левый shift одно и тоже! Live expression в консоли показывает {16: 1, 65: 0, 68: 0, 83: 0, 87: 0} Так какая именно клавиша нажата? Кстати у вас происходит раздувание объекта после других нажатии!
В моём примере вы можете узнать, нажат ли правый shift, или левый или оба, цифра 2 нажата на цифровой клавиатуре или нет. Если не поняли, то вот с пример с информацией о нажатых клавишах... Нажмите кнопку Посмотреть!, а затем нажмите на пустое появившееся поле, чтобы оно могло ловить нажатия клавиш!
<p id="info"></p>
<script>
var pressedKeys = {};
onkeydown = function(e) {
if(e.code in pressedKeys) return;
pressedKeys[e.code] = true;
};
onkeyup = function(e) {
delete pressedKeys[e.code];
};
(function loop() {
info.textContent = Object.keys(pressedKeys).join(", ");
setTimeout(loop, 50);
})();
</script>
Сообщение от рони
|
для чего это?
|
Размер игрового поля.
Последний раз редактировалось Malleys, 02.08.2019 в 14:00.
|
|
![Старый](/forum/images/ca_serenity/statusicon/post_old.gif)
02.08.2019, 16:56
|
![Аватар для j0hnik](https://javascript.ru/forum/image.php?u=50436&dateline=1483015396) |
Профессор
|
|
Регистрация: 01.12.2016
Сообщений: 3,650
|
|
Malleys,
Я в курсе всего очевидного что вы написали, про шифты тут вообще без разницы, они не участвуют.
Пример демонстрирует идею!, но раз у вас на душе не спокойно то добавьте.Object.preventExtensions(key);
|
|
![Старый](/forum/images/ca_serenity/statusicon/post_old.gif)
02.08.2019, 17:17
|
![Аватар для рони](https://javascript.ru/forum/image.php?u=7416&dateline=1372796129) |
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,134
|
|
Сообщение от Malleys
|
Размер игрового поля.
|
ок.
|
|
![Старый](/forum/images/ca_serenity/statusicon/post_old.gif)
02.08.2019, 18:35
|
![Аватар для Malleys](https://javascript.ru/forum/image.php?u=4857&dateline=1261338679) |
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от j0hnik
|
про шифты тут вообще без разницы, они не участвуют.
|
Если человек не указал все клавиши, которые используются/будут использоваться в игре, то это не значит, что это не важно. В играх такое различие как раз важно!
Сообщение от j0hnik
|
Object.preventExtensions(key);
|
Оно и без этого работает... Я про то, что для игр лучше использовать KeyboardEvent.prototype.key или KeyboardEvent.prototype.code, а не KeyboardEvent.prototype.keyCode
|
|
![Старый](/forum/images/ca_serenity/statusicon/post_old.gif)
02.08.2019, 18:48
|
![Аватар для j0hnik](https://javascript.ru/forum/image.php?u=50436&dateline=1483015396) |
Профессор
|
|
Регистрация: 01.12.2016
Сообщений: 3,650
|
|
Сообщение от Malleys
|
Оно и без этого работает...
|
Это что не было эффекта
Сообщение от Malleys
|
происходит раздувание объекта после других нажатии!
|
ок, не знаю ни одной игры где шифты по разному работают, но учту ваше замечание ![](https://javascript.ru/forum/images/smilies/wink.gif)
|
|
|
|