练手写了个贪吃蛇玩玩(
屏幕驱动库:ssd1306 · 连志安/3861智能家居套件代码仓库 - 码云 - 开源中国 (gitee.com)
user键开始,S1向左,S2向右
#include <string.h> #include <stdio.h> #include <time.h> #include "ssd1306.h" #include "ssd1306_tests.h" #include "link.h" #include <unistd.h> #include <hi_types_base.h> #include <hi_io.h> #include <hi_early_debug.h> #include <hi_gpio.h> #include <hi_task.h> #include "ohos_init.h" #include "cmsis_os2.h" #include <hi_adc.h> #include <hi_stdlib.h> #include <hi_early_debug.h> #define KEY_EVENT_NONE 0 #define KEY_EVENT_S1 1 #define KEY_EVENT_S2 2 #define KEY_EVENT_S3 3 #define KEY_EVENT_S4 4 #define ADC_TEST_LENGTH 64 #define VLT_MIN 100 //--------------------------------------------------------------------------------// hi_u16 g_adc_buf[ADC_TEST_LENGTH] = {0}; int key_status = KEY_EVENT_NONE; char key_flg = 0; int get_key_event(void){ int tmp = key_status; key_status = KEY_EVENT_NONE; return tmp; } hi_void convert_to_voltage(hi_u32 data_len){ float vlt_max = 0; float vlt_min = VLT_MIN; float vlt_val = 0; //均值 hi_u16 vlt; for(hi_u32 i=0;i<data_len;i++){ vlt = g_adc_buf[i]; float voltage = (float)vlt * 1.8 * 4 /4096.0; //码字转化电压值 vlt_max = (voltage > vlt_max) ? voltage : vlt_max; vlt_min = (voltage < vlt_min) ? voltage : vlt_min; } //output // printf("vlt_min: %.3f , vlt_max: %.3f \n", vlt_min,vlt_max); vlt_val = (vlt_max + vlt_min) / 2.0; //根据电压识别按钮 if(vlt_val > 0.4 && vlt_val < 0.6){ //S1 if(key_flg == 0){ key_flg = 1; key_status = KEY_EVENT_S1; } } if(vlt_val > 0.8 && vlt_val < 1.1){ //S2 if(key_flg == 0){ key_flg = 1; key_status = KEY_EVENT_S2; } } if(vlt_val>0.01 && vlt_val < 0.3){ //USER if(key_flg == 0){ key_flg = 1; key_status = KEY_EVENT_S3; } } if(vlt_val > 3.0){ //NONE key_flg = 0; key_status = KEY_EVENT_NONE; } } void adc_read(void){ hi_u16 data; //清空数组 memset_s(g_adc_buf, sizeof(g_adc_buf), 0x0, sizeof(g_adc_buf)); //循环检查ADC数值 for(hi_u32 i=0;i<ADC_TEST_LENGTH;i++){ //读取adc数值,存在地址data hi_u32 ret = hi_adc_read( (hi_adc_channel_index)HI_ADC_CHANNEL_2, &data, HI_ADC_EQU_MODEL_1, HI_ADC_CUR_BAIS_DEFAULT, 0 ); //失败检查 if(ret != HI_ERR_SUCCESS){ printf("ADC read fail !\n"); return; } g_adc_buf[i] = data; } convert_to_voltage(ADC_TEST_LENGTH); } void key_Init(){ hi_u32 ret; (hi_void)hi_gpio_init(); //设置GPIO5复用功能 hi_io_set_func(HI_IO_NAME_GPIO_5, HI_IO_FUNC_GPIO_5_GPIO); //设置GPIO5方向 ret = hi_gpio_set_dir(HI_GPIO_IDX_5, HI_GPIO_DIR_IN); if(ret != HI_ERR_SUCCESS){ printf("===== ERROR ====== gpio -> hi_gpio_set_dir1 ret:%d\r\n", ret); return; } } void gameover(){ ssd1306_Fill(Black); ssd1306_SetCursor(38, 28); ssd1306_DrawString("Game Over!", Font_7x10, White); ssd1306_UpdateScreen(); } void init_map(void){ ssd1306_Fill(Black); //上下边界 for(int i=0;i<=127;i++){ ssd1306_DrawPixel(i,0,White); ssd1306_DrawPixel(i,63,White); } //左右边界 for(int i=1;i<63;i++){ ssd1306_DrawPixel(0,i,White); ssd1306_DrawPixel(127,i,White); } ssd1306_UpdateScreen(); } //检查是否在链表中 bool check(PNODE head, int x, int y){ PNODE p = head->pNext; while (p != NULL) { if(p->x==x && p->y==y) return 1; p = p->pNext; } return 0; } //随机数 void random(int* x,int* y) { time_t ts = time(NULL); srand(ts); *x=rand()%127+3; srand(ts*ts); *y=rand()%63+3; } void snake(void){ //蛇与地图初始化 init_map(); bool start = 0; int speed_key = 0; int item_x=20, item_y=10; //初始化道具位置 ssd1306_DrawPixel(item_x, item_y, White); int mo[][2] = {1,0,0,1,-1,0,0,-1}; int sp[] = {5000,2500,1250,750,350}; PNODE head = create_list(); insert_list(head, 2, 9, 10); insert_list(head, 3, 8, 10); insert_list(head, 4, 7, 10); insert_list(head, 5, 6, 10); insert_list(head, 6, 5, 10); PNODE p = head->pNext; while (p != NULL) { ssd1306_DrawPixel(p->x, p->y, White); p = p->pNext; } ssd1306_UpdateScreen(); int res=0; while(1){ //按钮控制 //读取ADC数值 adc_read(); //按键判断与输出 switch(get_key_event()){ case KEY_EVENT_NONE: {} break; case KEY_EVENT_S1: { res--; res=(res+4)%4; } break; case KEY_EVENT_S2: { res++; res%=4; } break; case KEY_EVENT_S3: { start=1; speed_key++; speed_key%=5; } break; } if(!start){ usleep(1); continue; } int x = head->pNext->x, y = head->pNext->y; //头部坐标 int hx=x+mo[res][0], hy=y+mo[res][1]; //头部新坐标 //检查头部是否越界或撞到自身 if(hx<0 || hx>127 || hy<0 || hy>63 || check(head, hx, hy)){ usleep(500000); return; } // 头部前进1 insert_list(head, 1, hx, hy); ssd1306_DrawPixel(hx, hy, White); //是否吃到道具 if(hx==item_x && hy==item_y){ //更新道具位置 while(check(head, item_x, item_y)){ random(&item_x, &item_y); } ssd1306_DrawPixel(item_x, item_y, White); } else{ //没吃到道具则删除尾部 int px,py; //尾部坐标 delete_list(head, length_list(head), &px, &py); ssd1306_DrawPixel(px, py, Black); } // 刷新 ssd1306_UpdateScreen(); usleep(sp[speed_key]); // traverse_list(head); } } void ssd1306_sanke() { ssd1306_Init(); key_Init(); while(1){ snake(); gameover(); HAL_Delay(2000); } }
标签:head,KEY,Hi3861,贪吃蛇,key,include,vlt,ssd1306 From: https://www.cnblogs.com/memo2586/p/17757890.html