Skip to content

Instantly share code, notes, and snippets.

@osteele
Last active November 24, 2021 05:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save osteele/54566a328c78cf12c000cbcea2e12a75 to your computer and use it in GitHub Desktop.
Save osteele/54566a328c78cf12c000cbcea2e12a75 to your computer and use it in GitHub Desktop.
Demonstrate how to keep track of held keys (array version)
/*
* This sketch demonstrates how to keep track of which keyboard keys are held
* down (pressed, and not released). Multiple keys can be held at the same time
* (if a second key is pressed before the first key is released).
*
* This is an alternative implementation of https://gist.githubusercontent.com/osteele/986252244a0e7973ca3ffe92f85fef18
* See the comments in that gist for more details.
*
* This sketch uses a `char[]` array instead of an instance of `IntList`.
* This is less efficient, because it requires a new array to be created
* every time a key is pressed or released.
*
* Author: Oliver Steele
* Date: 2021-11-23
*/
/** An array of all the keyboard keys that are currently held (have been pressed
* but not released).
*/
char[] heldKeys = new char[0];
void setup() {
size(100, 100);
}
// This sketch doesn't draw anything. However, if this function is not defined,
// Processing never calls keyPressed() or keyReleased().
void draw() {
}
void keyPressed() {
// Because keyPressed() is called repeatedly while a key is held down, in
// addition to when it is first pressed, heldKeys may already contain the key.
// In this case, don't add it a second time, and don't print to the console
// again.
if (!charArrayContains(heldKeys, key)) {
heldKeys = append(heldKeys, key);
heldKeys = sort(heldKeys); // this is optional, but it makes the output easier to read
printHeldKeys();
}
}
void keyReleased() {
// It should always be the case that heldKeys contains key, but the
// conditional guard makes the code more robust in case this turns out not be
// true. (For example, what happens if the user is holding down some keys when
// the sketch starts running?)
if (charArrayContains(heldKeys, key)) {
heldKeys = charArrayRemove(heldKeys, key);
printHeldKeys();
}
}
/** Print the currently pressed keys to the console. */
void printHeldKeys() {
print("Currently pressed keys: ");
var sep = "";
for (var c: heldKeys) {
print(sep);
print(char(c));
sep = " ";
}
if (heldKeys.length == 0) {
print("none");
}
println();
}
boolean charArrayContains(char[] array, char value) {
// Since the array is sorted, we could use java.Collections.binarySearch()
// instead
for (var x: array) {
if (x == value) {
return true;
}
}
return false;
}
int charArrayFindIndex(char[] array, char value) {
for (var i = 0; i < array.length; i++) {
if (array[i] == value) {
return i;
}
}
return -1;
}
char[] charArrayRemove(char[] array, char value) {
while (true) {
var index = charArrayFindIndex(array, value);
if (index < 0) {
break;
}
array = concat(subset(array, 0, index), subset(array, index + 1));
// Here's a more efficient alternative to the previous two lines. However,
// it leaves the elements in a different order. If you follow the call to
// charArrayRemove() by a call to sort(), it ends up being less efficient.
//
// Swap the element to be removed into the final position, and then shorten
// the array. (Since the final element will be removed, we don't actually
// need to move the value into it, just rescue the value from it.)
// array[index] = array[array.length - 1];
// array = shorten(array);
}
return array;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment