countdown works. normal mode feels better/faster. game-over buttons
This commit is contained in:
+318
-115
@@ -67,11 +67,21 @@
|
|||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#title-container {
|
||||||
|
justify-self: center;
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 100%;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
#text-box {
|
#text-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: column;
|
||||||
align-content: end;
|
align-content: end;
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
|
gap: 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: red;
|
color: red;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -104,23 +114,26 @@
|
|||||||
<div id="text-box">
|
<div id="text-box">
|
||||||
|
|
||||||
<!-- intro related -->
|
<!-- intro related -->
|
||||||
<div style="display: flex; gap: 1rem;">
|
<div id="title-container">
|
||||||
<span id="intro1" class="hidden title">QUICK</span>
|
<span id="title1" class="hidden title">QUICK</span>
|
||||||
<span id="intro2" class="hidden title">DRAW</span>
|
<span id="title2" class="hidden title">DRAW</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- gamemode menu buttons-->
|
<!-- gamemode menu buttons-->
|
||||||
<div id="game-modes" class="hidden fade">
|
<div id="game-modes" class="hidden fade">
|
||||||
<button id="normal" onclick="handleNormalMode()">normal</button>
|
<button id="normal" onclick="handleNormalMode()">normal</button>
|
||||||
<button id="countdown">countdown</button>
|
<button id="countdown" onclick="handleCountdownMode()">countdown</button>
|
||||||
<!-- <button id="infinite">infinite</button> -->
|
<!-- <button id="infinite">infinite</button> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- pre-round text -->
|
<!-- pre-round text -->
|
||||||
<span id="gameText" class="hidden fade"></span>
|
<span id="game-text" class="hidden fade"></span>
|
||||||
|
|
||||||
<!-- post round text -->
|
<!-- post game buttons -->
|
||||||
<span id="round-end" class="hidden fade"></span>
|
<div id="game-over-buttons" class="hidden fade">
|
||||||
|
<button id="play-again" onclick="handlePlayAgain()">play again</button>
|
||||||
|
<button id="reset-game" onclick="handleReset()">back to main menu</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- countdown text -->
|
<!-- countdown text -->
|
||||||
<span id="ready" class="hidden title">READY?</span>
|
<span id="ready" class="hidden title">READY?</span>
|
||||||
@@ -132,6 +145,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// SCREEN / SETUP VARIABLES
|
||||||
let gameBorderWidth = 1;
|
let gameBorderWidth = 1;
|
||||||
let targetWidth = 50;
|
let targetWidth = 50;
|
||||||
let targetHeight = 50;
|
let targetHeight = 50;
|
||||||
@@ -150,38 +164,77 @@
|
|||||||
let xFrameAdjustment;
|
let xFrameAdjustment;
|
||||||
let yFrameAdjustment;
|
let yFrameAdjustment;
|
||||||
|
|
||||||
let hovering = false;
|
// UX HELPERS
|
||||||
|
let drawingCircle = false;
|
||||||
|
let needsResizeAdjustment = false;
|
||||||
|
|
||||||
let hoverCount = 0; // number of times the cursor has hovered over bullseye. used to cleanly handle round starting / cancelling
|
// GAME STATE VARIABLES
|
||||||
|
|
||||||
let targetsClickedThisRound = 0;
|
|
||||||
let gamemode = ""; // can be: "normal", "countdown", "infinite"
|
let gamemode = ""; // can be: "normal", "countdown", "infinite"
|
||||||
let roundmode = ""; // if gamemode is "countdown" or "infinite", can be: "rounds" or "frenzy"
|
let countingDown = false;
|
||||||
|
let hovering = false;
|
||||||
|
let hoverCount = 0; // number of times the cursor has hovered over bullseye. used to cleanly handle round starting / cancelling
|
||||||
|
let gameIsOver = false;
|
||||||
|
|
||||||
let currentRound = 0;
|
// GAMEPLAY VARIABLES
|
||||||
let countingDown = false;
|
let targetsClicked = 0;
|
||||||
|
|
||||||
let totalTime = 0.0;
|
// "NORMAL" MODE ONLY VARIABLES
|
||||||
|
let currentRound = 0;
|
||||||
|
let totalTime = 0.0;
|
||||||
|
let roundSeconds = 0.0;
|
||||||
let roundTimeStart = 0;
|
let roundTimeStart = 0;
|
||||||
let roundTimeEnd = 0;
|
let roundTimeEnd = 0;
|
||||||
let roundSeconds = 0.0;
|
let bestNormalTime = 0;
|
||||||
|
|
||||||
let bestNormalTime = "none";
|
// "COUNTDOWN" MODE ONLY VARIABLES
|
||||||
|
let countdownTime = 0;
|
||||||
|
let bestCountdownScore = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// menu / text elements
|
||||||
|
let titleContainer = document.getElementById("title-container");
|
||||||
|
let title1 = document.getElementById("title1");
|
||||||
|
let title2 = document.getElementById("title2");
|
||||||
|
|
||||||
|
let gameModes = document.getElementById("game-modes");
|
||||||
|
let gameText = document.getElementById("game-text");
|
||||||
|
let gameOverButtons = document.getElementById("game-over-buttons");
|
||||||
|
|
||||||
// text elements
|
|
||||||
let ready = document.getElementById("ready");
|
let ready = document.getElementById("ready");
|
||||||
let intro1 = document.getElementById("intro1");
|
|
||||||
let intro2 = document.getElementById("intro2");
|
|
||||||
let gameText = document.getElementById("gameText");
|
|
||||||
|
|
||||||
let one = document.getElementById("countdown1");
|
let one = document.getElementById("countdown1");
|
||||||
let two = document.getElementById("countdown2");
|
let two = document.getElementById("countdown2");
|
||||||
let three = document.getElementById("countdown3");
|
let three = document.getElementById("countdown3");
|
||||||
|
|
||||||
let draw = document.getElementById("draw");
|
let draw = document.getElementById("draw");
|
||||||
|
|
||||||
|
// setup initialization
|
||||||
window.addEventListener("load", initGame);
|
window.addEventListener("load", initGame);
|
||||||
|
|
||||||
|
async function initGame() {
|
||||||
|
// determine screen parameters + listen for changes
|
||||||
|
setParameters();
|
||||||
|
window.addEventListener("resize", handlePageResize);
|
||||||
|
|
||||||
|
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
|
||||||
|
center.id = "center";
|
||||||
|
document.body.insertAdjacentElement("afterbegin", center);
|
||||||
|
|
||||||
|
await drawTargetsInCircle(2);
|
||||||
|
if (needsResizeAdjustment) {
|
||||||
|
// auto-reset screen if page was resized during animation
|
||||||
|
handlePageResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
await fadeMainMenuIn();
|
||||||
|
|
||||||
|
if (localStorage.getItem("bestNormalTime") != null) {
|
||||||
|
bestNormalTime = Number.parseFloat(localStorage.getItem("bestNormalTime"));
|
||||||
|
}
|
||||||
|
if (localStorage.getItem("bestCountdownScore") != null) {
|
||||||
|
bestCountdownScore = Number.parseInt(localStorage.getItem("bestCountdownScore"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function to determine screen-size + ratios for rendering targets
|
||||||
function setParameters(event) {
|
function setParameters(event) {
|
||||||
pageHeight = window.innerHeight;
|
pageHeight = window.innerHeight;
|
||||||
pageWidth = window.innerWidth;
|
pageWidth = window.innerWidth;
|
||||||
@@ -203,45 +256,25 @@
|
|||||||
console.log('frame: ' + frameWidth + ' x ' + frameHeight);
|
console.log('frame: ' + frameWidth + ' x ' + frameHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initGame() {
|
async function handlePlayAgain(e) {
|
||||||
setParameters();
|
gameIsOver = false;
|
||||||
|
|
||||||
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
|
// hide game over buttons
|
||||||
center.id = "center";
|
gameOverButtons.style.display = "none";
|
||||||
document.body.insertAdjacentElement("afterbegin", center);
|
gameOverButtons.style.opacity = "0";
|
||||||
|
|
||||||
// await drawTargetsInCircle(2);
|
// remove game text from DOM flow
|
||||||
await drawTargetsInCircle(false);
|
gameText.style.display = "none";
|
||||||
|
gameText.style.opacity = "0";
|
||||||
|
|
||||||
// insert intro elements into document flow
|
if (gamemode == "normal") {
|
||||||
intro1.style.display = "inline";
|
handleNormalMode(e);
|
||||||
intro2.style.display = "inline";
|
}
|
||||||
|
else if (gamemode == "countdown") {
|
||||||
// reveal intro elements
|
handleCountdownMode(e);
|
||||||
intro1.style.opacity = "100";
|
}
|
||||||
await sleep(500);
|
else {
|
||||||
intro2.style.opacity = "100";
|
alert("cannot play again, gamemode does not exit?");
|
||||||
await sleep(1500);
|
|
||||||
|
|
||||||
intro1.classList.add("fade");
|
|
||||||
intro2.classList.add("fade");
|
|
||||||
|
|
||||||
intro1.style.opacity = "0";
|
|
||||||
intro2.style.opacity = "0";
|
|
||||||
|
|
||||||
await sleep(1000);
|
|
||||||
|
|
||||||
intro1.style.display = "none";
|
|
||||||
intro2.style.display = "none";
|
|
||||||
|
|
||||||
window.addEventListener("resize", handlePageResize);
|
|
||||||
|
|
||||||
document.getElementById("game-modes").style.display = "inline";
|
|
||||||
await sleep(500);
|
|
||||||
document.getElementById("game-modes").style.opacity = "100";
|
|
||||||
|
|
||||||
if (localStorage.getItem("bestNormalTime") != null) {
|
|
||||||
bestNormalTime = Number.parseFloat(localStorage.getItem("bestNormalTime"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,42 +282,58 @@
|
|||||||
gamemode = "normal";
|
gamemode = "normal";
|
||||||
console.log("game mode: " + gamemode);
|
console.log("game mode: " + gamemode);
|
||||||
|
|
||||||
|
// setup mode parameters
|
||||||
currentRound = 1;
|
currentRound = 1;
|
||||||
totalTime = 0;
|
totalTime = 0;
|
||||||
|
|
||||||
center.addEventListener("mouseover", handleHoverStart);
|
await fadeMainMenuOut();
|
||||||
center.addEventListener("mouseleave", handleHoverEnd);
|
|
||||||
|
|
||||||
document.getElementById("game-modes").style.opacity = "0";
|
|
||||||
await sleep(500);
|
|
||||||
document.getElementById("game-modes").style.display = "none";
|
|
||||||
|
|
||||||
intro1.style.display = "none";
|
|
||||||
intro2.style.display = "none";
|
|
||||||
|
|
||||||
|
// 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";
|
||||||
gameText.style.display = "inline";
|
gameText.style.display = "inline";
|
||||||
await sleep(500);
|
await sleep(500);
|
||||||
gameText.style.opacity = "100";
|
gameText.style.opacity = "100";
|
||||||
|
|
||||||
|
// enable player to start first round
|
||||||
|
center.addEventListener("mouseover", handleHoverStart);
|
||||||
|
center.addEventListener("mouseleave", handleHoverEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleCountdownMode(e) {
|
||||||
|
gamemode = "countdown";
|
||||||
|
console.log("game mode: " + gamemode);
|
||||||
|
|
||||||
|
await fadeMainMenuOut();
|
||||||
|
// set game instruction text + fade it in
|
||||||
|
gameText.innerText = "hover on middle circle to start the countdown,\nthen click as many targets as possible!";
|
||||||
|
gameText.style.opacity = "0";
|
||||||
|
gameText.style.display = "inline";
|
||||||
|
await sleep(500);
|
||||||
|
gameText.style.opacity = "100";
|
||||||
|
|
||||||
|
// enable player to start game
|
||||||
|
center.addEventListener("mouseover", handleHoverStart);
|
||||||
|
center.addEventListener("mouseleave", handleHoverEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleReset(e) {
|
async function handleReset(e) {
|
||||||
|
gameIsOver = false;
|
||||||
|
gamemode = "";
|
||||||
currentRound = 0;
|
currentRound = 0;
|
||||||
center.removeEventListener("mouseover", handleReset);
|
|
||||||
|
// hide buttons
|
||||||
|
gameOverButtons.style.display = "none";
|
||||||
|
gameOverButtons.style.opacity = "0";
|
||||||
|
|
||||||
|
// remove game text from DOM flow
|
||||||
gameText.style.display = "none";
|
gameText.style.display = "none";
|
||||||
gameText.style.opacity = "0";
|
gameText.style.opacity = "0";
|
||||||
|
|
||||||
intro1.style.display = "inline";
|
// reintroduce main menu elements into DOM flow
|
||||||
intro2.style.display = "inline";
|
await sleep(800);
|
||||||
intro1.style.opacity = "100";
|
|
||||||
intro2.style.opacity = "100";
|
|
||||||
|
|
||||||
document.getElementById("game-modes").style.display = "inline";
|
|
||||||
await sleep(500);
|
|
||||||
document.getElementById("game-modes").style.opacity = "100";
|
|
||||||
await drawTargetsInCircle(2);
|
await drawTargetsInCircle(2);
|
||||||
|
await fadeMainMenuIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleHoverStart(e) {
|
async function handleHoverStart(e) {
|
||||||
@@ -294,27 +343,91 @@
|
|||||||
console.log('hover count: ' + hoverCount);
|
console.log('hover count: ' + hoverCount);
|
||||||
console.log('current round: ' + currentRound);
|
console.log('current round: ' + currentRound);
|
||||||
|
|
||||||
|
// remove all targets
|
||||||
frameElement.replaceChildren();
|
frameElement.replaceChildren();
|
||||||
|
|
||||||
// intro1.style.display = "none";
|
|
||||||
// intro2.style.display = "none";
|
|
||||||
gameText.style.display = "none";
|
gameText.style.display = "none";
|
||||||
|
|
||||||
if (gamemode == "normal") {
|
if (gamemode == "normal") {
|
||||||
await startNormalRound(currentRound);
|
await startNormalRound(currentRound);
|
||||||
}
|
}
|
||||||
|
else if (gamemode == "countdown") {
|
||||||
|
await startCountdownMode();
|
||||||
|
}
|
||||||
// if (infinityMode)
|
// if (infinityMode)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function startCountdownMode() {
|
||||||
|
// if user cancels hover countdown, don't start round
|
||||||
|
if (!await normalModeRoundCountdown(hoverCount)) {
|
||||||
|
console.log("player canceled coundown");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup mode parameters
|
||||||
|
targetsClicked = 0;
|
||||||
|
tempTargetsClicked = 0;
|
||||||
|
countdownTime = 15.0;
|
||||||
|
|
||||||
|
// clear screen + render countdown / score
|
||||||
|
center.remove();
|
||||||
|
gameText.innerText = countdownTime.toFixed(3) + "s\ntargets clicked: " + targetsClicked;
|
||||||
|
gameText.style.display = "inline";
|
||||||
|
gameText.style.opacity = "100";
|
||||||
|
|
||||||
|
// begin actual game loop!
|
||||||
|
randomTargetGenerator(1);
|
||||||
|
while (countdownTime > 0.0) {
|
||||||
|
gameText.innerText = countdownTime.toFixed(3) + "s\ntargets clicked: " + targetsClicked;
|
||||||
|
// auto-reset screen if page was resized during animation
|
||||||
|
if (needsResizeAdjustment) {
|
||||||
|
handlePageResize();
|
||||||
|
}
|
||||||
|
// generate new target if last one was clicked
|
||||||
|
if (targetsClicked != tempTargetsClicked) {
|
||||||
|
randomTargetGenerator(1);
|
||||||
|
tempTargetsClicked++;
|
||||||
|
}
|
||||||
|
countdownTime = countdownTime - .01;
|
||||||
|
await sleep(10);
|
||||||
|
}
|
||||||
|
gameIsOver = true;
|
||||||
|
|
||||||
|
// ensure no targets are still on screen after timer ends
|
||||||
|
frameElement.replaceChildren();
|
||||||
|
|
||||||
|
// show end of round text. if high score, alert player and save
|
||||||
|
if (targetsClicked > bestCountdownScore || bestCountdownScore == 0) {
|
||||||
|
if (bestCountdownScore == 0) {
|
||||||
|
alert("NEW HIGHEST SCORE!!! congratulations cowboy.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert("NEW HIGHEST SCORE!!! previous best: " + bestCountdownScore + " targets. congratulations cowboy.");
|
||||||
|
}
|
||||||
|
bestCountdownScore = targetsClicked;
|
||||||
|
localStorage.setItem("bestCountdownScore", bestCountdownScore);
|
||||||
|
}
|
||||||
|
gameText.innerText = "TARGETS CLICKED: " + targetsClicked +
|
||||||
|
"\nHIGH SCORE: " + bestCountdownScore +
|
||||||
|
"\nhover on circle to go back to main menu..";
|
||||||
|
|
||||||
|
// bring bullseye back to screen
|
||||||
|
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
|
||||||
|
center.id = "center";
|
||||||
|
document.body.insertAdjacentElement("afterbegin", center);
|
||||||
|
|
||||||
|
gameOverButtons.style.display = "flex";
|
||||||
|
gameOverButtons.style.opacity = "100";
|
||||||
|
}
|
||||||
|
|
||||||
async function startNormalRound(roundNumber) {
|
async function startNormalRound(roundNumber) {
|
||||||
if (roundNumber > 3) {
|
if (roundNumber > 3) {
|
||||||
handleReset({});
|
handleReset({});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!await startCountdown(hoverCount)) {
|
// if user cancels hover countdown, don't start round
|
||||||
// if user canceled hover, don't continue round
|
if (!await normalModeRoundCountdown(hoverCount)) {
|
||||||
console.log("player canceled coundown");
|
console.log("player canceled coundown");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -332,13 +445,13 @@
|
|||||||
|
|
||||||
// effectively begin the round
|
// effectively begin the round
|
||||||
console.log("starting round " + roundNumber);
|
console.log("starting round " + roundNumber);
|
||||||
document.getElementById("center").remove();
|
center.remove();
|
||||||
targetsClickedThisRound = 0;
|
targetsClicked = 0;
|
||||||
roundTimeStart = Date.now();
|
roundTimeStart = Date.now();
|
||||||
placeTarget(numTargets);
|
randomTargetGenerator(numTargets);
|
||||||
while (targetsClickedThisRound < numTargets) {
|
while (targetsClicked < numTargets) {
|
||||||
await sleep(10);
|
await sleep(10);
|
||||||
if (targetsClickedThisRound == numTargets) break;
|
if (targetsClicked == numTargets) break;
|
||||||
}
|
}
|
||||||
roundTimeEnd = Date.now();
|
roundTimeEnd = Date.now();
|
||||||
roundSeconds = (roundTimeEnd - roundTimeStart) / 1000;
|
roundSeconds = (roundTimeEnd - roundTimeStart) / 1000;
|
||||||
@@ -351,22 +464,29 @@
|
|||||||
center.id = "center";
|
center.id = "center";
|
||||||
document.body.insertAdjacentElement("afterbegin", center);
|
document.body.insertAdjacentElement("afterbegin", center);
|
||||||
|
|
||||||
// ensure draw isn't still lingering on screen
|
// ensure "DRAW" isn't still lingering on screen after round
|
||||||
draw.style.display = "none";
|
draw.style.display = "none";
|
||||||
draw.style.opacity = "0";
|
draw.style.opacity = "0";
|
||||||
|
|
||||||
if (roundNumber == 3) {
|
if (roundNumber == 3) {
|
||||||
// GAME OVER STUFF
|
// GAME OVER STUFF
|
||||||
if (totalTime < bestNormalTime || bestNormalTime == "none") {
|
gameIsOver = true;
|
||||||
alert("NEW FASTEST TIME!!! previous best: " + bestNormalTime + "s. congratulations cowboy.");
|
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;
|
bestNormalTime = totalTime;
|
||||||
localStorage.setItem("bestNormalTime", bestNormalTime);
|
localStorage.setItem("bestNormalTime", bestNormalTime);
|
||||||
}
|
}
|
||||||
gameText.innerText = "ROUND: " + roundSeconds.toFixed(3) +
|
gameText.innerText = "ROUND: " + roundSeconds.toFixed(3) +
|
||||||
"s\nTOTAL: " + totalTime.toFixed(3) +
|
"s\nTOTAL: " + totalTime.toFixed(3) +
|
||||||
"s\nBEST SCORE: " + bestNormalTime.toFixed(3) +
|
"s\nBEST SCORE: " + bestNormalTime.toFixed(3);
|
||||||
"s\nhover on circle to go back to main menu..";
|
|
||||||
center.addEventListener("mouseover", handleReset);
|
gameOverButtons.style.display = "flex";
|
||||||
|
gameOverButtons.style.opacity = "100";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log("ROUND: " + roundSeconds.toFixed(3) + "s\nTOTAL: " + totalTime.toFixed(3) + "\nhover on circle to start round " + currentRound);
|
console.log("ROUND: " + roundSeconds.toFixed(3) + "s\nTOTAL: " + totalTime.toFixed(3) + "\nhover on circle to start round " + currentRound);
|
||||||
@@ -376,16 +496,16 @@
|
|||||||
center.addEventListener("mouseleave", handleHoverEnd);
|
center.addEventListener("mouseleave", handleHoverEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gameText.style.display = "inline";
|
gameText.style.display = "inline";
|
||||||
gameText.style.opacity = "100";
|
gameText.style.opacity = "100";
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HELPER TO KICK-OFF "NORMAL MODE" ROUNDS
|
||||||
async function startCountdown(hoverNumber) {
|
*/
|
||||||
|
async function normalModeRoundCountdown(hoverNumber) {
|
||||||
gameText.style.display = "none";
|
gameText.style.display = "none";
|
||||||
countingDown = true;
|
countingDown = true;
|
||||||
|
|
||||||
@@ -411,15 +531,15 @@
|
|||||||
|
|
||||||
if (!hovering || hoverNumber != hoverCount) return false;
|
if (!hovering || hoverNumber != hoverCount) return false;
|
||||||
three.style.opacity = "100";
|
three.style.opacity = "100";
|
||||||
await sleep(1000);
|
await sleep(500);
|
||||||
|
|
||||||
if (!hovering || hoverNumber != hoverCount) return false;
|
if (!hovering || hoverNumber != hoverCount) return false;
|
||||||
two.style.opacity = "100";
|
two.style.opacity = "100";
|
||||||
await sleep(1000);
|
await sleep(500);
|
||||||
|
|
||||||
if (!hovering || hoverNumber != hoverCount) return false;
|
if (!hovering || hoverNumber != hoverCount) return false;
|
||||||
one.style.opacity = "100";
|
one.style.opacity = "100";
|
||||||
await sleep(1000);
|
await sleep(500);
|
||||||
|
|
||||||
if (!hovering || hoverNumber != hoverCount) return false;
|
if (!hovering || hoverNumber != hoverCount) return false;
|
||||||
one.style.display = "none";
|
one.style.display = "none";
|
||||||
@@ -434,10 +554,12 @@
|
|||||||
draw.style.opacity = "100";
|
draw.style.opacity = "100";
|
||||||
|
|
||||||
countingDown = false;
|
countingDown = false;
|
||||||
|
// keep "DRAW" on screen for first second of the round
|
||||||
setTimeout(() => {draw.style.display = "none"; draw.style.opacity = "0"; }, 1000);
|
setTimeout(() => {draw.style.display = "none"; draw.style.opacity = "0"; }, 1000);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleHoverEnd(e) {
|
function handleHoverEnd(e) {
|
||||||
hovering = false;
|
hovering = false;
|
||||||
|
|
||||||
@@ -455,46 +577,80 @@
|
|||||||
|
|
||||||
draw.style.opacity = "0";
|
draw.style.opacity = "0";
|
||||||
|
|
||||||
if (currentRound <= 1) {
|
if (gamemode == "normal") {
|
||||||
drawTargetsInCircle();
|
if (currentRound <= 1) {
|
||||||
gameText.innerText = "hover on middle circle to start the countdown,\nthen click the targets as fast as possible!";
|
drawTargetsInCircle(0);
|
||||||
|
gameText.innerText = "hover on middle circle to start the countdown,\nthen click the targets as fast as possible!";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gameText.innerText = "ROUND: " + roundSeconds.toFixed(3) + "s\nTOTAL: " + totalTime.toFixed(3) + "s\nhover on circle to start round " + currentRound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
gameText.innerText = "ROUND: " + roundSeconds.toFixed(3) + "s\nTOTAL: " + totalTime.toFixed(3) + "s\nhover on circle to start round " + currentRound;
|
else if (gamemode == "countdown") {
|
||||||
|
drawTargetsInCircle(0);
|
||||||
|
gameText.innerText = "hover on middle circle to start the countdown,\nthen click as many targets as possible!";
|
||||||
}
|
}
|
||||||
|
|
||||||
gameText.style.display = "inline";
|
gameText.style.display = "inline";
|
||||||
countingDown = false;
|
countingDown = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTargetClick(e) {
|
function handleTargetClick(e) {
|
||||||
targetsClickedThisRound++;
|
targetsClicked++;
|
||||||
e.target.remove();
|
e.target.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePageResize(event) {
|
function handlePageResize(event) {
|
||||||
|
// take note if page was resized during animation or mid-countdown round to auto-reset at earliest convenience
|
||||||
|
if (!needsResizeAdjustment && (drawingCircle || countdownTime > 0)) {
|
||||||
|
needsResizeAdjustment = true; return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if no game has started yet, re-draw circle
|
||||||
|
*
|
||||||
|
* no matter what, if targets on screen, do not reset, do not redraw middle circle, but do flag for reset
|
||||||
|
*
|
||||||
|
* if adding eventListener, need to redraw center circle!
|
||||||
|
*
|
||||||
|
* if we are playing normal mode:
|
||||||
|
* -- if round 1, redraw cirlce and addEventListener for hover
|
||||||
|
* -- if round 2/3, only addEventListener for hover
|
||||||
|
* -- if round 4, only addEvenListener for reset
|
||||||
|
*
|
||||||
|
* if we are playing countdown mode:
|
||||||
|
* -- if countdownTimer == 0,
|
||||||
|
* ----- need a way to know if this is before or after the game!
|
||||||
|
* ----- if before game, redraw cirlce and addEventListener for hover
|
||||||
|
* ----- if after game, only addEventListener for reset
|
||||||
|
* -- if countdownTimer > 0, flag for reset upon next target clicked, no event listeners
|
||||||
|
**/
|
||||||
|
|
||||||
frameElement.replaceChildren();
|
frameElement.replaceChildren();
|
||||||
setParameters();
|
setParameters();
|
||||||
|
|
||||||
document.getElementById("center").remove();
|
center.remove();
|
||||||
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
|
center = generateTarget(xFrameAdjustment, yFrameAdjustment);
|
||||||
center.id = "center";
|
center.id = "center";
|
||||||
document.body.insertAdjacentElement("afterbegin", center);
|
document.body.insertAdjacentElement("afterbegin", center);
|
||||||
|
|
||||||
if (currentRound == 0 || (gamemode == "normal" && currentRound == 1)) {
|
if (gamemode == "") {
|
||||||
drawTargetsInCircle();
|
drawTargetsInCircle(0);
|
||||||
}
|
}
|
||||||
|
else if (gamemode != "") {
|
||||||
if (currentRound >= 1) {
|
|
||||||
center.addEventListener("mouseover", handleHoverStart);
|
center.addEventListener("mouseover", handleHoverStart);
|
||||||
center.addEventListener("mouseleave", handleHoverEnd);
|
center.addEventListener("mouseleave", handleHoverEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('page: ' + pageWidth + ' x ' + pageHeight);
|
console.log('page: ' + pageWidth + ' x ' + pageHeight);
|
||||||
console.log('frame: ' + frameWidth + ' x ' + frameHeight);
|
console.log('frame: ' + frameWidth + ' x ' + frameHeight);
|
||||||
|
needsResizeAdjustment = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function drawTargetsInCircle(drawDurationSeconds) {
|
async function drawTargetsInCircle(drawDurationSeconds) {
|
||||||
|
drawingCircle = true;
|
||||||
let r, x, y;
|
let r, x, y;
|
||||||
let radians;
|
let radians;
|
||||||
let target;
|
let target;
|
||||||
@@ -507,8 +663,55 @@
|
|||||||
target = generateTarget(x, y);
|
target = generateTarget(x, y);
|
||||||
document.getElementById("frame").insertAdjacentElement("afterbegin", target);
|
document.getElementById("frame").insertAdjacentElement("afterbegin", target);
|
||||||
|
|
||||||
if (drawDurationSeconds) await sleep((drawDurationSeconds * 1000) / 180);
|
if (drawDurationSeconds) {
|
||||||
|
target.classList.add("fade");
|
||||||
|
await sleep((drawDurationSeconds * 1000) / 180);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
drawingCircle = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// helpers for rendering main menu stuff
|
||||||
|
async function fadeMainMenuIn() {
|
||||||
|
title1.classList.remove("fade");
|
||||||
|
title2.classList.remove("fade");
|
||||||
|
|
||||||
|
// add main menu elements to DOM flow
|
||||||
|
titleContainer.style.display = "flex";
|
||||||
|
title1.style.display = "inline";
|
||||||
|
title2.style.display = "inline";
|
||||||
|
gameModes.style.display = "inline";
|
||||||
|
|
||||||
|
// make title elements actually visible
|
||||||
|
title1.style.opacity = "100";
|
||||||
|
await sleep(500);
|
||||||
|
title2.style.opacity = "100";
|
||||||
|
await sleep(1500);
|
||||||
|
|
||||||
|
// add fade class for when elements are removed
|
||||||
|
title1.classList.add("fade");
|
||||||
|
title2.classList.add("fade");
|
||||||
|
|
||||||
|
// fade in gamemodes
|
||||||
|
await sleep(500);
|
||||||
|
gameModes.style.opacity = "100";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fadeMainMenuOut() {
|
||||||
|
let targets = document.getElementsByClassName("target");
|
||||||
|
for (let i = 0; i < targets.length; i++) {
|
||||||
|
console.log(targets[i]);
|
||||||
|
targets[i].style.opacity = 0;
|
||||||
|
};
|
||||||
|
title1.style.opacity = "0";
|
||||||
|
title2.style.opacity = "0";
|
||||||
|
gameModes.style.opacity = "0";
|
||||||
|
await sleep(500);
|
||||||
|
titleContainer.style.display = "none";
|
||||||
|
gameModes.style.display = "none";
|
||||||
|
|
||||||
|
title1.style.display = "none";
|
||||||
|
title2.style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -517,7 +720,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// function to place a target somewhere random on the circle
|
// function to place a target somewhere random on the circle
|
||||||
function placeTarget(numTargets) {
|
function randomTargetGenerator(numTargets) {
|
||||||
let radians, radius
|
let radians, radius
|
||||||
let x, y;
|
let x, y;
|
||||||
let target;
|
let target;
|
||||||
|
|||||||
Reference in New Issue
Block a user