diff --git a/quickdraw-game.html b/quickdraw-game.html
index a2f92c1..bdb8737 100644
--- a/quickdraw-game.html
+++ b/quickdraw-game.html
@@ -90,14 +90,16 @@
margin-top: 2rem;
}
+ #game-over-buttons {
+ gap: 2rem;
+ align-items: center;
+ justify-content: center;
+ }
+
@media screen and (max-width: 750px) {
html {
font-size: 32px;
}
- #text-box {
- flex-direction: column;
- align-items: center;
- }
.text { font-size: .5rem; }
.title { font-size: 2rem; }
}
@@ -173,10 +175,10 @@
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;
// GAMEPLAY VARIABLES
let targetsClicked = 0;
+ let numTargets = 0;
// "NORMAL" MODE ONLY VARIABLES
let currentRound = 0;
@@ -187,6 +189,7 @@
let bestNormalTime = 0;
// "COUNTDOWN" MODE ONLY VARIABLES
+ let countdownBullseyeNeeded = false;
let countdownTime = 0;
let bestCountdownScore = 0;
@@ -257,8 +260,6 @@
}
async function handlePlayAgain(e) {
- gameIsOver = false;
-
// hide game over buttons
gameOverButtons.style.display = "none";
gameOverButtons.style.opacity = "0";
@@ -271,6 +272,10 @@
handleNormalMode(e);
}
else if (gamemode == "countdown") {
+ setParameters();
+ center = generateTarget(xFrameAdjustment, yFrameAdjustment);
+ center.id = "center";
+ document.body.insertAdjacentElement("afterbegin", center);
handleCountdownMode(e);
}
else {
@@ -280,7 +285,6 @@
async function handleNormalMode(e) {
gamemode = "normal";
- console.log("game mode: " + gamemode);
// setup mode parameters
currentRound = 1;
@@ -302,7 +306,7 @@
async function handleCountdownMode(e) {
gamemode = "countdown";
- console.log("game mode: " + gamemode);
+ countdownBullseyeNeeded = true;
await fadeMainMenuOut();
// set game instruction text + fade it in
@@ -318,7 +322,15 @@
}
async function handleReset(e) {
- gameIsOver = false;
+ // (bullseye won't be on screen after a countdown round)
+ if (gamemode == "countdown") {
+ setParameters();
+ center = generateTarget(xFrameAdjustment, yFrameAdjustment);
+ center.id = "center";
+ document.body.insertAdjacentElement("afterbegin", center);
+ }
+
+ // refresh game state variables
gamemode = "";
currentRound = 0;
@@ -334,6 +346,11 @@
await sleep(800);
await drawTargetsInCircle(2);
await fadeMainMenuIn();
+
+ // auto-reset bullseye if page was resized during animation
+ if (needsResizeAdjustment) {
+ handlePageResize();
+ }
}
async function handleHoverStart(e) {
@@ -366,32 +383,36 @@
// setup mode parameters
targetsClicked = 0;
- tempTargetsClicked = 0;
+ numTargets = 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";
+
+ // delay reveal of score until after "DRAW" fades
+ setTimeout(() => {
+ gameText.style.display = "inline";
+ gameText.style.opacity = "100";}, 1000);
// begin actual game loop!
randomTargetGenerator(1);
+ numTargets++;
+ countdownBullseyeNeeded = false;
while (countdownTime > 0.0) {
- gameText.innerText = countdownTime.toFixed(3) + "s\ntargets clicked: " + targetsClicked;
- // auto-reset screen if page was resized during animation
+ gameText.innerText = countdownTime.toFixed(2) + "s\ntargets clicked: " + targetsClicked;
+ // auto-reset target spawn paremeters if page was resized
if (needsResizeAdjustment) {
handlePageResize();
}
// generate new target if last one was clicked
- if (targetsClicked != tempTargetsClicked) {
+ if (targetsClicked == numTargets) {
randomTargetGenerator(1);
- tempTargetsClicked++;
+ numTargets++;
}
countdownTime = countdownTime - .01;
await sleep(10);
}
- gameIsOver = true;
// ensure no targets are still on screen after timer ends
frameElement.replaceChildren();
@@ -408,14 +429,11 @@
localStorage.setItem("bestCountdownScore", bestCountdownScore);
}
gameText.innerText = "TARGETS CLICKED: " + targetsClicked +
- "\nHIGH SCORE: " + bestCountdownScore +
- "\nhover on circle to go back to main menu..";
+ "\nHIGH SCORE: " + bestCountdownScore;
+
+ numTargets = 0;
+ targetsClicked =0;
- // 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";
}
@@ -432,7 +450,6 @@
return;
}
- let numTargets = 0;
if (roundNumber == 1) {
numTargets = 1;
}
@@ -459,10 +476,16 @@
currentRound++;
- // bring bullseye back to screen
- center = generateTarget(xFrameAdjustment, yFrameAdjustment);
- center.id = "center";
- document.body.insertAdjacentElement("afterbegin", center);
+ // auto-reset bullseye if page gets resized at all
+ if (needsResizeAdjustment) {
+ handlePageResize();
+ }
+ // even if no resize, bring bullseye back to screen
+ else {
+ center = generateTarget(xFrameAdjustment, yFrameAdjustment);
+ center.id = "center";
+ document.body.insertAdjacentElement("afterbegin", center);
+ }
// ensure "DRAW" isn't still lingering on screen after round
draw.style.display = "none";
@@ -470,7 +493,6 @@
if (roundNumber == 3) {
// GAME OVER STUFF
- gameIsOver = true;
if (totalTime < bestNormalTime || bestNormalTime == 0) {
if (bestNormalTime == 0) {
alert("NEW FASTEST TIME!!! congratulations cowboy.");
@@ -485,6 +507,9 @@
"s\nTOTAL: " + totalTime.toFixed(3) +
"s\nBEST SCORE: " + bestNormalTime.toFixed(3);
+ numTargets = 0;
+ targetsClicked =0;
+
gameOverButtons.style.display = "flex";
gameOverButtons.style.opacity = "100";
}
@@ -503,7 +528,7 @@
}
/**
- * HELPER TO KICK-OFF "NORMAL MODE" ROUNDS
+ * HELPER TO KICK-OFF COUNTDOWNS FROM HOVER
*/
async function normalModeRoundCountdown(hoverNumber) {
gameText.style.display = "none";
@@ -578,8 +603,7 @@
draw.style.opacity = "0";
if (gamemode == "normal") {
- if (currentRound <= 1) {
- drawTargetsInCircle(0);
+ if (currentRound == 1) {
gameText.innerText = "hover on middle circle to start the countdown,\nthen click the targets as fast as possible!";
}
else {
@@ -588,7 +612,6 @@
}
else if (gamemode == "countdown") {
- drawTargetsInCircle(0);
gameText.innerText = "hover on middle circle to start the countdown,\nthen click as many targets as possible!";
}
@@ -603,46 +626,40 @@
}
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;
+ // take note if page was resized during animation or mid gameplay to auto-reset at earliest convenience
+ if (drawingCircle || (targetsClicked < numTargets)) {
+ 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();
setParameters();
-
- center.remove();
- center = generateTarget(xFrameAdjustment, yFrameAdjustment);
- center.id = "center";
- document.body.insertAdjacentElement("afterbegin", center);
+ // if at main menu, resize bullseye
if (gamemode == "") {
+ center.remove();
+ center = generateTarget(xFrameAdjustment, yFrameAdjustment);
+ center.id = "center";
+ document.body.insertAdjacentElement("afterbegin", center);
drawTargetsInCircle(0);
}
- else if (gamemode != "") {
+ // if inbetween gameplay rounds, move middle circle and add game event listener
+ else if ((gamemode == "normal" && currentRound < 4) ||
+ (gamemode == "countdown" && countdownBullseyeNeeded)
+ ) {
+ center.remove();
+ center = generateTarget(xFrameAdjustment, yFrameAdjustment);
+ center.id = "center";
+ document.body.insertAdjacentElement("afterbegin", center);
center.addEventListener("mouseover", handleHoverStart);
center.addEventListener("mouseleave", handleHoverEnd);
}
+ else if (gamemode == "normal" && currentRound == 4) {
+ center.remove();
+ center = generateTarget(xFrameAdjustment, yFrameAdjustment);
+ center.id = "center";
+ document.body.insertAdjacentElement("afterbegin", center);
+ }
console.log('page: ' + pageWidth + ' x ' + pageHeight);
console.log('frame: ' + frameWidth + ' x ' + frameHeight);
@@ -661,6 +678,7 @@
y = (r * ratio * Math.sin(radians)) + yFrameAdjustment;
target = generateTarget(x, y);
+ target.classList.add("target");
document.getElementById("frame").insertAdjacentElement("afterbegin", target);
if (drawDurationSeconds) {
@@ -724,7 +742,7 @@
let radians, radius
let x, y;
let target;
- for (let i = 0; i < numTargets; i++){
+ for (let i = 0; i < numTargets; i++) {
radians = degreesToRadians(getRandomInt(0, 360));
radius = (frameWidth / 2) - (targetWidth / 2) - (gameBorderWidth * 2);
x = (radius * 1 * Math.cos(radians)) + xFrameAdjustment;
@@ -739,10 +757,8 @@
function generateTarget(x, y) {
const target = document.createElement("div");
- target.classList.add("target");
target.style.top = y +'px';
target.style.left = x + 'px';
- // console.log(target);
return target;
}