当前位置: 首页 > news >正文

【STM32单片机】贪吃蛇游戏设计

文章目录

  • 一、功能简介
  • 二、软件设计
  • 三、实验现象
  • 联系作者


一、功能简介

本项目使用STM32F103C8T6单片机控制器,使用IIC OLED模块、按键等。

主要功能:
系统运行后,OLED显示游戏界面,可通过K1-K4键控制蛇的方向,当蛇吃到食物,得分加1;K1左,K2右,K3上,K4下。


二、软件设计

/*
作者:嗨小易(QQ:3443792007)*/void GUI_Init()//界面初始化
{OLED_Clear();Snake_Init();Food();OLED_Refresh();	
}void GUI_Refresh(int map[32][12])//界面刷新
{int i,j,temp;for(i=0;i<32;i++){for(j=0;j<12;j++){temp=map[i][j];if(temp==2){Paint_Body(i,j);  }else if(temp==-2){Paint_Map(i,j);  }else if(temp==-1){Paint_Food(i,j);  }else if(temp==0){Paint_Clean(i,j);  } 		  }}OLED_Refresh();}void Creat_map(int map[32][12])//创建地图
{int i,j;for(i=0;i<12;i++){for(j=0;j<32;j++){if(i==0||i==11){map[j][i]=-2;}if(j==0||j==31){map[j][i]=-2;}}}
}
void Paint_Map(int x,int y)//绘制地图
{int i,j;for(i=4*y;i<4*y+4;i++)     {for(j=4*x;j<4*x+4;j++){OLED_DrawPoint(j,i+16); }}}void Paint_Head(int x,int y )//绘制蛇头
{int i,j;for(i=4*y;i<4*y+4;i++)     {for(j=4*x;j<4*x+4;j++){OLED_DrawPoint(j,i+16); }}
}void Paint_Food(int x,int y )//绘制食物
{int i,j;for(i=4*y;i<4*y+4;i++)     {for(j=4*x;j<4*x+4;j++){if(i==4*y+1||i==4*y+2){OLED_DrawPoint(j,i+16);  }if(j==4*x+1||j==4*x+2){OLED_DrawPoint(j,i+16);  } }}}
void Paint_Tail(int x,int y )//绘制尾巴
{int i,j;for(i=4*y;i<4*y+4;i++)     {for(j=4*x;j<4*x+4;j++){if(i==4*y+1||i==4*y+2){OLED_DrawPoint(j,i+16);  }if(j==4*x+1||j==4*x+2||j==4*x+3){OLED_DrawPoint(j,i+16);  } }}}
void Paint_Body(int x,int y )//绘制身体
{int i,j;for(i=4*y;i<4*y+4;i++)     {for(j=4*x;j<4*x+4;j++){if(i==4*y||i==4*y+3){OLED_DrawPoint(j,i+16);  }if(j==4*x||j==4*x+3){OLED_DrawPoint(j,i+16);  }}}
}
void Paint_Clean(int x,int y )//清除点
{int i,j;for(i=4*y;i<4*y+4;i++)     {for(j=4*x;j<4*x+4;j++){OLED_ClearPoint(j,i+16);  }}
}void Snake_Init()//蛇及食物初始化
{  int i;length=5;score=0;snake_Grid[0][0]=7;//x坐标,蛇头坐标snake_Grid[0][1]=5;//y坐标for(i=1;i<5;i++){snake_Grid[i][0]=snake_Grid[0][0]-i;snake_Grid[i][1]=snake_Grid[0][1];  //给刚开始的蛇身几个初始坐标}direction=RIGHT;Creat_map(map);
}void Move()//移动
{int i;map[snake_Grid[length-1][0]][snake_Grid[length-1][1]]=0;//清除尾巴if(eated)               //如果吃到了食物{length++;eated=false;        //设置为false,不然无限变长}for(i=length-1;i>0;i--)    //从尾巴开始,每一个点的位置等于它前面一个点的位置{snake_Grid[i][0]=snake_Grid[i-1][0];snake_Grid[i][1]=snake_Grid[i-1][1];}switch(direction){case UP:snake_Grid[0][1]--;break;case DOWN:snake_Grid[0][1]++;break;case LEFT:snake_Grid[0][0]--;break;case RIGHT:snake_Grid[0][0]++;break;}Grid_Bound();//坐标限定}
void drawSnake()            //画蛇
{int i,x,y;for(i=0;i<length;i++){x=snake_Grid[i][0];y=snake_Grid[i][1];map[x][y]=2;       }
}
void Get_Command()//获取键盘值
{int key=0;key=KEY_Scan(0);if(key){switch(key){case 1:if(direction!=RIGHT)         //上direction=LEFT;break;case 2:if(direction!=LEFT)           //下direction=RIGHT;break;case 3:if(direction!=DOWN)        //左direction=UP;break;case 4:if(direction!=UP)         //右direction=DOWN;break;}}
}void  Grid_Bound()//坐标限定
{if(snake_Grid[0][0]==31)snake_Grid[0][0]=1;else if(snake_Grid[0][0]==0)snake_Grid[0][0]=30;else if(snake_Grid[0][1]==11)snake_Grid[0][1]=1;else if(snake_Grid[0][1]==0)snake_Grid[0][1]=10;  }bool GameOver()//游戏结束
{bool isGameOver=false;int sx=snake_Grid[0][0],sy=snake_Grid[0][1],i;//蛇头坐标for(i=1; i<length; i++)    //判断有没有吃到自己{if(snake_Grid[i][0]==sx&&snake_Grid[i][1]==sy)isGameOver=true;}return isGameOver;
}int Chek(int i,int j)//检查地图空位
{if(map[i][j]!=0){return 0;}return 1;   //是空位就返回1
}void Food()//生成食物
{int i,j;do{i=rand()%30;                 //生成0~H-1之间的一个数j=rand()%10;}while(Chek(i,j)==0);map[i][j]=-1;//画出食物
}void Eat_Food()//吃食物
{if(map[snake_Grid[0][0]][snake_Grid[0][1]]==-1) //如果蛇头碰到食物,就重新投放食物,并且把食物点重置为0{eated=true;            //标记已经吃到食物score+=1;Food();map[snake_Grid[0][0]][snake_Grid[0][1]]=0;  //去掉食物}
}void Show_Score()//显示分数
{OLED_ShowString(30,0,"Score:",16);OLED_ShowNum(80,0,score,2,16);}

三、实验现象

B站演示视频:https://space.bilibili.com/444388619
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


联系作者

专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。

相关文章:

【STM32单片机】贪吃蛇游戏设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用STM32F103C8T6单片机控制器&#xff0c;使用IIC OLED模块、按键等。 主要功能&#xff1a; 系统运行后&#xff0c;OLED显示游戏界面&#xff0c;可通过K1-K4键控制蛇的方向&#xff0c;当蛇吃…...

【Java 基础】32 定时调度

文章目录 Timer 类创建 Timer注意事项 ScheduledExecutorService 接口创建 ScheduledExecutorService注意事项 选择合适的定时调度方式Timer 的适用场景ScheduledExecutorService 的适用场景 总结 在软件开发中&#xff0c;定时任务是一种常见的需求&#xff0c;用于周期性地执…...

C++ 教程 - 02 复合数据类型

文章目录 数组vector字符串输入输出结构体枚举指针引用综合案例 数组 相同类型的数据的集合{ }&#xff0c;通过索引访问元素&#xff1b;在内存中连续存储&#xff0c;属于顺序表&#xff1b;插入、删除时间复杂度 O ( n ) O(n) O(n)&#xff0c;访问复杂度 O ( 1 ) O(1) O(1…...

【数据处理】NumPy数组的合并操作,如何将numpy数组进行合并?

&#xff0c;NumPy中的合并操作是指将两个或多个数组合并成一个数组的操作。这种操作可以通过不同的函数来实现。 一、横向合并&#xff08;水平合并&#xff09; 横向合并是指将两个具有相同行数的数组按列方向合并成一个数组的操作。在NumPy中&#xff0c;可以使用hstack()…...

JavaScript实现飘窗功能

实现飘窗功能很简单 html代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title…...

Docker笔记:容器转换成镜像,导出导入镜像,数据拷贝,查看日志

docker commit 将容器转换成镜像 可以把容器转换成镜像镜像没有写入权限&#xff0c;但可以通过修改容器把容器制作成新镜像启动容器后&#xff0c;就给容器提供了一个可写层&#xff0c; 在容器里&#xff0c;可安装软件&#xff0c;可创建文件 …转换成镜像&#xff0c;之后…...

串行计时芯片D1380/D1381,2.0V~5.5V 工作电流: 2V时 与TTL 兼容,采用DIP8、SOP8封装

D1380/D1381是一个带秒、分、时、日、日期、月、年的串行时钟保持芯片,每个月多少天以及闰年能自动调节, D1380/D1381低功耗工作方式, D1380/D1381用若干寄存器存储对应信息&#xff0c;一个32.768kHz 的晶振校准时钟&#xff0c;为了使用最小弓|脚&#xff0c;D1380/D1381使用…...

中间件系列 - Redis入门到实战(基础篇)

前言 1.学习视频&#xff1a; 黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目 2. 本内容仅用于个人学习笔记&#xff0c;如有侵扰&#xff0c;联系删除 3. 本章学习目标&#xff1a; 初始Redis 认识NoSQL认识Redi…...

项目经理和产品经理该如何选择?

最近很多人咨询“项目经理跟产品经理该怎么选&#xff0c;我更适合哪个&#xff1f;”“项目经理跟产品经理哪个更有钱途 ”“项目经理转产品经理好转吗”等等&#xff0c;今天就一次性说清楚项目经理跟产品经理有什么区别&#xff0c;应该怎么选择。 不想看长篇大论的&#x…...

java WebSocket带参数处理使用

1、webSocket实现代码 Component public class WebSocketStompConfig {//这个bean的注册,用于扫描带有ServerEndpoint的注解成为websocket// ,如果你使用外置的tomcat就不需要该配置文件Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpoi…...

OkHttp: 拦截器和事件监听器

文章目录 1. 拦截器1. 拦截器链2. 实际案例1. 注册为应用拦截器2. 注册为网络拦截器 3. 如何选择用哪种拦截器1. 应用拦截器2. 网络层拦截器3. 重写请求4. 重写响应 4. 可用性 2. 事件监听器1. 请求的生命周期2. EventListener使用案例3. EventListener.Factory4. 调用失败的请…...

总结一些vue3小知识2

1.el-tree-select和el-tree组件报错&#xff08;有的下拉选项选择不了&#xff0c;一点击就报错&#xff0c;但是有的却能选择&#xff0c;不会报错&#xff09; 原因:就如同v-for一样&#xff0c;需要添加key才不会出现渲染错误&#xff0c;而el-tree-select和el-tree组件需要…...

【Excel设置动态图表】

设置系列&#xff0c;设置水平轴标签。 效果如图&#xff1a; 经验总结&#xff1a; 方法1&#xff1a;如果设置A、B列为水平轴标签&#xff0c;目前无法设置只是日期为横轴&#xff0c;店铺名称只在最下面显示一个&#xff0c;只能并排1列显示。 优点&#xff1a;如果多选…...

用 C 写一个卷积神经网络

用 C 写一个卷积神经网络 深度学习领域最近发展很快&#xff0c;前一段时间读transformer论文《Attention Is All You Need》时&#xff0c;被一些神经网络和深度学习的概念搞得云里雾里&#xff0c;其实也根本没读懂。发现深度学习和传统的软件开发工程领域的差别挺大&#xf…...

直面双碳目标,优维科技携手奥意建筑打造绿色低碳建筑数智云平台

优维“双碳”战略合作建筑 为落实创新驱动发展战略&#xff0c;增强深圳工程建设领域科技创新能力&#xff0c;促进技术进步、科技成果转化和推广应用&#xff0c;根据《深圳市工程建设领域科技计划项目管理办法》《深圳市住房和建设局关于组织申报2022年深圳市工程建设领域科…...

docker 基础入门

docker 基础入门 引言 在当今快速演进的软件开发领域&#xff0c;Docker 已经成为一个革命性的工具&#xff0c;它极大地改变了我们构建、部署和管理应用程序的方式。作为一种开源容器化平台&#xff0c;Docker 提供了一个轻量级且一致的环境&#xff0c;使得软件能够在几乎任…...

HarmonyOS:NativeWindow 开发指导

场景介绍 NativeWindow 是 HarmonyOS 本地平台化窗口&#xff0c;表示图形队列的生产者端。开发者可以通过 NativeWindow 接口进行申请和提交 Buffer&#xff0c;配置 Buffer 属性信息。 针对 NativeWindow&#xff0c;常见的开发场景如下&#xff1a; ● 通过 NativeWindow…...

汉威科技传感器为农业加点“智慧”

农业是国家之根本&#xff0c;历来受到高度重视&#xff0c;在央视《传感中国》系列节目中&#xff0c;智慧农业独占一期&#xff0c;重要性不言而喻。 随着传感器、物联网、GIS、大数据、5G、人工智能、区块链等技术的快速发展&#xff0c;智慧农业成为种植、养殖行业的新趋势…...

springboot listener、filter登录实战

转载自&#xff1a; www.javaman.cn 博客系统访问&#xff1a; http://175.24.198.63:9090/front/index 登录功能 1、前端页面 采用的是layui-admin框架&#xff0c;文中的验证码内容&#xff0c;请参考作者之前的验证码功能 <!DOCTYPE html> <html lang"zh…...

【数据结构—栈的实现(数组栈)】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、栈 1.1栈的概念及结构 二、栈的实现 2.1头文件的实现—Stack.h 2.2源文件的实现—Stack.c 2.3源文件的测试—test.c 三、栈的实际测试数据展示 3.1正常的出…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...