submodes for normal mode
This commit is contained in:
+181
-157
@@ -112,9 +112,10 @@
|
|||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#game-modes {
|
.button-container {
|
||||||
display: flex;
|
/** display: flex; */
|
||||||
align-content: center;
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
@@ -122,8 +123,6 @@
|
|||||||
|
|
||||||
#game-over-buttons {
|
#game-over-buttons {
|
||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
@@ -182,17 +181,23 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- gamemode menu buttons-->
|
<!-- 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="normal" onclick="handleNormalMode()">normal</button>
|
||||||
<button id="countdown" onclick="handleCountdownMode()">countdown</button>
|
<button id="countdown" onclick="handleCountdownMode()">countdown</button>
|
||||||
<!-- <button id="infinite">infinite</button> -->
|
<!-- <button id="infinite">infinite</button> -->
|
||||||
</div>
|
</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 -->
|
<!-- pre-round text -->
|
||||||
<span id="game-text" class="hidden fade"></span>
|
<span id="game-text" class="hidden fade"></span>
|
||||||
|
|
||||||
<!-- post game buttons -->
|
<!-- 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="play-again" onclick="handlePlayAgain()">play again</button>
|
||||||
<button id="reset-game" onclick="handleReset()">back to main menu</button>
|
<button id="reset-game" onclick="handleReset()">back to main menu</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -260,6 +265,10 @@
|
|||||||
let title2 = document.getElementById("title2");
|
let title2 = document.getElementById("title2");
|
||||||
|
|
||||||
let gameModes = document.getElementById("game-modes");
|
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 gameText = document.getElementById("game-text");
|
||||||
let gameOverButtons = document.getElementById("game-over-buttons");
|
let gameOverButtons = document.getElementById("game-over-buttons");
|
||||||
|
|
||||||
@@ -318,40 +327,30 @@
|
|||||||
console.log('frame: ' + frameWidth + ' x ' + frameHeight);
|
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) {
|
async function handleNormalMode(e) {
|
||||||
gamemode = "normal";
|
gamemode = "normal";
|
||||||
|
|
||||||
// setup mode parameters
|
// ensure mode parameters are reset
|
||||||
currentRound = 1;
|
currentRound = 1;
|
||||||
totalTime = 0;
|
totalTime = 0;
|
||||||
|
|
||||||
await fadeMainMenuOut();
|
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
|
// 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.innerText = "hover on middle circle to start the countdown,\nthen click the targets as fast as possible!";
|
||||||
gameText.style.opacity = "0";
|
gameText.style.opacity = "0";
|
||||||
@@ -365,6 +364,96 @@
|
|||||||
center.addEventListener("touchend", handleHoverEnd);
|
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) {
|
async function handleCountdownMode(e) {
|
||||||
gamemode = "countdown";
|
gamemode = "countdown";
|
||||||
countdownBullseyeNeeded = true;
|
countdownBullseyeNeeded = true;
|
||||||
@@ -383,36 +472,6 @@
|
|||||||
center.addEventListener("touchend", handleHoverEnd);
|
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) {
|
async function handleHoverStart(e) {
|
||||||
hovering = true;
|
hovering = true;
|
||||||
hoverCount++;
|
hoverCount++;
|
||||||
@@ -436,7 +495,7 @@
|
|||||||
|
|
||||||
async function startCountdownMode() {
|
async function startCountdownMode() {
|
||||||
// if user cancels hover countdown, don't start round
|
// if user cancels hover countdown, don't start round
|
||||||
if (!await normalModeRoundCountdown(hoverCount)) {
|
if (!await drawCountdown(hoverCount)) {
|
||||||
console.log("player canceled coundown");
|
console.log("player canceled coundown");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -498,101 +557,10 @@
|
|||||||
gameOverButtons.style.opacity = "100";
|
gameOverButtons.style.opacity = "100";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startNormalRound(roundNumber) {
|
|
||||||
if (roundNumber > 3) {
|
|
||||||
handleReset({});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if user cancels hover countdown, don't start round
|
/** HELPER TO KICK-OFF COUNTDOWNS FROM HOVER */
|
||||||
if (!await normalModeRoundCountdown(hoverCount)) {
|
async function drawCountdown(hoverNumber) {
|
||||||
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) {
|
|
||||||
gameText.style.display = "none";
|
gameText.style.display = "none";
|
||||||
countingDown = true;
|
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) {
|
function handleTargetClick(e) {
|
||||||
targetsClicked++;
|
targetsClicked++;
|
||||||
e.target.remove();
|
e.target.remove();
|
||||||
|
|||||||
Reference in New Issue
Block a user