Show strikes on controller

This commit is contained in:
redfast00 2022-02-11 23:05:09 +01:00
parent 0c1722a330
commit 0df4f8d489
No known key found for this signature in database
GPG key ID: 5946E0E34FD0553C
4 changed files with 77 additions and 20 deletions

View file

@ -187,6 +187,8 @@ def status():
for address, state
in sorted(serial_to_web.registered_modules.items(), key=(lambda kv: kv[0].as_binary()))
]
status_dict['max_allowed_strikes'] = web_to_serial.max_allowed_strikes
status_dict['game_duration'] = web_to_serial.game_duration.total_seconds()
print(status_dict)
return jsonify(status_dict)

View file

@ -15,6 +15,12 @@
<div>Game state: <span id="gamestate"></span></div>
</div>
<!-- Strikes -->
<div class="box" id="strikeContainer">
<div>Strikes</div>
<div id="strikeIndicatorContainer"></div>
</div>
<!-- Actions -->
<div>
<button id="buttonStart" onclick="onStartButtonClick()">START</button>

View file

@ -94,6 +94,27 @@ button:disabled {
margin: 8px;
}
#strikeContainer {
text-align: center;
height: 4em;
}
#strikeContainer .strikeIndicator {
padding: 20px;
font-family: sans-serif;
font-weight: 900
}
#strikeContainer .inactive {
color: #ff000033;
}
#strikeContainer .active {
color: #ff0000;
}
.solved {
background-color: green !important;
color: white !important;

View file

@ -24,6 +24,12 @@ const state = {
// If the alarm has been played already
alarmPlayed: false,
// Number of mistakes allowed without exploding the bomb
maxAllowedStrikes: 0,
// Time on the timer at the beginning of a game
gameDuration: 0
};
/**
@ -75,6 +81,22 @@ function updateModules(puzzles) {
modulesElement.replaceChildren(...modules);
}
function updateStrikes() {
const indicators = [];
for (let idx = 0; idx < state.maxAllowedStrikes; idx++) {
let indicator = document.createElement("span");
indicator.classList.add('strikeIndicator');
indicator.textContent = '!';
if (idx < state.strikes) {
indicator.classList.add('active');
} else {
indicator.classList.add('inactive');
}
indicators.push(indicator);
}
document.getElementById("strikeIndicatorContainer").replaceChildren(...indicators);
}
/**
* Initialize the game state.
*/
@ -92,11 +114,13 @@ function updateGameState() {
.then((data) => {
// Update the game state
state.gamestate = data.gamestate;
state.gameDuration = data.game_duration;
state.maxAllowedStrikes = data.max_allowed_strikes;
document.getElementById("gamestate").innerHTML = state.gamestate;
// Reset the strike amount if the game is not running anymore.
if (state.gamestate != "GAME") {
state.strikeAmount = 0;
if (state.gamestate === "INACTIVE") {
state.strikes = 0;
state.alarmPlayed = false;
}
@ -111,19 +135,17 @@ function updateGameState() {
.map((p) => p.strikes)
.reduce((a, b) => a + b, 0);
// Play a "buzzer" sound when a strike is made.
// Play a "buzzer" sound when a strike is made and update total amount of strikes.
if (state.strikes < newStrikes) {
playSound(sounds.strike);
state.strikes = newStrikes;
}
// Play a "alarm" sound when the time is at 10 seconds.
// Play a "alarm" sound when the time is at 20 seconds.
if (data.timeleft <= 20 && data.timeleft > 19 && !state.alarmPlayed) {
playSound(sounds.alarm);
state.alarmPlayed = true;
}
// Update the total amount of strikes
state.strikes = newStrikes;
}
// Update the start/restart button visibility.
@ -134,6 +156,7 @@ function updateGameState() {
// Update the modules
updateModules(data.puzzles);
updateStrikes();
});
}
@ -173,23 +196,12 @@ function initializeSegmentDisplay() {
setInterval(updateSegmentDisplay, 100);
}
/**
* Update the segment display with the latest game data.
*/
function updateSegmentDisplay() {
// Do not update the timer when the game is not running.
if (state.gamestate != "GAME" || !state.estimatedTimeout) {
return;
}
const timeLeft = (state.estimatedTimeout - new Date()) / 1000;
function setTimeleft(timeLeft) {
// Set the display to 0 when there is no time left.
if (timeLeft <= 0) {
if (isNaN(timeLeft) || timeLeft <= 0) {
display.setValue("00:00.0");
return;
}
const integral = Math.floor(timeLeft);
const fractional = timeLeft - integral;
const minutes = Math.floor(integral / 60);
@ -202,6 +214,22 @@ function updateSegmentDisplay() {
display.setValue(`${minutesStr}:${secondsStr}.${fractionalStr}`);
}
/**
* Update the segment display with the latest game data.
*/
function updateSegmentDisplay() {
console.log(state.gamestate);
if (state.gamestate === "INACTIVE" || state.gamestate === "INFO" || state.gamestate === "DISCOVER") {
setTimeleft(state.gameDuration);
}
// Do not update the timer when the game is not running.
else if (state.gamestate != "GAME" || !state.estimatedTimeout) {
return;
} else {
setTimeleft((state.estimatedTimeout - new Date()) / 1000);
}
}
/**
* When the window is loaded.
*/