【Proteus仿真】【51单片机】贪吃蛇游戏

文章目录


一、功能简介

本项目使用Proteus8仿真51单片机控制器,使用8*8LED点阵、按键模块等。

主要功能:

系统运行后,可操作4个按键控制小蛇方向。


二、软件设计

c 复制代码
/*
作者:嗨小易(QQ:3443792007)

*/


#include "PBDATA.H"



/****************************************
 蛇体 和 食物 相关的数据 和 函数
*****************************************/
uchar bodyRow[16], bodyCol[16];  // 蛇身的数组

uchar code dirRow[4] = {-1, 0, 1, 0};  // 上右下左方向X增量
uchar code dirCol[4] = {0, 1, 0, -1};  // 上右下左方向Y增量
extern uchar dir;
uchar maxRow = 8, maxCol = 8;  // 行的范围 [0, maxRow), 列范围同理
uchar speed = 5;  // 蛇的速度,单位是50ms
uchar snakeBodyLength = 0;  // 蛇身体的长度
uchar isDead = 0;  // 表示蛇是否死亡

uchar foodRow = 0, foodCol = 0, needCreate = 1;  // 食物坐标和食物是否被吃标志
 
void InitSnake()
{
	bodyRow[0] = 7;
	bodyCol[0] = 2;
	bodyRow[1] = 7;
	bodyCol[1] = 1;
	
	snakeBodyLength = 2;
	
	dir = 1;
	
	// 生成蛇打印的内容
	Matrix_GenerateTab(bodyRow, bodyCol, snakeBodyLength);
	
	// 设置时间种子
	srand(0);
}

void GenerateFood()
{
	uchar i = 0;
	while(needCreate) {
		// 随机生成 Row 和 Col
		foodRow = rand() % maxRow;
		foodCol = rand() % maxCol;
		
		// 判断食物是否和当前蛇身体冲突 
		for(i = 0; i < snakeBodyLength; i++) {
			if(bodyRow[i] == foodRow && bodyCol[i] == foodCol) {
				break;
			}
		}
		if(i == snakeBodyLength) {
			needCreate = 0;
			bodyRow[snakeBodyLength] = foodRow;
			bodyCol[snakeBodyLength] = foodCol;
		} 
	}
}

/****************************************
 定时器相关的代码
*****************************************/

uchar count;  // time = count * 50ms

void InitTimer()
{
  TMOD = 0x01;
  
  // 初始值 : 50ms
  TH0 = (65536 - 50000) / 256;  // 初始值取高八位
  TL0 = (65536 - 50000) % 256;  // 初始值取低八位
  
  // 中断开启
  ET0 = 1;  // 开启定时器0的中断
  EA = 1;   // 开启总的中断

  // 配置TCON
  // TR0 : 1, 启动定时器0
  TR0 = 1;    
}

void TimerIsr() interrupt 1
{
	uchar nextHeadRow = 0, nextHeadCol = 0, i = 0;
	
  // 重新装填
  // 初始值 : 50ms
  TH0 = (65536 - 50000) / 256;  // 初始值取高八位
  TL0 = (65536 - 50000) % 256;  // 初始值取低八位
  
  if(count == speed && !isDead) {  // count * 50ms 触发一次
    count = 0;
	
		// 生成食物
		GenerateFood();
		
		// 预测蛇头
		nextHeadRow = bodyRow[0] + dirRow[dir];
		nextHeadCol = bodyCol[0] + dirCol[dir];
		if(nextHeadRow >= maxRow || nextHeadRow < 0 
			 || nextHeadCol >= maxCol || nextHeadCol < 0) {
				isDead = 1;
				return;
		}
		
		// 身体撞击
		for(i = 0; i < snakeBodyLength; i++) {
			if(nextHeadRow == bodyRow[i] && nextHeadCol == bodyCol[i]) {
				isDead = 1;
				return;
			}
		}
		
		
		// 吃到食物与否
		if(nextHeadRow == foodRow && nextHeadCol == foodCol) {
			snakeBodyLength += 1;
			needCreate = 1;
			
			// 再生成新的食物
			GenerateFood();
		}
		
		// 蛇身体移动
		for(i = snakeBodyLength - 1; i > 0; i--) {
			bodyRow[i] = bodyRow[i - 1];
			bodyCol[i] = bodyCol[i - 1];
		}
		
		// 新的蛇头
		bodyRow[0] = nextHeadRow;
		bodyCol[0] = nextHeadCol;
		
		
		// 生成需要显示的图形
		Matrix_GenerateTab(bodyRow, bodyCol, snakeBodyLength + 1);
	}
	count++;	
	
	// 每50ms进行一次按键扫描
	DirKeyScan();
}

void main()
{
	uchar i = 0, a = 0;

	count = speed;
	InitSnake();
	InitTimer();

	while(1){
		if(isDead) {
			Matrix_ShowAll();
		} else {
			// 打印蛇的身体
			Matrix_ShowPointByCode();		
		}
	}
}

三、实验现象

B站演示视频:https://space.bilibili.com/444388619

联系作者

视频地址:https://space.bilibili.com/444388619/video

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

相关推荐
菩提祖师_11 分钟前
基于单片机指纹密码门禁的设计与实现
数据库·单片机·嵌入式硬件
广州灵眸科技有限公司12 分钟前
瑞芯微(EASY EAI)RV1126B RTC使用
单片机·物联网·实时音视频
白书宇22 分钟前
【STM32实战】从零开始写Linux 0.12内核 第2个实验 准备开发板
linux·stm32·嵌入式硬件
三佛科技-1341638421239 分钟前
SM7055-18 输出18V 250mA低成本非隔离BUCK、 BUCK-BOOST方案典型应用电路(电磁炉方案)
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
d111111111d1 小时前
STM32 I2C通信详解:从机地址 vs 寄存器地址
笔记·stm32·单片机·嵌入式硬件·学习·模块测试
q_30238195561 小时前
宇树机器人又刷第一!具身智能靠强化学习解锁直立行走与快速奔跑
人工智能·python·单片机·机器人·ai编程
安当加密1 小时前
断网服务器如何防“物理入侵”?用SLA 操作系统双因素认证实现离线双因子认证
服务器·stm32·单片机
User_芊芊君子1 小时前
2026年1月网易UU远程深度测评:从云游戏到办公的真实体验
游戏·测评·uu远程
广州灵眸科技有限公司10 小时前
瑞芯微(EASY EAI)RV1126B CAN使用
linux·网络·单片机·嵌入式硬件
SmartRadio10 小时前
CH584M vs nRF52840 vs 主流BLE SoC全面对比
单片机·嵌入式硬件·mcu·物联网·开源·硬件工程