# 程式挑戰啦~~
###### 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);
}
```