I’m trying to make a program that can take for example, “LG” (pressed at the same time) as an input and output a unique letter. So far I’ve done the usual
if (key == 108) {
lDown = true;
}
if (key == 103) {
gDown = true;
}
if (lDown == true && gDown == true) {
System.out.println("ʊər");
}
Right, the usual stuff. But the problem I’m running into is that the output isn’t ʊər it’s “l \n ʊər” I’ve tried making a while(breakloop == true) loop and saying breakloop = false; after every part. I’m not sure what to do. When I did this with triple letters it would end up printing “l” over and over again, so I’m not sure if I messed up the syntax of the while loop or not (been trying to figure out this for a long time and there are a lot of lines) I’ve copy pasted the code that repeats letters over and over. Also, I’m not too well-versed in how this forum works so please, if I’ve messed anything up or you need more information let me know.
for some reason I can’t attach my code because it says that “new users can only link 2 sites” or something but if it’s necessary to see the code lmk. It’s really messy and I brute forced a lot of solutions that never worked and didn’t clean it up so it’s kind of an eyesore.
Basically keyboard won’t type two keys at once
One of the two keys response fast than other depends on which hit first you are going to get LGGG etc or GLLL etc
There are plenty of solutions for multiple keys in this forum that a search will reveal.
One simple example for just a and b keys:
boolean a, b;
int count = 0;
void setup()
{
size(200, 200);
}
void draw()
{
background(255);
if (a == true && b == true)
{
//System.out.println("ʊərπ");
println("ab");
println(count++);
// Comment these two for non repeating !
//a = false;
//b = false;
}
}
void keyPressed()
{
if (key == 'a')
a = true;
if (key == 'b')
b = true;
}
void keyReleased()
{
if (key == 'a')
a = false;
if (key == 'b')
b = false;
}
I’m on windows 10, processing 3 and the default font (I didn’t change anything after downloading processing) but the letters themselves aren’t the problem, I also got “??”. I also tried
but this only output “ae” once and doesn’t output anything else afterwards. My original post was badly worded, the letters it outputs don’t matter, it’s just a place holder to get things working first. Basically I’m trying to make a keyboard that makes different sounds when you press different keys. And since there are more sounds than keys I wanted two or three keys being pressed at once to make their own unique sound. Instead of uploading all the sounds, I just used System.out.println() to represent them for the time being. The problem I ran into was that pressing two keys at once would make two outputs, not one unique output. Thank you so much for taking the time to read this!
that’s what I was thinking but isn’t there a way to make the program wait for a split second to check if two keys are being pressed before sending the single key output. Also my keyboard can type glglglglgl it just takes good timing.
the thing is, I have all of that in my code. for a program that only needs to move a character, a tiny forward movement before diagonal movement is fine. But for mine, pressing two keys at once will give two outputs. I want one output
@Mook is this more what you were looking for? i made it so holding both and only both a and e together change the background to red, can use that setup for anything though including playing a unique sound file
Edit: if you want a and e to do their own thing, simply add another if statement in draw asking if that list contains just their keyCode values
I tried it with the print statement instead and it wasnt the solution that you’re looking for but replace the if statement in draw with and it does what you want, if both keys aren’t pressed at exactly the same time and lifted at the same time you’ll still get either the a or e on their own, ill keep trying other solutions
if (keys.size() > 1) {
if (keys.contains(65) && keys.contains(69)) {
background(0, 0, 255);
println("ab");
}
} else if (keys.size() == 1) {
if (keys.contains(65)) {
background(255, 0, 0);
println("a");
}
if (keys.contains(69)) {
background(0, 255, 0);
println("b");
}
}
Hi, I was able to ask someone in person and they came up with a solution. The code is kind of complex but basically the keyboard starts out unarmed and once any key is pressed it becomes armed. Any other keys pressed within this period counts as a single press and the program prints out the ascii values.
class KeyManager {
private final int HOTKEY_WAIT = 100; //(ms)
private boolean[] keyPresses;
HotKey result;
private int first_press;
private boolean armed;
KeyManager() {
keyPresses = new boolean[130];
armed = true;
result = new HotKey();
}
public void pressKey(char key) {
int ascii = int(Character.toLowerCase(key));
keyPresses[ascii] = true;
}
public void releaseKey(char key) {
int ascii = int(Character.toLowerCase(key));
keyPresses[ascii] = false;
}
//In draw loop
public HotKey checkHotkeyPressed() {
if (armed && allKeysUp()) { return new HotKey(); }
if (armed && !allKeysUp()) {
armed = false;
first_press = millis();
}
//Key has been pressed
if (millis()-first_press <= HOTKEY_WAIT) {
if (result.full()) {
return new HotKey();
}
for (int i = 0; i < keyPresses.length; i++) {
if (result.full()) {
break;
}
if (keyPresses[i] && !result.hasAscii(i)) {
result.addKey(i);
}
}
} else {
if (allKeysUp()) { armed = true; }
HotKey temp = result;
result = new HotKey();
return temp;
}
//Past time and not armed
return new HotKey();
}
private boolean allKeysUp() {
for (int i = 0; i < keyPresses.length; i++) {
if (keyPresses[i]) { return false; }
}
return true;
}
}
class HotKey {
public int ascii1;
public int ascii2;
public int ascii3;
public int length;
HotKey() { length = 0; }
HotKey(char a1) {
ascii1 = int(Character.toLowerCase(a1));
length = 1;
}
HotKey(char a1, char a2) {
ascii1 = int(Character.toLowerCase(a1));
ascii2 = int(Character.toLowerCase(a2));
length = 2;
}
HotKey(char a1, char a2, char a3) {
ascii1 = int(Character.toLowerCase(a1));
ascii2 = int(Character.toLowerCase(a2));
ascii3 = int(Character.toLowerCase(a3));
length = 3;
}
public void addKey(int a) {
if (length == 0) {
length = 1;
ascii1 = a;
} else if (length == 1) {
length = 2;
ascii2 = a;
} else if (length == 2) {
length = 3;
ascii3 = a;
}
}
public boolean full() {
return length >= 3;
}
public boolean hasAscii(int a) {
if (length == 0) { return false; }
if (length == 1) { return ascii1 == a; }
if (length == 2) { return ascii1 == a || ascii2 == a; }
if (length == 3) { return ascii1 == a || ascii2 == a || ascii3 == a; }
return false;
}
public boolean isEquivalent(HotKey h) {
if (length != h.length) { return false; }
if (length == 1) { return ascii1 == h.ascii1; }
if (length == 2) {
if (ascii1 == h.ascii1 && ascii2 == h.ascii2) { return true; }
if (ascii1 == h.ascii2 && ascii2 == h.ascii1) { return true; }
return false;
}
if (length == 3) {
if (ascii1 == h.ascii1 && ascii2 == h.ascii2 && ascii3 == h.ascii3) { return true; }
if (ascii1 == h.ascii1 && ascii2 == h.ascii3 && ascii3 == h.ascii2) { return true; }
if (ascii1 == h.ascii2 && ascii2 == h.ascii1 && ascii3 == h.ascii3) { return true; }
if (ascii1 == h.ascii2 && ascii2 == h.ascii3 && ascii3 == h.ascii1) { return true; }
if (ascii1 == h.ascii3 && ascii2 == h.ascii2 && ascii3 == h.ascii1) { return true; }
if (ascii1 == h.ascii3 && ascii2 == h.ascii1 && ascii3 == h.ascii2) { return true; }
return false;
}
return false;
}
@Override
public String toString() {
if (length == 0) { return "{}"; }
if (length == 1) { return "{" + ascii1 + "}"; }
if (length == 2) { return "{" + ascii1 + ", " + ascii2 + "}"; }
if (length == 3) { return "{" + ascii1 + ", " + ascii2 + ", " + ascii3 + "}"; }
println("UNCAUGHT LENGTH ERROR!");
return "";
}
}
KeyManager keyManager = new KeyManager();
HotKey cool_one = new HotKey('a', 'b');
HotKey cool_two = new HotKey('b', 'f', 'g');
void setup() {
size(400, 400);
}
void draw() {
background(150);
HotKey pressed = keyManager.checkHotkeyPressed();
if (pressed.length > 0) {
println(pressed);
}
if (pressed.isEquivalent(cool_one)) {
println("GOT COOL_ONE");
}
if (pressed.isEquivalent(cool_two)) {
println("GOT COOL_TWO");
}
}
void keyPressed() {
//Guaranteed Ascii
if (int(key) < 200) {
keyManager.pressKey(key);
}
}
void keyReleased() {
//Guaranteed Ascii
if (int(key) < 200) {
keyManager.releaseKey(key);
}
}
That’s the code he came up with. I’ll be able to reformat it with more if loops to make key specific actions. Thank you all for the help I appreciate it a lot!
I swear I saw you posted your solution for less than 1 minute and then it vanished!
Anyways, I’m gonna leave my own approach for every1 to see:
The solution above can keep track up to 6 keys at once.
Up to 6 keyCode values are stored as a 5-bit value inside the single int variable heldKeys.
Each keyCode is mapped via function abc() to a range of 1 to 26, representing ‘A’ to ‘Z’.
Once all keys are released, the final result of heldKeys is used as a key index to access the HashMapphs in order to get() its corresponding associated String object.
Either that String or an ERROR message is displayed on the canvas.