51单片机贪吃蛇初稿

目录

 

前言

游戏介绍

代码

主函数

LED矩阵驱动

总结


前言

c语言水平不太好,单片机水平也一般。所以写了这个玩意练练手,只有基础功能,有bug。基于普中A2开发板。

楼主水平较低,还望各位大佬多多指点,感谢各位。

灵感来自@__fang学长的基础版贪吃蛇(C语言版本)___fang的博客-CSDN博客,不知道算不算移植?哈哈哈

游戏介绍

sbit left=P3^2;
sbit right=P3^3;
sbit up=P3^1;
sbit down=P3^0;

四个按钮控制上下左右,蛇身最大长度10。采用伪随机函数生成食物,故每局生成位置固定。

代码

主函数

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


sbit left=P3^2;
sbit right=P3^3;
sbit up=P3^1;
sbit down=P3^0;



unsigned char placeflag;//0123上下左右
 char snake_x[20];//蛇坐标
 char snake_y[20];
unsigned char foodx,foody;//食物坐标
unsigned char length,over;//length为长度,over暂时未使用


void Timer0Init();//定时器函数声明

unsigned int random(unsigned int x)//随机数
{
  unsigned int value,i;
  for(i=0;i<x;i++)
  {
    value = rand() % 8 ;               //获取一个随机数
  }
  return value;
}


 void food()//食物生成
{
foodx=random(1);
foody=random(1);
}


void snakeinit()//蛇 初始化
{
snake_x[0]=2;
snake_y[0]=0;
snake_x[1]=1;
snake_y[1]=0;
snake_x[2]=0;
snake_y[2]=0;
	
	food();
placeflag=5;//默认无方向
	length=3;//长度

}

void key()//按钮防抖 方向判断 范围限制
{
	
	
	unsigned char i;
			
	
				if (left==0){TR0=1;}//若按钮按下启动定时器防抖判断
				if (right==0){TR0=1;}
				if (up==0){TR0=1;}
				if (down==0){TR0=1;}
				


				
				
				if(placeflag!=5)//若按钮按下
					{
							if((snake_x[0]==foodx)&&(snake_y[0]==foody)){food();length=length+1;}//若蛇头坐标和食物坐标重合判断为吃到了,重新生成食物,长度加一
							
							for(i=length-1; i>0; i--)//蛇身跟随蛇头
							{	
							snake_y[i]=snake_y[i-1];
							snake_x[i]=snake_x[i-1];
							}
							switch (placeflag)//按钮判断
						{
						case 0:	snake_y[0]+= 1;placeflag=5;break;//上下左右
						case 1:	snake_y[0]-= 1;placeflag=5;break;
						case 2:	snake_x[0]-= 1;placeflag=5;break;	
						case 3:	snake_x[0]+= 1;placeflag=5;break;	
						default:break;
						}
					}
			
					
				
				if(snake_y[0]>7)snake_y[0]=0;	
				else if(snake_y[0]<0)snake_y[0]=7;	
				if(snake_x[0]<0)snake_x[0]=7;	
				else if(snake_x[0]>7)snake_x[0]=0;	//范围限制(穿墙)
				
				
}



void main()
{
unsigned char i;
	MatrixLED_Init();
	Timer0Init();
	snakeinit();
	while(1)
	{
		
		key();
		
		for(i=0;i<length;i++)MatrixLED_ShowColumn(snake_x[i],snake_y[i]);
		MatrixLED_ShowColumn(foodx,foody);
		
		
	}
}
/*************************************定时器******************************************/
void Timer0Init(void)
{
	TMOD |= 0x11;		//设置定时器模式
	TH0=0xDC;	//给定时器赋初值,定时10ms
	TL0=0x00;
	ET0=1;
	EA=1;
	TR0=0;
}

void Timer0_Routine() interrupt 1  //按钮防抖
{

	TH0=(65536-10000)/256;	//给定时器赋初值,定时10ms
	TL0=(65536-10000)%256;	
	TR0=0;
		
	if(left==0)	 //左
	{	
	placeflag=2;
		while(left==0);	  
	}
	
	if(right==0)	//右
	{	
	placeflag=3;
		while(right==0);	  
	}
	
		if(up==0)	
	{	
	placeflag=0;
		while(up==0);	  
	}
	
	if(down==0)	 
	{	
	placeflag=1;
		while(down==0);	  
	}	
}






LED矩阵驱动

#include <REGX52.H>
#include "Delay.h"

sbit RCK=P3^5;		//RCLK
sbit SCK=P3^6;		//SRCLK
sbit SER=P3^4;		//SER

#define MATRIX_LED_PORT		P0

/**
  * @brief  74HC595写入一个字节
  * @param  Byte 要写入的字节
  * @retval 无
  */
void _74HC595_WriteByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		SER=Byte&(0x80>>i);
		SCK=1;
		SCK=0;
	}
	RCK=1;
	RCK=0;
}

/**
  * @brief  点阵屏初始化
  * @param  无
  * @retval 无
  */
void MatrixLED_Init()
{
	SCK=0;
	RCK=0;
}

/**
  * @brief  LED点阵屏显示一列数据
  * @param  Column 要选择的列,范围:0~7,0在最左边
  * @param  Data 选择列显示的数据,高位在上,1为亮,0为灭
  * @retval 无
  */
void MatrixLED_ShowColumn(unsigned char Column,Data)
{		
	unsigned char Y;
				if(Data==0)Y=0x01;
				if(Data==1)Y=0x02;
				if(Data==2)Y=0x04;
				if(Data==3)Y=0x08;
				if(Data==4)Y=0x10;
				if(Data==5)Y=0x20;
				if(Data==6)Y=0x40;
				if(Data==7)Y=0x80;
	_74HC595_WriteByte(Y);
	MATRIX_LED_PORT=~(0x80>>Column);
	Delay(1);
	MATRIX_LED_PORT=0xFF;
}

总结

我自认为水平一般,也是第一次写这种有点复杂度的。不过万事开头难,只要有思路,根本停不下来!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值