Skip to content

Instantly share code, notes, and snippets.

@bigjosh
Created December 1, 2017 19:30
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 bigjosh/89d5986f09c0ffc092dc4e803e820b18 to your computer and use it in GitHub Desktop.
Save bigjosh/89d5986f09c0ffc092dc4e803e820b18 to your computer and use it in GitHub Desktop.
/*
* Speed up the rotation of LEDs lights or slow down based on button press
*/
#include "blinklib.h"
#include "blinkstate.h"
#include "Serial.h"
ServicePortSerial Serial;
#define ALONE_TIMEOUT_MS 200 // If I haven;t seen anyone on any face for this long, then I am alone state
#define NORMAL_TIMEOUT_MS 200 // Time from when I see my first neighboor in ALONE until I switch to normal.
#define MS_PER_S (1000)
uint16_t speed_d_per_s = 360; // speed is represented in degrees/sec, 360 would be a single rotation per second
float speed_d_per_ms = ( (float) speed_d_per_s) / MS_PER_S ;
uint32_t timeOfLastLoop_ms = 0;
typedef enum team_t { TEAM_A , TEAM_B };
byte teamHues[] = { 0 , 128 };
typedef enum state_t { STATE_DEAD , STATE_NORMAL , STATE_ALONE };
// Health starts game at 60. Max tiles are
uint32_t health; // Units ms
#define HEALTH_START 30000 // Starting value of health
//#define HEALTH_START 60000 // Starting value of health
#define HEALTH_MAX 120000 // We need a cap here to prevent overflow uint16
//#define HEALTH_MAX_DISPLAY 60000 // any health above this will just look full
team_t team;
state_t state;
void setup() {
// put your setup code here, to run once:
// No setup needed for this simple example!
Serial.begin();
Serial.println("Mortals Debug");
team = TEAM_A;
state = STATE_DEAD;
timeOfLastLoop_ms = millis();
}
// Sin in degrees ( standard sin() takes radians )
float sin_d( uint16_t degrees ) {
return sin( ( degrees / 360.0F ) * 2.0F * PI );
}
float rotation_d = 0; // Spin in time
void loop() {
// put your main code here, to run repeatedly:
if (buttonLongPressed()) {
if (team==TEAM_A) {
team=TEAM_B;
} else {
team=TEAM_A;
}
}
if (buttonMultiClicked()) {
state = STATE_NORMAL;
health = HEALTH_START;
}
uint32_t now = millis();
uint32_t timeDiff_ms = now - timeOfLastLoop_ms;
if (state != STATE_DEAD ) {
if ( timeDiff_ms > health ) {
// Oh no! We died!
state = STATE_DEAD;
setColor( WHITE ); // Death flash
delay(100);
} else {
health -= timeDiff_ms;
}
}
//setColor( OFF ); // JL: Don't want this! You will get aliasing effects if colors just happen to get sampled when off. There is a vertcal retrace if you want to sync.
// Especially pronounced becuase the floating point calcs below are so s...l...o....w on 8 bit AVR.
// calculate the amount of rotation
//speed_d_per_ms = ( ((1.0f - (min( health , HEALTH_MAX_DISPLAY ) / HEALTH_MAX_DISPLAY ))) * 4.0 * 360.0) / MS_PER_S;
//speed_d_per_ms = ((1.0f - ( (HEALTH_MAX_DISPLAY/1.5) / HEALTH_MAX_DISPLAY )) * 4.0 * 360.0) / MS_PER_S;
rotation_d += timeDiff_ms * speed_d_per_ms ;
if(rotation_d >= 360.f) {
rotation_d -= 360.f;
}
//byte angularWidth_d = max( health , HEALTH_MAX_DISPLAY ) * 360 / HEALTH_MAX_DISPLAY;
//byte brightness = min( health , HEALTH_MAX_DISPLAY ) * 255 / HEALTH_MAX_DISPLAY;
FOREACH_FACE(f) {
// determine brightness based on the unit circle (sinusoidal fade)
if (state == STATE_DEAD ) {
setFaceColor( f , OFF );
} else {
// Not dead
uint16_t angle_of_face_d = 60 * f; // (360 degrees) / (6 faces) = degrees per face
uint16_t angle_of_health_d = (min( health , 30000 ) / 30000.0) * 360;
byte brightness;
if ( angle_of_face_d < angle_of_health_d ) {
brightness = 255;
} else {
brightness = 0;
}
//int brightness = 255 * (1 + sin_d( angle_of_face_d + rotation_d ) ) / 2;
setFaceColor( f , makeColorHSB( teamHues[team] , 255 , brightness ) );
// if(f==4) {
// Serial.print("rotation: ");
// Serial.println(rotation);
// Serial.print("brightness: ");
// Serial.println(brightness);
// }
}
}
setState( state );
timeOfLastLoop_ms = now;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment