【平头哥RVB2601创意应用开发】8 超过一定数量的字母没被击落,显示游戏结束
[复制链接]
超过一定数量的字母没有被击落而自然落下,则显示游戏结束。这其实就类似塔防。
为了实现这个功能,首先要设置一个变量,记录数量:
int enemy_go_home=0;
其次,还需要设置一个lvgl标签,用于显示有多少个字母掉落而没有被击落:
lv_obj_t *enemy_go_home_label = lv_label_create(lv_scr_act(), NULL);
lv_obj_set_pos(enemy_go_home_label, 80, 0);
lv_obj_set_size(enemy_go_home_label, 30, 30);
lv_label_set_text_fmt(enemy_go_home_label, "lost: %d", enemy_go_home);
那么,如何区分字母是否被击落呢?
很简单,在结构体里增加一个代表是否被击落的状态:
struct Obj{
char name[20];
char code[20];
lv_obj_t *label;
int x;
int y;
int die;//1代表被击落,0代表没有被击落
}
然后设置字母数组的时候,让die为0。
当字母被击落时,让die变为1:
for(int i=0;i<size;i++){
if("这里判断输入的摩尔电码是否等于数组中定义的摩尔电码符号"){
objs[i].die = 1;//如果是,就让die等于1
}
}
当然上面有个伪代码,就是为了让逻辑清晰,实际上代码是这样的:
for(int i=0;i<size;i++){
if(objs[i].die==0){//如果没有被击中(已被击落的就不去判断了)
if(objs[i].y>0 && objs[i].y<64){//在可视区间
if(strcmp(input,objs[i].code)==0){
lv_label_set_text(objs[i].label, "");
objs[i].die = 1;//标记被击中
score++;
lv_label_set_text_fmt(score_label, "score: %d", score);
}
}
}
}
之后,只要在让字母落下的循环中,让没有被击落的字母超过屏幕高度时,计数+1即可:
//如果没有被击中,而且落下去了
if(objs[i].y>64){
enemy_go_home+=1;
lv_label_set_text_fmt(enemy_go_home_label, "lost: %d", enemy_go_home);
objs[i].die=1;
}
然后,在主循环中,通过数量大于等于5个来实现游戏结束:
if(enemy_go_home>=5){
for(int i=0;i<size;i++){
lv_label_set_text(objs[i].label, "");
}
lv_label_set_text(text_gameover, "GameOver");
status = 3; //game over
}
以下是gui_game_task的全部代码:
static void gui_game_task(void *arg){
time_t t;
srand((unsigned) time(&t));
int looptime = 0;
int score=0;//分数初始为0
int status=0;//初始状态为 0 游戏中 1 胜利 2 失败 3
lv_obj_t *text_gameover = lv_label_create(lv_scr_act(), NULL);
lv_obj_set_pos(text_gameover, 28, 30);
lv_obj_set_size(text_gameover, 128, 60);
lv_label_set_text(text_gameover, "");
//输入的标签
lv_obj_t *text_input = lv_label_create(lv_scr_act(), NULL);
lv_obj_set_pos(text_input, 100, 50);
lv_obj_set_size(text_input, 80, 20);
lv_label_set_text(text_input, "");
lv_obj_t *score_label = lv_label_create(lv_scr_act(), NULL);
lv_obj_set_pos(score_label, 0, 0);
lv_obj_set_size(score_label, 128, 30);
lv_label_set_text_fmt(score_label, "score: %d", score);
int enemy_go_home=0;//没有被击落的字母就是敌人,这是敌人落下(家门口)的数量
// enemy go home count
lv_obj_t *enemy_go_home_label = lv_label_create(lv_scr_act(), NULL);
lv_obj_set_pos(enemy_go_home_label, 80, 0);
lv_obj_set_size(enemy_go_home_label, 30, 30);
lv_label_set_text_fmt(enemy_go_home_label, "lost: %d", enemy_go_home);
int size = 36;
struct Obj{
char name[20];
char code[20];
lv_obj_t *label;
int x;
int y;
int die;
}objs[36]={
{"A",".-"},
{"B","-..."},
{"C","-.-."},
{"D","-.."},
{"E","."},
{"F","..-."},
{"G","--."},
{"H","...."},
{"I",".."},
{"J",".---"},
{"K","-.-"},
{"L",".-.."},
{"M","--"},
{"N","-."},
{"O","---"},
{"P",".--."},
{"Q","--.-"},
{"R",".-."},
{"S","..."},
{"T","-"},
{"U","..-"},
{"V","...-"},
{"W",".--"},
{"X","-..-"},
{"Y","-.--"},
{"Z","--.."},
{"0","-----"},
{"1",".----"},
{"2","..---"},
{"3","...--"},
{"4","....-"},
{"5","....."},
{"6","-...."},
{"7","--..."},
{"8","---.."},
{"9","----."},
};
for(int i=0;i<size;i++){
objs[i].label=lv_label_create(lv_scr_act(), NULL);
objs[i].x=10 + rand() % (128-30);
objs[i].y=-1*(rand() % size)-30;
objs[i].die=0;
lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y);
lv_obj_set_size(objs[i].label, 20, 20);
lv_label_set_text(objs[i].label, objs[i].name);
}
for (int i = 0; i < size; ++i){
for (int j = i + 1; j < size; ++j){
if (objs[i].y < objs[j].y){
struct Obj temp = objs[i];
objs[i] = objs[j];
objs[j] = temp;
}
}
}
for(int i=0;i<size;i++){
objs[i].y=-1*30*i;
}
status=1;
while (1) {
/* Periodically call the lv_task handler.
* It could be done in a timer interrupt or an OS task too.*/
lv_task_handler();
if(status==1){
looptime+=1;
if(looptime % 10 ==0){
for(int i=0;i<size;i++){
if(objs[i].die==0){
objs[i].y+=1;
lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y);
//如果没有被击中,而且落下去了
if(objs[i].y>64){
enemy_go_home+=1;
lv_label_set_text_fmt(enemy_go_home_label, "lost: %d", enemy_go_home);
objs[i].die=1;
}
}
}
if(enemy_go_home>=5){
for(int i=0;i<size;i++){
lv_label_set_text(objs[i].label, "");
}
lv_label_set_text(text_gameover, "GameOver");
status = 3; //game over
}
// if(objs[size-1].y>64){
// lv_label_set_text(text_gameover, "GameOver");
// status = 3; //game over
// }
}
}
if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)) {
//当低电平(按下时)
if(button1_pressed==0){
// 如果button1的状态没有被按下,则设为按下
button1_pressed = 1;
}
if(button1_pressed==1){
//如果button1的状态是按下,则计时
time_for_pressed++;
}
}
if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key1)) {
if(button1_pressed==0){
nopress_time++;
if(nopress_time>30){
//check_input();
for(int i=0;i<size;i++){
//如果没有被击中
if(objs[i].die==0){
if(objs[i].y>0 && objs[i].y<64){
//在可视区间
if(strcmp(input,objs[i].code)==0){
lv_label_set_text(objs[i].label, "");
objs[i].die = 1;//标记被击中
score++;
lv_label_set_text_fmt(score_label, "score: %d", score);
}
}
}
}
strcpy(input,"");
lv_label_set_text(text_input,"");//输入效果清空
//check win
//if status == playing
if(score==size){
//status == "win"
}
}
}
if(button1_pressed==1){
nopress_time=0;
printf("%d",time_for_pressed);
//通过判断time_for_pressed的大小,得出是长按还是短按
if(time_for_pressed>20){
//长按
printf("-");
strcat(input,"-");
}else{
//短按
printf(".");
strcat(input,".");
}
lv_label_set_text(text_input,input);//输入效果
time_for_pressed=0;//恢复计数
button1_pressed = 0;
}
}
if(GPIO_PIN_LOW == csi_gpio_pin_read(&key2)) {
if(button2_pressed==0){
button2_pressed=1;
}
}
if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key2)) {
if(button2_pressed==1){
printf("\n");
button2_pressed=0;
strcpy(input,"");
lv_label_set_text(text_input,"");//输入效果清空
}
}
aos_msleep(5);
lv_tick_inc(1);
}
}
效果如下:
|