利用51单片机和LCD12864实现贪吃蛇游戏代码
时间: 2023-11-06 10:04:14 浏览: 174
基于51单片机实现的贪吃蛇游戏
以下是一个基于51单片机和LCD12864的简单贪吃蛇游戏代码,需要配合相应的硬件电路使用:
```c
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//定义LCD引脚
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
sbit LCD_CS1=P2^3;
sbit LCD_CS2=P2^4;
sbit LCD_RST=P2^5;
//定义按键引脚
sbit KEY_UP=P1^0;
sbit KEY_DOWN=P1^1;
sbit KEY_LEFT=P1^2;
sbit KEY_RIGHT=P1^3;
//定义贪吃蛇结构体
struct Snake
{
uchar x;
uchar y;
uchar dir;
}snake[100];
//定义食物结构体
struct Food
{
uchar x;
uchar y;
}food;
//定义游戏参数
uchar score=0;
uchar speed=10;
uchar len=3;
uchar over=0;
//初始化LCD
void InitLCD()
{
LCD_RST=0;
_nop_();
LCD_RST=1;
LCD_EN=0;
LCD_CS1=0;
LCD_CS2=0;
LCD_RW=0;
LCD_RS=0;
_nop_();
P0=0x3F;
LCD_EN=1;
_nop_();
LCD_EN=0;
_nop_();
P0=0xC0;
LCD_EN=1;
_nop_();
LCD_EN=0;
_nop_();
P0=0x40;
LCD_EN=1;
_nop_();
LCD_EN=0;
_nop_();
}
//写命令到LCD
void WriteCmd(uchar cmd)
{
LCD_RS=0;
LCD_RW=0;
_nop_();
P0=cmd;
LCD_EN=1;
_nop_();
LCD_EN=0;
_nop_();
}
//写数据到LCD
void WriteData(uchar dat)
{
LCD_RS=1;
LCD_RW=0;
_nop_();
P0=dat;
LCD_EN=1;
_nop_();
LCD_EN=0;
_nop_();
}
//清屏
void ClearScreen()
{
uchar i,j;
for(i=0;i<8;i++)
{
WriteCmd(0xB8+i);
WriteCmd(0x40);
for(j=0;j<128;j++)
{
WriteData(0x00);
}
}
}
//显示字符
void ShowChar(uchar x, uchar y, uchar ch)
{
uchar i;
WriteCmd(0xB8+y);
WriteCmd(0x40+x*8);
for(i=0;i<8;i++)
{
WriteData(font[ch-32][i]);
}
}
//显示字符串
void ShowString(uchar x, uchar y, uchar *str)
{
while(*str)
{
ShowChar(x++,y,*str++);
}
}
//绘制贪吃蛇
void DrawSnake()
{
uchar i;
for(i=0;i<len;i++)
{
WriteCmd(0xB8+snake[i].y/8);
WriteCmd(0x40+snake[i].x);
WriteData(0x01<<(snake[i].y%8));
}
}
//生成食物
void GenerateFood()
{
uchar x,y;
do
{
x=rand()%120+4;
y=rand()%8;
}while(GetPixel(x,y));
food.x=x;
food.y=y;
WriteCmd(0xB8+y);
WriteCmd(0x40+x);
WriteData(0xFF>>(7-food.y%8));
}
//获取像素点
uchar GetPixel(uchar x, uchar y)
{
WriteCmd(0xB8+y/8);
WriteCmd(0x40+x);
return (ReadData()>>(7-y%8))&0x01;
}
//读取数据
uchar ReadData()
{
uchar dat;
LCD_RS=1;
LCD_RW=1;
LCD_EN=1;
_nop_();
dat=P0;
LCD_EN=0;
_nop_();
return dat;
}
//移动贪吃蛇
void MoveSnake()
{
uchar i;
for(i=len-1;i>0;i--)
{
snake[i].x=snake[i-1].x;
snake[i].y=snake[i-1].y;
}
switch(snake[0].dir)
{
case 1: snake[0].y--; break;
case 2: snake[0].x--; break;
case 3: snake[0].x++; break;
case 4: snake[0].y++; break;
}
}
//检测游戏是否结束
void CheckOver()
{
uchar i;
if(snake[0].x<4||snake[0].x>123||snake[0].y<0||snake[0].y>7)
{
over=1;
return;
}
for(i=1;i<len;i++)
{
if(snake[0].x==snake[i].x&&snake[0].y==snake[i].y)
{
over=1;
return;
}
}
}
//检测是否吃到食物
void CheckFood()
{
if(snake[0].x==food.x&&snake[0].y==food.y)
{
len++;
score++;
GenerateFood();
}
}
//检测按键
void CheckKey()
{
if(KEY_UP==0&&snake[0].dir!=4) snake[0].dir=1;
if(KEY_DOWN==0&&snake[0].dir!=1) snake[0].dir=4;
if(KEY_LEFT==0&&snake[0].dir!=3) snake[0].dir=2;
if(KEY_RIGHT==0&&snake[0].dir!=2) snake[0].dir=3;
}
//延时函数
void Delay(uint n)
{
uint i,j;
for(i=0;i<n;i++)
{
for(j=0;j<50;j++);
}
}
//主函数
void main()
{
InitLCD();
ClearScreen();
ShowString(0,0,"Score:");
ShowString(0,1,"Speed:");
ShowString(0,2,"Snake");
ShowString(0,3,"Game");
GenerateFood();
snake[0].x=60;
snake[0].y=3;
snake[0].dir=3;
DrawSnake();
while(1)
{
CheckKey();
MoveSnake();
CheckFood();
CheckOver();
if(over) break;
DrawSnake();
ShowChar(7,0,score/10+'0');
ShowChar(8,0,score%10+'0');
ShowChar(7,1,speed/10+'0');
ShowChar(8,1,speed%10+'0');
Delay(100-speed);
}
ShowString(0,4,"Game Over!");
while(1);
}
```
注意:以上代码仅供参考,具体实现方式可能有所不同。在实际使用中,需要根据硬件电路和开发环境进行相应的修改。
阅读全文