1803|2

26

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【平头哥RVB2601创意应用开发】9~11 游戏结束重新开始及优化代码等 [复制链接]

 

9、游戏结束重新开始

想要游戏结束后重新开始,就需要用一个变量去表示游戏状态:

int status=0;//初始状态为 0    游戏中 1    胜利 2 

同时,把游戏部分的lvgl部分提取为一个方法 :

void game_init(){
	for(int i=0;i<size;i++){
		objs[i].label=lv_label_create(lv_scr_act(), NULL);
		lv_obj_set_size(objs[i].label, 20, 20);
		lv_obj_add_style(objs[i].label, LV_LABEL_PART_MAIN, &style); 
		lv_label_set_text(objs[i].label, objs[i].name);
	}
}

把数据初始化提取为一个方法,以便于游戏结束后复用,也就是重新开始:

void game_start(){
		for(int i=0;i<size;i++){
			objs[i].x=20 + rand() % (128-80);
			objs[i].y=-1*(rand() % size)-30;
			objs[i].die=0;
			lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y);
		}

		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;
		}
		
		lv_label_set_text(text_gameover, "");
		
		score=0;
		looptime=0;
		enemy_go_home=0;
		lv_label_set_text_fmt(score_label,"%d " LV_SYMBOL_OK, score);
		lv_label_set_text_fmt(enemy_go_home_label,LV_SYMBOL_WARNING " %d", enemy_go_home);
		status=1;
	}

第一次执行:

game_init();
game_start();

当游戏结束后重新开始执行:

game_start();

在游戏的主循环里:

while (1) {
    lv_task_handler();
	if(status==1){
        // 游戏中的代码
	}
		
	if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)&&status==3) {
		// 重新开始游戏
		game_start();
	}
		
    aos_msleep(5);
    lv_tick_inc(1);
}

 

10、摩尔斯电码输入错误时重新计算长度

实际上并不需要判断对错。因为这里用的是超过一定时间就算输入,一旦输入,判断对错是用于游戏计分的。因此,对于重新计算输入的电码长度,就可以忽略了,也就是,对于输入后,只需要把输入清空就可以了。

if(nopress_time>30){
	// 判断是否击中代码区域开始
    ...
    // 判断是否击中代码区域结束

	strcpy(input,""); //强制把输入的摩尔斯电码情况
	lv_label_set_text(text_input,"");//输入效果清空
}

11、优化代码:

开机进入一个画面,之后通过按钮进入另外的画面。

static void gui_welcome_task(void *arg){
	lv_obj_t *title;
	lv_obj_t * btn_left;
	lv_obj_t * btn_right;

	void init_title(void){
		title = lv_label_create(lv_scr_act(), NULL);
//		lv_label_set_align(title, LV_LABEL_ALIGN_CENTER);不知道这个为什么不好使
		lv_obj_set_pos(title, 22, 10);
		lv_label_set_text(title,"Morse Code");	
	}
	
	void buttonInput(void){
		lv_obj_t * label;
		btn_left = lv_btn_create(lv_scr_act(), NULL);
		lv_obj_set_pos(btn_left, 0, 30);
		lv_obj_set_size(btn_left, 70, 30);
		label = lv_label_create(btn_left, NULL);
		lv_label_set_text(label,LV_SYMBOL_EDIT " Test");
	}
	
	void buttonGame(void){
		lv_obj_t * label;
		btn_right = lv_btn_create(lv_scr_act(), NULL);
		lv_obj_set_pos(btn_right, 60, 30);
		lv_obj_set_size(btn_right, 70, 30);
		label = lv_label_create(btn_right, NULL);
		lv_label_set_text(label,LV_SYMBOL_PLAY " Play");
	}
	
	void destroy (void){
		lv_obj_del(title);
		lv_obj_del(btn_left);
		lv_obj_del(btn_right);
		aos_task_exit(0);
	}
	
	init_title();
	buttonInput();
	buttonGame();
	
	while(1){
		lv_task_handler();
		if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)) {
			aos_task_new("gui", gui_game_task, NULL, 10 * 1024);
			destroy();
			break;
		}
		if(GPIO_PIN_LOW == csi_gpio_pin_read(&key2)) {
			aos_task_new("gui", gui_test_task, NULL, 10 * 1024);
			destroy();
			break;
		}
		aos_msleep(5);
        lv_tick_inc(1);
	}
}

