We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › keysPressed[] idea
Page Index Toggle Pages: 1
keysPressed[] idea (Read 1699 times)
keysPressed[] idea
Jun 5th, 2005, 9:14am
 
This is to do with user interaction with processing via the keyboard... I guessed this was the best section to post in.

I was earlier frustrated by the number of variables I was having to write to track which keys were currently being pressed. This is very important if you want to press the up and left key at the same time, for example in a driving game to accelerate and turn at the same time. As I understand the keyPressed variable on its own doesn't contain enough information about which keys have been pressed and which ones have been released.

So, my usual solution is as follows:
Code:
boolean keyPressedUp = false;
boolean keyPressedDown = false;

void keyPressed() {
 if(keyCode == UP) keyPressed = true;
 if(keyCode == DOWN) keyPressed = true;
}

void keyReleased() {
 if(keyCode == UP) keyPressed = false;
 if(keyCode == DOWN) keyPressed = false;
}

Now I can keep track of which keys are current depressed, well for UP and DOWN. If I want to track LEFT, UP, SHIFT, or any of the others, I have to create a new variable, and add logic to keyPressed() and keyReleased().

My newest solution/idea is:
Code:
boolean[] keysPressed = new boolean[128];

void keyPressed() {
 keysPressed[keyCode] = true;
}

void keyReleased() {
 keysPressed[keyCode] = false;
}


Now I don't have to worry about which keys I want to use, because their states are all being stored for me:
Code:
if(keysPressed[LEFT]) {
 ...turn car left...
}
if(keysPressed[RIGHT]) {
 ...turn car right...
}
if(keysPressed[UP]) {
 ...accellerate...
}
if(keysPressed[DOWN]) {
 ...brake...
}
if(keysPressed[SHIFT]) {
 ...handbrake...
}
...etc...


This seems to work really well for me. My big limitation however is if you want to track letters such as 'a', 'w', '5', 'z', etc. - I can't see a method to calculate their keycodes. They all have keycodes, and they are being set in the array during the keyPressed() and keyReleased() methods but this is a one way process at the moment.

The missing part to help open up keyboard states would be to have a int keyCode('a'); method so you could do checks such as:
Code:
if(keysPressed[keyCode('q')]) {
 ...quit...
}

Anyone got any ideas/comments on this system?
Re: keysPressed[] idea
Reply #1 - Jun 5th, 2005, 9:23am
 
yeah, that was pretty smart actually.. got a bit tired of 7-12 different keypressed-vars, so this is a really good idea Smiley
I'm converting!

-seltar
Re: keysPressed[] idea
Reply #2 - Jun 5th, 2005, 6:31pm
 
Hey, i was just "inventing" the same thing two days ago. but i used an int array instead if bool. bool in fact is even better! but i was asking mayself if an array of 128 in lenght is just too big to store in memory?

nevertheless it works great!
Re: keysPressed[] idea
Reply #3 - Jun 5th, 2005, 6:52pm
 
I've done something similar, and just wrapped it in a class of it's own:
Code:

class keys
{
boolean[] k;
keys()
{
k=new boolean[255];
for(int i=0;i<k.length;i++)
{
k[i]=false;
}
}

void press(int x)
{
k[x]=true;
}

void release(int x)
{
k[x]=false;
}

boolean pressed(int x)
{
return k[x];
}

void releaseAll()
{
for(int i=0;i<k.length;i++)
{
k[i]=false;
}
}

boolean anyPressed()
{
for(int i=0;i<k.length;i++)
{
if(k[i]==true)
return true;
}
return false;
}
}
Re: keysPressed[] idea
Reply #4 - Jun 5th, 2005, 7:09pm
 
_020200_ wrote on Jun 5th, 2005, 6:31pm:
Hey, i was just "inventing" the same thing two days ago. but i used an int array instead if bool. bool in fact is even better! but i was asking mayself if an array of 128 in lenght is just too big to store in memory

nevertheless it works great!

Since its an array of boolean values, I don't think so - a simple 1 or 0 can be used to store that information making it the smallest array type available.

John, how would you implement your class
Re: keysPressed[] idea
Reply #5 - Jun 5th, 2005, 7:44pm
 
Well,I just reaslised my class won't handle extended keys properly, but works for all normal keys:
Code:

keys k;

....

void keyPressed()
{
if(key<256)
k.press(key);
}

void keyReleased()
{
if(key<256)
k.release(key);
}

void someFunction()
{
if(k.pressed('f'))
{
do something;
}
if(k.pressed('x'))
{
k.release('x'); // only want to do something once per press
do something else;
}
if(k.anyPressed())
{
k.releaseAll();
//don't care what key... so release all so we don't have to find out which is pressed to "release" it.
}
}
Re: keysPressed[] idea
Reply #6 - Jun 5th, 2005, 8:22pm
 
I tried the following, but unfortnatelly it can't handle more the 2 keys at once.

Code:

void keyPressed() {
input_array[keyCode] = true;
}

void keyReleased() {
input_array[keyCode] = false;
}

void checkKeys() {
for (int i=0; i<128; i++) {
if (input_array[37]) {xpos-=shpspeed; break;}
if (input_array[38]) {ypos-=shpspeed; break;}
if (input_array[39]) {xpos+=shpspeed; break;}
if (input_array[40]) {ypos+=shpspeed; break;}

// y || z
if (input_array[89] || input_array[90]) {shoot(); break;}
// x
if (input_array[88]) {shootSpecial(); break;}
}
}


Before that, i had a version with an int array. This also isn't that flexible, but this does handle as much keys pressed at the same time as you want. i think i'm gonna try johnG's version...

