takeone-kicker/Firmware Code/KICKER_V2/game_time_attack.ino

262 lines
7.3 KiB
C++

//======================================================
// 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(JSON_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
//------------------------------------------------------
// Display Welcome Message
// TERMINAL("");
// TERMINAL("==================================================");
// TERMINAL(" -->> Time Attack Game Settings");
// TERMINAL("--------------------------------------------------");
// TERMINAL("Timer : " + String(time) + " Seconds");
// TERMINAL("Strike Limit : " + String(limit));
// TERMINAL("Limit Enabled : " + String(limitEnable));
// TERMINAL("--------------------------------------------------");
// TERMINAL("2 Seconds To Start Get Ready & Good Luck !!");
// TERMINAL("==================================================");
// TERMINAL("");
// 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
// TERMINAL("");
// TERMINAL("---------------------------------------------------");
dualcomm(GAME_OVER);
// TERMINAL("===================================================");
// TERMINAL("");
// LightUp
rainbowCycle(2);
// Grean Light In
LED_GREEN_FADEOUT();
// Return
return;
}
}
// Send End Game Signal To Smart Phone
// TERMINAL("");
// TERMINAL("---------------------------------------------------");
dualcomm(GAME_OVER);
// TERMINAL("===================================================");
// TERMINAL("");
// 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(JSON_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(3);
// Grean Light In
LED_GREEN();
}
//======================================================
// 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();
}