xxxxxxxxxx
297
/*
Instructions:
- Press enter to load your text input
- Use Arrow keys Left and Right to move the paddle
- Use Arrow keys up and down to change the threshold
- Press r when webcam shows on canva
Text Rain Tutorial by Patt Vira
https://youtu.be/iIYYdYxAIAM
Interacting with DOM (text input) tutorial by Daniel Shiffman
https://www.youtube.com/watch?v=uNQSVU0IKec
Text Rain (Drawing w Webcam) by Patt Vira
https://www.youtube.com/watch?v=1GfKfjgf4cQ&t=914s
Feedback
- State machine with instructions for user
- Try to have somet parts work on time
*/
let myInput; // input box
let myText = ""; // stores input from user
let x0, y0; // original x and y coordinates of text
let txtSize = 100; // size of text
let font;
let myprompt =
"What is your personal rain today?\nWrite down your worries so we can catch them together.";
let myLetters = []; // initialize my letters as an empty array
let floatingLetters = [];
let video;
let cameraLetters = [];
let threshold = 0.6;
let myPaddle;
let myalpha = 0;
let score = 70;
let rainState = ""; // switch to start letter rain
let gameOverTimeout;
let showGameOverText = false; // Flag to control text display
let videoStart = false;
function preload() {
// load fonts and assign to variable
font = loadFont("assets/Basedone.ttf");
font2 = loadFont("assets/Monospace.otf");
}
function setup() {
createCanvas(600, 500);
video = createCapture(VIDEO);
video.hide();
myInput = createInput();
myInput.position(
width / 2 - myInput.width / 2,
height / 2 - myInput.height / 2
);
/* the .changed functions as a key control:
basically when you press ENTER,
the function loadLetters is called*/
myInput.changed(function () {
myText = myInput.value();
loadLetters();
loadFloatingLetters();
loadCameraLetters();
rainState = "float";
});
// make a paddle and assign initial position
myPaddle = new Paddle(width / 2, (height * 2) / 3);
print("Initial score:", score);
}
function draw() {
background(255);
print(rainState);
if (score <= 0) {
rainState = "gameOver";
wait(5000);
score = 1;
}
switch (rainState) {
case "": {
textFont(font2);
textSize(20);
text(myprompt, myprompt.length / 2, height / 2 - myInput.height - 10);
break;
}
case "float": {
// hide input textbox
myInput.hide();
// Handle floating letters
let allAboveThreshold = true; // Flag to check if all letters are above -50
for (let floatL of floatingLetters) {
floatL.floatUp();
floatL.display();
// If any letter is still below -50, flag to false
if (floatL.y >= -50) {
allAboveThreshold = false;
}
}
// If all letters are above -50, change state to "rain"
if (allAboveThreshold) {
// delete array
floatingLetters = null;
//start rain
rainState = "rain";
}
break;
}
case "rain": {
// for each letter
for (let i = 0; i < myLetters.length; i++) {
// update position
myLetters[i].update(
myPaddle.posX,
myPaddle.posY,
myPaddle.paddleW,
myPaddle.paddleH
);
// show letter
myLetters[i].display();
}
// Handle paddle
myPaddle.display(); // show paddle (rectangle)
myPaddle.move(); // move paddle (ARROW KEYS)
break;
}
case "gameOver": {
textSize(20);
if (showGameOverText) {
if (myalpha <= 255) {
myalpha++;
} else {
myalpha--;
}
fill(0, 0, 0, myalpha); // Use alpha for transparency
text("You can't catch every drop of rain", 100, height / 4);
text("but you can pause", 100, height / 4 + 40);
text("and let them fall one at a time", 100, height / 4 + 80);
// Change color for the word "SPACE"
fill(67, 207, 214, myalpha); // Change color
text("let the SPACE between drops", 100, height / 4 + 160);
// Reset color for the following text
fill(0, 0, 0, myalpha);
text("allow you to set", 100, height / 4 + 200);
text("the rhythm of rain", 100, height / 4 + 240);
}
break;
}
case "cameraText": {
if(videoStart)
{
image(video,0, 0, width, height); // Draw the video
filter(THRESHOLD, threshold);
}
for (let i = 0; i < cameraLetters.length; i++) {
cameraLetters[i].update();
cameraLetters[i].display();
}
break;
}
}
}
function loadLetters() {
letterIndex = 0;
for (let i = 0; i < myText.length; i++) {
if (myText[i] != " ") {
myLetters.push(new Letter(myText[i]));
letterIndex++;
}
}
for (let i = 0; i < myLetters.length; i++) {
print(myLetters[i].t);
}
print("letters loaded");
//rainState = "rain";
}
function loadFloatingLetters() {
// Get the x-position of the input box
let startX = myInput.x/2 ;
// Calculate the y-position
let startY = height / 2 - myInput.height / 2;
// Track the current x position for each letter
let currentX = startX;
for (let i = 0; i < myText.length; i++) {
let letter = myText[i];
// Calculate the width of the current letter
let letterWidth = textWidth(letter);
// Create new FloatingLetter at the current x and y positions
floatingLetters.push(new FloatingLetter(letter, currentX, startY));
// Update the currentX to the position for the next letter
currentX += letterWidth;
// Add spacing between letterS
currentX += 10;
}
print("floating letters loaded");
}
function loadCameraLetters() {
let letterIndex = 0;
for (let i = 0; i < myText.length; i++) {
if (myText[i] != " ") {
cameraLetters.push(
new CameraLetter(myText[i], (width / myText.length) * letterIndex)
);
letterIndex++;
}
}
print("camera letters loaded");
}
function wait(waitTime) {
if (!gameOverTimeout) {
gameOverTimeout = setTimeout(() => {
showGameOverText = true; // Show the game over text after the wait
gameOverTimeout = null; // Reset timeout reference
}, waitTime); // 5000 milliseconds = 5 seconds
}
}
function keyPressed() {
if (keyCode == UP_ARROW && threshold < 1) {
threshold += 0.05; // increase threshold
threshold = round(threshold * 100) / 100; // Round to two decimal places
print(threshold);
}
if (keyCode == DOWN_ARROW && threshold > 0) {
threshold -= 0.05; // increase threshold
threshold = round(threshold * 100) / 100; // Round to two decimal places
print(threshold);
}
// if spacebar pressed
if (keyCode == 32 && rainState !="" ) {
rainState = "cameraText";
videoStart = true;
}
if(key == "r"){
for (let i = 0; i < cameraLetters.length; i++) {
cameraLetters[i].falling = true;
}
}
}