Last active
November 24, 2021 05:08
-
-
Save osteele/54566a328c78cf12c000cbcea2e12a75 to your computer and use it in GitHub Desktop.
Demonstrate how to keep track of held keys (array version)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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