Well lately i got interested in creating JS games. (not an area i have experience with but it interests me).
i know there are several gaming engines for JS out there but i dont really want to create a game. rather i am curious on how things work / how can i create one.
I have several questions:
Anyone with suggestions on where can I read about it? Prerequisite (what knowledge is needed).
I tried making a small game of something walking in a rectangular. By binding keyup to the window and checking the event.which to get the key that was pressed. I realized that if i clicked on 2 buttons same time only 1 of them is being registered. how can i overcome that?
$(window).keyup(function(event){
globalEvent = event.which;
});
To directly answer your second question.
Here is one way:
var keyPressed = {};
$(window).keydown(function(e) {
keyPressed[e.which] = true;
}).keyup(function(e) {
keyPressed[e.which] = false;
});
Now you can use keyPressed whenever you want to determine if a key is down:
// wherever
var key1 = 65, key2 = 66; // A and B
if (keyPressed[key1] && keyPressed[key2]) {
// A and B are both being pressed.
}
In order to detect multiple keys being held down, use the keydown and keyup events.
var keys = {};
$(document).keydown(function (e) {
keys[e.which] = true;
});
$(document).keyup(function (e) {
delete keys[e.which];
});
Related
First code--> My first example does not work, and I am not sure why. I would say a condition, like if(keys[38]) where 38 in the example would be the event.keyCode. If true, it should execute the if statement.
second code--> The second example only works when there is one key being pushed, and I am not sure why it does not work for multiple keys, either. For multiple keys I would say something like if(keys[38] && keys[40]), but that will not work, it should be noted, however, that it would work for just one key, like just if(keys[38]).
I know that there are other ways to get this to work, but my objective is to figure out why these code pieces do not work.
first code piece:
var keys = [];
addEventListener("keydown", function(event) {
keys[event.keyCode] = event.type == "keydown";
event.preventDefault();
});
/*conditions*/
second code piece:
var keys = [];
addEventListener("keydown", function(event) {
keys[event.keyCode] = event.type == "keydown";
event.preventDefault();
/* conditions with multiple keys accessing by if(keys[38] && keys[40]*/
});
thanks ahead of time :)
When you press multiple keys, your addEventListener no longer listens to your first keypress. That's why your if statement is failing. You can test that out on the first example on http://api.jquery.com/event.which/ Try holding one key, then holding a second key, and then releasing the second key. You'll notice that the first key won't be logged anymore.
*edit: A way around that would be to implement it like this:
var keys = {};
$(document).keydown(function (e) {
keys[e.which] = true;
});
$(document).keyup(function (e) {
delete keys[e.which];
});
The difference is that in this case, nothing is getting overwritten, where as in your example your first key press is getting overwritten (and no longer saved) by the second key press.
I'm fiddling around trying to build a game, and added some even listeners to find out which keys are down. I stack 'm up into one array, and use that array to manipulate the game-state.
If this is the wrong way to go about it, feel free to comment on that specifically, but I'm just going to assume for a moment that this is one of the ways to Rome.
My question; when someone presses multiple keys at once (or lots of them in the case of PS2 boards) these case might get "stuck" in the array, while not being down.
How would one prune this array, without removing keys that are actually down at that very moment?
var keysDown = []; // this is where I toss all they keyCodes
function keyDown(e) {
e = e || event;
if (keysDown.indexOf(e.keyCode) < 0) {
keysDown.push(e.keyCode)
console.log(keysDown);
};
};
function keyUp(e) {
e = e || event;
if (keysDown.indexOf(e.keyCode) > -1) {
keysDown.splice(keysDown.indexOf(e.keyCode), 1);
console.log(keysDown);
};
};
document.onkeydown = keyDown;
document.onkeyup = keyUp;
.edit: Fiddled it.
It looks like, with JS this just isn't possible.
The neatest way to handle this is to do nothing.
Alternatively you can consider keeping track of the total number of keys punched in and if it exceeds a certain number (hard to say how many) you could delete the first pressed keys, but that's more like patching a leaking barrel with some tape.
Using Javascript / jQuery, how can I get automatically repeating keydown events, or equivalent, when someone holds down a key?
What I actually want is to be able to check whether a key is down, but from other questions here it looks like that's not possible. The suggested workaround seems to be recording keydown and keyup events and then assuming the key is down if a keydown event has been recorded and no subsequent keyup.
That solution runs into a problem in my case. I am designing an online experiment. The user is supposed to hold down the "T" key for the entire experiment, never letting it up. The experiment consists of multiple trials and each trial has no access to information recorded by the previous trials. So, trial 1 could record keydown for T, but trial 2 wouldn't have access to that record and thus wouldn't know whether T was down or not.
Now, if holding down the T key would produce automatically repeating keydown events for T, I would have no problem because trial 2 would just catch the next keydown event for T to come along. But it looks like I don't get automatically repeating keydown events from holding the key down, at least in Firefox. From what I can see it seems there is variation in the way different browsers handle holding a key down. What is a good cross-browser way to solve my problem?
By the way, if it matters, I also need to be able to detect keyup and keydown events for other keys while all this is going on.
EDIT: after reading some of the comments I went back and verified that I do indeed get repeating keydown events under ordinary circumstances. But I really don't get them in the specific situation in which I need them. I've got some simple code which I think isolates the issue:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<div id="target"></div>
</body>
<script type="text/javascript">
var i;
function foo() {
i++;
$('#target').html(i);
}
function doTrial() { // do trial
i=0;
$(document).keydown(foo);
$(document).keyup(endTrial);
}
function endTrial() { // end trial
$('#target').html('');
$(document).unbind('keydown',foo);
$(document).unbind('keyup',endTrial);
doTrial();
}
doTrial();
</script>
</html>
If you press a key and hold it down, then release, then press again, the behavior is as expected, i.e. there is a counter which increments while the key is held down, disappears when it's released, and then starts incrementing again when it's pressed again.
But if you press TWO keys down, then release ONE, I would have thought that the other (not released) key would continue sending keydown events so that the counter would (after resetting) continue incrementing. In fact, that doesn't happen. Any idea why and how to make it happen?
In the browsers I tried this in, I got repeated keydown events when holding a typeable key down. I don't know if this is a problem you actually need to solve.
But, if you did think you need to solve it OR if you want to control the repeat-rate yourself, you could do it like this:
Capture the events for keydown and keyup.
On keydown, set an interval timer that fires however often you want to know that the key is still down.
On keyup for that key, stop the interval timer.
You will get repeated notification in a cross browser way as long as the key is held down.
Working demo here: http://jsfiddle.net/jfriend00/XbZYs/
var downTimer;
var lastKey;
$(document.body).keydown(function(e) {
// if not still the same key, stop the timer
if (e.which !== lastKey) {
if (downTimer) {
clearInterval(downTimer);
downTimer = null;
}
}
// remember previous key
lastKey = e.which;
if (!downTimer) {
// start timer
downTimer = setInterval(function() {
$("#result").append("+");
}, 125);
}
}).keyup(function(e) {
// stop timer
if (downTimer) {
clearInterval(downTimer);
downTimer = null;
lastKey = 0;
}
});
If you want a key to auto-repeat forever until it is raised, even if other keys are pressed and released in the meantime and you want those other keys to do their own auto-repeating, then the OS does not ipmlement that behavior so you would have to implement it yourself. You can do something like this which calls a callback function for every key repeat event:
Working demo: http://jsfiddle.net/jfriend00/aD3Eg/
// this is called for every manufactured repeat event
// the frequency of the repeat event is determined by the time value set
// on setInterval() below
function repeatCallback(key) {
$("#result").append(key + " ");
}
var repeatState = {};
$(document.body).keydown(function(e) {
var key = e.which;
// if no time yet for this key, then start one
if (!repeatState[key]) {
// make copy of key code because `e` gets reused
// by other events in IE so it won't be preserved
repeatState[key] = setInterval(function() {
repeatCallback(key);
}, 125);
} else {
// nothing really to do here
// The key was pressed, but there is already a timer
// firing for it
}
}).keyup(function(e) {
// if we have a timer for this key, then stop it
// and delete it from the repeatState object
var key = e.which;
var timer = repeatState[key];
if (timer) {
clearInterval(timer);
delete repeatState[key];
}
});
The repeatCallback function is called for all of these manufactured auto-repeat events and passed the key that is auto-repeating.
Take a look at this jQuery plugin: fastKeys I think, that it is what you want/need...
I'm working on an RTS style webapp in processingJS, meaning that there is a little minimap that represents a larger map, which the user can only see a small part of at any given moment. I just added the ability to use arrow keys to navigate the map, i.e.:
void keyPressed(){
if(key == CODED){
switch(keyCode){
case(UP): //go up
case(DOWN): //go down , etc
However, I'd like to be able to let a user move diagonally by pressing a combination of two arrow keys. Right now, it seems like this is impossible to do, seeing as how "keyCode" can only seem to hold one value at a time.
Does anybody know any workarounds to this issue?
Best,Sami
As #Xenethyl pointed to in his link in the comments, one way to get around this is by keeping tracks of when a key is pressed and then watching for when the key is released. It is safe to assume that a key is held down in the period of time in between those two events.
I would just do the following in javascript:
document.onkeydown = keydown;
function keydown(evt) {
if (!evt) evt = event;
if (evt.ctrlKey && evt.altKey && evt.keyCode==115) {
alert("CTRL+ALT+F4"); }
else if (evt.shiftKey && evt.keyCode == 9) {
alert("Shift+TAB"); }
}
I haven't tested this - but have you tried:
void keyPressed(){
if(key == 'a' && key == 'b'){
println("this just happened");
}
}
If this works you can find the ascii values for the arrow keys instead of using key CODED.
Is there a way to read keyboard state outside of a keyboard event handler? Specifically, I need to check if the shift key is down during page load. I am using jQuery.
There is no querying of keyboard state in JavaScript. Wish there was. You have listen to events and track state yourself.
This code seems to work when you're holding the shift key down but it will work on subsequent keypresses. You could unbind it after the first keypress but this also means that it will run even after the page has loaded.
$(document).ready(function() {
$(document).keydown(function(e) {
if(e.shiftKey)
alert("Shift was held");
});
});
Stolen and improved from Marko's answer.
$(document).keydown(function(e) {
if(e.shiftKey)
alert("Shift was held");
});
simply removed the $(document).ready, since you want it while page is loading, not after.
You can use my library KeyboardJS. It has a method called .getActiveKeys() which will tell you what keys are active. The library is really for binding to keys and key combos in a common sense way.
I would suggest using the event binding.
KeyboardJS.bind.key('shift', function(){
//logic on key down
}, function(){
//logic on key up
});
Note that you can do complex things too such as shift + z + x or z + x + c. This will fire if shift, z, x are pressed together, or z, x, c are pressed together.
KeyboardJS.bind.key('shift + z + x, z + x + c', function(){
//logic on key down
}, function(){
//logic on key up
});
You can read what keys are pressed outside of an event callback like this
var activeKeys = KeyboardJS.getActiveKeys();
Hope that helps,
Cheers!
It's not exactly the solution I was hopping for but here's a workaround relying on events:
var shiftKeyState = false;
var ctrlKeyState = false;
$(document).ready(function () {
$(document).bind("keydown keyup click", function (e) {
shiftKeyState = e.shiftKey;
ctrlKeyState = e.ctrlKey;
});
});