# 程式挑戰啦~~ ###### tags: `創客社` 填入 ==\\\*Your Code Here*\\== 中的程式,依挖空程度分為三種難度: - 「一塊蛋糕啦」 - 「有點難」 - 「乾這是要我重新打喔」 複製貼上各自難度的Code~有問題盡量問!!解不出來也不用氣餒,就直接看解答~ -----> [解答!!!!](https://github.com/william0503tw/TFTGameConsole_Piano/blob/main/piano.ino) <----- #### 難度敘述: - 「一塊蛋糕啦」 : - 只需大概懂程式,挖掉像顏色、基本語法、class中的基本參數以及搭配滿滿的Hint,上下觀察即可看出解答 - **適用者**:快樂生活,且被期中周荼毒的可憐學子,深有同感,服用此可增加信心,延長益壽 - 難度: :star: :star: - 「有點難」: - 難上加難啦~,挖掉蠻多的,也沒Hint參考,但憑藉理解code原理可以打出解答 - **適用者**:想測試最近所學者,以及對遊戲機特性的人,那他很適合你,但跟「一塊蛋糕啦」有點難度落差 - 難度: :star: :star: :star2: :star2: - 「乾這是要我重新打喔」: - 好啦,基本上都不見了,但架構還存在40% - **適用者**: 夜晚難眠者,服用此配方後,一覺到天亮,為此,難度直接開到頂,直接把code挖到他老媽都認不出(建議搭配上次社課講義 - 難度: :star2: :star2: :star2: :star2: :star2: :star2: :star2: ==把你選擇難度的code貼在IDE中開改吧~== --- ## 難度「一塊蛋糕啦」 ```cpp= #include "config.h" #include <math.h> // Declare object tft(display) and ts(touch screen) Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); XPT2046_Touchscreen ts(TS_CS); // parameters for screen calibration float xCalC = 0.0, yCalC = 0.0; float xCalM = 0.0, yCalM = 0.0; // Piano has White note and black note // And below is the dimensions of them (pixel) const int8_t BlackNoteHeight = 120 ; const int8_t BlackNoteWidth = 30 ; const uint16_t WhiteNoteHeight = 240 ; const int8_t WhiteNoteWidth = 40 ; // Declare "BaseFreq" for calculate output frequency float BaseFreq = 261.6 ; //C4 class ScreenPoint { public: int16_t x; int16_t y; //Constructor take (x,y) as parameters ScreenPoint(int16_t xIn, int16_t yIn){ /* //////////Your Code Here//////////// Hint: Copy "xIn" into x, and copy "yIn" into y */ } }; ScreenPoint getScreenCoords(TS_Point p) { int16_t xCoord = round((p.x * xCalM) + xCalC); int16_t yCoord = round((p.y * yCalM) + yCalC); if(xCoord < 0) xCoord = 0; if(xCoord >= tft.width()) xCoord = tft.width() - 1; if(yCoord < 0) yCoord = 0; if(yCoord >= tft.height()) yCoord = tft.height() - 1; return(/*//Your Code Here////*/); //Hint: return type : ScreenPoint using its Constructor } void calibrateTouchScreen(){ TS_Point p; int16_t x1,y1,x2,y2; tft.fillScreen(ILI9341_BLACK); while(ts.touched()); tft.drawFastHLine(10,20,20,ILI9341_WHITE); tft.drawFastVLine(20,10,20,ILI9341_WHITE); while(!ts.touched()); p = ts.getPoint(); x1 = p.x; y1 = p.y; tft.drawFastHLine(10,20,20,ILI9341_BLACK); tft.drawFastVLine(20,10,20,ILI9341_BLACK); delay(500); while(ts.touched()); tft.drawFastHLine(tft.width() - 30,tft.height() - 20,20,/*//////Your Code Here//////*/); tft.drawFastVLine(tft.width() - 20,tft.height() - 30,20,/*//////Your Code Here//////*/); while(!ts.touched()); p = ts.getPoint(); x2 = p.x; y2 = p.y; tft.drawFastHLine(tft.width() - 30,tft.height() - 20,20,/*//////Your Code Here//////*/); tft.drawFastVLine(tft.width() - 20,tft.height() - 30,20,/*//////Your Code Here//////*/); int16_t xDist = tft.width() - 40; int16_t yDist = tft.height() - 40; xCalM = (float)xDist / (float)(x2 - x1); xCalC = 20.0 - ((float)x1 * xCalM); yCalM = (float)yDist / (float)(y2 - y1); yCalC = 20.0 - ((float)y1 * yCalM); } void drawPiano(){ tft.fillScreen(/*//////Your Code Here//////*/); int count = 0 ; bool t = 0 ; String note[9] = {"C","D","E","F","G","A","B","C"}; tft.setTextSize(2); tft.setTextColor(ILI9341_BLACK); for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ tft.drawFastVLine(i,0,tft.height(),/*//////Your Code Here//////*/); tft.setCursor(i + 15,210); //Print String "note" declare above tft.print(/*//////Your Code Here//////*/); } for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ if(count == 2 && !t){ count = 0 ; t = 1 ; continue; }else if(count == 3){ count = 0; t = 0 ; continue; } tft.fillRect(i + 25 ,/*///Your Code Here////*/ , BlackNoteWidth , BlackNoteHeight ,/*///Your Code Here///*/); count++; } } frequency void playNote(ScreenPoint p,int8_t shift){ bool isBlackPlayed = 0 ; // Black Notes bool t = 0 ; int count = 0 ; //For avoiding white notes for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ if(count == 2 && !t){ count = 0 ; t = 1 ; continue; }else if(count == 3){ count = 0; t = 0 ; continue; } if(p.x > i + 25 && p.x < i + 25 + BlackNoteWidth && p.y > 0 && p.y < BlackNoteHeight){ tone(/*//////Your Code Here//////*/,getPianoFreq('B',i / 40 , shift),100); isBlackPlayed = 1 ; } count++ ; } //White Notes //Enter the loop if the black notes aren't touched if(!isBlackPlayed){ for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ if(p.x > i && p.x < i + WhiteNoteWidth && p.y > 0 && p.y < WhiteNoteHeight){ tone(/*//////Your Code Here//////*/,getPianoFreq('W',i / 40 , shift),100); } } } } float getPianoFreq(char n,int p,int8_t shift){ if(n == 'B'){ /*//////Your Code Here//////*/(p){ case 0: p = 41 + shift; break; case 1: p = 43 + shift; break; case 3: p = 46 + shift; break; case 4: p = 48 + shift; break; case 5: p = 50 + shift; break; case 7: p = 53 + shift; break; } return pow(pow(2,0.0833333),p-49) * 440.0 ; }else if(n == 'W'){ /*//////Your C Here//////*/(p){ case 0: p = 40 + shift; break; case 1: p = 42 + shift; break; case 2: p = 44 + shift; break; case 3: p = 45 + shift; break; case 4: p = 47 + shift; break; case 5: p = 49 + shift; break; case 6: p = 51 + shift; break; case 7: p = 52 + shift; break; } return pow(pow(2,0.0833333),p-49) * 440.0 ; } } void printLevel(int shift){ tft.fillRect(2,2,22,22,/*//////Your Code Here//////*/); tft.setCursor(4,4); tft.setTextColor(/*//////Your Code Here//////*/); tft.setTextSize(2); tft.print(shift); } int8_t shift = 0 ; int level = 4 ; void setup() { Serial.begin(BUADRATE); //Avoid confronation between touchscreen and tft display pinMode(TS_CS, OUTPUT); digitalWrite(TS_CS, HIGH); pinMode(TFT_CS, OUTPUT); digitalWrite(TFT_CS, HIGH); //pinMode pinMode(buzzer, OUTPUT); //Button pinMode pinMode(UP,/*//////Your Code Here//////*/); pinMode(DOWN,/*//////Your Code Here//////*/); pinMode(RIGHT,/*//////Your Code Here//////*/); pinMode(LEFT,INPUT_PULLU); //tft display and touch screen initialization tft.begin(); tft.setRotation(ROTATION); tft.fillScreen(ILI9341_BLACK); ts.begin(); ts.setRotation(ROTATION); //touchscreen's calibration calibrateTouchScreen(); //500 ms delay for safety (optional) delay(500); //draw the piano drawPiano(); //print level printLevel(level); } void loop() { //If I did not touch the screen, the program would stuck in while loop. while(!ts.touched()){ if(digitalRead(RIGHT) == 0){ shift += 12 ; level += 1 ; printLevel(level); }else if(digitalRead(LEFT) == 0){ shift -= 12 ; level -= 1 ; printLevel(level); }; delay(300); }; ScreenPoint sp = getScreenCoords(ts.getPoint()); playNote(sp,shift); } ``` ## 難度「有點難」 ```cpp= #include "config.h" #include <math.h> // Declare object tft(display) and ts(touch screen) Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); XPT2046_Touchscreen ts(TS_CS); // parameters for screen calibration float xCalC = 0.0, yCalC = 0.0; float xCalM = 0.0, yCalM = 0.0; const int8_t BlackNoteHeight = 120 ; const int8_t BlackNoteWidth = 30 ; const uint16_t WhiteNoteHeight = 240 ; const int8_t WhiteNoteWidth = 40 ; float BaseFreq = 261.6 ; //C4 class ScreenPoint { public: int16_t x; int16_t y; ScreenPoint(int16_t xIn, int16_t yIn){ /*//////Your Code Here//////*/ }; }; ScreenPoint getScreenCoords(TS_Point p) { int16_t xCoord = round((p.x * xCalM) + xCalC); int16_t yCoord = round((p.y * yCalM) + yCalC); if(xCoord < 0) xCoord = 0; if(xCoord >= tft.width()) xCoord = tft.width() - 1; if(yCoord < 0) yCoord = 0; if(yCoord >= tft.height()) yCoord = tft.height() - 1; return(/*//Your Code Here////*/); //Hint: return type : ScreenPoint using its Constructor } void calibrateTouchScreen(){ TS_Point p; int16_t x1,y1,x2,y2; tft.fillScreen(ILI9341_BLACK); while(ts.touched()); tft.drawFastHLine(10,20,20,/*//Your Code Here////*/); tft.drawFastVLine(20,10,20,/*//Your Code Here////*/); while(!ts.touched()); p = ts.getPoint(); x1 = p.x; y1 = p.y; tft.drawFastHLine(10,20,20,/*//Your Code Here////*/); tft.drawFastVLine(20,10,20,/*//Your Code Here////*/); delay(500); while(ts.touched()); tft.drawFastHLine(tft.width() - 30,tft.height() - 20,20,/*//////Your Code Here//////*/); tft.drawFastVLine(tft.width() - 20,tft.height() - 30,20,/*//////Your Code Here//////*/); while(!ts.touched()); p = ts.getPoint(); x2 = p.x; y2 = p.y; tft.drawFastHLine(tft.width() - 30,tft.height() - 20,20,/*//////Your Code Here//////*/); tft.drawFastVLine(tft.width() - 20,tft.height() - 30,20,/*//////Your Code Here//////*/); int16_t xDist = tft.width() - 40; int16_t yDist = tft.height() - 40; xCalM = (float)xDist / (float)(x2 - x1); xCalC = 20.0 - ((float)x1 * xCalM); yCalM = (float)yDist / (float)(y2 - y1); yCalC = 20.0 - ((float)y1 * yCalM); } void drawPiano(){ tft.fillScreen(/*//////Your Code Here//////*/); int count = 0 ; bool t = 0 ; String note[9] = {"C","D","E","F","G","A","B","C"}; tft.setTextSize(2); tft.setTextColor(ILI9341_BLACK); for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ tft.drawFastVLine(i,0 , /*//Your Code Here////*/ , /*//////Your Code Here//////*/); tft.setCursor(i + 15,210); //Print String "note" declare above tft.print(/*//////Your Code Here//////*/); } for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ if(count == 2 && !t){ count = 0 ; t = 1 ; continue; }else if(count == 3){ count = 0; t = 0 ; continue; } tft.fillRect(i + 25 ,/*///Your Code Here////*/ , BlackNoteWidth , BlackNoteHeight ,/*///Your Code Here///*/); count++; } } void playNote(ScreenPoint p,int8_t shift){ bool isBlackPlayed = 0 ; // Black Notes bool t = 0 ; int count = 0 ; //For avoiding white notes for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ if(count == 2 && !t){ count = 0 ; t = 1 ; continue; }else if(count == 3){ count = 0; t = 0 ; continue; } if(p.x > i + 25 && p.x < i + 25 + BlackNoteWidth && p.y > 0 && p.y < BlackNoteHeight){ tone(/*//////Your Code Here//////*/,getPianoFreq('B',/*//Your Code Here////*/, shift),100); isBlackPlayed = 1 ; } count++ ; } //White Notes //Enter the loop if the black notes aren't touched if(!isBlackPlayed){ for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ if(p.x > i && p.x < i + WhiteNoteWidth && p.y > 0 && p.y < WhiteNoteHeight){ tone(/*//////Your Code Here//////*/,getPianoFreq('W',i, shift),100); } } } } float getPianoFreq(char n,int p,int8_t shift){ if(n == 'B'){ /*//////Your Code Here//////*/(p){ case 0: p = 41 + shift; break; case 1: p = 43 + shift; break; case 3: p = 46 + shift; break; case 4: p = 48 + shift; break; case 5: p = 50 + shift; break; case 7: p = 53 + shift; break; } return pow(pow(2,0.0833333),p-49) * 440.0 ; }else if(n == 'W'){ /*//////Your C Here//////*/(p){ case 0: p = 40 + shift; break; case 1: p = 42 + shift; break; case 2: p = 44 + shift; break; case 3: p = 45 + shift; break; case 4: p = 47 + shift; break; case 5: p = 49 + shift; break; case 6: p = 51 + shift; break; case 7: p = 52 + shift; break; } /*//Your Code Here////*/ pow(pow(2,0.0833333),p-49) * 440.0 ; } } void printLevel(int shift){ tft.fillRect(2,2,22,22,/*//////Your Code Here//////*/); tft.setCursor(4,4); tft.setTextColor(/*//////Your Code Here//////*/); tft.setTextSize(2); tft.print(shift); } int8_t shift = 0 ; int level = 4 ; void setup() { Serial.begin(BUADRATE); //Avoid confronation between touchscreen and tft display pinMode(TS_CS, OUTPUT); digitalWrite(TS_CS, /*//Your Code Here////*/); pinMode(TFT_CS, OUTPUT); digitalWrite(TFT_CS, /*//Your Code Here////*/); //pinMode pinMode(buzzer, OUTPUT); //Button pinMode pinMode(UP,/*//////Your Code Here//////*/); pinMode(DOWN,/*//////Your Code Here//////*/); pinMode(RIGHT,/*//////Your Code Here//////*/); pinMode(LEFT,INPUT_PULLU); //tft display and touch screen initialization tft.begin(); tft.setRotation(ROTATION); tft.fillScreen(ILI9341_BLACK); ts.begin(); ts.setRotation(ROTATION); //touchscreen's calibration calibrateTouchScreen(); //500 ms delay for safety (optional) delay(500); //draw the piano drawPiano(); //print level printLevel(level); } void loop() { //If I did not touch the screen, the program would stuck in while loop. while(/*//////Your Code Here//////*/){ if(/*//////Your Code Here//////*/){ //Right Button shift += 12 ; level += 1 ; printLevel(level); }else if(/*//////Your Code Here//////*/){ //Left Button shift -= 12 ; level -= 1 ; printLevel(level); }; delay(300); }; ScreenPoint sp = getScreenCoords(ts.getPoint()); playNote(sp,shift); } ``` ## 難度「乾這是要我重新打喔」 ```cpp= #include "config.h" #include <math.h> // Declare object tft(display) and ts(touch screen) Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); XPT2046_Touchscreen ts(TS_CS); // parameters for screen calibration float xCalC = 0.0, yCalC = 0.0; float xCalM = 0.0, yCalM = 0.0; const int8_t BlackNoteHeight = 120 ; const int8_t BlackNoteWidth = 30 ; const uint16_t WhiteNoteHeight = 240 ; const int8_t WhiteNoteWidth = 40 ; float BaseFreq = 261.6 ; //C4 class ScreenPoint { public: int16_t x; int16_t y; ScreenPoint(int16_t xIn, int16_t yIn){ /*//////Your Code Here//////*/ }; }; ScreenPoint getScreenCoords(TS_Point p) { //Transfer into calibrated coordinate /*//////Your Code Here//////*/ if(xCoord < 0) xCoord = 0; if(xCoord >= tft.width()) xCoord = tft.width() - 1; if(yCoord < 0) yCoord = 0; if(yCoord >= tft.height()) yCoord = tft.height() - 1; return(/*//Your Code Here////*/); //Hint: return type : ScreenPoint using its Constructor } void calibrateTouchScreen(){ /*//////Your Code Here//////*/ //加油 } void drawPiano(){ tft.fillScreen(/*//////Your Code Here//////*/); int count = 0 ; bool t = 0 ; String note[9] = {"C","D","E","F","G","A","B","C"}; tft.setTextSize(2); tft.setTextColor(ILI9341_BLACK); for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ tft.drawFastVLine(i,0 , /*//Your Code Here////*/ , /*//////Your Code Here//////*/); tft.setCursor(i + 15,210); //Print String "note" declare above tft.print(/*//////Your Code Here//////*/); } for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ if(/*//////Your Code Here//////*/){ count = 0 ; t = 1 ; continue; }else if(/*//////Your Code Here//////*/){ count = 0; t = 0 ; continue; } tft.fillRect(i + 25 ,/*///Your Code Here////*/ , BlackNoteWidth , BlackNoteHeight ,/*///Your Code Here///*/); count++; } } void playNote(ScreenPoint p,int8_t shift){ bool isBlackPlayed = /*//////Your Code Here//////*/ ; // Black Notes bool t = 0 ; int count = 0 ; //For avoiding white notes for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ if(/*//////Your Code Here//////*/){ count = 0 ; t = 1 ; continue; }else if(/*//////Your Code Here//////*/){ count = 0; t = 0 ; continue; } if(p.x > i + 25 && p.x < i + 25 + BlackNoteWidth && p.y > 0 && p.y < BlackNoteHeight){ tone(/*//////Your Code Here//////*/,getPianoFreq('B',/*//Your Code Here////*/, shift),100); isBlackPlayed = 1 ; } count++ ; } //White Notes //Enter the loop if the black notes aren't touched if(!isBlackPlayed){ for(int i = 0 ; i <= tft.width() ; i += tft.width() / 8){ if(/*//////Your Code Here//////*/){ tone(/*//////Your Code Here//////*/,getPianoFreq('W',i, shift),100); } } } } float getPianoFreq(char n,int p,int8_t shift){ if(/*//////Your Code Here//////*/){ /*//////Your Code Here//////*/(p){ case 0: p = 41 + shift; break; case 1: p = 43 + shift; break; case 3: p = 46 + shift; break; case 4: p = 48 + shift; break; case 5: p = 50 + shift; break; case 7: p = 53 + shift; break; } return pow(pow(2,0.0833333),p-49) * 440.0 ; }else if(/*//////Your Code Here//////*/){ /*//////Your Code Here//////*/(p){ case 0: p = 40 + shift; break; case 1: p = 42 + shift; break; case 2: p = 44 + shift; break; case 3: p = 45 + shift; break; case 4: p = 47 + shift; break; case 5: p = 49 + shift; break; case 6: p = 51 + shift; break; case 7: p = 52 + shift; break; } /*//Your Code Here////*/ pow(pow(2,0.0833333),p-49) * 440.0 ; } } void printLevel(int shift){ tft.fillRect(2,2,22,22,/*//////Your Code Here//////*/); tft.setCursor(4,4); tft.setTextColor(/*//////Your Code Here//////*/); tft.setTextSize(2); tft.print(shift); } int8_t shift = 0 ; int level = 4 ; void setup() { Serial.begin(BUADRATE); //Avoid confronation between touchscreen and tft display pinMode(TS_CS, OUTPUT); digitalWrite(TS_CS, /*//Your Code Here////*/); pinMode(TFT_CS, OUTPUT); digitalWrite(TFT_CS, /*//Your Code Here////*/); //pinMode pinMode(buzzer, OUTPUT); //Button pinMode pinMode(UP,/*//////Your Code Here//////*/); pinMode(DOWN,/*//////Your Code Here//////*/); pinMode(RIGHT,/*//////Your Code Here//////*/); pinMode(LEFT,INPUT_PULLU); //tft display and touch screen initialization tft.begin(); tft.setRotation(ROTATION); tft.fillScreen(ILI9341_BLACK); ts.begin(); ts.setRotation(ROTATION); //touchscreen's calibration calibrateTouchScreen(); //500 ms delay for safety (optional) delay(500); //draw the piano drawPiano(); //print level printLevel(level); } void loop() { //If I did not touch the screen, the program would stuck in while loop. while(/*//////Your Code Here//////*/){ if(/*//////Your Code Here//////*/){ //Right Button shift += 12 ; level += 1 ; printLevel(level); }else if(/*//////Your Code Here//////*/){ //Left Button shift -= 12 ; level -= 1 ; printLevel(level); }; delay(300); }; ScreenPoint sp = getScreenCoords(ts.getPoint()); playNote(sp,shift); } ```