Code:

void keyPressed() {
input_array[keyCode] = keyCode;
}

void keyReleased() {
input_array[keyCode] = 0;
}

void checkKeys() {
for (int i=0; i<128; i++) {
switch (input_array[i]) {
case 37:
xpos-=shpspeed;
break;
case 38:
ypos-=shpspeed;
break;
case 39:
xpos+=shpspeed;
break;
case 40:
ypos+=shpspeed;
break;

case 89:
shoot();
break;
case 88:
shootSpecial();
break;
}
}
}
Re: keysPressed[] idea
Reply #7 - Jun 5th, 2005, 9:01pm
 
There were two little mistakes in JohnG script.

1. The init of the class has to go "Keys k = new Keys();" and not only "Keys k;"
[Note: I prefer classes to start with an capital letter. Beware of case sensitive]

2. In the implementation it has to go:
Code:

// note the !
if(!k.anyPressed()) {
k.releaseAll();
}


Just for convenience i post here te corrented version of JohnG's code.

class:
Code:

class Keys {
boolean[] k;

Keys() {
k=new boolean[255];
for(int i=0;i<k.length;i++) {
k[i]=false;
}
}

void press(int x) {
k[x]=true;
}

void release(int x) {
k[x]=false;
}

boolean pressed(int x) {
return k[x];
}

void releaseAll() {
for(int i=0;i<k.length;i++) {
k[i]=false;
}
}

boolean anyPressed() {
for(int i=0;i<k.length;i++) {
if(k[i]==true) return true;
}
return false;
}
}


implementation:
Code:

void keyPressed() {
if(keyCode<256) k.press(keyCode);
}

void keyReleased() {
if(keyCode<256) k.release(keyCode);
}

void doSomething() {
if(k.pressed(37)) ...;
if(k.pressed(38)) ...;
if(k.pressed(39)) ...;
if(k.pressed(40)) ...;

if(k.pressed(88)) {
k.release(88); // only want to do something once per press
do something else;
}
if(!k.anyPressed()) {
k.releaseAll();
//don't care what key... so release all so we don't have to find out which is pressed to "release" it.
}
}
Re: keysPressed[] idea
Reply #8 - Jun 5th, 2005, 9:14pm
 
I don't see why you want to ! the anyPressed() call.. it's a test to see if there's a key pressed, and returns true if any of the keys are pressed (e.g. "press any key to continue") does something, then unsets all the keys, since we want to return to a default state.

Edit: Oh, and I know the one I posted works, since it's copied directly from my zombie4 game...
Re: keysPressed[] idea
Reply #9 - Jun 5th, 2005, 9:33pm
 
Okay, maybe it depends on the context. i wanted to have motion just as long i keep the key pressed. but without the ! it only moved once when i pressed it down.
Re: keysPressed[] idea
Reply #10 - Jun 5th, 2005, 9:36pm
 
Ah okay, then you probbaly want:

Code:
while(k.anyPressed())
{
<stuff>
}

Then it'll automatically be unset when the user stops holding any keys.

Re: keysPressed[] idea
Reply #11 - Jun 6th, 2005, 10:13pm
 
I was playing around with the char data format, and discovered that char(<a number from 0-127 here>) would give you the ascii equivelant of that number. I wrote a little program which supplies the ascii value of a char. this can be used with the keysPressed[] concept to allow usage of all keys. Code to follow...

Code:

boolean[] keysPressed = new boolean[128];

void keyReleased() {
   if(!(ascii(key) == -1)){
 keysPressed[ascii(key)] = false;
 }else{
 keysPressed[keyCode] = false;
 }
}

int ascii(char Char){
 for(int i = 0; i < 128; i++){
   if(Char == char(i)){
     return i;
   }
 }
 return -1;
}

implementation is the same as with the previous keysPressed[], only for ascii keys you need to use

keysPressed[ascii(<what char you want to test>)]
Re: keysPressed[] idea
Reply #12 - Jun 6th, 2005, 10:55pm
 
BlueNinja wrote on Jun 6th, 2005, 10:13pm:
I was playing around with the char data format, and discovered that char(<a number from 0-127 here>) would give you the ascii equivelant of that number. I wrote a little program which supplies the ascii value of a char. this can be used with the keysPressed[] concept to allow usage of all keys. Code to follow...


you can just use single quotes round a character to get the value.. e.g. 'a' == 97 so you can used keysPressed['a']; instead of keysPressed[97];
Re: keysPressed[] idea
Reply #13 - Sep 28th, 2006, 4:52pm
 
Another way to do smooth keyboard input without having to use a multi-key tracking class or array is to simply have state variables in whatever object you are trying to control.

So your car class would look something like this:

Code:

class Car {
boolean accelerate, left, right, brake;

...

void update()
{
if (accelerate) // do accelerating mojo
if (left) // turn left
if (right) // turn right
if (brake) // do braking mojo
}
}


You might want to have more complicated rules so you aren't trying to accelerate and brake at the same time.

Then your keyboard functions would look like this:

Code:

void keyPressed()
{
if (keyCode == UP) car.accelerate = true;
if (keyCode == LEFT) car.left = true;
if (keyCode == RIGHT) car.right = true;
if (keyCode == DOWN) car.brake = true;
}

void keyReleased()
{
if (keyCode == UP) car.accelerate = false;
if (keyCode == LEFT) car.left = false;
if (keyCode == RIGHT) car.right = false;
if (keyCode == DOWN) car.brake = false;
}
Page Index Toggle Pages: 1