续上篇:
W801学习笔记二十一:英语背单词学习应用——上
五、处理用户交互
由于英语也是采用了和唐诗一样的《三分钟限时挑战》《五十题竞速挑战》《零错误闯关挑战》,所以用户交互的逻辑和唐诗是一样的。所以,我们抽一个基类,让代码可以重用。
1、抽取基类
StudyBase
class StudyBase : public IScean
{
public:
StudyBase(){};
virtual ~StudyBase(){};
protected:
u8 gameMode=0;
u8 winMode=0;
u8 isFinished=0;
u16 correntCount =0;
u16 wrongCount = 0;
u32 totalTime=0;
u32 lastTotalTime=0;
//×○△□
const char *controlInfo="EXIT: 返回 SELECT: 重新开始";
const char *answerInfo="× 选择 ○ 选择 □ 选择 △ 选择";
u16 answerBGColor[4] = {DBLUE, DRED, DGREEN, BROWN };
void startPrepare();
void errorDelay(u8 t);
u8 checkFinish();
void showScore();
void showTime();
u8 answerTitle[4][8] = {
{0x20,0xA1,0xC1,0x20,0x25,0x73,0x20, 0x0}, // × %s ,
{0x20,0xA1,0xF0,0x20,0x25,0x73,0x20, 0x0},
{0x20,0xA1,0xF5,0x20,0x25,0x73,0x20, 0x0},
{0x20,0xA1,0xF7,0x20,0x25,0x73,0x20, 0x0}};
private:
DisplayOption optionScore = {FONT_SIZE_1516, YELLOW, BLACK, 0, 0};
DisplayOption optionCorrentCount = {FONT_SIZE_1516, GREEN, BLACK, 0, 0};
DisplayOption optionWrongCount = {FONT_SIZE_1516, RED, BLACK, 0, 0};
DisplayOption optionTime = {FONT_SIZE_1516, YELLOW, BLACK, 0, 0};
DisplayOption optionDeCount = {FONT_SIZE_3232, WHITE, DRED, 1, 0};
DisplayOption optionDelay = {FONT_SIZE_2424, WHITE, DRED, 0, 0};
void finish();
};
StudyBase.cpp
void StudyBase::errorDelay(u8 t){
for(;t>0;t--){
Display_String2(400, 50, &optionDelay," %d ",t);
tls_os_time_delay(1000);
}
Display_Fill_Rectangle2(400, 50, 80, 80, BLACK);
}
u8 StudyBase::checkFinish(){
switch (winMode) {
case 1:
if(totalTime > 180000) {
finish();
return 1;
}
break;
case 2:
if(correntCount+ wrongCount == 50) {
finish();
return 1;
}
break;
case 3:
if(wrongCount>0) {
finish();
return 1;
}
break;
}
return 0;
}
void StudyBase::finish(){
isFinished = 1;
show_status_info(controlInfo);
optionDeCount.backColor = DBLUE;
Display_String(Prepare_LOC, &optionDeCount, " 挑 战 结 束 ");
}
void StudyBase::showScore()
{
int score = correntCount* 60 - wrongCount * 20;
if(score<0 ) score =0;
Display_String2(10, 5, &optionScore, "得分: %06d ", score);
Display_String2(150, 5, &optionCorrentCount, "正确: %04d ", correntCount);
Display_String2(270, 5, &optionWrongCount, "错误: %04d ", wrongCount);
}
void StudyBase::showTime()
{
if(lastTotalTime == totalTime/1000){
return;
}
lastTotalTime = totalTime/1000;
if(winMode == 2)
Display_String2(400, 5, &optionTime, "%02d:%02d", ((180000- totalTime) / 1000) / 60, ((180000- totalTime) / 1000) % 60);
else
Display_String2(400, 5, &optionTime, "%02d:%02d", (totalTime / 1000) / 60, (totalTime / 1000) % 60);
}
2、继承基类
YingYu.h
typedef struct {
uint16_t question;
uint16_t answer[4];
uint8_t ans;
} EngQuestion;
class YingYu : public StudyBase
{
public:
YingYu();
~YingYu();
SceanResult tick(u32 ticks);
int scean_init(cJSON* param);
private:
EngQuestion *currentQuestion;
void start();
void createQuestion();
void createQuestionMode3();
void showQuetion();
void showAnswer();
void correct();
void wrong();
DisplayOption optionQuetion = {FONT_SIZE_2424, YELLOW, BLACK, 1, 1};
DisplayOption optionZY = {FONT_SIZE_2424, WHITE, BLACK, 1, 1};
DisplayOption optionAnswer[4] = {
{FONT_SIZE_1516, WHITE, answerBGColor[0], 0, 1},
{FONT_SIZE_1516, WHITE, answerBGColor[1], 0, 1},
{FONT_SIZE_1516, WHITE, answerBGColor[2], 0, 1},
{FONT_SIZE_1516, WHITE, answerBGColor[3], 0, 1}};
u16 Eng_Answer_LOC_X=20;
u16 Eng_Answer_LOC_Y[4] = {195,220,245,270};
char errEngWord[4][40];
unsigned char *DataBuff;
int YingYuCount;
};
3、完成实现
YingYu.cpp
int YingYu::scean_init(cJSON* param){
setKeyAdepterIntervalAll(200);
setKeyAdepterInterval(KEY_GPIO_A, 65535);
setKeyAdepterInterval(KEY_GPIO_B, 65535);
setKeyAdepterInterval(KEY_GPIO_C, 65535);
setKeyAdepterInterval(KEY_GPIO_D, 65535);
winMode= cJSON_GetObjectItem(param,"w")->valueint;
gameMode = cJSON_GetObjectItem(param,"m")->valueint;
printf("start chinese. winMode=%d, gameMode=%d.\n", winMode, gameMode);
fatfs_readFile(cJSON_GetObjectItem(param,"f")->valuestring, &DataBuff);
YingYuCount = DataBuff[12] | (DataBuff[13]<<8) | (DataBuff[14]<<16)| (DataBuff[15]<<24);
start();
return 0;
}
void YingYu::start(){
startPrepare();
show_status_info(answerInfo);
showScore();
createQuestion();
showQuetion();
}
看看效果: