当前位置:文档之家› 12864液晶贪吃蛇游戏

12864液晶贪吃蛇游戏

//D300开发板测试运行通过
//https://www.doczj.com/doc/8e98208.html,
//2013年2月1日pangjineng
#include
#include
#define uint unsigned int
#define uchar unsigned char

const uchar hang3[] = {"吃到自己得分为"};
const uchar hang4[] = {"撞到墙面得分为"};

#define LCD P2
sbit RS = P0^7;
sbit RW = P0^6;
sbit EN = P0^5;
sbit LEFT=P1^1;//左
sbit RIGHT=P1^3;//右
sbit UP=P1^5;//上
sbit DOWN=P1^7;//下

/*游戏的初始化值*/
uchar gamestatus=0;
uchar flag=1; //折点个数标志
uchar a[]={20,0,0,0,0,0,0,0};
uchar b[]={32,32,0,0,0,0,0,0};
uchar c[]={0,0,0,0,0,0,0,0};
uchar x=54,y=32,pointstatus,allpoints;

//uchar tt;

uchar timestatus; //中断标志

void delay(uchar i)
{
for(;i>0;i--);
}
void delayms( uint i)
{ uint j;
for(;i>0;i--)
{ for(j=1000;j>0;j--);}
}
uchar readstatus()
{ uchar i;
LCD=0xff;
RW=1;
RS=0;
EN=0;
delay(2);
EN=1;
delay(5);
i=LCD;
delay(5);
EN=0;
return(i);
}
void writecmd(uchar cmd)//写指令
{
while((readstatus() & 0x80)!= 0x00);
LCD=0x00;
RW=0;
RS=0;
EN=0;
LCD=cmd;
delay(2);
EN=1;
delay(5);
EN=0;
}
void writedate(uchar date)
{
while((readstatus() &0x80 )!=0x00);
LCD=0x00;
RW=0;
RS=1;
EN=0;
LCD=date;
delay(2);
EN=1;
delay(5);
EN=0;
}
uchar readdate()
{
uchar i;
while((readstatus() &0x80 )!=0x00);
RW=1;
RS=1;
EN=0;
delay(2);
EN=1;
delay(5);
i=LCD;
delay(5);
EN=0;
return i;
}
/*******************************************
函数名称:LCD_init
功 能: 初始化LCD
参 数:无
返回值 :无
********************************************/
void LCD_init()
{
writecmd(0x30);
delayms(1);
writecmd(0x30);
delayms(1);
writecmd(0x0c);
delayms(1);
writecmd(0x01);
delayms(1);
writecmd(0x06);
delayms(1);
}
/*******************************************
函数名称:Disp_HZ
功 能:指定地址输入指定个数的字
参 数:无
返回值 :无
********************************************/
void Disp_HZ(uchar addr,const uchar * pt,uchar num)
{
uchar i;
writecmd(addr);
for(i = 0;i < (num*2);i++)
{
writedate(*(pt++));
delayms(1);
}
}
void write_sfm(uchar x,uchar y,uchar shu)
{
uchar d1,d2,add,ah;
d1=shu/10;
d2=shu%10;
if(x==0)
ah=0x80;
else if(x==1)
ah=0x90;
else if(x==2)
ah=0x88;
else ah=0x98;
add=ah+y; //相当于ah+al
writecmd(add);
writedate( d1+'0');
writedate( d2+'0');
}
/*******************************************
函数名称:Clear_GDRAM
功 能:清除液晶GDRAM内部的随机数据
参 数:无
返回值 :无
********************************************/
void Clear_GDRAM(void)
{
uchar x,y,i,j;

writecmd(0x34); //打开扩展指令集
y=0x80;
x=0x80;

for(i=0;i<32;i

++)
{
writecmd(y);
writecmd(x);
for(j=0;j<16;j++)
{
writedate(0x00);
}
y++;
}

y=0x80;
x=0x88;

for(i=0;i<32;i++)
{
writecmd(y);
writecmd(x);
for(j=0;j<16;j++)
{
writedate(0x00);
}
y++;
}
writecmd(0x30); //回到基本指令集
}
/*******************************************
函数名称:Draw_PM
功 能:在整个屏幕上画一个图片
参 数:ptr--指向保存图片位置的指针
返回值 :无
********************************************/
/*void Draw_PM(uchar *ptr)
{ uchar x,y,i,j;
y=0x80;
x=0x80;
for(i=0;i<32;i++)
{
writecmd(y);
writecmd(x);
for(j=0;j<16;j++)
{
writedate(*ptr++);
}
y++;
}

y=0x80;
x=0x88;

for(i=0;i<32;i++)
{
writecmd(y);
writecmd(x);
for(j=0;j<16;j++)
{
writedate(*ptr++);
}
y++;
}
} */
/*******************************************
函数名称:Draw_point
功 能:在整个屏幕上画一个点 X 0~127 Y 0~63
参 数:ptr--指向保存图片位置的指针
返回值 :无
********************************************/
void Draw_point(uchar X,uchar Y,uchar clour) // clour为0时画点为其它清除这个点
{
uchar x_pos,y_pos,x_bit;
uint read_data1,read_data2,dat1,dat2;
//计算LCD位置
x_pos=X/16; //取16*16首地址
if(Y>31)
x_pos+=8; //计算该点所属LCD液晶中X坐标位置,上半屏0-7,下半屏8-15
x_bit=X%16; //该点位于所在16bit中的第几位
y_pos=Y%32;

// writecmd(0x34);
writecmd(0x36);

writecmd(0x80+y_pos);
writecmd(0x80+x_pos);
readdate(); //此处为什么要中上不知道为什么????
read_data1 = readdate(); //高八位!
read_data2 = readdate(); //低八位!

if(x_bit<8)
{
if(clour==0)
{
dat1=read_data1|(1<<(7-x_bit));
}
else
{
dat1=read_data1&~(1<<(7-x_bit));
}
dat2=read_data2;
}
else
{
dat1=read_data1;
if(clour==0)
{
dat2=read_data2|(1<<(15-x_bit));
}
else
{
dat2=read_data2&~(1<<(15-x_bit));
}
}

writecmd(0x80+y_pos);
writecmd(0x80+x_pos);
writedate(dat1);
writedate(dat2);

writecmd(0x30);
}
/*******************************************
函数名称:Draw_zhi
功 能:在整个屏幕上画一条直线
参 数:
返回值 :无
********************************************/
void Draw_zhi(uchar X1,uchar X2,uchar Y)
{
uchar i,temp ;
if(X1>X2) //X轴上,起点大于终点,交换数据
{
temp=X2;
X2=X1;
X1=temp;
}
for(i=X1;i<=X2;i++)
{
Draw_point(i,Y,0);
}
}


/*******************************************
函数名称:Draw_shu
功 能:在整个屏幕上画一条竖线
参 数:
返回值 :无
********************************************/
void Draw_shu(uchar X,uchar Y1,uchar Y2)
{
uchar i ,temp;
if(Y1>Y2) //X轴上,起点大于终点,交换数据
{
temp=Y2;
Y2=Y1;
Y1=temp;
}
for(i=Y1;i<=Y2;i++)
{
Draw_point(X,i,0);
}
}
/*******************************************
函数名称:Draw_line
功 能:在整个屏幕上画一条线
参 数:ptr--指向保存图片位置的指针
返回值 :无
********************************************/
void Draw_line(uchar x0,uchar y0,uchar x1,uchar y1) //只能是横线或者是竖线@!!!!!!
{
int dx,dy; //定义X.Y轴上增加的变量值
dx=x1-x0; //X轴方向上的增量
dy=y1-y0; //Y轴方向上的增量
if(dx==0)
Draw_shu(x0,y0,y1);
if(dy==0)
Draw_zhi(x0,x1,y0);

}
/***********************************************************************************/

/*以上是12864的相关函数*/

/***********************************************************************************/
/***********************************************************************************/

/*以下是12864的按键函数*/

/***********************************************************************************/
void keyscan() //按键函数
{
if(RIGHT==0)
{
delayms(5);
if(RIGHT==0)
{
gamestatus=0;
}
}

if(DOWN==0)
{
delayms(5);
if(DOWN==0)
{
gamestatus=1;
}
}

if(UP==0)
{
delayms(5);
if(UP==0)
{
gamestatus=3;
}
}

if(LEFT==0)
{
delayms(5);
if(LEFT==0)
{
gamestatus=2;
}
}
}

