xxxxxxxxxx
188
let angle = 0;
let visualizers = []; // Array to hold ShapeVisualizer instances
let oscillators = {}; // Object to hold active oscillators
let playingNotes = {}; // Track which notes are currently playing
let gameState = "start";
let notes = {
'A': 261.63, // C4
'S': 293.66, // D4
'D': 329.63, // E4
'F': 349.23, // F4
'G': 392.00, // G4
'H': 440.00, // A4
'J': 493.88, // B4
'K': 523.25, // C5
};
function setup() {
createCanvas(windowWidth, windowHeight);
colorMode(HSB, 360, 100, 100, 100);
noFill();
// Instantiate ShapeVisualizer objects for each position
let positions = [
[width * 0.5, height * 0.5],
[width * 0.25, height * 0.25],
[width * 0.75, height * 0.25],
[width * 0.25, height * 0.75],
[width * 0.75, height * 0.75]
];
for (let i = 0; i < positions.length; i++) {
visualizers.push(new ShapeVisualizer(positions[i][0], positions[i][1]));
}
}
function draw() {
if(gameState == "game"){
background(0, 0.1);
let newPositions = [
[width * 0.5, height * 0.5],
[width * 0.25, height * 0.25],
[width * 0.75, height * 0.25],
[width * 0.25, height * 0.75],
[width * 0.75, height * 0.75]
];
// Update each ShapeVisualizer with the new position
for (let i = 0; i < visualizers.length; i++) {
visualizers[i].updatePosition(newPositions[i][0], newPositions[i][1]);
}
let activeNotes = Object.keys(playingNotes).length;
let minSize = 1;
let maxSize = map(activeNotes, 0, Object.keys(notes).length, windowHeight / 10, windowHeight / 2);
let size = minSize + maxSize;
let alpha = map(activeNotes, 0, 7, 50, 255);
let weight = map(activeNotes, 0, 7, 0.5, 8);
angle += 0.05; // Increment angle for evolving noise values
// Call draw method on each visualizer
for (let i = 0; i < visualizers.length; i++) {
visualizers[i].draw(size, alpha, weight);
}
}
else{
background(0); // Black background for the start screen
fill(255); // White text
textSize(32);
textAlign(CENTER, CENTER);
text("Press ENTER to start experience", width / 2, height / 2);
}
}
class ShapeVisualizer {
constructor(x, y) {
this.x = x;
this.y = y;
}
draw(size, alpha, weight) {
strokeWeight(weight);
push();
translate(this.x, this.y);
beginShape();
for (let a = 0; a < TWO_PI; a += 0.02) {
let xoff = map(cos(a), -1, 1, 0, 5) + angle;
let yoff = map(sin(a), -1, 1, 0, 5) + angle;
let r = map(noise(xoff, yoff), 0, 1, size * 0.5, size);
let x = r * cos(a);
let y = r * sin(a);
let hue = (angle * 50) % 360;
stroke(hue, 100, 100, alpha);
vertex(x, y);
}
endShape(CLOSE);
pop();
}
updatePosition(newX, newY) {
this.x = newX;
this.y = newY;
}
}
// Keyboard interaction functions for playing notes and stopping sounds remain the same
function keyPressed() {
if(keyCode == ENTER && gameState == "start"){
gameState = "game";
background(0);
noFill();
}
if(gameState == "game"){
// Trigger fullscreen or play notes
if (key === ' ') {
let fs = fullscreen();
fullscreen(!fs);
return;
}
let noteFreq = notes[key.toUpperCase()];
if (noteFreq && !playingNotes[key]) {
let osc = new p5.Oscillator('sine');
osc.freq(noteFreq);
osc.start();
osc.amp(0.5);
oscillators[key] = osc;
playingNotes[key] = true;
}
if(key=="Q"){
stopAllSounds();
}
}
}
function keyReleased() {
if (gameState == "game"){
if (playingNotes[key] && oscillators[key]) {
let osc = oscillators[key];
osc.amp(0, 0.1); // Ramp down to silence before stopping
setTimeout(() => {
osc.stop();
osc.dispose();
delete oscillators[key];
delete playingNotes[key];
}, 100); // Allow some time for the amp to ramp down
}
}
}
// Use a specific key to stop all sounds, e.g., spacebar
function stopAllSounds() {
Object.keys(oscillators).forEach(key => {
let osc = oscillators[key];
osc.stop();
osc.dispose();
delete oscillators[key];
});
playingNotes = {}; // Clear the playing notes
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}