xxxxxxxxxx
241
let serial; // Variable to hold the serial port object
let currentImage; // Variable to hold the currently displayed image
let welcomeImg, instImg, num1Img, num2Img, num3Img, congratsImg, wrongImg, timeupImg; // Variables to hold image objects
let dashValues = [0, 0, 0, 0]; // Initial values for the four dashes
let currentDashIndex = 0; // Index of the current dash being edited
let allowNumberSelection = false; // Flag to allow number selection using potentiometer
let numberSize = 48; // Variable to control the size of the displayed number
let numberColor = 255; // Variable to control the color of the displayed number (white)
let dashSymbol = '-'; // Symbol to represent the dash below the selected digit
let timerValue = 30; // Initial value for the tximer
let timerInterval; // Interval for updating the timer
let correctCodes = {
num1: 2379,
num2: 4940,
num3: 5441
};
let bgmSound, tickSound, winSound, errorSound;
function preload() {
// Load images
welcomeImg = loadImage('welcome.png');
instImg = loadImage('inst.png');
num1Img = loadImage('num1.png');
num2Img = loadImage('num2.png');
num3Img = loadImage('num3.png');
congratsImg = loadImage('congrats.png');
wrongImg = loadImage('wrong.png');
timeupImg = loadImage('timeup.png');
// Load sound effects
bgmSound = loadSound('bgm.mp3');
tickSound = loadSound('tick.mp3');
winSound = loadSound('win.mp3');
errorSound = loadSound('error.mp3');
}
function setup() {
createCanvas(1600, 900); // Create a canvas
serial = new p5.SerialPort(); // Create a new serial port object
serial.on('list', printList); // List available serial ports
serial.on('data', serialEvent); // Call serialEvent() when data is received
serial.open('/dev/tty.usbmodem1401'); // Open the serial port
currentImage = welcomeImg; // Set initial image to welcomeImg
// Start background music
bgmSound.loop();
}
function draw() {
background(220); // Clear the background
imageMode(CENTER); // Set image mode to center
// Display the current image at the center of the canvas
image(currentImage, width / 2, height / 2, width, height);
// Draw the dashes if applicable
if (allowNumberSelection && currentImage !== welcomeImg && currentImage !== instImg) {
drawDashes();
}
// Display the timer if applicable
if (currentImage === num1Img || currentImage === num2Img || currentImage === num3Img) {
displayTimer();
}
}
function drawDashes() {
// Display the values inside the dashes
textSize(numberSize);
textAlign(CENTER, CENTER);
let startX = width / 2 - (numberSize + 10) * 2; // Start X position for the first dash
for (let i = 0; i < dashValues.length; i++) {
if (i === currentDashIndex) {
fill(numberColor); // Set color for the digit
text(dashValues[i], startX + (numberSize + 10) * i, height - 50); // Draw the digit
fill(0); // Set color for the dash symbol
text(dashSymbol, startX + (numberSize + 10) * i, height - 25); // Draw the dash symbol below the digit
} else {
fill(numberColor);
text(dashValues[i], startX + (numberSize + 10) * i, height - 50);
}
}
}
function displayTimer() {
textSize(24);
textAlign(RIGHT, TOP);
fill(255); // Set color to white
text("Timer: " + timerValue + " Secs left", width - 10, 10); // Display the timer in top right corner
}
function serialEvent() {
let message = serial.readLine(); // Read the incoming serial data
if (message.includes("Button pressed!")) {
// Toggle between images based on currentImage
if (currentImage === welcomeImg) {
serial.write('0');
currentImage = instImg;
// Stop all other sounds and play bgm
stopAllSounds();
bgmSound.play();
// Reset the dashes to 0 when returning to welcomeImg
dashValues = [0, 0, 0, 0];
currentDashIndex = 0;
allowNumberSelection = false;
// Send signal to reset servo motor to 0 degrees
} else if (currentImage === instImg) {
allowNumberSelection = true; // Allow number selection using potentiometer
// Display a random number image
let randomIndex = int(random(1, 4)); // Generate a random index (1, 2, or 3)
switch (randomIndex) {
case 1:
currentImage = num1Img;
startTimer();
// Stop all other sounds and play tick
stopAllSounds();
tickSound.play();
break;
case 2:
currentImage = num2Img;
startTimer();
// Stop all other sounds and play tick
stopAllSounds();
tickSound.play();
break;
case 3:
currentImage = num3Img;
startTimer();
// Stop all other sounds and play tick
stopAllSounds();
tickSound.play();
break;
}
} else if (allowNumberSelection && (currentImage === num1Img || currentImage === num2Img || currentImage === num3Img)) {
currentDashIndex++; // Move to the next dash
if (currentDashIndex === dashValues.length) {
// All dashes have been edited, display the final number
displayResult();
}
} else if (currentImage === congratsImg || currentImage === wrongImg || currentImage === timeupImg) {
restartProject(); // Restart the project if the user clicks the button after displaying 'congrats.png', 'wrong.png', or 'timeup.png'
}
} else if (allowNumberSelection) {
let newValue = int(message); // Parse the message as an integer
if (!isNaN(newValue) && newValue >= 0 && newValue <= 9) {
// Ensure the value stays within the range 0-9
dashValues[currentDashIndex] = newValue;
}
// Check if the user tapped the button twice
if (message.includes("Button tapped!")) {
currentDashIndex++; // Move to the next dash
if (currentDashIndex === dashValues.length) {
// All dashes have been edited, display the final number
displayResult();
}
}
}
}
function displayResult() {
let finalNumber = parseInt(dashValues.join('')); // Convert dashes to a single number
let currentNumCode; // Variable to hold the correct code for the current image
// Determine the correct code based on the current image
if (currentImage === num1Img) {
currentNumCode = correctCodes.num1;
} else if (currentImage === num2Img) {
currentNumCode = correctCodes.num2;
} else if (currentImage === num3Img) {
currentNumCode = correctCodes.num3;
}
// Check if the final number matches the correct code
if (finalNumber === currentNumCode) {
currentImage = congratsImg; // Display 'congrats.png'
// Stop all other sounds and play win
stopAllSounds();
winSound.play();
// Send signal to turn servo motor to 90 degrees
serial.write('1');
} else {
currentImage = wrongImg; // Display 'wrong.png'
// Stop all other sounds and play error
stopAllSounds();
errorSound.play();
}
// Reset values for the next round
dashValues = [0, 0, 0, 0];
currentDashIndex = 0;
allowNumberSelection = false;
clearInterval(timerInterval); // Stop the timer
}
function startTimer() {
timerValue = 30; // Reset timer value to 30
clearInterval(timerInterval); // Clear any existing timer interval
timerInterval = setInterval(updateTimer, 1000); // Start the timer interval
}
function updateTimer() {
timerValue--; // Decrease timer value by 1
if (timerValue === 0) {
clearInterval(timerInterval); // Stop the timer when it reaches 0
displayTimeUp(); // Display 'timeup.png' when time runs out
}
}
function displayTimeUp() {
currentImage = timeupImg; // Display 'timeup.png'
// Stop all other sounds and play error
stopAllSounds();
errorSound.play();
}
function restartProject() {
currentImage = welcomeImg; // Restart the project from welcome.png
// Stop all other sounds and play bgm
stopAllSounds();
bgmSound.play();
}
function stopAllSounds() {
bgmSound.stop();
tickSound.stop();
winSound.stop();
errorSound.stop();
}
function printList(portList) {
for (let i = 0; i < portList.length; i++) {
print(i + " " + portList[i]);
}
}