首页 > 其他分享 >Hi3861 : 使用ssd1306玩贪吃蛇

Hi3861 : 使用ssd1306玩贪吃蛇

时间:2023-10-11 18:48:37浏览次数:38  
标签:head KEY Hi3861 贪吃蛇 key include vlt ssd1306

练手写了个贪吃蛇玩玩(

屏幕驱动库: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

相关文章

  • 【好玩】如何在github主页放一条贪吃蛇
    前言......
  • 【好玩】如何在github主页放一条贪吃蛇
    前言......
  • 贪吃蛇
    1、实现游戏背景首先是游戏界面是-个矩形框,雷要设置它在屏幕中的位置以及长宽,之后要设置贪吃蛇最外层的墙体,用双层线表示。最后要将游戏界面划分为一个个的正方形,并且设置正方形的边长。2、初始化对象“蛇”:首先对游戏对象进行分析:刚开始是一个正方形方格,我们需要设置这一正方......
  • NO.3 C语言实现贪吃蛇游戏(Linux)
     一、简易说明:实现了初步的游戏模型,可以玩,但有一些细节bug没有解决。用WASD控制方向  二、源代码+头文件1#include<stdio.h>2#include"snake.h"34567intmain(intargc,constchar*argv[])8{91011system("cl......
  • python贪吃蛇模块设计一(真正的游戏效果还未实现)
    importrandomimporttimeimportturtle#分数score=0#最高分heigh_score=0#移动延迟delay=0.2#创建屏幕window=turtle.Screen()#设置标题window.title("贪吃蛇")#背景颜色window.bgcolor("white")#窗口大小window.setup(width=600,height=600)#创建蛇head=t......
  • js 游戏编程:(平滑跟随算法+碰撞检测算法) 贪吃蛇
    相信大家都用c语言写过贪吃蛇吧!今天让我们来试试js写的贪吃蛇!<metaname="viewport"content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"/><style>@keyframesrot{0%{transform:rota......
  • 简单代码贪吃蛇
    #include<stdio.h>#include<stdlib.h>#include<stdbool.h>#include<Windows.h>#include<time.h>#include<conio.h>/*键盘输入获取*/boolgameOver;boolstop=false;boolhit=false;/*游戏的边框大小*/constintwidth=50;con......
  • Java学习之路--GUI编程--贪吃蛇小游戏
    贪吃蛇小游戏界面实现四步走1.定义数据2.面板里将数据画上去3.监听事件键盘事件packagecom.gui.snake;importjavax.swing.*;importjava.net.URL;//2023.3.28GUI编程--贪吃蛇小游戏的实现--数据中心(只有一堆图片的数据)--贪吃蛇各个部分的导入--图片文件夹有两种导入......
  • 如何使用javascript制作一个网页端3D贪吃蛇游戏(附源码)
    3D网页版贪吃蛇游戏!下面来具体讲一下如何实现。该游戏使用Hightopo的SDK制作,总共100多行代码,没有WebGL基础的同学们也可很快掌握。场景初始化首先,我们对页面进行初始化,包括初始化3D场景,设置地面网格,以及开启事件监听等。主要代码及注释如下:w=40;//网格间距m=20;//......
  • 20.贪吃蛇,GUI最后的项目
    总结:1.定义数据2.画上去3.监听事件键盘事件(动作)事件把一个大项目分成很多个小项目,依次完成小项目即可,掳清思虑路!packagesnake;importjavax.swing.*;//主界面,正常的游戏界面都应该在面板上publicclassStartGame{publicstaticvoidmain(String......