Respond to 2 Keypresses at same time - javascript

I'm practicing moving around objects when a user presses an arrow key. I've got it so when they press right it moved an object to the right and when they press up it moves it up. However, my function is only able to record 1 of these keypresses at once, so they can't move diagonally:
document.onkeydown = function(e){
if (e.which == 39){ // Move Right
var position = $("#ball1").position();
$("#ball1").offset({left:position.left+2});
}
if (e.which == 38){ // Move Up
var position = $("#ball1").position();
$("#ball1").offset({top:position.top-2});
}
};
Is there a way to respond to both key presses at the same time?

You have to detect both keydown and keyup
var key = {};
document.onkeydown = function(e){
if (e.which == 39 || e.which == 38){ // Move Right
key[e.which] = true;
if (key[39]) {
var position = $("#ball1").position();
$("#ball1").offset({left:position.left+2});
}
if (key[38]) {
var position = $("#ball1").position();
$("#ball1").offset({top:position.top-2});
}
}
};
document.onkeyup = function(e){
if (key[e.which])
delete key[e.which];
};

Related

Move player javascript

I do not understand this part :
self.keyDown = function() { keys[event.keyCode] = 1; };
self.keyUp = function() { delete (keys[event.keyCode]); };
explain what this code does, please)
MVC :
Controller:
this.init = function() {
keys = {};
}
self.trgt = function(){
if(this.event.target === myContainer.querySelector('#start')) {
myModel.startGame();
window.addEventListener('keydown', self.keyDown);
window.addEventListener('keyup', self.keyUp);
}
}
self.keyDown = function() {
keys[event.keyCode] = 1;
};
self.keyUp = function() {
delete (keys[event.keyCode]);
};
self.moveHero = function(keycode) {
myModel.moveHero(keycode);
};
setInterval(function() {
for (let keycode in keys) {
self.move(keycode);
}
}, 20);
Model:
if (!sometask) {
if (keycode == 37 || keycode == 65) {
self.moveLeft();
}
if (keycode == 38 || keycode == 87) {
self.moveTop();
}
if (keycode == 39 || keycode == 68) {
self.moveRight();
}
if (keycode == 40 || keycode == 83) {
self.moveBottom();
}
}
};
the code in question:
self.keyDown = function() { keys[event.keyCode] = 1; };
self.keyUp = function() { delete (keys[event.keyCode]); };
is just assigning which keys are currently pressed. Lets say event.keyCode = 37, In this instance your keys variable, which is an object, will now have a property that says keys[37] = 1, and it will remain that way until the keyUp function is called, deleting it. Whiile keys[37] = 1, the character will continue moving left, and this will stop once that key is deleted.
self.keyDown = function() { keys[event.keyCode] = 1; };
self.keyUp = function() { delete (keys[event.keyCode]); };
Translating to plain English:
If the user press the keyDown (number 40) then set the key 40 in the object keys to 1.
If the user press the keyUp (number 38) then delete from the keys object the key 38
These lines are to set functions that will be called each time the event keyDown (press a key) or keyUp (release the key) are called.
So let's focus on the actual code inside the function :
for keyDown, it sets a variable in a dictionary to a value. for instance, if you press down 'a', 'a' key on the keyboard has some int value which is 65 (see https://keycode.info/), and it will set the keys[65] = 1.
As long as you keep the button press, this value will stay, but as soon as you release it, the value is unset by using delete .
And so on for each keyboard key.
Then the main loop of the game will look which variables are set (by using "for ... in keys), and will execute a move function for each variable that has a special values, corresponding, I guess, to a-w-s-d or left-up-right-down.

Touch control for html5 game

I've been working on a simple html5 canvas game, and I'm trying to add touch controls for devices as well as keyboard input for desktops etc.
The keyboard controls are perfect: space bar is tapped to jump, and held for a longer jump.
I've added event listeners for touch control, which emulate the single tap of the spacebar, but I can't figure out how to recreate holding the space bar for longer jumps with the touch control. My keyboard code looks like this:
// jump if not currently jumping or falling
if (KEY_STATUS.space && player.dy === 0 && !player.isJumping) {
player.isJumping = true;
assetLoader.sounds.jump.play();
player.dy = player.jumpDy;
jumpCounter = 12;
}
// jump higher if the space bar is continually pressed
if (KEY_STATUS.space && jumpCounter) {
player.dy = player.jumpDy;
assetLoader.sounds.jump.play();
}
jumpCounter = Math.max(jumpCounter-1, 0);
this.advance();
And that gets tracked with this code:
var KEY_CODES = {
32: 'space'
};
var KEY_STATUS = {};
for (var code in KEY_CODES) {
if (KEY_CODES.hasOwnProperty(code)) {
KEY_STATUS[KEY_CODES[code]] = false;
}
}
document.onkeydown = function(e) {
var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
if (KEY_CODES[keyCode]) {
e.preventDefault();
KEY_STATUS[KEY_CODES[keyCode]] = true;
}
};
document.onkeyup = function(e) {
var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
if (KEY_CODES[keyCode]) {
e.preventDefault();
KEY_STATUS[KEY_CODES[keyCode]] = false;
}
};
My new event listeners for touch screen devices looks like this:
document.addEventListener("touchstart", touchHandler);
document.addEventListener("touchhold", touchHandler);
document.addEventListener("touchend", touchHandler);
And then I have this function, which is more or less identical to the function for keyboard input, only 'e.touches' is referenced, rather than 'KEY_STATUS':
function touchHandler(e) {
if(e.touches && player.dy === 0 && !player.isJumping) {
player.isJumping = true;
assetLoader.sounds.jump.play();
player.dy = player.jumpDy;
jumpCounter = 12;
e.preventDefault();
}
}
That function enables the little jump. If I include this 'if' statement, it enables multiple jumps:
if (e.touches && jumpCounter) {
player.dy = player.jumpDy;
assetLoader.sounds.jump.play();
}
...rather than enabling the player to perform the longer jump. Essentially, the player could tap to fly throughout the game, which I don't want! Is there a way to specify within the 'touchHandler()' function which kind of jump is being made ie. is the screen being tapped or held? Or would I need to write a separate function for that?
Thanks in advance.

JavaScript or jquery trigger left arrow key press event (Simulate arrow key press)

I am trying to simulate the left and the right arrow key press in a text area within a rad grid control (Telerik).
I have a bug that is specific to the browser Firefox where the tab event(got this part fixed) and the arrow keys wont work. Every other browser works fine.
So as a workaround i want to simulate the arrow keys using JavaScript or jquery.
Below is what i have working with the tab event fix included. In addition to this I check if the key code 37 (this is the left arrow key) is pressed. At this point i want to simulate the left arrow press in the text area.
$(document).on('keydown', function (event) {
if (event.keyCode == 9) { //tab pressed
event.preventDefault(); // stops default action
}
});
$('body').keyup(function (e) {
var code = e.keyCode || e.which;
//Left arrow key press
if (code == '37')
{
moveLeft();// This does not trigger the left arrow event
}
//Tab button pressed
if (code == '9') {
//shift was down when tab was pressed focus -1
if (e.shiftKey && code == 9) {
var focused = $(':focus');
var inputs = $(focused).closest('form').find(':input');
inputs.eq(inputs.index(focused) - 1).focus();
}
//tab was pressed focus +1
else {
var focused = $(':focus');
var inputs = $(focused).closest('form').find(':input');
inputs.eq(inputs.index(focused) + 1).focus();
}
}
});
Any help on this issue would be appreciated
I got this working by moving the cursor back one space, below is the code I used to simulate the left arrow key press.
Note - To simulate right the key code is 39 and set the myval property to -1.
$('body').keydown(function (e) {
var code = e.keyCode || e.which; //Find the key pressed
if (code == '37') {
e.preventDefault(); // stop default action
var elementId = e.target.id;// get id of input text area
var el = document.getElementById(elementId),
myval = 1 // set mouse cursor to move back one space
cur_pos = 0;
if (el.selectionStart) {
cur_pos = el.selectionStart;
}
else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r != null) {
var re = el.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
cur_pos = rc.text.length;
}
}
if (el.setSelectionRange) {
el.focus();
el.setSelectionRange(cur_pos - myval, cur_pos - myval);
}
else if (el.createTextRange) {
var range = el.createTextRange();
range.collapse(true);
range.moveEnd('character', cur_pos - myval);
range.moveStart('character', cur_pos - myval);
range.select();
}
}

Click a specified event on the input in keyboard: up, down, left, right

I need an event that gives one click right, up, down or left. Below is the logic:
if (gesture.left) {
Click Event for left direction
} Else if (gesture.right) {
Click Event for right direction
}
I need to detect only one condition after the click button
Try this code:
$(function(){
$('html').keydown(function(e){
if(e.keyCode == 37) { // left
}
else if(e.keyCode == 39) { // right
}
else if(e.keyCode == 38) { // up
}
else if(e.keyCode == 40) { // down
}
});
});
arrow keys are only triggered by onkeydown, not onkeypress
keycodes are:
left = 37;
up = 38;
right = 39;
down = 40;
or you can look at this thread sample

How to know which key was held when left mouse button was clicked?

I wan't to detect if some other key is held when the left mouse button is clicked how can i do it?
i used this to detect ctrl+shift but now i wan't to know if 'A' or 'B' or both were held.
if(e.shiftKey && e.ctrlKey) console.log("ctrl+shift key was held when pressing the left mouse button");
the mouse event I receive doesn't have a keyCode for held keys. I want pure Javascript.
Maybe something like this (listening for keydown and keyup):
var keys = [];
$(document).keydown(function(e){
var index = keys.indexOf(e.keyCode);
if(index === -1){
keys.push(e.keyCode);
}
}).keyup(function(e){
var index = keys.indexOf(e.keyCode);
if(index !== -1){
keys.splice(index, 1);
}
}).click(function(e){
console.log(keys);
});
A pure javascript solution would be:
var held_key = null;
function key_down(event) {
var key = event.keyCode || event.which;
// get string representation of held key
var keychar = String.fromCharCode(key);
// store held key in global variable
held_key = keychar;
}
//revert held_key to null onkeyup
function key_up(event) {
var key = event.keyCode || event.which;
held_key = null;
}
window.onload = function() {
window.onkeydown = key_down;
window.onkeyup = key_up;
window.onclick = function(e) {
// put condition for the key you want here
if (held_key == 'A') {
//do something
console.log('hi!');
}
}
}

Categories