/*******************************************
函数名称:statuschange()
功 能:状态函数
参 数
返回值 :无
********************************************/
void statuschange() //状态发生改变处理函数 必须跟在按键涵数后面!!!!
{
uchar i;
if((gamestatus!=c[0])&&((gamestatus%2)!=(c[0]%2)))
{
flag++;
for(i=flag;i>0;i--)
{
a[i]=a[i-1];
b[i]=b[i-1];
c[i]=c[i-1];
}
c[0]=gamestatus;

}
}
void stat_point()
{
if(c[0]==0)
{
a[0]=a[0]+1;
}
else if(c[0]==1)
{
b[0]=b[0]+1;
}
else if(c[0]==2)
{
a[0]=a[0]-1;
}
else
{
b[0]=b[0]-1;
}
}
void last_point()
{
if(c[flag-1]==0)
{
a[flag]=a[flag]+1;
}
else if(c[flag-1]==1)
{
b[flag]=b[flag]+1;
}
else if(c[flag-1]==2)
{
a[flag]=a[flag]-1;
}
else
{
b[flag]=b[flag]-1;
}
if((a[flag]==a[flag-1])&&(b[flag]==b[flag-1]))
{
flag--;
}


}
void Draw_all_lines()
{
uchar i;
for(i=0;i{
Draw_line(a[i],b[i],a[i+1],b[i+1]);
}
}
/*******************************************
函数名称: all_point()
功 能: 加分函数 不能正常的显示
参 数:ptr--指向保存图片位置的指针
返回值 :无
********************************************/
void all_point()
{

write_sfm(3,7,allpoints);
}
/*******************************************
函数名称: bumpwall
功 能:判断是否撞边框
参 数:ptr--指向保存图片位置的指针
返回值 :无
********************************************/
void bumpwall()
{
if((a[0]>127||a[0]<0)||(b[0]<0||b[0]>63))
{
TR0=0;
Disp_HZ(0x98,hang4,8);
write_sfm(3,7,allpoints);
}
}

/*******************************************
函数名称: selfbump()
功 能:自身相撞函数!!
参 数:
返回值 :无
********************************************/
void selfbump()
{
uchar i,j;
for(j=flag-1;j>=3;j--)
{
if(c[j]==0)
{
for(i=a[j+1];i{
if((a[0]==i)&&(b[0]==b[j]))
{
TR0=0;
Disp_HZ(0x98,hang3,7);
all_point();
}
}
}

else if(c[j]==1)
{
for(i=b[j+1];i{
if((a[0]==a[j])&&(b[0]==i))
{
TR0=0;
Disp_HZ(0x98,hang3,7);
all_point();
}
}
}

else if(c[j]==2)
{
for(i=a[j];i{
if((a[0]==i)&&(b[0]==b[j]))
{
TR0=0;
Disp_HZ(0x98,hang3,7);
all_point();
}
}
}


else
{
for(i=b[j];i{
if((a[0]==a[j])&&(b[0]==i))
{
TR0=0;
Disp_HZ(0x98,hang3,7);
all_point();
}
}
}
}
}



/*******************************************
函数名称: add_point()
功 能:加点函数!! 有待改进!!!! 不重叠在线上!!!
参 数:ptr--指向保存图片位置的指针
返回值 :无
********************************************/
void add_point()
{

if(c[0]==0)
{
if((a[0]+1)==x&&(b[0]==y))
{
a[0]=x;
pointstatus=1;
allpoints++;
}
}
else if(c[0]==1)
{
if((b[0]+1)==y&&(a[0]==x))
{
b[0]=y;
pointstatus=1;
allpoints++;
}
}
else if(c[0]==2)
{
if((a[0]-1)==x&&(b[0]==y))
{
a[0]=x;
pointstatus=1;
allpoints++;
}
}

else
{
if((a[0])==x&&(b[0]-1)==y)
{
b[0]=y;
pointstatus=1;
allpoints++;
}
}


Draw_point(x,y,0);
if(pointstatus)
{
pointstatus=0;
Draw_point(x,y,1); //清除这个点,下面再加上一个点!!!!

x=x+5;
y=y+6;
if(x>127)
{
x=1;
}
if(y>63)
{
y=0;
}

/* srand(tt); // 怎么产生不了一个随机数所以只能用上面固定的点
x=(uint)(127*rand()/65537);
y=(uint)(127*rand()/65537); */
}

}

/*******************************************
函数名称: Time_init()
功 能:定时器初始化函数!!
参 数:ptr--指向保存图片位置的指针
返回值 :无
********************************************/
void Time_init()
{
TMOD=0x11;
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
EA=1;
TR0=1;
ET0=1;
}

void main()
{

Time_init();
LCD_init();
Clear_GDRAM();
while(1)
{
keyscan();
statuschange();
if(timestatus)
{
timestatus=0;
Draw_point(a[0],b[0],1);
stat_point();
add_point();
bumpwall();
Draw_point(a[flag],b[flag],1);
last_point();
selfbump();
}
Draw_all_lines();
}
}

void exter0() interrupt 1
{
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
timestatus=1;
// tt++;
}

相关主题
文本预览
相关文档 最新文档