// All STUDENT instructions are in this tab. // STUDENT AVATAR & any extra variables for it go in STUDENT tab unless otherwise noted. // This is due via D2L Assignment 3 at 11:59 PM Thursday November 10. // STUDENT 1 (10%) Copy your Avatar class (nothing else) into this tab and add constructor // calls in the setup function within this loop. //for (int i = avatars.length/2-2 ; i < avatars.length ; i++) { // // STUDENT 1 construct your avatars in this loop. //} // Test that your avatar displays and moves properly before STEP 2. // STUDENT 2 (10%) The constructor function should not need to change from Assignment 2. // There are no new argyuments. The MIDI instrument, channel, and other MIDI properties are // defined inside my Professor class and inside your class after it displays. // Class Professor is in tab Parson. Here are the MIDI data fields at the top of the class: //int ProfessorScaleStep = 0 ; //int ProfessorTimeDelaySlot = 0 ; //class Professor extends CollisionDetector { // /* The data fields store the state of the Avatar. */ // protected int legdist = 0 ; // You can initialize to a constant here. // int channel = 0 ; // int mypitch = 0 ; // float mydelay = 0 ; // float [] delaySeconds = {.1, .15, .25}; IGNORE THE DELAY // I stopped using the delay and swicthed to making sound upon collisions. // int instrument = 106 ; // http://midi.teragonaudio.com/tutr/gm.htm // and in the constructor code: //int [] myscale = scales[2]; // major scale //mypitch = myscale[ProfessorScaleStep] + 48 ; //// major scale, next note in scale, halfway up keyboard //ProfessorScaleStep = (ProfessorScaleStep + 1) % myscale.length ; //mydelay = delaySeconds[ProfessorTimeDelaySlot]; STUDENT IGORE DELAY //instrument += ProfessorTimeDelaySlot ; //ProfessorTimeDelaySlot = (ProfessorTimeDelaySlot + 1) % delaySeconds.length ; // I used two global variables ProfessorScaleStep and ProfessorTimeDelaySlot deined // just outside the class to vary the note (mypitch) instrument, and timing // (mydelay) for each newly constructed Professor object. Normally a Java "class static" // variable inside the class would have only 1 value shred by all objects of that class, // but the Processing framework disallows class static variables for framework // implementation reasons, so I put them outside the class. // Your Avatar MUST use channel 10 (I am using 0 and 1 and reserving the others), // a range of instruments away from my 106 and its neighbors (see // // http://midi.teragonaudio.com/tutr/gm.htm ) or explore with ConcentricCirclesInterval sketch. // STUDENT 3 (50%) All of my Professor's MIDI function calls are inside its move() function. // Note that detectCollisions() now returns a java.util.Set object containing // all of the colliding Avatar objects, if any, including bales of HayBale clovers. //Set colliders = detectCollisions(); //if (colliders.size() > 0) { // sendMIDI(ShortMessage.PROGRAM_CHANGE, channel, instrument, 0); // int volumeAdjust = 7 ; // sendMIDI(ShortMessage.CONTROL_CHANGE, channel, volumeAdjust, 127); // int balanceControl = 8 ; // int balanceLocation = int(constrain(map(myx, 0, width, 0, 127),0,127)); // 64 is centered in stereo field // sendMIDI(ShortMessage.CONTROL_CHANGE, channel, balanceControl, balanceLocation); // sendMIDI(ShortMessage.NOTE_ON, channel, mypitch, 127); // // See http://midi.teragonaudio.com/tech/midispec.htm //} //for (Avatar other : colliders) { // float probability = random(0, 100); // if (probability < 60) { // mow 60% of them // other.mow(); // } //} // 3a. CHANGE the probability if mow()ing a HayBale from 60% to something else. Play around with values. // 3b. Add a CONTROL_CHANGE MIDI effect that you can hear, see // http://midi.teragonaudio.com/tech/midispec.htm and experiment with ConcentricCirclesInterval sketch. // Take a listen to modulation wheel (controller 1) and chorus (controller 93) Note that unlike the // instrument numbers, these start at 0, i.e., mod wheel is 1, bank select is 0. Make it a mapped // function of y location relative to [0, height-1] or another avatar varying variable. // 3c. Add a second CONTROL_CHANGE MIDI effect that you can hear. Make it a mapped function // of z location relative to minimumZ and maximumZ or anotehr avara varying variable. // STUDENT 4 (30%) Make an exploding HayBale similar to a video I will post. Here is what I did for // the video: // 4a. changed this in HayBale's mow() function: // void mow() { // avatars[avatarsIndex] = null ; // hayBaleCount = constrain(hayBaleCount-1, 0, hayBaleCount); // // println("DEBUG hayBaleCount hayBaleMAX", hayBaleCount, hayBaleMax); // if (hayBaleCount == 0) { // sendMIDI(ShortMessage.NOTE_OFF, channel, pitch, 0); // } //} // TO THIS: //void mow() { // mowCounter += 1 ; //} // I also initialized the "int mowCounter = 0" code in the top of class HayBale. // You must define "int mowCounter = 0". // 4b. The move() function in HayBale now does the following pseudo-code: // If the mowCounter is greater than 0 // Add 1 to mowCounter // If mowCounter is greater than 50 // Do the steps previously in HayBaler.mow(), i.e., null this object's avatars[] entry // and send the NOTE_OFF // 4c. In HayBale.display, immediately after translate, if the mowCounter is greater than 0, // call scale with three arguments for X, Y, and Z, at least one of which is a function of // mowCounter, for example a multiple or division of mowCounter. Play with it to get a good // look & sound. // 4d. Make some kind of color change to HayBale.display() as it explodes. // This sketch shows: demoBox.setFill(color(0, 255, 0)); // https://faculty.kutztown.edu/parson/fall2022/CSC220FA2022DemoSome3D.txt // Hit 'T' and 't' to see mixture of the texture and fill.