2. November 2011
Gruppenarbeit: Dominik Stucky, Diego Martinez In der erste Aufgabe haben wir eine (Mac-) Tastatur aufgeschraubt und den Controller ausgebaut. Auf dem Controller befinden sich zwei Blöcke mit Anschlüssen, welche wir mit einem Kabel jeweils verbunden haben. Mittels “Reverse Engineering” konnten wir so den verschiedenen Kombinationen Buchstaben zuordnen. Hat man ein paar Kombinationen gefunden, kann man an diese nun eigene Controller wie Taster anbauen. Idee// AUFGABE 01: KEYBOARD HACK // Embodied Interaction Design Basics // Moritz Kemper, IAD Physical Computing Lab // ZHdK, 30/10/2011 //** //* PPGAME //* Ping Pong Bat as Interface and Game Controller //* Project by Dominik Stucky & Diego Martinez //* ZHdK VIAD 2011 //* //* INSTRUCTIONS //* Key 'm' sets a hit //* key 'n' removes a hit //* // libraries import ddf.minim.*; //import ddf.minim.analysis.*; import fullscreen.*; SoftFullScreen fs; AudioPlayer song; AudioPlayer ping; int maxHits = 100; int counterValid = 0; int counterWrong = 0; int counterMain = 0; int hitsWidth = 36; float numRows = 10; // number of rows float numCols = 6; // number of columns float marginSquare = 10; float hitsYStart; float hitsY; float hitsXStart; float hitsX; float colsValidWrong = 12; float hitsYwrongStart; float hitsYwrong; float hitsXwrongStart; float hitsXwrong; float hitsYvalidStart; float hitsYvalid; float hitsXvalidStart; float hitsXvalid; PImage b; ArrayList animationHits = new ArrayList(); // sets of values for animation void setup() // setup() routine { size(1024, 600); background(255); smooth(); frameRate(24); // Sound Minim minim = new Minim(this); song = minim.loadFile("mariosong.wav", 1024); song.loop(); song.play(); ping = minim.loadFile("wetbox_schritte_schuhe1.aiff", 1024); hitsXStart = (width-((hitsWidth+marginSquare)*numCols))/2 +marginSquare/2; hitsYStart = (height-((hitsWidth+marginSquare)*numRows))/2+marginSquare/2; hitsX = hitsXStart; hitsY = hitsYStart; hitsXwrongStart = marginSquare; hitsYwrongStart = hitsYStart; hitsXwrong = hitsXwrongStart; hitsYwrong = hitsYwrongStart; hitsXvalidStart = width - ((hitsWidth/2+marginSquare))*colsValidWrong; hitsYvalidStart = hitsYStart+marginSquare; hitsXvalid = hitsXvalidStart; hitsYvalid = hitsYvalidStart; b = loadImage("testblock.png"); for(int nr=1; nr<=numRows; nr++) { for(int nc=1; nc<=numCols; nc++) { //* INI HITS * hitsX = hitsXStart+(hitsWidth+marginSquare)*(nc-1); hitsY = hitsYStart+(hitsWidth+marginSquare)*(nr-1); animationHits.add(new AnimHit(hitsX, hitsY, false)); } } // fullscreen fs = new SoftFullScreen(this); // add (... ,1) to display on second display //fs.setShortcutsEnabled(true); // enable shortcut (cmd f) fs.enter(); } void draw() // Empty draw() to keep the programm running { background(10); hitsXwrong = hitsXwrongStart; hitsYwrong = hitsYwrongStart; //* background squares * for(int vnr=1; vnr<=counterWrong; vnr++) { //* INI HITS * pushStyle(); fill(102,0,0); noStroke(); rect(hitsXwrong, hitsYwrong, hitsWidth/2, hitsWidth/2); popStyle(); hitsXwrong+= (hitsWidth/2+marginSquare); if (vnr%colsValidWrong==0) { hitsXwrong = hitsXwrongStart; hitsYwrong+= (hitsWidth/2+marginSquare); } } pushMatrix(); rotate(radians(180)); translate(-1*width-hitsXvalidStart+marginSquare, -1*height-marginSquare); hitsXvalid = hitsXvalidStart; hitsYvalid = hitsYvalidStart; //* background squares * for(int vnr=1; vnr<=counterValid; vnr++) { //* INI HITS * pushStyle(); fill(0,102,0); noStroke(); rect(hitsXvalid, hitsYvalid, hitsWidth/2, hitsWidth/2); popStyle(); hitsXvalid+= (hitsWidth/2+marginSquare); if (vnr%colsValidWrong==0) { hitsXvalid = hitsXvalidStart; hitsYvalid+= (hitsWidth/2+marginSquare); } } popMatrix(); pushMatrix(); rotate(radians(180)); translate(-1*width, -1*height); //* background squares * for(int nr=1; nr<=numRows; nr++) { for(int nc=1; nc<=numCols; nc++) { //* INI HITS * hitsX = hitsXStart+(hitsWidth+marginSquare)*(nc-1); hitsY = hitsYStart+(hitsWidth+marginSquare)*(nr-1); pushStyle(); fill(26,26,26); strokeWeight(1); stroke(51,51,51); rect(hitsX, hitsY, hitsWidth, hitsWidth); popStyle(); } } //pushStyle(); for(int i=0; i<counterWrong; i++) { image(b, (width-(width/4))+(hitsWidth/2)+i*25, 0); } fill(255,0,0); noStroke(); popStyle();*/ //* HIT CIRCLE * for(int i=0; i<animationHits.size(); i++) { AnimHit animHit = (AnimHit)animationHits.get(i); animHit.update(); } popMatrix(); } void keyPressed() // Do something if a key is pressed (I/O) { switch(key) // Find out which key is pressed { case 'm': // VALID if (counterMain>=0 && counterMain<numCols*numRows) { counterValid++; // start animation AnimHit animHit = (AnimHit)animationHits.get(counterMain); animHit.valid=true; animHit.reset(); counterMain++; //println(counterMain + " :: " + animationHits.size()); //if(!ping.isPlaying()){ // ping.rewind(); // ping.play(); //} } break; case 'n': // INVALID if (counterMain>0 && counterMain<=numCols*numRows) { counterWrong++; counterMain--; // reset animation (set valid false) AnimHit animHit = (AnimHit)animationHits.get(counterMain); animHit.valid=false; animHit.reset(); //println(counterMain + " :: " + animationHits.size()); } break; } } // NOT YET IN USE void keyReleased() // Do something if a key is released (I/O) { switch(key) // Find out which key is released { case 'a': // Do something if 'a' is released break; case 'b': // Do something if 'b' is released break; } } // * CLASS AnimHit //* drawing and animation of hits class AnimHit { float radiusV, radiusN, x, y; float strW; boolean valid; boolean highlighted; // constructor AnimHit (float extX, float extY, boolean extValid) { x = extX; y = extY; valid = extValid; reset(); } // reset values void reset() { radiusV = 0; radiusN = 0; strW = 10; highlighted = false; } // update animation void update() { if (valid==true) { // draw rectangle pushStyle(); noStroke(); if (valid==true) { println(counterMain); fill(0,255,0); if (counterMain>=numCols*numRows) { if (highlighted==false) { fill(255,255,255); highlighted=true; } else { fill(0,255,0); highlighted=false; } } } else { //fill(255,0,0); } rect(x, y, hitsWidth, hitsWidth); popStyle(); } // draw hit animation if (strW>0.1) { if (valid==true) { radiusV += 10; strW*= 0.85; pushStyle(); noFill(); stroke(0,255,0); strokeWeight(strW); ellipse(x+(hitsWidth/2),y+(hitsWidth/2),radiusV,radiusV); popStyle(); } else { radiusN += 10; strW*= 0.85; pushStyle(); noFill(); stroke(204,0,0); strokeWeight(strW); ellipse(x+(hitsWidth/2),y+(hitsWidth/2),radiusN,radiusN); popStyle(); } } else { strokeWeight(0); } } }