Our game is an interactive hide-and-seek experience built using the Circuit Playground Express, NeoPixels, a potentiometer, a direction switch, a freeze button, and an external photoresistor. The NeoPixel ring represents a circular playing field with ten positions. At the start of each round, the system randomly selects a hidden target position that the player must find.
The player continuously moves around the circle using a direction switch, which determines clockwise or counterclockwise movement. A potentiometer controls movement speed, allowing for adjustable difficulty. When the player believes they are close to the hidden target, they press the freeze button to stop moving. To check their position, they cover the photoresistor, triggering a “hot or cold” color response. The NeoPixel changes color based on how close the player is to the target, ranging from blue (far away) to red (very close).
The goal is to land exactly on the hidden target. If
successful, the player wins, and the NeoPixel turns green before a new round
begins.
#include <Adafruit_CircuitPlayground.h>const int NUM_PIXELS = 10;const int FREEZE_BUTTON_PIN = A3;const int PHOTO_PIN = A2;const int PHOTO_THRESHOLD = 40;//game stateint playerPosition = 0;int targetPosition = 0;bool frozen = false;//timingunsigned long lastMoveTime = 0;int moveDelay = 300;//button states (edge detection)bool lastD4 = HIGH;// Light detectionbool photoTriggered = false;void drawBackground() {for (int i = 0; i < NUM_PIXELS; i++) {CircuitPlayground.setPixelColor(i, 25, 25, 25); //dim white, was very bright for me}}void drawPlayer(uint8_t r, uint8_t g, uint8_t b) {CircuitPlayground.setPixelColor(playerPosition, r, g, b);}void resetGame() {drawBackground();playerPosition = 0;targetPosition = random(NUM_PIXELS);frozen = false;}int circularDistance(int a, int b) {int d = abs(a - b);return min(d, NUM_PIXELS - d);}void setup() {Serial.begin(9600);CircuitPlayground.begin();CircuitPlayground.setBrightness(20);pinMode(FREEZE_BUTTON_PIN, INPUT_PULLUP);pinMode(A4, INPUT_PULLUP);randomSeed(analogRead(A0));resetGame();}void loop() {Serial.println(digitalRead(FREEZE_BUTTON_PIN));delay(100);unsigned long now = millis();int potValue = analogRead(A1);//map pot to speed (slow → fast)moveDelay = map(potValue, 0, 1023, 800, 80);int cw = (targetPosition - playerPosition + 10) % 10;int ccw = (playerPosition - targetPosition + 10) % 10;int distance = min(cw, ccw);// --------- BUTTON (freeze) ----------bool freezeButton = digitalRead(FREEZE_BUTTON_PIN);if (freezeButton == LOW && lastD4 == HIGH) {frozen = !frozen;photoTriggered = false;}lastD4 = freezeButton;//press button again to unfreeze player, cover photoresistor while frozen to check your position relative to the target// --------- PLAYER MOVEMENT ----------if (!frozen && now - lastMoveTime > moveDelay) {lastMoveTime = now;drawBackground();bool directionCW = (digitalRead(A4) == HIGH);if (directionCW) {//clockwiseplayerPosition = (playerPosition + 1) % NUM_PIXELS;} else {//counterclockwiseplayerPosition = (playerPosition - 1 + NUM_PIXELS) % NUM_PIXELS;}}bool directionCW = (digitalRead(A4) == HIGH);// --------- PHOTORESISTOR (check position) ----------int lightValue = analogRead(PHOTO_PIN);//debug to check photoresistor value neededSerial.print("Light: ");Serial.println(lightValue);//trigger once when light drops below thresholdif (frozen && lightValue < PHOTO_THRESHOLD && !photoTriggered) {photoTriggered = true;drawBackground();if (distance == 0) {//exact hit = win, show greenCircuitPlayground.setPixelColor(playerPosition, 0, 255, 0);delay(3000);//new roundtargetPosition = random(NUM_PIXELS);frozen = false;drawBackground();return;} else {int r = 0;int g = 0;int b = 0;switch (distance) {case 1:r = 255; g = 0; b = 0; // very hotbreak;case 2:r = 200; g = 40; b = 0; // warmbreak;case 3:r = 80; g = 0; b = 120; // coolbreak;case 4:r = 0; g = 120; b = 200; // colderbreak;case 5:default:r = 0; g = 0; b = 255; // coldestbreak;}CircuitPlayground.setPixelColor(playerPosition, r, g, b);}delay(3000);drawBackground();}//reset trigger when light comes backif (lightValue > PHOTO_THRESHOLD + 50) {photoTriggered = false;}// --------- DRAW PLAYER ----------drawPlayer(255, 0, 255); //purple}

No comments:
Post a Comment
Note: Only a member of this blog may post a comment.