1804 views|2 replies

26

Posts

0

Resources
The OP
 

[RVB2601 Creative Application Development] 9~11 Game End Restart and Optimize Code, etc. [Copy link]

 

9. Game over and restart

If you want to restart the game after it ends, you need to use a variable to represent the game state:

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

At the same time, extract the lvgl part of the game into a method:

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);
	}
}

Extract data initialization into a method so that it can be reused after the game ends, that is, restart:

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;
	}

First execution:

game_init();
game_start();

When the game is finished, restart the execution:

game_start();

In the main game loop:

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. Recalculate the length when the Morse code is entered incorrectly

In fact, there is no need to judge right or wrong. Because here, input is considered as input after a certain time. Once input, judging right or wrong is used for game scoring. Therefore, the recalculation of the input code length can be ignored, that is, after input, you only need to clear the input.

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

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

11. Optimize code:

Turn on the computer to enter one screen, and then press the button to enter another screen.

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);
	}
}

It can be found that a new subtask for free input practice has been added:

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);
    }
}

The final game code:

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);
    }
}

Latest reply

When the Morse code is entered incorrectly, the length is recalculated. If it exceeds a certain time, it is considered entered. Once entered, the judgment of right or wrong is used for game scoring. How is the initial length calculated?   Details Published on 2022-5-28 07:33
 
 

6593

Posts

0

Resources
2
 

When the Morse code is entered incorrectly, the length is recalculated. If it exceeds a certain time, it is considered entered. Once entered, the judgment of right or wrong is used for game scoring.
How is the initial length calculated?

Comments

Traverse and judge in objs (Morse code structure array): strcmp(input,objs.code)==0  Details Published on 2022-5-31 15:16
 
 
 

26

Posts

0

Resources
3
 
Jacktang posted on 2022-5-28 07:33 When the Morse code is entered incorrectly, the length is recalculated. If it exceeds a certain time, it is considered entered. Once entered, the judgment of right and wrong is used for game scoring...

Traverse and judge in objs (Morse code structure array): strcmp(input,objs.code)==0

 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list