01 March 2026

Mapping: "Brain Shaker" - Analog Team 11



The concept of our game is to test players' memory and reaction times. The game starts off by first setting up, playing a start sequence of lights that is triggered when the player first turns it on. In order to begin the actual rounds, the player shakes the board. Using a random generator, a random neopixel will be chosen, staying lit up for a few seconds to give the player time to memorize the spot. By using the potentiometer, the player rotates and until they light up the pixel they were shown, using the button to choose it as their response. 

The win condition is simple: if the player locks in the correct pixel shown to them, the game responds with a green flash and plays a "win" sound, continuing the round and progressively increasing in difficulty by decreasing the amount of time the neopixel is shown for. The lose condition, on the other hand, shows a red flash and plays a "lose" sound, resetting the player's progress this far and restarting the countdown for each neopixel, decreasing the difficulty until players can progress through the rounds once more. 


Circuit Schematic:




Video Demonstration:



Code:

#include <Adafruit_CircuitPlayground.h> #include <Adafruit_Circuit_Playground.h> //Global variables int pot; float smoothed_pot = 0; //Used for a trick that helps make the player selection pixel not as jittery int pot_map; int gen_pixel_value; int current_pixel; int previous_map = -1; // Starts negative to make sure that on the first time, it will always change int show_time = 2000; // Variable for the length of time the random pixel is shown at the start of each round void setup() { // put your setup code here, to run once: Serial.begin(9600); CircuitPlayground.begin(); pinMode(A3, INPUT); delay(1000); start_sequence(); } void loop() { //Player shakes to start round. The absolute value must be strong enough on the x, y, and z axes to start each round float shake_strength = abs(CircuitPlayground.motionX()) + abs(CircuitPlayground.motionY()) + abs(CircuitPlayground.motionZ()); if (shake_strength > 22) { randomSeed(millis()); //Randomize the seed based on the time before the player shakes the board. Seems to work better for randomness in testing play_round(); } } void play_round() { //Picks a number 0-9 and assigns to gen_pixel_value gen_pixel_value = random(0, 10); CircuitPlayground.setPixelColor(gen_pixel_value, 0, 255, 255); //Plays a incrementing 5 tone sound effect while the random pixel is being displayed. Shortens with each round int beep_length = show_time / 5; for (int i = 0; i < 5; i++) { CircuitPlayground.playTone(300 + (i * 100), beep_length); } //Clears the pixel and starts the player control CircuitPlayground.clearPixels(); bool has_chosen_pixel = false; //Variable to determine if the player has clicked the button to make their choice yet or not //While the player has not yet selected a pixel, run this loop while (has_chosen_pixel == false) { pot = analogRead(A2); //Math trick to make the pixel that lights up when selecting more clearly defined smoothed_pot = (0.1 * pot) + (0.9 * smoothed_pot); pot_map = map((int)smoothed_pot, 0, 1000, 0, 9); pot_map = constrain(pot_map, 0, 9); //Makes it so the pixel turns off and the next turns on only when they move the pot to a new pixel number if (pot_map != previous_map) { CircuitPlayground.clearPixels(); CircuitPlayground.setPixelColor(pot_map, 255, 255, 255); previous_map = pot_map; } //If the user has clicked the button to choose their pixel, break out of the while loop if (digitalRead(A3) == true) { has_chosen_pixel = true; delay(200); } } //After the while loop ends (due to player clicking the button) check if their selection is correct if (pot_map == gen_pixel_value) { win_round(); } else { lose_round(); } } void win_round() { //Play a little win sound and flash green CircuitPlayground.clearPixels(); CircuitPlayground.playTone(800, 100); CircuitPlayground.playTone(1000, 100); for (int i = 0; i < 2; i++) { CircuitPlayground.strip.fill(CircuitPlayground.strip.Color(0, 255, 0), 0, 10); CircuitPlayground.strip.show(); delay(400); CircuitPlayground.clearPixels(); delay(100); } //Makes the display time for next round faster (but caps it so it doesnt become impossible or break the game) show_time = show_time -300; if (show_time < 200) { show_time = 200; } //Wait a moment then returns to the main loop delay(500); } void lose_round() { //Play a little lose sound and flash red CircuitPlayground.clearPixels(); CircuitPlayground.playTone(400, 100); CircuitPlayground.playTone(200, 100); for (int i = 0; i < 2; i++) { CircuitPlayground.strip.fill(CircuitPlayground.strip.Color(255, 0, 0), 0, 10); CircuitPlayground.strip.show(); delay(400); CircuitPlayground.clearPixels(); delay(100); } //Makes the display time for next round back to the default value show_time = 2000; //Wait a moment then returns to the main loop delay(500); } void start_sequence() { for (int i = 0; i < 10; i++) { CircuitPlayground.setPixelColor(i, 255, 30*i, 99-i); CircuitPlayground.playTone(100 + (i * 100), 100); CircuitPlayground.clearPixels(); } }






No comments:

Post a Comment

Note: Only a member of this blog may post a comment.