xxxxxxxxxx
545
//variables for beat sequencer
let numRows = 6; // number of rows/instruments
let numCols = 17; // Number of steps in the sequence+1 for name
let grid = [];
let currentStep = 0;
let soundFiles = [];
let bpm = 120; // Beats per minute
let interval; // Time between steps
let instrumentNames= ["kick","snare", "open hat","closed hat",'crash','clap' ]
let isPlaying =false;
let PlayPauseButton;
let rowColors =[];
//variables for closet
let nextButton, backButton;
let clothesImages = [];
let currentImageIndex = 0;
let img; // Variable to store the loaded image
let compHighlight; // Variable storing highlighted computer image
let showDorm = false; // Flag to track whether to show the image or not
let showCloset =false;
let mainFont, numFont, computerFont;
let showCompHighlight = false;
let showClosetHighlight=false;
let showMenu = false; // Flag to track if the menu should be shown
let computerBackground;
let snake;
let fruit;
let gameState = 'start';
let currentView = 'menu';
function preload() {
img = loadImage('dormroomp.jpg'); // Load the image
mainFont = loadFont('MisterGrape.otf');
numFont = loadFont("crashingNumber.ttf");
computerFont=loadFont("computerFont.otf")
compHighlight = loadImage('comphighlight.jpg');
compback = loadImage("computerbackground.jpeg");
closetHighlight = loadImage("closetHighlight.jpg")
//closet images
clothesImages.push(loadImage("clothes1 Large.png"));
clothesImages.push(loadImage("clothes2 Large.png"));
clothesImages.push(loadImage("clothes3 Large.png"));
clothesImages.push(loadImage("clothes4 Large.png"));
clothesImages.push(loadImage("clothes5 Large.png"));
clothesImages.push(loadImage("clothes6 Large.png"));
clothesImages.push(loadImage("clothes7 Large.png"));
clothesImages.push(loadImage("clothes8 Large.png"));
clothesImages.push(loadImage("clothes9 Large.png"));
//sound files
soundFormats('mp3', 'wav');
soundFiles[0] = loadSound('kick_bip.wav'); // Kick drum
soundFiles[1] = loadSound('snare_bip.wav'); // Snare drum
soundFiles[2] = loadSound('open hat_bip.wav'); // open Hi-hat
soundFiles[3] = loadSound('closed hhat_bip.wav'); // closed Hi-hat
soundFiles[4] = loadSound('crash_bip.wav'); // open Hi-hat
soundFiles[5] = loadSound('clap_bip.wav'); // open Hi-hat
}
function setup() {
fullscreen(true);
createCanvas(850, 450);
snake = new Snake(20); // Initialize snake with grid size of 20
fruit = new Fruit(600, 600, 20); // Initialize fruit
// Create buttons for closet image cycling
nextButton = createButton('→');
backButton = createButton('←');
// Position buttons on each door of the closet
nextButton.position(355, 180); // Right door button
backButton.position(45, 180); // Left door button
// button size
nextButton.size(50, 20);
backButton.size(50, 20);
// Add functionality to the buttons
nextButton.mousePressed(showNextImage);
backButton.mousePressed(showPreviousImage);
nextButton.hide(); // Initially hide buttons until closet view is activated
backButton.hide();
//drummachine setup
// Initialize the grid properly in setup
for (let i = 0; i < numRows; i++) {
grid[i] = []; // Create a new row
for (let j = 0; j < numCols; j++) {
grid[i][j] = false; // Initialize each step as false (inactive)
}
}
rowColors = [
color(255, 100, 100), // Kick
color(100, 255, 100), // Snare
color(100, 100, 255), // Open hat
color(255, 255, 100), // Closed hat
color(255, 100, 255), // Crash
color(100, 255, 255) // Clap
];
interval = (60 / bpm) * 1000 / 4; // Divide by 4 for 16th notes
playPauseButton = createButton('Play');
playPauseButton.position(3, 320);
playPauseButton.mousePressed(togglePlayPause);
playPauseButton.hide();
}
function draw() {
print(mouseX, mouseY);
background(250, 249, 240); // Set the default background color
if (showMenu) {
// Handle views within the menu (menu or snake game)
if (currentView === 'menu') {
resizeCanvas(850, 450);
drawMenu(); // Show computer menu
} else if (currentView === 'snake') {
resizeCanvas(600, 600);
background(250, 249, 240);
frameRate(10);
drawSnakeGame(); // Run the Snake game
} else if (currentView === 'drumMachine') {
resizeCanvas(850, 350);
drawDrumMachine();
}
} else if (showCloset==true) {
resizeCanvas(450, 450);
drawCloset(); // Show the closet interaction when in 'closet' view
} else if (showDorm) {
resizeCanvas(850, 450);
drawDorm(); // Separate out drawing the dorm view
} else {
drawDoors();
}
}
// Function to draw the dorm room
function drawDorm() {
clear();
image(img, 0, 0, 850, 450);
if (showCompHighlight) {
image(compHighlight, 0, 0, 850, 450); // Display computer hover
} else if (showClosetHighlight) {
image(closetHighlight, 0, 0, 850, 450); // Display closet hover
}
// Handle hover detection
checkHoverOverComputer();
checkHoverOverCloset();
}
function drawDoors() {
//Main page text
textFont(mainFont);
textSize(80);
strokeWeight(5);
textAlign(CENTER);
text("Linus's Dorm experience",width/2,100);
rectMode(CENTER);
// Coordinates and dimensions for the doors
let middleDoorX = width - 400;
let doorY = height / 1.5;
let doorW = 150;
let doorH = 250;
// Middle Door (Interaction on hover)
if (mouseX > middleDoorX - doorW / 2 && mouseX < middleDoorX + doorW / 2 &&
mouseY > doorY - doorH / 2 && mouseY < doorY + doorH / 2) {
strokeWeight(5); // Thicker border on hover
} else {
strokeWeight(1); // Default stroke weight
}
// Draw the middle door
fill(20, 180, 190);
rect(middleDoorX, doorY, doorW, doorH);
fill(250);
rect(middleDoorX, height / 1.75, 50, 35);
circle(middleDoorX + 50, doorY + 15, 15);
fill(0);
textAlign(CENTER);
textFont(numFont);
textSize(20);
text('705', middleDoorX, (height / 1.75) + 5);
// Left and Right doors (Not interactive)
strokeWeight(1);
fill(20, 180, 190);
rect(width - 700, doorY, doorW, doorH);
rect(width - 100, doorY, doorW, doorH);
fill(250);
rect(width - 700, height / 1.75, 50, 35);
rect(width - 100, height / 1.75, 50, 35);
circle(width - 650, doorY + 15, 15);
circle(width - 50, doorY + 15, 15);
fill(0);
text('704', width - 700, (height / 1.75) + 5);
text('706', width - 100, (height / 1.75) + 5);
}
function drawMenu() {
background(50, 50, 50); // Change the background color for the menu
image(compback,0,0,width,height)
textFont(computerFont);
textSize(50);
fill(255);
textAlign(CENTER);
textSize(30);
text("Press 1: Open Drum Machine", width / 2, 150);
text("Press 2: Play Snake", width / 2, 250);
text("Press ESC to go back", width / 2, 350);
}
function drawSnakeGame() {
if (gameState === 'start') {
// Display start screen
fill(0);
textAlign(CENTER);
textSize(50);
text("Snake Game", 600 / 2, 600 / 4); // Game title
textSize(36);
text("Press ENTER to Start", 600/ 2 , 600/ 2); // Instructions to start
text("control using W A S D", 600/2, 600/2+100 )
}
else if (gameState === 'playing') {
if (gameActive) {
snake.update(); // Update the snake's position
snake.draw(); // Draw the snake
// Check if the snake eats the fruit
if (snake.x === fruit.x && snake.y === fruit.y) {
snake.grow(); // Make the snake grow
fruit.move(); // Move the fruit to a new position
}
fruit.draw(); // Draw the fruit
// Check if the game is over
if (gameOver()) {
gameState = 'gameOver'; // If game over, change state
}
}
}
else if (gameState === 'gameOver') {
// Display "Game Over" screen
fill(0);
textAlign(CENTER);
textSize(72);
text("Game Over", width / 2, height / 4); // Display "Game Over" text
textSize(60);
text(snake.body.length + 1, width / 2, height / 2); // Display the snake's length as score
textSize(36);
text("Press ENTER to Play Again", width / 2, height * 0.75); // Instructions to replay
}
}
function drawDrumMachine() {
background(200);
fill(0);
strokeWeight(1);
text("Select the instruments for each beat with your mouse", 120, 310);
// Draw the grid for the drum machine
for (let i = 0; i < numRows; i++) {
for (let j = 0; j < numCols + 1; j++) { // Adjust for extra column for instrument names
if (j === 0) {
// Draw instrument name in the first column
fill(250, 249, 240);
stroke(0);
rect(j * 50, i * 50, 50, 50); // Draw instrument name cell
fill(0);
textSize(10);
textAlign(CENTER, CENTER);
if (instrumentNames[i]) { // Check if instrument name exists
text(instrumentNames[i], j * 50 + 25, i * 50 + 25);
}
} else {
// Regular grid cells for beat steps
if (grid[i][j - 1]) { // Adjust column access for grid
fill(rowColors[i]); // Fill with the row color if the step is active
} else {
fill(250, 249, 240); // Fill with inactive color
}
// Highlight the current step
if (j - 1 === currentStep) {
stroke(255, 0, 0); // Red stroke for current step
} else {
stroke(0); // Default stroke
}
// Draw each cell
rect(j * 50, i * 50, 50, 50);
}
}
}
playPauseButton.show();
}
function drawCloset() {
background(250, 249, 240);
// Closet drawing
strokeWeight(3);
// Closet frame
rectMode(RADIUS);
fill(166, 138, 109);
rect(225, height - 250, 125, 150); // Closet body
// Closet doors
rectMode(CORNER);
fill(196, 164, 132);
rect(100, 343, 250, 75);
rect(110, 360, 230, 50); // Door base
// Closet top shelf
fill(192);
strokeWeight(0);
rect(100, 90, 250, 5);
// Closet handle
rectMode(CENTER);
strokeWeight(2);
fill(170, 127, 36);
rect(225, 385, 40, 5); // Handle
// Closet top design
fill(196, 164, 132);
quad(80, 23, 370, 23, 350, 50, 100, 50);
rectMode(CORNER);
strokeWeight(0);
fill(53, 33, 0);
rect(92, 36.5, 266, 5);
// Drawer details
strokeWeight(3);
quad(110, 420, 115, 450, 130, 450, 135, 420); // Left drawer
quad(340, 420, 335, 450, 320, 450, 315, 420); // Right drawer
// Closet sides
strokeWeight(3);
fill(196, 164, 132);
quad(345, 50, 415, 30, 415, 345, 345, 335); // Right side
quad(105, 50, 35, 30, 35, 345, 105, 335); // Left side
// Show the current image in the center of the closet
if (clothesImages[currentImageIndex]) {
imageMode(CENTER);
image(clothesImages[currentImageIndex], 225, 200, 150, 200); // Display image in the center
}
// Show the buttons for next/previous images when in closet view
nextButton.show();
backButton.show();
}
function showNextImage() {
currentImageIndex = (currentImageIndex + 1) % clothesImages.length;
}
function showPreviousImage() {
currentImageIndex = (currentImageIndex - 1 + clothesImages.length) % clothesImages.length;
}
function mousePressed() {
let middleDoorX = width - 400;
let doorY = height / 1.5;
let doorW = 150;
let doorH = 250;
// Check if the mouse is within the middle door to display the main room image
if (!showDorm && mouseX > middleDoorX - doorW / 2 && mouseX < middleDoorX + doorW / 2 &&
mouseY > doorY - doorH / 2 && mouseY < doorY + doorH / 2) {
showDorm = true; // Set flag to true to show the dorm room image
showCompHighlight = false; // Reset highlight to ensure no immediate transition to computer menu
return; // Exit the function after entering the dorm room
}
// Check if the user clicks on the computer only after dorm room is shown
if (showDorm && !showMenu && showCompHighlight) {
showMenu = true; // Show the menu when the user clicks on the computer
}
if (showDorm && showClosetHighlight) {
showCloset=true; // Switch to the closet view
}
if (currentView === 'drumMachine') {
let col = floor(mouseX / 50);
let row = floor(mouseY / 50);
if (col < numCols && row < numRows) {
grid[row][col] = !grid[row][col];
}
}
}
function keyPressed() {
if (keyCode === ESCAPE) {
if (currentView === 'snake' || currentView ==='drumMachine') {
currentView = 'menu'; // Go back to the computer menu from Snake
playPauseButton.hide();
} else if (showMenu) {
showMenu = false; // Close the menu if it is open
} else if (showCloset) {
// Exit closet and return to dorm
showCloset =false;
imageMode(CORNER)
showDorm=true;
nextButton.hide(); // Hide closet buttons
backButton.hide();
} else if (showDorm) {
// Exit dorm and return to doors
showDorm = false;
}
}
// Handle the computer menu view
if (showMenu) {
if (currentView === 'menu') {
if(key ==='1'){
currentView = 'drumMachine';
}
if (key === '2') {
currentView = 'snake'; // Switch to the Snake game when '2' is pressed
gameState='start';
}
}
if (currentView === 'snake') {
if (gameState === 'start' && keyCode === ENTER) {
// Start the Snake game when ENTER is pressed
resetGame();
gameState = 'playing';
}
if (gameState === 'gameOver' && keyCode === ENTER) {
// Replay the Snake game when ENTER is pressed on the game over screen
resetGame();
gameState = 'playing';
}
if (gameState === 'playing') {
snake.action(key); // Pass the key to the snake's action method
}
}
}
}
function gameOver() {
// Check if the snake goes out of bounds
if (snake.x < 0 || snake.x >= 600 || snake.y < 0 || snake.y >= 600) {
return true;
}
// Check if the snake runs into its own body
for (let i = 0; i < snake.body.length; i++) {
if (snake.x === snake.body[i][0] && snake.y === snake.body[i][1]) {
return true;
}
}
return false;
}
// Function to reset the Snake game
function resetGame() {
snake = new Snake(20); // Reset the snake object
fruit = new Fruit(600, 600, 20); // Reset the fruit object
gameActive = true; // Reactivate the game
}
// Function to check if the mouse is hovering over the computer area
function checkHoverOverComputer() {
let computerX = 344; // X coordinate of the c omputer
let computerY = 225; // Y coordinate of the computer
let computerW = 130; // Width of the computer area
let computerH = 93; // Height of the computer area
// Check if mouse is over the computer only when the user is in the dorm room and menu is not showing
if (showDorm && !showMenu && mouseX > computerX && mouseX < computerX + computerW &&
mouseY > computerY && mouseY < computerY + computerH) {
showCompHighlight = true; // Show the hover image
} else {
showCompHighlight = false; // Revert back to the main image
}
}
function checkHoverOverCloset() {
let closetX = 660; // X coordinate of the closet
let closetY = 90; // Y coordinate of the closet
let closetW = 140; // Width of the computer area
let closetH = 340; // Height of the computer area
// Check if mouse is over the computer only when the user is in the dorm room and menu is not showing
if (showDorm && mouseX > closetX && mouseX < closetX + closetW &&
mouseY > closetY && mouseY < closetY + closetH) {
showClosetHighlight = true; // Show the hover image
} else {
showClosetHighlight = false; // Revert back to the main image
}
}
//beat sequencer/drum machine functions
//function to play beat sequencer
function playStep() {
if (isPlaying && currentView === 'drumMachine') {
for (let i = 0; i < numRows; i++) {
if (grid[i][currentStep]) { // Ensure valid access to grid
if (soundFiles[i]) { // Check if soundFiles[i] exists
soundFiles[i].play();
} else {
console.log("Undefined sound file at index " + i);
}
}
}
currentStep = (currentStep + 1) % numCols; // Step to the next column
}
}
//function to toggle play pause of beat sequencer
function togglePlayPause() {
isPlaying = !isPlaying;
if (isPlaying) {
playPauseButton.html('Pause');
} else {
playPauseButton.html('Play');
}
}