//====================================================== // TIME ATTACK GAME MAIN ROUTINE //====================================================== /* TIME ATTACK GAME SETTINGS PARAMETERS NOTE: * ------------------------------------------ * * FORMAT : * -------- * {"tm": 10, "le": false, "lm": 10} * * tm : count down timer starting value * 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 COUNT DOWN "tm" REACH TO ZERO * 2. BY A COMMAND "FROM APP VIA BLUETOOTH" * 3. BY LIMITS MEET "WHEN NUMBER OF YOUR KICKS REACH TO lm VALUE" * * CALCULATING RESULTS : * --------------------- * Rapid Kick Speed = Number Of Kickes Made / Elasped Time In Sec * Delay Between Kicks = Time Of Current Kick - Time Of Last Kick * * RETURNNING DATA FORMAT : * ------------------------ * {"tm" : 82, "ct" : 10, "dl" : 1234, "st" : 585} * * tm : timer count in Sec * ct : strike counter (number of kicks) * dl : delay between strikes * st : time stampe of the strike in milli Seconds */ void game_timeAttack(String settings) { //------------------------------------------------------ // START OF READING THE SETTINGS //------------------------------------------------------ // CONVERTING GAME TEXT TO JSON DynamicJsonDocument play(capacity); // building JSON Buffer // Deserialize the JSON document DeserializationError error = deserializeJson(play, settings); // the main JSON body container // JSON ERROR if(error) { dualcomm(JSON_ERROR); return; } // PUBLIC VARIABLES uint16_t time = play["tm"]; // Time Window To Play uint16_t timer = time; uint16_t limit = play["lm"]; // Kick Target Limit bool limitEnable = play["le"]; // Enable Kick Target Limit // Clearing Buffer play.clear(); //------------------------------------------------------ // PREPARE FOR GAME START //------------------------------------------------------ // Send Initial Display dualcomm(timeAttack_data_json(timer, 0, 0, 0)); // Start LED Signal TimeAttack_Start(); // Building Timers 1000mSec -> 1Sec TimeTrigger sec_tick(1000); // Kick Counter uint16_t counter = 0; // staring Of time stamp unsigned long startStamp = millis(); // store the time of the previous kick unsigned long lastStamp = 0; // reseting time ticker sec_tick.Reset(); // While The Game Is Still On while(timer != 0) { // Time Stamp unsigned long timeStamp = millis() - startStamp; // If Stop Command Came From Smart Phone if(isBluetooth) { String msg = Bluetooth.readString(); msg.trim(); if(msg == CM_STOP) { dualcomm(GAME_OVER); // Grean Light In LED_GREEN_FADEOUT(); // Return return; } else if(msg == CM_RESET) { timer = time; counter = 0; startStamp = millis(); timeStamp = startStamp; lastStamp = timeStamp; sec_tick.Reset(); dualcomm(timeAttack_data_json(timer, counter, lastStamp, timeStamp)); } } // Every Kick ---------------------------->>> if(readImpact() > 100) { counter++; dualcomm(timeAttack_data_json(timer, counter, lastStamp, timeStamp)); lastStamp = timeStamp; delay(100); } // Every Second ---------------------------->>> if(sec_tick.Trigger()) { timer--; dualcomm(timeAttack_data_json(timer, counter, 0, 0)); } // If Limits Are Enabled And Meet if(limitEnable == true && counter == limit) { // END GAME dualcomm(GAME_OVER); // LightUp rainbowCycle(2); // Grean Light In LED_GREEN_FADEOUT(); // Return return; } } // Send End Game Signal To Smart Phone dualcomm(GAME_OVER); // LightUp LED_RED_FADEIN(); // RED Color delay(2000); // Delay 2000 LED_CLEAR(); // CLEAR OFF // Return return; } //====================================================== // TIME ATTACK KICK DATA JSON -> To Send Back To Server //====================================================== String timeAttack_data_json(unsigned int RunningTime, unsigned int KickCount, unsigned int LastStamp, unsigned int TimeStamp) { // Building The Buffer DynamicJsonDocument data(capacity); data["tm"] = RunningTime; data["ct"] = KickCount; // Calculations if(TimeStamp > 0 ) { // Calculate Time Stamp In Seconds float st = TimeStamp; st /= 1000; data["st"] = String(st, 3).toFloat(); // Calculate Strike Delay In Seconds float dl = TimeStamp - LastStamp; dl /= 1000; data["dl"] = String(dl, 3).toFloat(); } String output; serializeJson(data, output); data.clear(); return output; } //====================================================== // REACTION GAME START LED SIGNAL //====================================================== void TimeAttack_Start() { // LightUp LED_WHITE_CROSSFADE(2); // Grean Light In LED_GREEN_FADEIN(); } //====================================================== // REACTION GAME END SINGNAL LED SIGNAL //====================================================== void TimeAttack_End() { // Grean Light In LED_GREEN_FADEOUT(); // Red Light In LED_RED_FADEIN(); // Wait For 2 Sec delay(2000); // Red Light Out LED_RED_FADEOUT(); } //====================================================== // REACTION GAME START LED CELEBRATION //====================================================== void TimeAttack_Celebration() { // LightUp rainbowCycle(2); // Grean Light OUT LED_GREEN_FADEOUT(); } //====================================================== // REACTION GAME RESET LED SIGNAL //====================================================== void TimeAttack_Reset() { LED_BLUE(); delay(250); LED_BLUE_FADEOUT(); }