submodes for normal mode

This commit is contained in:
2026-08-02 20:15:55 -05:00
parent 61a98ca89d
commit 88c8dca057
+180 -156
View File
@@ -112,9 +112,10 @@
margin-top: 2rem;
}
#game-modes {
display: flex;
.button-container {
/** display: flex; */
align-content: center;
align-items: center;
justify-content: center;
width: 100%;
gap: 1rem;
@@ -122,8 +123,6 @@
#game-over-buttons {
gap: 2rem;
align-items: center;
justify-content: center;
}
button {
@@ -182,17 +181,23 @@
</div>
<!-- gamemode menu buttons-->
<div id="game-modes" class="hidden fade">
<div id="game-modes" class="button-container hidden fade">
<button id="normal" onclick="handleNormalMode()">normal</button>
<button id="countdown" onclick="handleCountdownMode()">countdown</button>
<!-- <button id="infinite">infinite</button> -->
</div>
<div id="normal-sub-modes" class="button-container hidden fade">
<button id="normal-3-rounds" onclick="setNormalRounds(3)">3 rounds</button>
<button id="normal-6-rounds" onclick="setNormalRounds(6)">6 rounds</button>
<button id="normal-10-rounds" onclick="setNormalRounds(10)">10 rounds</button>
</div>
<!-- pre-round text -->
<span id="game-text" class="hidden fade"></span>
<!-- post game buttons -->
<div id="game-over-buttons" class="hidden fade">
<div id="game-over-buttons" class="button-container hidden fade">
<button id="play-again" onclick="handlePlayAgain()">play again</button>
<button id="reset-game" onclick="handleReset()">back to main menu</button>
</div>
@@ -260,6 +265,10 @@
let title2 = document.getElementById("title2");
let gameModes = document.getElementById("game-modes");
let normalSubModes = document.getElementById("normal-sub-modes");
let countdownSubModes = document.getElementById("countdown-sub-modes");
let gameText = document.getElementById("game-text");
let gameOverButtons = document.getElementById("game-over-buttons");
@@ -318,40 +327,30 @@
console.log('frame: ' + frameWidth + ' x ' + frameHeight);
}
async function handlePlayAgain(e) {
// hide game over buttons
gameOverButtons.style.display = "none";
gameOverButtons.style.opacity = "0";
// remove game text from DOM flow
gameText.style.display = "none";
gameText.style.opacity = "0";
setParameters();
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
center.id = "center";
document.body.insertAdjacentElement("afterbegin", center);
if (gamemode == "normal") {
handleNormalMode(e);
}
else if (gamemode == "countdown") {
handleCountdownMode(e);
}
else {
alert("cannot play again, gamemode does not exit?");
}
}
async function handleNormalMode(e) {
gamemode = "normal";
// setup mode parameters
// ensure mode parameters are reset
currentRound = 1;
totalTime = 0;
await fadeMainMenuOut();
normalSubModes.style.display = "flex";
normalSubModes.style.opacity = "100";
}
function setNormalRounds(numRounds) {
// fade buttons out
normalSubModes.style.opacity = "0";
sleep(500);
normalSubModes.style.display = "none";
maxNormalRounds = numRounds;
beginNormalMode();
}
async function beginNormalMode() {
// set game instruction text + fade it in
gameText.innerText = "hover on middle circle to start the countdown,\nthen click the targets as fast as possible!";
gameText.style.opacity = "0";
@@ -365,6 +364,96 @@
center.addEventListener("touchend", handleHoverEnd);
}
async function startNormalRound(roundNumber) {
if (roundNumber > maxNormalRounds) {
handleReset({});
return;
}
// if user cancels hover countdown, don't start round
if (!await drawCountdown(hoverCount)) {
console.log("player canceled coundown");
return;
}
if (roundNumber == maxNormalRounds) {
numTargets = roundNumber * 2;
}
else {
numTargets = roundNumber;
}
// effectively begin the round
console.log("starting round " + roundNumber);
center.remove();
targetsClicked = 0;
roundTimeStart = Date.now();
randomTargetGenerator(numTargets);
while (targetsClicked < numTargets) {
await sleep(10);
if (targetsClicked == numTargets) break;
}
roundTimeEnd = Date.now();
roundSeconds = (roundTimeEnd - roundTimeStart) / 1000;
totalTime += roundSeconds;
currentRound++;
// auto-reset bullseye if page gets resized at all
if (needsResizeAdjustment) {
handlePageResize();
}
// ensure "DRAW" isn't still lingering on screen after round
draw.style.display = "none";
draw.style.opacity = "0";
// GAME OVER STUFF
if (roundNumber == maxNormalRounds) {
if (totalTime < bestNormalTime || bestNormalTime == 0) {
if (bestNormalTime == 0) {
alert("NEW FASTEST TIME!!! congratulations cowboy.");
}
else {
alert("NEW FASTEST TIME!!! previous best: " + bestNormalTime.toFixed(3) + "s. congratulations cowboy.");
}
bestNormalTime = totalTime;
localStorage.setItem("bestNormalTime", bestNormalTime);
}
gameText.innerText = "ROUND: " + roundSeconds.toFixed(3) +
"s\nTOTAL: " + totalTime.toFixed(3) +
"s\nBEST SCORE: " + bestNormalTime.toFixed(3);
numTargets = 0;
targetsClicked =0;
gameOverButtons.style.display = "flex";
gameOverButtons.style.opacity = "100";
}
// NORMAL END OF ROUND STUFF
else {
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
center.id = "center";
document.body.insertAdjacentElement("afterbegin", center);
console.log("ROUND: " + roundSeconds.toFixed(3) + "s\nTOTAL: " + totalTime.toFixed(3) + "\nhover on circle to start round " + currentRound);
gameText.innerText = "ROUND: " + roundSeconds.toFixed(3) + "s\nTOTAL: " + totalTime.toFixed(3) + "s\nhover on circle to start round " + currentRound;
center.addEventListener("mouseover", handleHoverStart);
center.addEventListener("mouseleave", handleHoverEnd);
center.addEventListener("touchend", handleHoverEnd);
}
gameText.style.display = "inline";
gameText.style.opacity = "100";
return;
}
async function handleCountdownMode(e) {
gamemode = "countdown";
countdownBullseyeNeeded = true;
@@ -383,36 +472,6 @@
center.addEventListener("touchend", handleHoverEnd);
}
async function handleReset(e) {
// bullseye won't be on screen after a game
setParameters();
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
center.id = "center";
document.body.insertAdjacentElement("afterbegin", center);
// refresh game state variables
gamemode = "";
currentRound = 0;
// hide buttons
gameOverButtons.style.display = "none";
gameOverButtons.style.opacity = "0";
// remove game text from DOM flow
gameText.style.display = "none";
gameText.style.opacity = "0";
// reintroduce main menu elements into DOM flow
await sleep(800);
await drawCircle(2);
await fadeMainMenuIn();
// auto-reset bullseye if page was resized during animation
if (needsResizeAdjustment) {
handlePageResize();
}
}
async function handleHoverStart(e) {
hovering = true;
hoverCount++;
@@ -436,7 +495,7 @@
async function startCountdownMode() {
// if user cancels hover countdown, don't start round
if (!await normalModeRoundCountdown(hoverCount)) {
if (!await drawCountdown(hoverCount)) {
console.log("player canceled coundown");
return;
}
@@ -498,101 +557,10 @@
gameOverButtons.style.opacity = "100";
}
async function startNormalRound(roundNumber) {
if (roundNumber > 3) {
handleReset({});
return;
}
// if user cancels hover countdown, don't start round
if (!await normalModeRoundCountdown(hoverCount)) {
console.log("player canceled coundown");
return;
}
if (roundNumber == 1) {
numTargets = 1;
}
else if (roundNumber == 2) {
numTargets = 3;
}
else if (roundNumber == 3) {
numTargets = 5;
}
// effectively begin the round
console.log("starting round " + roundNumber);
center.remove();
targetsClicked = 0;
roundTimeStart = Date.now();
randomTargetGenerator(numTargets);
while (targetsClicked < numTargets) {
await sleep(10);
if (targetsClicked == numTargets) break;
}
roundTimeEnd = Date.now();
roundSeconds = (roundTimeEnd - roundTimeStart) / 1000;
totalTime += roundSeconds;
currentRound++;
// auto-reset bullseye if page gets resized at all
if (needsResizeAdjustment) {
handlePageResize();
}
// even if no resize, bring bullseye back to screen
// ensure "DRAW" isn't still lingering on screen after round
draw.style.display = "none";
draw.style.opacity = "0";
// GAME OVER STUFF
if (roundNumber == 3) {
if (totalTime < bestNormalTime || bestNormalTime == 0) {
if (bestNormalTime == 0) {
alert("NEW FASTEST TIME!!! congratulations cowboy.");
}
else {
alert("NEW FASTEST TIME!!! previous best: " + bestNormalTime.toFixed(3) + "s. congratulations cowboy.");
}
bestNormalTime = totalTime;
localStorage.setItem("bestNormalTime", bestNormalTime);
}
gameText.innerText = "ROUND: " + roundSeconds.toFixed(3) +
"s\nTOTAL: " + totalTime.toFixed(3) +
"s\nBEST SCORE: " + bestNormalTime.toFixed(3);
numTargets = 0;
targetsClicked =0;
gameOverButtons.style.display = "flex";
gameOverButtons.style.opacity = "100";
}
// NORMAL END OF ROUND STUFF
else {
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
center.id = "center";
document.body.insertAdjacentElement("afterbegin", center);
console.log("ROUND: " + roundSeconds.toFixed(3) + "s\nTOTAL: " + totalTime.toFixed(3) + "\nhover on circle to start round " + currentRound);
gameText.innerText = "ROUND: " + roundSeconds.toFixed(3) + "s\nTOTAL: " + totalTime.toFixed(3) + "s\nhover on circle to start round " + currentRound;
center.addEventListener("mouseover", handleHoverStart);
center.addEventListener("mouseleave", handleHoverEnd);
center.addEventListener("touchend", handleHoverEnd);
}
gameText.style.display = "inline";
gameText.style.opacity = "100";
return;
}
/**
* HELPER TO KICK-OFF COUNTDOWNS FROM HOVER
*/
async function normalModeRoundCountdown(hoverNumber) {
/** HELPER TO KICK-OFF COUNTDOWNS FROM HOVER */
async function drawCountdown(hoverNumber) {
gameText.style.display = "none";
countingDown = true;
@@ -682,6 +650,62 @@
}
}
async function handlePlayAgain(e) {
// hide game over buttons
gameOverButtons.style.display = "none";
gameOverButtons.style.opacity = "0";
// remove game text from DOM flow
gameText.style.display = "none";
gameText.style.opacity = "0";
setParameters();
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
center.id = "center";
document.body.insertAdjacentElement("afterbegin", center);
if (gamemode == "normal") {
handleNormalMode(e);
}
else if (gamemode == "countdown") {
handleCountdownMode(e);
}
else {
alert("cannot play again, gamemode does not exit?");
}
}
async function handleReset(e) {
// bullseye won't be on screen after a game
setParameters();
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
center.id = "center";
document.body.insertAdjacentElement("afterbegin", center);
// refresh game state variables
gamemode = "";
currentRound = 0;
// hide buttons
gameOverButtons.style.display = "none";
gameOverButtons.style.opacity = "0";
// remove game text from DOM flow
gameText.style.display = "none";
gameText.style.opacity = "0";
// reintroduce main menu elements into DOM flow
await sleep(800);
await drawCircle(2);
await fadeMainMenuIn();
// auto-reset bullseye if page was resized during animation
if (needsResizeAdjustment) {
handlePageResize();
}
}
function handleTargetClick(e) {
targetsClicked++;
e.target.remove();