📄 snake.c
字号:
/*---------------------------------------------------------
* 贪吃蛇游戏 测试版 V0.1 snake
* 采用AT89S51+62256(RAM)+12864LCD(液晶)+RSM2222-001(遥控)
---------------------------------------------------------*/
#include <AT89x52.H>
#include <STDLIB.H>
#include "snake.h"
//移动标志位 1=上,2=下,3=左,4=右(初始向右移动)
uchar MoveDirection = 4;
uchar RandCounter=0;//由于产生的随机数有问题在这加个.
bit UpMove = 0;//向上移动标志位
bit DownMove = 0;//向下移动标志位
bit LeftMove = 0;//向左移动标志位
bit RightMove = 1;//向右移动标志位
bit FoodFlag = 0;//食物有无标志位
bit Pause = 0;//暂停标志位
bit GameStart = 0;//游戏开始标志位
bit GameOver = 0;//游戏结束标志位
sbit Beep = P3^3; //音频输出脚
//存放遥控接收数据
uchar xdata KeyCoding[4]={0,0,0,0};
uchar counter; //计时用
uchar SnakeLong = 2;//记录蛇身的长度
/*Snake[0]记录蛇头的坐标位置,Snake[1]-Snake[20]记录蛇身的坐标位置,
蛇的移动是将蛇尾清空,在第一个蛇头位置补上*/
uchar xdata Snake[21]={
//0 1 2 3 4 5 6 7 8 9 10 11 12
35,34,33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
//13 14 15 16 17 18 19 20
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
//复制地图
uchar xdata Map[128];
/****************** 用于绘图显示 *****************/
uchar xdata GDRAM[1024];
/****************** 8X8的图形点阵数据 *****************/
//空=0,墙=1,食物=2,蛇身=3,蛇头=4
uchar code empty[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//空
uchar code wall[8] ={0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA};//墙
uchar code food[8] ={0x24,0x7E,0xFF,0xFF,0xFF,0x7E,0x3C,0x18};//食物
uchar code body[8] ={0x3C,0x7E,0xFF,0xFF,0xFF,0xFF,0x7E,0x3C};//蛇身
uchar code head[8] ={0x3C,0x7E,0xFB,0xFF,0xF8,0xFF,0x7E,0x3C};//蛇头
/****************** 8X16格的绘图坐标 *****************/
uint code MoveData[128] ={
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,
384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,
512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,
640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,
768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,
896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911};
/****************** 8X16格的地图 *****************/
//空=0,墙=1,食物=2,蛇身=3,蛇头=4
uchar code GameMap[128]={ //地图自己可以编辑增加障碍物,增加游戏难度
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,3,3,4,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
/*---------------------------------------------------------
函数:CopyMap()
说明:复制地图
---------------------------------------------------------*/
void CopyMap()
{
uchar i;
for (i=0;i<128;i++) Map[i]= GameMap[i];
}
/**********************************************************
*函数名:WriteMemorizer()
*功 能:将图形数据写入显存
*pos:要显示图形的位置,*p:指针指向要显示的图形
**********************************************************/
void WriteMemorizer(uchar pos,uchar *p)
{
uchar i;
uint zb;
zb = MoveData[pos]; //取显存地址(显示坐标)
for (i=0;i<8;i++)
{
GDRAM[zb] = *p; //要显示的图形写入显存
p++; //下一个数据
zb+=16; //显存的下一个地址(每个地址之间的差是16)
} //或者说是间隔是16.
}
/**********************************************************
*函数名:MapCreate()
*功 能:地图生成程序
**********************************************************/
void MapCreate()
{
uchar i;
for (i=0;i<128;i++) //生成8X8的地图(64块组成)
{ //每1块是8X8的点阵
switch (Map[i])//获得地图上的图形数据
{ //将图形编号对应的数据写入显存
case 0:
WriteMemorizer(i,empty);//空=0
break;
case 1:
WriteMemorizer(i,wall);//墙=1
break;
case 2:
WriteMemorizer(i,food);//食物=2
break;
case 3:
WriteMemorizer(i,body);//蛇身=3
break;
case 4:
WriteMemorizer(i,head);//蛇头=4
break;
}
}
}
/**********************************************************
*函数名:GameDisplay()
*功 能:游戏图形显示程序(从左到右,从上到下)
* *point指向外部RAM存储的128X64的图片数据
**********************************************************/
void GameDisplay(uchar *point)
{
uchar i,j;
LCDWriteCommand(0x34);//扩充指令集
LCDWriteCommand(0x36);//绘图显示开
for (i=0;i<32;i++) //写上半屏(32行)
{
LCDWriteCommand(0x80+i);//Y地址寄存器
LCDWriteCommand(0x80); //X地址(LCM自动加1)
for (j=0;j<16;j++) //16x8列
{ //获得GamePic的首地址
LCDWriteData(*point);//写入一个字节图形数据
point++; //指向下一个图形字节
}
}
for (i=0;i<32;i++) //写下半屏
{
LCDWriteCommand(0x80+i);//Y地址寄存器
LCDWriteCommand(0x88); //X地址(LCM自动加1)
for (j=0;j<16;j++)//
{
LCDWriteData(*point);//写入一个字节图形数据
point++;
}
}
}
/*---------------------------------------------------------
函数:SnakeCoor()
说明:读取蛇头当前坐标
---------------------------------------------------------*/
uchar SnakeCoor()
{
uchar i;
uchar SnakeHead;
for (i=0;i<128;i++)
{//逐个比较找出蛇头
if (Map[i]==4)
{ //获得蛇头的当前坐标
SnakeHead = i;
break;//跳出循环
}
}
return (SnakeHead);
}
/*---------------------------------------------------------
函数:PlacedFood()
说明:放置食物
---------------------------------------------------------*/
void PlacedFood()
{
uchar i=0;
srand(16); //随机数发生器初始值
if (FoodFlag==0)
{
RandCounter++;
if (RandCounter==28) RandCounter=0;
do
{ //rand ()产生一个0-32767之间的虚拟随机数
i = rand (); //赋给一个字符型,取低8位
i+=RandCounter;//由于产生的随机数非常的有规律所以加一个
if (i<111&&Map[i]==0)
{//产生的随机数在坐标范围以内且没刷到墙和蛇上就刷出.
Map[i] = 2; //放食物
break;//跳出循环
}
}
while(1);
FoodFlag = 1;//食物标志位置1,表明放了食物
}
}
/*---------------------------------------------------------
函数:Init()
说明:初始化
---------------------------------------------------------*/
void Init()
{
IE = 0x83; //开外中断0,定时器0,总中断允许
IP = 0x01; //外中断INT0中断优先
TMOD = 0x01;//定时器0模式1
TH0 = 0xB1; //定时10mS
TL0 = 0xE0;
TCON = 0x11;//启动定时器0,外中断INT0边沿触发
}
/**********************************************************
*延时400us
**********************************************************/
void Delay400us() //晶振=12MHz 延时时间=404us
{ //晶振=11.0592MHz 延时时间≈438us
uchar i,j; //总的延时时间=[(2*i)+1]*j+1+1
for (j=4;j>0;j--) //j=2用12MHz,j=4 是24MHz晶振
for (i=100;i>0;i--);
}
/**********************************************************
*函数名:Sound()
*功 能:音效子程序
**********************************************************/
void Sound()
{
uchar i;
for (i=40;i>0;i--)
{
Beep=~Beep;
Delay400us();
}
}
/*---------------------------------------------------------
函数:main()
说明:主函数
---------------------------------------------------------*/
main ()
{
LCDInit();//液晶初始化
Init(); //初始化
CopyMap();//复制地图
MapCreate(); //生成地图
GameDisplay(GDRAM);//地图刷新显示
while(1)
{
switch (KeyCoding[2]) //可以放到主程序的while(1)循环中.
{//按键判断
case 0x51: //确定键
if (Pause==0)
{
Pause = 1;
TR0 = 0; //暂停
}
else
{
Pause = 0;
TR0 = 1; //继续
}
KeyCoding[2] = 0;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -