When you use a KeyListener in Java, you have to decide whether you are using key codes or key characters. And then you have to be consistent with this throughout your program.
This is the same for HSA2 and Swing. In this document, we'll look at how to do it in HSA2
Choose one of these two | |
Key Characters | Key Codes |
---|---|
reads every character that can be typed on a keyboard | reads every key that can be pressed on a keyboard |
Distinguishes between 'A' and 'a' | Cannot distinguish between 'A' and 'a' (It's exactly the same key being pressed) |
Cannot detect any special keys | Can detect function keys, cursor keys, shift keys, numberpad keys, etc |
Easy to use:if (gc.getKeyChar() == 'p') {...}unless you need to check both cases: if (gc.getKeyChar() == 'p' || gc.getKeyChar() =='P') { //pause game |
A little bit harder to use. You have to know the number for the up arrow key if (gc.getKeyCode() == 38) { //up arrow pressedor use a built in constant if (gc.getKeyCode() == KeyEvent.VK_UP) { //up arrow pressedbut the normal keys have the value of the uppercase letter: if (gc.getKeyCode() == 'Q') { // Q key pressed |
Pressing the key results in multiple keypresses being triggered
See the sample program below
Motion is not smooth as there is a delay caused by the OS
-- this does not seem to happen in HSA2 like it does in normal Swing graphics. I wonder why?
Copy and paste the code into Eclipse. I'm not going to colour code it here
import java.awt.Color; import java.awt.Rectangle; import hsa2.GraphicsConsole; public class Keyboard1 { public static void main(String[] args) { new Keyboard1(); } GraphicsConsole gc = new GraphicsConsole(700,500); Rectangle paddle = new Rectangle(300,450,80,10); Rectangle r1 = new Rectangle(100,100,50,160); final static int PADDLEMOVE = 5; //number of pixels that the paddle will move with each key press boolean trigger = false; Keyboard1() { gc.setBackgroundColor(Color.BLACK); gc.clear(); gc.setLocationRelativeTo(null); //gc.setTitle("Click on the Green Rectangle"); while(true) { /********** display keycodes in the TITLE *********/ // it's a quick and clever way to find them gc.setTitle("The keycode for the current key is " + gc.getKeyCode()); /***************************************************** * Move the paddle using keys * *************************************************** * PROBLEMS: * 1. Notice that the paddle should only move 5 pixels but it moves a LOT more * 2. Operating system delay * 3. No way to move diagonally by holding two keys down at the same time * ***************************************************/ if (gc.getKeyChar() == 'a') { if (paddle.x > 0) paddle.x -= PADDLEMOVE; } if (gc.getKeyChar() == 'd') { if (paddle.x < 690) paddle.x += PADDLEMOVE; //FIXME: ERROR: DO NOT USE MAGIC NUMBERS } if (gc.getKeyChar() == 'w') { if (paddle.y > 0) paddle.y -= PADDLEMOVE; } if (gc.getKeyChar() == 's') { if (paddle.y < 490) paddle.y += PADDLEMOVE; } /**************************************************** * 1. Problem 1. FAIL. * NO. THIS DOES NOT SOLVE THE PROBLEM OF MULTIPLE INPUTS WITH ONE PRESS OF A KEY!!! * * 2. Problem 2. SUCCESS (but not noticable on my computer) * * 3. Problem 3: SUCCESS *******************************************************/ if (gc.isKeyDown(37)) { //isKeyDown uses keyCodes. Left arrow if (paddle.x > 0) paddle.x -= PADDLEMOVE; } if (gc.isKeyDown(39)) { //right if (paddle.x < 690) paddle.x += PADDLEMOVE; } if (gc.isKeyDown(38)) { //up if (paddle.y > 0) paddle.y -= PADDLEMOVE; } if (gc.isKeyDown(40)) { //down if (paddle.y < 490) paddle.y += PADDLEMOVE; } /****************************************************************** * How to allow something to be done only once upon a keypress: * 'H' will make the block half the height ******************************************************************/ if (gc.isKeyDown('H')) { if (!trigger) { //if the trigger is ready trigger = true; //the trigger has already been pulled. It needs to be reset r1.height = r1.height /2; } } if (! gc.isKeyDown('H')) { //when you let go of the H key trigger = false; //reset the trigger. } /********** Do all drawing together ***********/ synchronized(gc) { gc.clear(); gc.setColor(Color.GRAY.darker().darker().darker().darker()); for (int i=0; i< 700; i += 10) { gc.drawLine(i, 0, i, 500); } gc.setColor(Color.GREEN); gc.fillRect(r1.x, r1.y, r1.width, r1.height); gc.setColor(Color.YELLOW); gc.fillRect(paddle.x, paddle.y, paddle.width, paddle.height); gc.drawString("The gray lines are 10 pixels apart", 20,20); gc.drawString("Each keypress should move the paddle " + PADDLEMOVE + " pixels.", 20,40); } gc.sleep(5); } //end of while loop } }