可以发现,新增了一个用于自由输入练习的子task:

static void gui_test_task(void *arg){
	lv_obj_t *text;
	
	void textarea_create(void)
	{
		text = lv_textarea_create(lv_scr_act(), NULL);
		lv_obj_set_size(text, 128, 60);
		lv_obj_align(text, NULL, LV_ALIGN_CENTER, 0, 0);
		lv_textarea_set_text(text, "");
		lv_textarea_set_placeholder_text(text, "Morse Code");
	}
	
	void text_append(char* c){
		int len = strlen(input);
		for(int i=0;i<len;i++){
			lv_textarea_del_char(text);
		}
		lv_textarea_add_text(text, c);
		strcpy(input,"");
	}
	
	void check_input(void)
	{
		if(strcmp(input,".-")==0){
			text_append("A");
		}
		if(strcmp(input,"-...")==0){
			text_append("B");
		}
		if(strcmp(input,"-.-.")==0){
			text_append("C");
		}
		if(strcmp(input,"-..")==0){
			text_append("D");
		}
		if(strcmp(input,".")==0){
			text_append("E");
		}
		if(strcmp(input,"..-.")==0){
			text_append("F");
		}
		if(strcmp(input,"--.")==0){
			text_append("G");
		}
		if(strcmp(input,"....")==0){
			text_append("H");
		}
		if(strcmp(input,"..")==0){
			text_append("I");
		}
		if(strcmp(input,".---")==0){
			text_append("J");
		}
		if(strcmp(input,"-.-")==0){
			text_append("K");
		}
		if(strcmp(input,".-..")==0){
			text_append("L");
		}
		if(strcmp(input,"--")==0){
			text_append("M");
		}
		if(strcmp(input,"-.")==0){
			text_append("N");
		}
		if(strcmp(input,"---")==0){
			text_append("O");
		}
		if(strcmp(input,".--.")==0){
			text_append("P");
		}
		if(strcmp(input,"--.-")==0){
			text_append("Q");
		}
		if(strcmp(input,".-.")==0){
			text_append("R");
		}
		if(strcmp(input,"...")==0){
			text_append("S");
		}
		if(strcmp(input,"-")==0){
			text_append("T");
		}
		if(strcmp(input,"..-")==0){
			text_append("U");
		}
		if(strcmp(input,"...-")==0){
			text_append("V");
		}
		if(strcmp(input,".--")==0){
			text_append("W");
		}
		if(strcmp(input,"-..-")==0){
			text_append("X");
		}
		if(strcmp(input,"-.--")==0){
			text_append("Y");
		}
		if(strcmp(input,"--..")==0){
			text_append("Z");
		}
		if(strcmp(input,"-----")==0){
			text_append("0");
		}
		if(strcmp(input,".----")==0){
			text_append("1");
		}
		if(strcmp(input,"..---")==0){
			text_append("2");
		}
		if(strcmp(input,"...--")==0){
			text_append("3");
		}
		if(strcmp(input,"....-")==0){
			text_append("4");
		}
		if(strcmp(input,".....")==0){
			text_append("5");
		}
		if(strcmp(input,"-....")==0){
			text_append("6");
		}
		if(strcmp(input,"--...")==0){
			text_append("7");
		}
		if(strcmp(input,"---..")==0){
			text_append("8");
		}
		if(strcmp(input,"----.")==0){
			text_append("9");
		}
	}
	
	textarea_create();
	
    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(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();
				}
			}
			
			if(button1_pressed==1){
				nopress_time=0;
				
				printf("%d",time_for_pressed);
				//通过判断time_for_pressed的大小,得出是长按还是短按
				if(time_for_pressed>20){
					//长按
					printf("-");
					strcat(input,"-");
					lv_textarea_add_text(text,"-");
					
				}else{
					//短按
					printf(".");
					strcat(input,".");
					lv_textarea_add_text(text,".");
				}
				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_textarea_del_char(text);
			}
		}
		
        aos_msleep(5);
        lv_tick_inc(1);
    }
}

最后游戏部分全部代码:

