单片机俄罗斯方块程序.docx
《单片机俄罗斯方块程序.docx》由会员分享,可在线阅读,更多相关《单片机俄罗斯方块程序.docx(19页珍藏版)》请在冰点文库上搜索。
单片机俄罗斯方块程序
#include"reg52.h"
#defineWINDOW_XADDR_START0x0050//HorizontalStartAddressSet
#defineWINDOW_XADDR_END0x0051//HorizontalEndAddressSet
#defineWINDOW_YADDR_START0x0052//VerticalStartAddressSet
#defineWINDOW_YADDR_END0x0053//VerticalEndAddressSet
#defineGRAM_XADDR0x0020//GRAMHorizontalAddressSet
#defineGRAM_YADDR0x0021//GRAMVerticalAddressSet
#defineGRAMWR0x0022//memorywrite
#defineuintunsignedint
#defineucharunsignedchar
sbitCS=P2^2;//片选
sbitRES=P2^1;//复位
sbitRS=P2^4;//数据/命令选择
sbitRW=P2^5;
constuintcol[9]={0x0000,0xFFFF,0x001F,0xFFE0,0xF800,0xF81F,0x07E0,0x7FFF,0x051F};
//BlackWhiteBlueYellowRedMagentaGreenCyanBlue2
constuintboxes[7]={//方块样式存储数组
0x0f00,
0x0740,
0x0e20,
0x0e40,
0x0c60,
0x06c0,
0x0660};
uintfi[23]={0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,
0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,
0xffff,0xffff,0xffff};
uchara,b;
uintt,p;
uintscore;
ucharspeed,leve,time;//游戏速度
ucharpcolor,color;
voidInit_Timer1(void)
{
TMOD|=0x10;//使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH1=0x3c;//给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
TL1=0xb0;
EA=1;//总中断打开
ET1=1;//定时器中断打开
TR1=1;//定时器开关打开
}
voiddelay(unsignedinti)//延时函数
while(i--);
ucharkeyscan(void)//键盘扫描函数,使用行列反转扫描法
uchark;
P1=0xff;
k=P1;
if(k!
=0xff)
delay(100);
if(k==0xfd)return1;
if(k==0xfb)return2;
if(k==0xf7)return3;
if(k==0xef)return4;
return8;
voiddelayms(uintcount)
inti,j;
for(i=0;i{for(j=0;j<260;j++);}}voidWrite_Cmd(ucharDH,ucharDL){CS=0;RS=0;P0=DH;RW=0;RW=1;P0=DL;RW=0;RW=1;CS=1;}voidWrite_Data(ucharDH,ucharDL){CS=0;RS=1;P0=DH;RW=0;RW=1;P0=DL;RW=0;RW=1;CS=1;}voidWrite_Cmd_Data(ucharx,uinty){ucharm,n;m=y>>8;n=y;Write_Cmd(0x00,x);Write_Data(m,n);}voidWrite_Data_U16(uinty){unsignedcharm,n;m=y>>8;n=y;Write_Data(m,n);}staticvoidLCD_SetPos(uintx0,uintx1,uinty0,uinty1){Write_Cmd_Data(WINDOW_XADDR_START,x0);Write_Cmd_Data(WINDOW_XADDR_END,x1);Write_Cmd_Data(WINDOW_YADDR_START,y0);Write_Cmd_Data(WINDOW_YADDR_END,y1);Write_Cmd_Data(GRAM_XADDR,x0);Write_Cmd_Data(GRAM_YADDR,y0);Write_Cmd(0x00,0x22);//LCD_WriteCMD(GRAMWR);}voidILI9325_Initial(void){CS=1;delayms(5);RES=0;delayms(5);RES=1;delayms(5);delayms(100);Write_Cmd_Data(0x0001,0x0100);Write_Cmd_Data(0x0002,0x0700);Write_Cmd_Data(0x0003,0x1030);Write_Cmd_Data(0x0004,0x0000);Write_Cmd_Data(0x0008,0x0207);Write_Cmd_Data(0x0009,0x0000);Write_Cmd_Data(0x000A,0x0000);Write_Cmd_Data(0x000C,0x0000);Write_Cmd_Data(0x000D,0x0000);Write_Cmd_Data(0x000F,0x0000);//poweronsequenceVGHVGLWrite_Cmd_Data(0x0010,0x0000);Write_Cmd_Data(0x0011,0x0007);Write_Cmd_Data(0x0012,0x0000);Write_Cmd_Data(0x0013,0x0000);//vghWrite_Cmd_Data(0x0010,0x1290);Write_Cmd_Data(0x0011,0x0227);//delayms(100);//vregioutWrite_Cmd_Data(0x0012,0x001d);//0x001b//delayms(100);//vomamplitudeWrite_Cmd_Data(0x0013,0x1500);//delayms(100);//vomHWrite_Cmd_Data(0x0029,0x0018);Write_Cmd_Data(0x002B,0x000D);//gammaWrite_Cmd_Data(0x0030,0x0004);Write_Cmd_Data(0x0031,0x0307);Write_Cmd_Data(0x0032,0x0002);//0006Write_Cmd_Data(0x0035,0x0206);Write_Cmd_Data(0x0036,0x0408);Write_Cmd_Data(0x0037,0x0507);Write_Cmd_Data(0x0038,0x0204);//0200Write_Cmd_Data(0x0039,0x0707);Write_Cmd_Data(0x003C,0x0405);//0504Write_Cmd_Data(0x003D,0x0F02);//ramWrite_Cmd_Data(0x0050,0x0000);Write_Cmd_Data(0x0051,0x00EF);Write_Cmd_Data(0x0052,0x0000);Write_Cmd_Data(0x0053,0x013F);Write_Cmd_Data(0x0060,0xA700);Write_Cmd_Data(0x0061,0x0001);Write_Cmd_Data(0x006A,0x0000);//Write_Cmd_Data(0x0080,0x0000);Write_Cmd_Data(0x0081,0x0000);Write_Cmd_Data(0x0082,0x0000);Write_Cmd_Data(0x0083,0x0000);Write_Cmd_Data(0x0084,0x0000);Write_Cmd_Data(0x0085,0x0000);//Write_Cmd_Data(0x0090,0x0010);Write_Cmd_Data(0x0092,0x0600);Write_Cmd_Data(0x0093,0x0003);Write_Cmd_Data(0x0095,0x0110);Write_Cmd_Data(0x0097,0x0000);Write_Cmd_Data(0x0098,0x0000);Write_Cmd_Data(0x0007,0x0133);}uchardir_y(uchark){return(1-k%2)*(k/2*2-1);}uchardir_x(uchark){return(k%2)*(k/2*2-1);}voidClearScreen(void){uinti,j;LCD_SetPos(0,240,0,320);//320x240for(i=0;i<320;i++){for(j=0;j<240;j++){if(j==59||i>=310)Write_Data_U16(col[8]);elseWrite_Data_U16(col[0]);}}}voidSET(charx,chary,uchark){uinti,bColor;bColor=col[k];LCD_SetPos(30+x*15,43+x*15,10+y*15,23+y*15);for(i=0;i<225;i++)Write_Data_U16(bColor);}voidSET1(uintz,uchark){chari;i=0;while(i<16){if(z&0x8000)SET(i%4+a,i/4+b,k);z<<=1;i++;}}ucharNUM(ucharn){switch(n){case0:return0x3f;break;case1:return0x06;break;case2:return0x5b;break;case3:return0x4f;break;case4:return0x66;break;case5:return0x6d;break;case6:return0x7d;break;case7:return0x07;break;case8:return0x7f;break;case9:return0x6f;break;}return0x00;}voidOUTNUM(charx,chary,ucharn){inta,b,i;a=30+x*15,b=10+y*15;LCD_SetPos(a,a+14,b,b+31);for(i=0;i<512;i++)Write_Data_U16(col[0]);if(n&0x80){LCD_SetPos(a+14,a+15,b+30,b+31);for(i=0;i<4;i++)Write_Data_U16(col[8]);}n<<=1;if(n&0x80){LCD_SetPos(a+4,a+11,b+16,b+17);for(i=0;i<16;i++)Write_Data_U16(col[8]);}n<<=1;if(n&0x80){LCD_SetPos(a+2,a+3,b+4,b+15);for(i=0;i<24;i++)Write_Data_U16(col[8]);}n<<=1;if(n&0x80){LCD_SetPos(a+2,a+3,b+18,b+29);for(i=0;i<24;i++)Write_Data_U16(col[8]);}n<<=1;if(n&0x80){LCD_SetPos(a+4,a+11,b+30,b+31);for(i=0;i<16;i++)Write_Data_U16(col[8]);}n<<=1;if(n&0x80){LCD_SetPos(a+12,a+13,b+18,b+29);for(i=0;i<24;i++)Write_Data_U16(col[8]);}n<<=1;if(n&0x80){LCD_SetPos(a+12,a+13,b+4,b+15);for(i=0;i<24;i++)Write_Data_U16(col[8]);}n<<=1;if(n&0x80){LCD_SetPos(a+4,a+11,b+2,b+3);for(i=0;i<16;i++)Write_Data_U16(col[8]);}}voidPRSCORE(void){uintk;chari,n,q;k=score;i=1;while(k){n=NUM(k%10);OUTNUM(i,2,n);k/=10;i--;}OUTNUM(-2,12,0x38);q=speed;i=0;while(q){n=NUM(q%10);OUTNUM(i,12,n);q/=10;i--;}}ucharCANMOVE(ucharq)//判定方块是否能朝q方向移动{uchari,j,z;uintk;if(!p)return0;i=a+dir_x(q);j=b+dir_y(q);z=0;k=0;while(z<4){k=k+(((fi[j+z]<>(4*z));z++;}if((k&p))return0;elsereturn1;}voidMOVE(ucharq)//朝q方向移动方块{SET1(p,0);a+=dir_x(q);b+=dir_y(q);SET1(p,color);}voidSYS(void)//将可活动的方块都变为不可活动的方块{ucharz;uintk;z=0;k=p;while(z<4){fi[b+z]|=((k&0xf000)>>a);k<<=4;z++;}p=0;}voidTURN(void)//方块变形{uintk,p1;ucharz;switch(p){case0x0f00:p1=0x4444;break;case0x4444:p1=0x0f00;break;case0x0740:p1=0x0622;break;case0x0622:p1=0x02e0;break;case0x02e0:p1=0x4460;break;case0x4460:p1=0x0740;break;case0x0e20:p1=0x2260;break;case0x2260:p1=0x0470;break;case0x0470:p1=0x0644;break;case0x0644:p1=0x0e20;break;case0x0e40:p1=0x4c40;break;case0x4c40:p1=0x4e00;break;case0x4e00:p1=0x4640;break;case0x4640:p1=0x0e40;break;case0x0c60:p1=0x2640;break;case0x2640:p1=0x0c60;break;case0x06c0:p1=0x4620;break;case0x4620:p1=0x06c0;break;case0x0660:p1=0x0660;break;}z=0;k=0;while(z<4){k=k+(((fi[b+z]<>(4*z));z++;}if(!(k&p1)){SET1(p,0);p=p1;SET1(p,color);}}ucharSCORED(void)//满行消去,返回加分{uchari,j,k,s=0,bcolor;bcolor=time%8+1;for(k=19;k>0;k--)if(fi[k]==0xffff){for(i=2;i<14;i++)for(j=k;j>0;j--)if((((fi[j]<{if(((fi[j]<elseSET(i,j,bcolor);}for(j=k;j>0;j--)fi[j]=fi[j-1];k++;s++;}returns;}voidputbox(void)//随机取一个方块,输出到左边并等待下次放出{chari;uintk;t=boxes[time%7];pcolor=time%8+1;i=0;k=t;while(i<16){if(k&0x8000)SET(i%4-2,i/4+5,pcolor);elseSET(i%4-2,i/4+5,0);k<<=1;i++;}}uchargetbox(void)//取上次存储的方块,放出,返回能否放出方块(不能则返回0,游戏结束){if(!p)p=t;a=6,b=0;color=pcolor;SET1(p,color);if(fi[0]!=0xc003)return0;elsereturn1;}voidmain(void){uchark,cm,cn,ins;a=6,b=0;p=0;score=1;time=0;leve=1;speed=leve+score/200;ILI9325_Initial();ClearScreen();PRSCORE();Init_Timer1();while(1){k=keyscan();if(k==1&&leve>1){leve--;speed=leve+score/200;PRSCORE();}if(k==3&&leve<9){leve++;speed=leve+score/200;PRSCORE();}if(k==4)break;if(k!=8)delay(30000);}putbox();getbox();while(1){cm=time;ins=speed*speed/10-3*speed+28;do{k=keyscan();if(k==1)if(CANMOVE(1))MOVE(1);if(k==3)if(CANMOVE(3))MOVE(3);if(k==2)if(CANMOVE(2)){MOVE(2);continue;}if(k==4)TURN();if(k!=8){delay(30000);if(k==4)delay(30000);}cn=time;if(cn>cm&&cn-cm>ins)break;if(cnins)break;}while(p);if(CANMOVE(2))MOVE(2);elseSYS();//方块自动下移,不可下移时把可移动方块变为不可移动k=SCORED();//满行消去,返回加分if(k){score+=(k+1)*(k+1);speed=leve+score/200;PRSCORE();}if(!p){k=getbox();if(!k)break;putbox();//无法放出方块己方游戏结束}}}voidTimer1_isr(void)interrupt3using1{TH1=0x3c;//重新赋值TL1=0xb0;time++;if(time>100)time=0;}
for(j=0;j<260;j++);
voidWrite_Cmd(ucharDH,ucharDL)
CS=0;
RS=0;
P0=DH;
RW=0;
RW=1;
P0=DL;
CS=1;
voidWrite_Data(ucharDH,ucharDL)
RS=1;
voidWrite_Cmd_Data(ucharx,uinty)
ucharm,n;
m=y>>8;
n=y;
Write_Cmd(0x00,x);
Write_Data(m,n);
voidWrite_Data_U16(uinty)
unsignedcharm,n;
staticvoidLCD_SetPos(uintx0,uintx1,uinty0,uinty1)
Write_Cmd_Data(WINDOW_XADDR_START,x0);
Write_Cmd_Data(WINDOW_XADDR_END,x1);
Write_Cmd_Data(WINDOW_YADDR_START,y0);
Write_Cmd_Data(WINDOW_YADDR_END,y1);
Write_Cmd_Data(GRAM_XADDR,x0);
Write_Cmd_Data(GRAM_YADDR,y0);
Write_Cmd(0x00,0x22);//LCD_WriteCMD(GRAMWR);
voidILI9325_Initial(void)
delayms(5);
RES=0;
RES=1;
delayms(100);
Write_Cmd_Data(0x0001,0x0100);
Write_Cmd_Data(0x0002,0x0700);
Write_Cmd_Data(0x0003,0x1030);
Write_Cmd_Data(0x0004,0x0000);
Write_Cmd_Data(0x0008,0x0207);
Write_Cmd_Data(0x0009,0x0000);
Write_Cmd_Data(0x000A,0x0000);
Write_Cmd_Data(0x000C,0x0000);
Write_Cmd_Data(0x000D,0x0000);
Write_Cmd_Data(0x000F,0x0000);
//poweronsequenceVGHVGL
Write_Cmd_Data(0x0010,0x0000);
Write_Cmd_Data(0x0011,0x0007);
Write_Cmd_Data(0x0012,0x0000);
Write_Cmd_Data(0x0013,0x0000);
//vgh
Write_Cmd_Data(0x0010,0x1290);
Write_Cmd_Data(0x0011,0x0227);
//delayms(100);
//vregiout
Write_Cmd_Data(0x0012,0x001d);//0x001b
//vomamplitude
Write_Cmd_Data(0x0013,0x1500);
//vomH
Write_Cmd_Data(0x0029,0x0018);
Write_Cmd_Data(0x002B,0x000D);
//gamma
Write_Cmd_Data(0x0030,0x0004);
Write_Cmd_Data(0x0031,0x0307);
Write_Cmd_Data(0x0032,0x0002);//0006
Write_Cmd_Data(0x0035,0x0206);
Write_Cmd_Data(0x0036,0x0408);
Write_Cmd_Data(0x0037,0x0507);
Write_Cmd_Data(0x0038,0x0204);//0200
Write_Cmd_Data(0x0039,0x0707);
Write_Cmd_Data(0x003C,0x0405);//0504
Write_Cmd_Data(0x003D,0x0F02);
//ram
Write_Cmd_Data(0x0050,0x0000);
Write_Cmd_Data(0x0051,0x00EF);
Write_Cmd_Data(0x0052,0x0000);
Write_Cmd_Data(0x0053,0x013F);
Write_Cmd_Data(0x0060,0xA700);
Write_Cmd_Data(0x0061,0x0001);
Write_Cmd_Data(0x006A,0x0000);
//
Write_Cmd_Data(0x0080,0x0000);
Write_Cmd_Data(0x0081,0x0000);
Write_Cmd_Data(0x0082,0x0000);
Write_Cmd_Data(0x0083,0x0000);
Write_Cmd_Data(0x0084,0x0000);
Write_Cmd_Data(0x0085,0x0000);
Write_Cmd_Data(0x0090,0x0010);
Write_Cmd_Data(0x0092,0x0600);
Write_Cmd_Data(0x0093,0x0003);
Write_Cmd_Data(0x0095,0x0110);
Write_Cmd_Data(0x0097,0x0000);
Write_Cmd_Data(0x0098,0x0000);
Write_Cmd_Data(0x0007,0x0133);
uchardir_y(uchark)
{return(1-k%2)*(k/2*2-1);}
uchardir_x(uchark)
{return(k%2)*(k/2*2-1);}
voidClearScreen(void)
uinti,j;
LCD_SetPos(0,240,0,320);//320x240
for(i=0;i<320;i++)
for(j=0;j<240;j++)
{if(j==59||i>=310)Write_Data_U16(col[8]);
elseWrite_Data_U16(col[0]);
voidSET(charx,chary,uchark)
uinti,bColor;
bColor=col[k];
LCD_SetPos(30+x*15,43+x*15,10+y*15,23+y*15);
for(i=0;i<225;i++)
Write_Data_U16(bColor);
voidSET1(uintz,uchark)
{chari;
i=0;
while(i<16)
{if(z&0x8000)SET(i%4+a,i/4+b,k);
z<<=1;i++;
ucharNUM(ucharn)
{switch(n)
{case0:
return0x3f;break;
case1:
return0x06;break;
case2:
return0x5b;break;
case3:
return0x4f;break;
case4:
return0x66;break;
case5:
return0x6d;break;
case6:
return0x7d;break;
case7:
return0x07;break;
case8:
return0x7f;break;
case9:
return0x6f;break;
return0x00;
voidOUTNUM(charx,chary,ucharn)
inta,b,i;
a=30+x*15,b=10+y*15;
LCD_SetPos(a,a+14,b,b+31);
for(i=0;i<512;i++)
Write_Data_U16(col[0]);
if(n&0x80)
LCD_SetPos(a+14,a+15,b+30,b+31);
for(i=0;i<4;i++)Write_Data_U16(col[8]);
n<<=1;
LCD_SetPos(a+4,a+11,b+16,b+17);
for(i=0;i<16;i++)Write_Data_U16(col[8]);
LCD_SetPos(a+2,a+3,b+4,b+15);
for(i=0;i<24;i++)Write_Data_U16(col[8]);
LCD_SetPos(a+2,a+3,b+18,b+29);
LCD_SetPos(a+4,a+11,b+30,b+31);
LCD_SetPos(a+12,a+13,b+18,b+29);
LCD_SetPos(a+12,a+13,b+4,b+15);
LCD_SetPos(a+4,a+11,b+2,b+3);
voidPRSCORE(void)
uintk;chari,n,q;
k=score;i=1;
while(k)
n=NUM(k%10);
OUTNUM(i,2,n);
k/=10;i--;
OUTNUM(-2,12,0x38);
q=speed;i=0;
while(q)
n=NUM(q%10);
OUTNUM(i,12,n);
q/=10;i--;
ucharCANMOVE(ucharq)//判定方块是否能朝q方向移动
uchari,j,z;uintk;
if(!
p)return0;
i=a+dir_x(q);j=b+dir_y(q);
z=0;k=0;
while(z<4)
k=k+(((fi[j+z]<>(4*z));z++;
if((k&p))return0;
elsereturn1;
voidMOVE(ucharq)//朝q方向移动方块
SET1(p,0);
a+=dir_x(q);b+=dir_y(q);
SET1(p,color);
voidSYS(void)//将可活动的方块都变为不可活动的方块
{ucharz;uintk;
z=0;k=p;
fi[b+z]|=((k&0xf000)>>a);
k<<=4;z++;
p=0;
voidTURN(void)//方块变形
uintk,p1;ucharz;
switch(p)
{case0x0f00:
p1=0x4444;break;case0x4444:
p1=0x0f00;break;
case0x0740:
p1=0x0622;break;case0x0622:
p1=0x02e0;break;case0x02e0:
p1=0x4460;break;case0x4460:
p1=0x0740;break;
case0x0e20:
p1=0x2260;break;case0x2260:
p1=0x0470;break;case0x0470:
p1=0x0644;break;case0x0644:
p1=0x0e20;break;
case0x0e40:
p1=0x4c40;break;case0x4c40:
p1=0x4e00;break;case0x4e00:
p1=0x4640;break;case0x4640:
p1=0x0e40;break;
case0x0c60:
p1=0x2640;break;case0x2640:
p1=0x0c60;break;
case0x06c0:
p1=0x4620;break;case0x4620:
p1=0x06c0;break;
case0x0660:
p1=0x0660;break;}
k=k+(((fi[b+z]<>(4*z));z++;
(k&p1))
{SET1(p,0);p=p1;SET1(p,color);}
ucharSCORED(void)//满行消去,返回加分
{uchari,j,k,s=0,bcolor;
bcolor=time%8+1;
for(k=19;k>0;k--)if(fi[k]==0xffff)
for(i=2;i<14;i++)for(j=k;j>0;j--)
if((((fi[j]<
{if(((fi[j]<
elseSET(i,j,bcolor);
for(j=k;j>0;j--)
fi[j]=fi[j-1];
k++;s++;
returns;
voidputbox(void)//随机取一个方块,输出到左边并等待下次放出
{chari;uintk;
t=boxes[time%7];
pcolor=time%8+1;
i=0;k=t;
{if(k&0x8000)SET(i%4-2,i/4+5,pcolor);
elseSET(i%4-2,i/4+5,0);
k<<=1;i++;
uchargetbox(void)//取上次存储的方块,放出,返回能否放出方块(不能则返回0,游戏结束)
p)p=t;a=6,b=0;
color=pcolor;
if(fi[0]!
=0xc003)return0;
voidmain(void)
{uchark,cm,cn,ins;
a=6,b=0;
score=1;time=0;
leve=1;speed=leve+score/200;
ILI9325_Initial();
ClearScreen();
PRSCORE();
Init_Timer1();
while
(1)
k=keyscan();
if(k==1&&leve>1){leve--;speed=leve+score/200;PRSCORE();}
if(k==3&&leve<9){leve++;speed=leve+score/200;PRSCORE();}
if(k==4)break;
=8)
delay(30000);
putbox();
getbox();
cm=time;
ins=speed*speed/10-3*speed+28;
do
if(k==1)if(CANMOVE
(1))MOVE
(1);
if(k==3)if(CANMOVE(3))MOVE(3);
if(k==2)if(CANMOVE
(2)){MOVE
(2);continue;}
if(k==4)TURN();
{delay(30000);if(k==4)delay(30000);}
cn=time;
if(cn>cm&&cn-cm>ins)break;
if(cnins)break;
}while(p);
if(CANMOVE
(2))MOVE
(2);elseSYS();//方块自动下移,不可下移时把可移动方块变为不可移动
k=SCORED();//满行消去,返回加分
if(k){score+=(k+1)*(k+1);speed=leve+score/200;PRSCORE();}
p)
k=getbox();
k)break;
putbox();//无法放出方块己方游戏结束
voidTimer1_isr(void)interrupt3using1
TH1=0x3c;//重新赋值
time++;
if(time>100)time=0;
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2