目录
前言
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;
}
总结
我自认为水平一般,也是第一次写这种有点复杂度的。不过万事开头难,只要有思路,根本停不下来!