static void gui_game_task(void *arg){
	static lv_style_t style;
	lv_style_init(&style);
	static int pad_width = 2;
	
	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, 2, 0);
	lv_obj_set_size(score_label, 128, 30);
	lv_style_set_bg_color(&style, LV_STATE_DEFAULT, LV_COLOR_BLUE);
	lv_style_set_text_color(&style, LV_STATE_DEFAULT, LV_COLOR_BLACK);
	
	// set padding
	lv_style_set_pad_left(&style,LV_STATE_DEFAULT,pad_width);
	lv_style_set_pad_right(&style,LV_STATE_DEFAULT,pad_width);
	lv_style_set_pad_top(&style,LV_STATE_DEFAULT,pad_width-1);
	lv_style_set_pad_bottom(&style,LV_STATE_DEFAULT,pad_width-1);
	
	lv_style_set_value_font(&style,LV_STATE_DEFAULT,LV_FONT_MONTSERRAT_12);
//	lv_style_set_text_font(&style, LV_STATE_DEFAULT,LV_FONT_MONTSERRAT_22  );
	lv_style_set_border_width(&style, LV_STATE_DEFAULT, 1);
	lv_style_set_radius(&style, LV_STATE_DEFAULT, 5);
    lv_style_set_border_color(&style, LV_STATE_DEFAULT, LV_COLOR_BLACK);
	
    
	
	lv_label_set_text_fmt(score_label,"%d" LV_SYMBOL_OK, 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, 95, 0);
	lv_obj_set_size(enemy_go_home_label, 30, 30);
	lv_label_set_text_fmt(enemy_go_home_label, LV_SYMBOL_WARNING " %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","----."},
	};
	
	void game_init(){
		for(int i=0;i<size;i++){
			objs[i].label=lv_label_create(lv_scr_act(), NULL);
			lv_obj_set_size(objs[i].label, 20, 20);
			lv_obj_add_style(objs[i].label, LV_LABEL_PART_MAIN, &style); 
			lv_label_set_text(objs[i].label, objs[i].name);
		}
	}
	
	void game_start(){
		for(int i=0;i<size;i++){
			objs[i].x=20 + rand() % (128-80);
			objs[i].y=-1*(rand() % size)-30;
			objs[i].die=0;
			lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y);
		}

		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;
		}
		
		lv_label_set_text(text_gameover, "");
		
		score=0;
		looptime=0;
		enemy_go_home=0;
		lv_label_set_text_fmt(score_label,"%d " LV_SYMBOL_OK, score);
		lv_label_set_text_fmt(enemy_go_home_label,LV_SYMBOL_WARNING " %d", enemy_go_home);
		status=1;
	}
	
	game_init();
	game_start();
	
    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, LV_SYMBOL_WARNING " %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(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)&&status==3) {
			//restart
			game_start();
		}
		
        if(GPIO_PIN_LOW == csi_gpio_pin_read(&key1)&&status==1) {
			//当低电平(按下时)
			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)&&status==1) {
			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){
									objs[i].die = 1;//标记被击中
									objs[i].y = 128;
									lv_obj_set_pos(objs[i].label, objs[i].x, objs[i].y);
									score++;
									lv_label_set_text_fmt(score_label,"%d " LV_SYMBOL_OK, 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)&&status==1) {
			if(button2_pressed==0){
				button2_pressed=1;
			}
			
		}
		if(GPIO_PIN_HIGH == csi_gpio_pin_read(&key2)&&status==1) {
			if(button2_pressed==1){
				printf("\n");
				button2_pressed=0;
				strcpy(input,"");
				lv_label_set_text(text_input,"");//输入效果清空
			}
		}
		
        aos_msleep(5);
        lv_tick_inc(1);
    }
}

 

最新回复

摩尔斯电码输入错误时重新计算长度,超过一定时间就算输入,一旦输入,判断对错是用于游戏计分的 那开始的长度是怎么计算的呢   详情 回复 发表于 2022-5-28 07:33
点赞 关注
 
 

回复
举报

6593

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

摩尔斯电码输入错误时重新计算长度,超过一定时间就算输入,一旦输入,判断对错是用于游戏计分的
那开始的长度是怎么计算的呢

点评

在objs(摩尔斯电码结构体数组)中遍历判断:strcmp(input,objs.code)==0  详情 回复 发表于 2022-5-31 15:16
 
 
 

回复

26

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
Jacktang 发表于 2022-5-28 07:33 摩尔斯电码输入错误时重新计算长度,超过一定时间就算输入,一旦输入,判断对错是用于游戏计分的 那开始的 ...

在objs(摩尔斯电码结构体数组)中遍历判断:strcmp(input,objs.code)==0

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表