2020-04-03 14:28:36 +03:00

265 lines
6.8 KiB
C++

//======================================================
// MAIN COUNTER GAME LOOP
//======================================================
/* This Game Can Be Called From
* Stand Alone Mode / Bluetooth Connection
* The primary mode is the standalone but
* if the bluetooth is connected it has the priority
* so it will take over the control of the device
*
* If you want to control the game via bluetooth
* you need to call : game_counter_bluetooth(JSON String)
* If you want to use the stand alone mode
* you need to call : game_counter_standalone()
*
* the game returns a float point number which is
* in seconds. so the athlete know how long he takes to react
*/
//======================================================
// THIS IS THE STAND ALONE CALL FOR THE GAME
//======================================================
void game_counter_standalone()
{
// Variables Of The Game
uint16_t limit = 10;
bool limitEnable = true;
// Play The Game
game_counter(limit, limitEnable);
// Give Permision To Change Display
DISPLAY_CHANGED = false;
}
//======================================================
// THIS IS THE BLUETOOTH CALL FOR THE GAME
//======================================================
/* COUNTER GAME SETTINGS PARAMETERS NOTE:
* --------------------------------------
*
* FORMAT :
* --------
* {"le": false, "lm": 10}
*
* MEANNING :
* ----------
* ct : count
* le : stands for limit enable, if is TRUE the game end if target value is meet
* lm : targeted amount of kicks
*
* THINGS THAT ENDS THE GAME :
* ---------------------------
* 1. BY A COMMAND "FROM APP VIA BLUETOOTH"
* 2. BY LIMITS MEET "WHEN NUMBER OF YOUR KICKS REACH TO lm VALUE"
*
* WHAT JSON TO BE COLLECTED :
* ---------------------------
* 1. FOR EVERY KICK YOU RECEIVE THE COUNTER DISJSON AND TIMESTAMP
* WE NEED TO COLLECT TIMESTAMPS AS AN ARRAY IN JSON FORMAT
*
* CALCULATING RESULTS :
* ---------------------
* No calculation required, Its directly the count
*/
void game_counter_bluetooth(String settings)
{
//------------------------------------------------------
// START OF READING THE SETTINGS
//------------------------------------------------------
// Deserialize the JSON document
DeserializationError error = deserializeJson(JSON, settings); // the main JSON body container
// JSON ERROR
if(error) {
dualcomm(JSON_ERROR);
return;
}
// PUBLIC VARIABLES
uint16_t limit = JSON["lm"]; // Kick Target Limit
bool limitEnable = JSON["le"]; // Enable Kick Target Limit
// Clearing Buffer
JSON.clear();
// Play The Game
game_counter(limit, limitEnable);
// Give Permision To Change Display
DISPLAY_CHANGED = false;
}
//======================================================
// COUNTER JSON JSON -> To Send Back To Server
//======================================================
void game_counter(uint16_t limit, bool limitEnable)
{
// Kick Counter
uint16_t counter = 0;
// Game Start Lights
//LED_SIGNAL_START();
// Display On OLED
GAME_COUNTER_DISPLAY(0, limit);
//-------------------------
// PREPARE FOR GAME START
//-------------------------
// staring Of time stamp
unsigned long startStamp = millis();
while(1)
{
// Time Stamp
unsigned long timeStamp = millis() - startStamp;
// If Stop Command Came From Smart Phone
if(isBluetooth)
{
String msg = Bluetooth.readStringUntil('\n');
flushBluetooth;
msg.trim();
if(msg == CM_STOP)
{
dualcomm(GAME_OVER);
// Grean Light In
//LED_SIGNAL_END();
// RESET
return;
}
else if(msg == CM_RESET)
{
// Counter Reset To Zero
counter = 0;
// Starting Stamp From Now
startStamp = millis();
// Time Stamp Is Now
timeStamp = startStamp;
// LED STRIP LED STRIP RESET SIGNAL
//LED_SIGNAL_RESET();
}
}
// Reset The Counter
if(BTN_INCREASE.pressed()) {
counter = 0;
startStamp = millis();
timeStamp = startStamp;
GAME_COUNTER_DISPLAY(counter, limit);
}
// Will Exit The Game
if(BTN_CENTER.pressed()) {
// Send Game Over JSON Signal
dualcomm(GAME_OVER);
// Give Permition To Change OLED
DISPLAY_CHANGED = false;
// Return To Main Menu
return;
}
// If Limits Are Enabled And Meet
if(limitEnable == true && counter == limit) {
// END GAME
dualcomm(GAME_OVER);
// Celebration
//LED_SIGNAL_CELEBRATION();
// Display On OLED
GAME_RESULT_DISPLAY(counter, limit);
// RESET
return;
}
// Read Impact
if(PIEZO_MAP >= VTH)
{
counter++;
GAME_COUNTER_DISPLAY(counter, limit);
dualcomm(counter_JSON_json(counter, timeStamp));
delay(100);
}
}
}
//======================================================
// COUNTER JSON -> To Send Back To Mobile
//======================================================
String counter_JSON_json(unsigned int ct, unsigned int st)
{
// Convert Int To Float
float stamp = st;
stamp /= 1000;
// Assignning JSONset
JSON["ct"] = ct;
JSON["st"] = String(stamp, 3).toFloat();
String output;
serializeJson(JSON, output);
JSON.clear();
return output;
}
//------------------------------------------------------
// OLED - GAME COUNTER PLAY
//------------------------------------------------------
void GAME_COUNTER_DISPLAY(uint16_t count, uint16_t limit)
{
OLED_CLEAR();
drawTextCenter(128/2, 0, 2, "KICKS");
drawTextCenter(128/2, 20, 3, String(count) + "/" + String(limit));
// Exit Button Command Only Via Stand Alone Mode
if(BLUETOOTH_STATUS == false) {
drawTextCenter(128/2, 50, 1, "<< EXIT >>");
}
OLED_SHOW();
}
//------------------------------------------------------
// OLED - GAME COUNTER RESULT
//------------------------------------------------------
void GAME_RESULT_DISPLAY(uint16_t count, uint16_t limit)
{
OLED_CLEAR();
drawTextCenter(128/2, 0, 2, "FINISHED");
drawTextCenter(128/2, 20, 3, String(count) + "/" + String(limit));
// Exit Button Command Only Via Stand Alone Mode
if(BLUETOOTH_STATUS == false) {
drawTextCenter(128/2, 50, 1, "<< EXIT >>");
}
// Show Data On OLED
OLED_SHOW();
// Waiting For Center Button To Move On
while(1){
if(BTN_CENTER.pressed()) {
break;
}
}
}