普中51单片机的贪吃蛇教程

之前在做贪吃蛇的时候一直想找一些好理解的51单片机贪吃蛇代码,不是找不到了就是很难理解,又或者CS某N要付费,后面就直接自己写了加上参考了一部分资料,几天才写完,就想着来分享一下吧本次代码采用模块化设计,分为主函数模块,点阵模块和延时模块。

#include <REGX52.H>
#include <stdlib.h>
#include <intrins.h>
#include "Delay.h"
#include "MatrixLED.h"

typedef  unsigned int  u16;
typedef  unsigned char u8;

sbit up=P3^1;
sbit down=P3^0;
sbit lt=P3^2;
sbit rt=P3^3;

u8 coordx[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,};
u8 coordy[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,};

u8	 foodx;
u8   foody;
u8   snake_x[20]={0};
u8   snake_y[20]={0};
u8   length;
u8   direction;

void initsnake();
void Keyboard();
void move();
void creatfood();
void snakegrow(void);
void drawsnake();


void initsnake()//蛇的初始化
{
    snake_x[0]=0;//1
    snake_y[0]=0;//1
    length=1;
    direction=2;
}
void move()//移动
{
    u8 len=length-1;//u16,漏-1
    for (len;len>0;len--)
    {
        snake_x[len]=snake_x[len-1];
        snake_y[len]=snake_y[len-1];
    }
    switch(direction)//case不加()
    {
        case 1:
            snake_y[0]--;
            break;
        case 2:
            snake_y[0]++;
            break;
        case 3:
            snake_x[0]--;
            break;
        case 4:
            snake_x[0]++;
            break;
        default:
            break;
    }
    
}

void Keyboard()//按钮
{
    if(up==0)
    {
        Delay(10);//避免
        if(up==0)
        {
            direction=1;
        }
        while(!up);//!up,原up==1
    }
    if(down==0)
    {
        Delay(10);
        if(down==0)
        {
            direction=2;
        }
        while(!down);//!down
    }
    if(lt==0)
    {
        Delay(10);
        if(lt==0)
        {
            direction=3;
        }
        while(!lt);//改
    }
    if(rt==0)
    {
        Delay(10);
        if(rt==0)
        {
            direction=4;
        }
        while(!rt);//改
    }
}

void creatfood()//食物创造
{
    u8 i;//u16
    foodx=rand()%8;
    foody=rand()%8;
    for(i=0; i<length; i++)
    {
        if((foodx==snake_x[i])&&(foody==snake_y[i]))//括号运算优先级
        {
            creatfood();
        }
    }
    
}

void snakegrow()//吃食物后增厂长
{
    if(foody==snake_y[0]&&foodx==snake_x[0])
    {
        creatfood();
        snake_x[length]=snake_x[length-1];
        snake_y[length]=snake_y[length-1];
        length++;
    }
}

void drawsnake()//调佣mtrixled来绘制蛇和食物
{
    u8 i;//u16
    for(i=0;i<length;i++)//应该是小于length
    {
        MatrixLED_ShowColumn(coordy[snake_y[i]],coordx[snake_x[i]]);
        MatrixLED_ShowColumn(coordy[foody],coordx[foodx]);
    }
}

void judgedeath()//判断死亡
{
    u8 i;//u16
    if((snake_x[0]>7)||(snake_y[0]>7))
    {
        _74H595_WriteByte(0x00);//MatrixLED_ShowColumn(0x00,0xff);//清屏
        while(1);
    }
    for(i=4; i<length;i++)
    {
        if((snake_x[0]==snake_x[i])&&(snake_y[0]==snake_y[i]))
        {
            P0=0xFF;//MatrixLED_ShowColumn(0x00,0xff);
            while(1);
        }
    }
}

void Timer0Init()
{
	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
	TH0=0XD8;	//给定时器赋初值,定时10ms
	TL0=0XF0;	
	ET0=1;//打开定时器0中断允许
	EA=1;//打开总中断
	TR0=1;//打开定时器			
}

void Timer0() interrupt 1
{
	static u16 i;
	TH0=0XD8;	//给定时器赋初值,定时10ms
	TL0=0XF0;
	i++;
	if(i==50)
	{
		i=0;
		move();
	}
}

void main()
{
    Timer0Init();
    initsnake();
    while (1)
    {   
    drawsnake();
    judgedeath();
    snakegrow();
    Keyboard();
    }
    
}
#include <intrins.h>//延时函数
void delay(unsigned char a)		//@11.0592MHz
{
	unsigned char b;
	for(b=1;b<=a;b++)
	{
		unsigned char i=2;
		while(--i);
	}
}
#include <REGX52.H>
#include "Delay.h"

sbit SER=P3^4;
sbit SCK=P3^6;
sbit RCK=P3^5;

typedef unsigned char u8;
typedef unsigned int u16;

void _74H595_WriteByte(unsigned char Byte)
{
	u8 i=0;
	for(i=0;i<8;i++)
	{
		SER=Byte>>7;
		Byte<<=1;
		SCK=1;//1
		Delay(1);
		SCK=0;//0
	}
	RCK=1;//1
	Delay(1);
	RCK=0;//0
}	
void MatrixLED_ShowColumn(u8 Column,u8 Date)//Column为行(74H595),Date为列(0有效)
{
	_74H595_WriteByte((Column));
	P0=(Date);//if(Date==0){P0=~0x80;}
	Delay(1);
	P0=0xff;//位清零
}

大概还有.h文件没有补充,一般来说学到这里的人应该都会模块化,.h的文件创建也很简单就懒得上传了。后面可以改善的就是死亡后的点阵动画,有兴趣的人可以自己写一下改善我的代码。另外本代码运用了vscode的EIDE模块,vscode真的在长一点的代码写作上面很有用,此外我在设置vscode的时候也遇了很多的问题,调试了我一下午,有空也可以写来分享下避免踩坑。 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值