It looks like REALbasic has a Key Up event.
All of this keyboard support really sucks though. Key Down is already pretty lousy and shouldn't be used for games at all. It should only be used for creating fake text fields like in the Palace Chat demo. Consider the fact that someone could simply adjust their key repeat rate to be very high and they would have an advantage in any game that uses Key Down to fire a weapon.
Another problem with Key Down is: what if they have a Dvorak keyboard?
OK, you say, who the hell uses Dvorak anyway? Consider instead a regular style French keyboard, pictured below:
What if you set up your game to use WASD for the movement? The French user would be completely screwed.
The solution to this problem, as implemented in REALbasic, is Key Codes - but I've resisted putting in key codes because the idea can be confusing to new programmers.
The idea of key codes is that instead of checking if the user is pressing "A", you instead check to see if the user is pressing the button where "A" typically is on a standard US English keyboard.
Map of keycodes:
http://boredzo.org/blog/wp-content/uploads/2007/05/imtx-virtual-keycodes.pngThe key codes are the same on Mac or Windows, I believe.
That way, instead of hard coding in your game "WASD", you would do something like this:
PRINT "To move left, press " + KEYNAME$(0)
PRINT "To move right, press " + KEYNAME$(2)
PRINT "To move up, press " + KEYNAME$(13)
PRINT "To move down, press " + KEYNAME$(1)
Then you would do something like this to check for movement in your TIMER:
IF KEYCODE(0) = TRUE THEN
// they are pressing left
END IF
IF KEYCODE(2) = TRUE THEN
// they are pressing right
END IF
IF KEYCODE(13) = TRUE THEN
// they are pressing up
END IF
IF KEYCODE(1) = TRUE THEN
// they are pressing down
END IF
Now this allows you to hold down multiple keys at the same time! What if they press left AND right at the same time? More code (this also applies to the regular arrow checking variables as well):
LET LEFT = FALSE
LET RIGHT = FALSE
LET UP = FALSE
LET DOWN = FALSE
LET KEYS = 0
IF KEYCODE(0) = TRUE THEN
LET LEFT = TRUE
LET KEYS += 1
END IF
IF KEYCODE(2) = TRUE THEN
LET RIGHT = TRUE
LET KEYS += 1
END IF
IF KEYCODE(13) = TRUE THEN
LET UP = TRUE
LET KEYS += 1
END IF
IF KEYCODE(1) = TRUE THEN
LET DOWN = TRUE
LET KEYS += 1
END IF
IF KEYS > 1 THEN
NOTEALERT "What the hell"
ELSE
// blah
END IF
It all gets very messy. I don't know of an elegant way to handle it.