#include <Adafruit_CircuitPlayground.h>
#include <math.h>
// Rotation tracking
float lastAngle = 0;
float threshold = 22.0; // Degrees of rotation needed to move one space
// Game variables
int playerPos = 0; // Player starts at the first LED
int goalPos = 9; // Goal starts at the last LED
// Pot + Button pins
const int POT_PIN = A2;
const int BUTTON_PIN = A3;
// Goal color storage
byte goalR = 0, goalG = 255, goalB = 0; // Starts green
// Convert 0-255 value into an RGB "rainbow wheel" color
void wheelColor(byte wheelPos, byte &r, byte &g, byte &b) {
wheelPos = 255 - wheelPos;
if (wheelPos < 85) {
r = 255 - wheelPos * 3;
g = 0;
b = wheelPos * 3;
} else if (wheelPos < 170) {
wheelPos -= 85;
r = 0;
g = wheelPos * 3;
b = 255 - wheelPos * 3;
} else {
wheelPos -= 170;
r = wheelPos * 3;
g = 255 - wheelPos * 3;
b = 0;
}
}
void randomizeGoal() {
// Randomize goal position (avoid landing on player to prevent instant win)
int newGoal = random(0, 10);
while (newGoal == playerPos) {
newGoal = random(0, 10);
}
goalPos = newGoal;
// Randomize goal color (random hue)
byte wheelPos = (byte)random(0, 256);
wheelColor(wheelPos, goalR, goalG, goalB);
}
void setup() {
Serial.begin(9600);
CircuitPlayground.begin();
CircuitPlayground.setBrightness(5);
// Button input (external pulldown resistor used)
pinMode(BUTTON_PIN, INPUT);
// Seed Randomness (So goal isn't the same every reset)
randomSeed(CircuitPlayground.lightSensor() + millis());
// Starting Angle
float x = CircuitPlayground.motionX();
float y = CircuitPlayground.motionY();
lastAngle = atan2(y, x) * 180 / PI;
}
void loop() {
// Button Randomizer (Goal Only)
static bool prevButton = false;
bool buttonNow = (digitalRead(BUTTON_PIN) == HIGH);
// Rising edge detect
if (buttonNow && !prevButton) {
randomizeGoal();
}
prevButton = buttonNow;
// POT Color Value
int potValue = analogRead(POT_PIN); // 0..1023
byte wheelPos = map(potValue, 0, 1023, 0, 255); // 0..255
byte pr, pg, pb;
wheelColor(wheelPos, pr, pg, pb);
// Rotational formula
float x = CircuitPlayground.motionX();
float y = CircuitPlayground.motionY();
float currentAngle = atan2(y, x) * 180 / PI;
float delta = currentAngle - lastAngle;
if (delta > 180) delta -= 360;
if (delta < -180) delta += 360;
if (abs(delta) > threshold) {
if (delta > 0) playerPos++;
else playerPos--;
if (playerPos < 0) playerPos = 0;
if (playerPos > 9) playerPos = 9;
lastAngle = currentAngle;
}
// Clear Neo Pixels
CircuitPlayground.clearPixels();
// Goal LED (random color)
CircuitPlayground.setPixelColor(goalPos, goalR, goalG, goalB);
// Player LED (pot-controlled color), don't overwrite goal LED
if (playerPos != goalPos) {
CircuitPlayground.setPixelColor(playerPos, pr, pg, pb);
}
// Win State
if (playerPos == goalPos) {
for (int i = 0; i < 3; i++) {
CircuitPlayground.clearPixels();
delay(200);
for (int p = 0; p < 10; p++) {
CircuitPlayground.setPixelColor(p, goalR, goalG, goalB); // flash goal color
}
delay(200);
}
playerPos = 0;
// Re-calibrate angle
x = CircuitPlayground.motionX();
y = CircuitPlayground.motionY();
lastAngle = atan2(y, x) * 180 / PI;
}
delay(50);
}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.