This really needs to be added to documentation somewhere. I don't have time to do it now ... First of all, we looked at gc.isKeyDown('W') .... so that you can hold multiple keys and get diagonal motion. That works great. But what if we want only 1 letter? What if we're making Wordle and the user wants to type OSCAR ? He/she presses O and the program fills the word: OOOOO ! Now we could include gc.sleep(500) to slow things down, however, when the program runs sleep, it does not detect keypresses. So you might now have to type the letter twice to get it accepted. Here's the solution in code: String s = ""; //Main game loop while(gc.getKeyCode() != 'Q') { //NOTE: type Q to quit moveBall(b1); moveBall(b2); checkCollision(); // ... NOTE THIS NEW SECTION. It gets a letter. You can do whatever you want with the letter. We're printing it out. char c = getLetter(); if (c != gc.VK_UNDEFINED) { s += c; System.out.println(s); } drawGraphics(); gc.sleep(5); } /* Get a letter from the user, but only one letter, even if it is held down. * If this method returns VK_UNDEFINED, then do not use the letter. It means that no letter has been pressed */ boolean acceptInput = false; char getLetter() { char letter = gc.getKeyChar(); //keyChar distinguishes between 'A' and 'a' //keyCode gets all keys (non-printing ones too), but every letter is uppercase if (letter == gc.VK_UNDEFINED) { //a key has been released acceptInput = true; //we can now get a key return letter; //this is the undefined constant that is used to say that no key is being typed } if (!acceptInput) return (char) gc.VK_UNDEFINED; if (letter >= 'a' && letter <= 'z') { acceptInput = false; return letter; } return (char) gc.VK_UNDEFINED; }