xxxxxxxxxx
243
let score = 0;
let notes = [];
let fsrThresholds = [130, 130, 130];
let serialInitialized = false;
let glowingDuration = 60;
let glowingFrames = 0;
let fsrValues = [0, 0, 0];
let resistorCooldowns = [0, 0, 0]; // resistor cooldown (in milliseconds)
const cooldownDuration = 120; // hit cooldown
let timer;
let timerDuration = 40; // game timer
let gameActive = true;
function setup() {
createCanvas(windowWidth, windowHeight);
print("Press f (possibly twice) to toggle fullscreen");
generateNotes();
startTimer();
}
function draw() {
background(20);
if (gameActive) {
displayNotes();
displayScore();
updateTimer();
checkHit();
} else {
displayGameOver();
}
// Update resistor cooldowns
for (let i = 0; i < resistorCooldowns.length; i++) {
resistorCooldowns[i] = max(0, resistorCooldowns[i] - deltaTime);
}
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
function keyPressed() {
if (!serialInitialized && key === ' ') {
setUpSerial();
serialInitialized = true;
}
if (gameActive) {
checkHit();
}
if (key === 'f') {
toggleFullscreen();
}
if (!gameActive && key === 'r') {
restartGame();
}
}
async function setUpSerial() {
noLoop();
await getPort();
serialActive = true;
runSerial();
loop();
}
function readSerial(value) {
fsrValues = split(value, ',');
checkHit();
}
async function writeSerial(msg) {
await writer.write(msg);
}
let glowingColor;
function displayNotes() {
for (let i = notes.length - 1; i >= 0; i--) {
let note = notes[i];
fill(note.color, 100);
ellipse(note.x, note.y, 100, 100);
if (glowingFrames > 0) {
glowingFrames--;
let alphaValue = map(glowingFrames, 0, glowingDuration, 150, 0);
glowingColor = color(random(255), random(255), random(255), alphaValue);
fill(glowingColor);
ellipse(note.x, note.y, 120, 120);
}
fill(255);
textSize(32);
textAlign(CENTER, CENTER);
text(note.number, note.x, note.y);
}
}
function displayScore() {
fill(255);
textSize(32);
textAlign(CENTER, TOP);
text('Score: ' + score, width / 2, 10);
}
function checkHit() {
for (let i = 0; i < fsrValues.length; i++) {
if (resistorCooldowns[i] <= 0) {
for (let j = notes.length - 1; j >= 0; j--) {
let note = notes[j];
if (fsrValues[i] > fsrThresholds[i] && !note.hit) {
let expectedNote = i + 1; // expected note based on resistor index
if (note.number === expectedNote) {
console.log("Hit detected for note " + expectedNote + "!");
score += 10;
glowingFrames = glowingDuration;
note.hit = true;
resistorCooldowns[i] = cooldownDuration; // set cooldown for the resistor
if (allNotesHit()) {
setTimeout(generateNotes, 1000); // wait for 1 second before generating new notes
}
break; // exit the loop once a hit is detected
}
}
}
}
}
// remove hit notes from the array
notes = notes.filter(note => !note.hit);
}
function allNotesHit() {
for (let j = 0; j < notes.length; j++) {
if (!notes[j].hit) {
return false;
}
}
return true;
}
function generateNotes() {
notes = [];
const maxAttempts = 100;
const minDistance = 120; // minimum distance between ellipses
for (let i = 1; i <= 3; i++) {
let attempt = 0;
let overlapping = true;
while (overlapping && attempt < maxAttempts) {
let note = {
x: random(width * 0.2, width * 0.8),
y: random(height * 0.2, height * 0.8),
number: Math.floor(random(1, 4)),
color: getColorForNumber(i),
hit: false,
};
// make sure notes do not appear on top of each other
overlapping = notes.some((existingNote) => dist(note.x, note.y, existingNote.x, existingNote.y) < minDistance);
if (!overlapping) {
notes.push(note);
}
attempt++;
}
}
}
function getColorForNumber(number) {
switch (number) {
case 1:
return color(255, 0, 0); // Red
case 2:
return color(0, 255, 0); // Green
case 3:
return color(0, 0, 255); // Blue
default:
return color(255);
}
}
// activate fullscreen - by Mang
function toggleFullscreen() {
let fs = fullscreen();
fullscreen(!fs);
}
function startTimer() {
timer = setInterval(() => {
timerDuration--;
if (timerDuration <= 0) {
endGame();
}
}, 1000);
}
function endGame() {
clearInterval(timer);
gameActive = false;
}
// game over screen
function displayGameOver() {
background(0);
fill(255);
textSize(48);
textAlign(CENTER, CENTER);
text('Game Over!', width / 2, height / 2 - 50);
text('Score: ' + score, width / 2, height / 2);
let ageText = '';
if (score < 350) {
ageText = 'Based on your reaction time, you are about 60 years old.';
} else if (score >= 350 && score < 400) {
ageText = 'Based on your reaction time, you are about 30 years old.';
} else {
ageText = 'Based on your reaction time, you are about 20 years old.';
}
text(ageText, width / 2, height / 2 + 50);
text('Press R to play again', width / 2, height / 2 + 100);
}
function updateTimer() {
fill(255);
textSize(32);
textAlign(CENTER, TOP);
text('Time: ' + timerDuration, width / 2, 50);
}
function restartGame() {
score = 0;
timerDuration = 40;
gameActive = true;
generateNotes();
startTimer();
}