51单片机的俄罗斯方块
- 格式:docx
- 大小:85.85 KB
- 文档页数:24
本科课程设计题目:基于单片机的8*8LED 俄罗斯方块设计姓名孙俊学号2008130346院(系)物理与信息科学学院电子系专业、年级电子信息科学与技术2008级指导教师刘美容二○一一年十月基于单片机的8x8 俄罗斯方块设计一、设计任务《俄罗斯方块》是一款世人皆知,看似简单实则变化无穷的小游戏。
本次设计以51单片机为基础,设计一款功能简单的8*8点阵俄罗斯方块游戏,我们将以汇编语言编程实现以下操作:图形的显示合成,通过按键控制图形的移动和旋转,满格消行,手动复位等。
本次设计俄罗斯方块功能简单,用单片机的最小系统就能得以实现。
而单片机的最小系统设计中实际上最重要的就是对键盘/显示器接口电路的设计,由于系统功能不同所以要求就不同,接口设计也就不同。
对一个键盘/显示器接口设计应从整个系统出发,综合考虑软、硬件特点。
其中,硬件设计包括初始的设计原理和原理图介绍,到最终的电路图实际焊接以及布局,软件设计我们会给出具体的设计方案,比如图形的显示合成,通过按键控制图形的移动和旋转,满格消行等的设计流程图,以及具体的汇编程序。
二、设计方案本次设计初期是在keil和proteus联合仿真中进行,编程语言为51汇编语言,后期是进行实物焊接。
本次我们采用单片机STC89C52控制模块提供电源,以点阵式LED 显示,采用独立按键,直接在I/O口线上接上按键开关。
因为设计时精简和优化了电路,所以剩余的口资源还比较多,我们使用四个按键,分别是旋转键,下键,左键,右键。
这种方案实现可行,既满足系统功能要求,又减少了系统实现的复杂度。
而由于STC89C52是一种带8K 字节闪烁可编程可檫除只读存储器的低电压,高性能COMOS8的微处理器,该器件采用ATMEL 搞密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
89C52内置8位中央处理单元、256字节内部数据存储器RAM 、8k 片内程序存储器(ROM )32个双向输入/输出(I/O)口、3个16位定时/计数器和5个两级中断结构,一个全双工串行通信口,片内时钟振荡电路。
基于51单片机的俄罗斯方块游戏毕业设计论文目录摘要..................................................... 错误!未定义书签。
ABSTRACT ..................................................... 错误!未定义书签。
1 绪论 (6)1.1 课题背景 (6)1.2 课题的主要研究内容 (6)1.3 课题的研究现状及意义 (7)2 系统硬件平台设计 (7)2.1 STC12C5A60S2单片机概述 (7)2.2 STC12C5A60S2最小系统 (8)2.3 电源系统 (8)2.4 振荡电路 (9)2.5 复位系统 (9)2.6 程序下载系统 (10)2.7 音乐播放系统 (11)2.8 LCD液晶显示接口电路 (11)2.9 操作控制接口 (12)3 系统软件平台构建 (13)3.1 μVision简介 (13)3.2 LCD12864液晶屏显示原理 (13)3.2.1 LCD模块总线选择及时序 (13)3.2.2 LCD显示RAM区映射概况 (14)3.2.3 LCD的驱动方法 (15)3.2.4 LCD驱动程序架构 (15)3.3 俄罗斯方块游戏设计 (16)3.3.1 俄罗斯方块游戏功能简介 (16)3.3.2 系统界面的设计 (17)3.3.3 游戏系统“枚举算法”概述 (19)3.3.4 俄罗斯方块造型设计的方法 (20)3.3.5 随机产生俄罗斯方块的方法 (20)3.3.6 俄罗斯方块平移的实现方法 (22)3.3.7 俄罗斯方块旋转的实现方法 (23)3.3.8 俄罗斯方块下移的实现方法 (25)3.3.9 满行检测及消行功能的实现方法 (26)3.3.10 游戏积分的计算方法 (27)3.4 双人俄罗斯方块游戏设计 (29)3.4.1 RTX51 Tiny简介 (29)3.4.2 RTX51 Tiny的内核分析 (29)3.4.3 游戏开发环境的配置 (32)3.4.4 双人单机对战模式的实现流程 (33)3.5 系统背景音乐的设计 (33)3.5.1音乐的设计原理 (33)3.5.2 音乐播放的实现方法 (35)3.5.3 音效程序流程 (35)3.6 系统主程序流程图 (36)4 产品功能说明与系统性能测试 (37)4.1 产品功能说明 (37)4.2 系统性能测试 (38)5 结束语 (38)参考文献 (40)致谢黄忠南基于单片机的俄罗斯方块游戏设计1 绪论1.1 课题背景如今,计算机系统的发展已明显地朝三个方向发展,这三个方向就是:巨型化,单片化,网络化。
#include"reg52.h"#define WINDOW_XADDR_START 0x0050 // Horizontal Start Address Set#define WINDOW_XADDR_END 0x0051 // Horizontal End Address Set#define WINDOW_YADDR_START 0x0052 // Vertical Start Address Set#define WINDOW_YADDR_END 0x0053 // Vertical End Address Set#define GRAM_XADDR 0x0020 // GRAM Horizontal Address Set#define GRAM_YADDR 0x0021 // GRAM Vertical Address Set#define GRAMWR 0x0022 // memory write#define uint unsigned int#define uchar unsigned charsbit CS=P2^2; //片选sbit RES=P2^1; //复位sbit RS=P2^4; //数据/命令选择sbit RW=P2^5;const uint col[9]={0x0000,0xFFFF,0x001F,0xFFE0,0xF800,0xF81F,0x07E0,0x7FFF,0x051F};//Black White Blue Yellow Red Magenta Green Cyan Blue2const uint boxes[7]={ //方块样式存储数组0x0f00,0x0740,0x0e20,0x0e40,0x0c60,0x06c0,0x0660 };uint fi[23]={0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xffff,0xffff,0xffff};uchar a,b;uint t,p;uint score;uchar speed,leve,time; //游戏速度uchar pcolor,color;void Init_Timer1(void){TMOD |= 0x10; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响TH1=0x3c; //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出TL1=0xb0;EA=1; //总中断打开ET1=1; //定时器中断打开TR1=1; //定时器开关打开}void delay(unsigned int i) //延时函数{while(i--);}uchar keyscan(void) //键盘扫描函数,使用行列反转扫描法{uchar k;P1=0xff;k=P1;if(k!=0xff){delay(100);if(k!=0xff){k=P1;if(k==0xfd) return 1;if(k==0xfb) return 2;if(k==0xf7) return 3;if(k==0xef) return 4;}}return 8;}void delayms(uint count){int i,j;for(i=0;i<count;i++){for(j=0;j<260;j++);}}void Write_Cmd(uchar DH,uchar DL) {CS=0;RS=0;P0=DH;RW=0;RW=1;P0=DL;RW=0;RW=1;CS=1;}void Write_Data(uchar DH,uchar DL) {CS=0;RS=1;P0=DH;RW=1;P0=DL;RW=0;RW=1;CS=1;}void Write_Cmd_Data (uchar x,uint y){uchar m,n;m=y>>8;n=y;Write_Cmd(0x00,x);Write_Data(m,n);}void Write_Data_U16(uint y){unsigned char m,n;m=y>>8;n=y;Write_Data(m,n);}static void LCD_SetPos(uint x0,uint x1,uint y0,uint y1) {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); }void ILI9325_Initial(void){CS=1;delayms(5);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);//power on sequence VGHVGLWrite_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);//vom amplitudeWrite_Cmd_Data(0x0013,0x1500);//delayms(100);//vom HWrite_Cmd_Data(0x0029,0x0018);Write_Cmd_Data(0x002B,0x000D);//gammaWrite_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);// 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);}uchar dir_y(uchar k){ return (1-k%2)*(k/2*2-1);}uchar dir_x(uchar k){ return (k%2)*(k/2*2-1);}void ClearScreen(void){uint i,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]);else Write_Data_U16(col[0]);}}}void SET(char x,char y,uchar k){uint i,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);}void SET1(uint z,uchar k){char i;i=0;while(i<16){if(z&0x8000) SET(i%4+a,i/4+b,k);z<<=1;i++;}}uchar NUM(uchar n){switch(n){case 0:return 0x3f;break;case 1:return 0x06;break;case 2:return 0x5b;break;case 3:return 0x4f;break;case 4:return 0x66;break;case 5:return 0x6d;break;case 6:return 0x7d;break;case 7:return 0x07;break;case 8:return 0x7f;break;case 9:return 0x6f;break;}return 0x00;}void OUTNUM(char x,char y,uchar n){int a,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]);}}void PRSCORE(void){uint k;char i,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--;}}uchar CANMOVE(uchar q)//判定方块是否能朝q 方向移动{uchar i,j,z;uint k;if(!p) return 0;i=a+dir_x(q);j=b+dir_y(q);z=0;k=0;while(z<4){k=k+(((fi[j+z]<<i)&0xf000)>>(4*z)); z++;}if((k&p)) return 0;else return 1;}void MOVE(uchar q)//朝q 方向移动方块{SET1(p,0);a+=dir_x(q);b+=dir_y(q);SET1(p,color);}void SYS(void)//将可活动的方块都变为不可活动的方块{uchar z;uint k;z=0;k=p;while(z<4){fi[b+z]|=((k&0xf000)>>a);k<<=4;z++;}p=0;}void TURN(void)//方块变形{uint k,p1;uchar z;switch(p){case 0x0f00: p1=0x4444;break;case 0x4444: p1=0x0f00;break;case 0x0740: p1=0x0622;break;case 0x0622: p1=0x02e0;break;case 0x02e0: p1=0x4460;break;case 0x4460: p1=0x0740;break;case 0x0e20: p1=0x2260;break;case 0x2260: p1=0x0470;break;case 0x0470: p1=0x0644;break;case 0x0644: p1=0x0e20;break;case 0x0e40: p1=0x4c40;break;case 0x4c40: p1=0x4e00;break;case 0x4e00: p1=0x4640;break;case 0x4640: p1=0x0e40;break;case 0x0c60: p1=0x2640;break;case 0x2640: p1=0x0c60;break;case 0x06c0: p1=0x4620;break;case 0x4620: p1=0x06c0;break;case 0x0660: p1=0x0660;break;}z=0;k=0;while(z<4){k=k+(((fi[b+z]<<a)&0xf000)>>(4*z)); z++;}if(!(k&p1)){ SET1(p,0);p=p1;SET1(p,color);}}uchar SCORED(void)//满行消去,返回加分{ uchar i,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]<<i)&0x8000)^((fi[j-1]<<i)&0x8000))){if(((fi[j]<<i)&0x8000)) SET(i,j,0);else SET(i,j,bcolor);}for(j=k;j>0;j--)fi[j]=fi[j-1];k++;s++;}return s;}void putbox(void)//随机取一个方块,输出到左边并等待下次放出{ char i;uint k;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);else SET(i%4-2,i/4+5,0);k<<=1;i++;}}uchar getbox(void)//取上次存储的方块,放出,返回能否放出方块(不能则返回0,游戏结束) {if(!p)p=t;a=6,b=0;color=pcolor;SET1(p,color);if(fi[0]!=0xc003) return 0;else return 1;}void main(void){ uchar k,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(cn<cm&&cn+100-cm>ins) break;} while(p);if(CANMOVE(2)) MOVE(2);else SYS();//方块自动下移,不可下移时把可移动方块变为不可移动k=SCORED(); //满行消去,返回加分if(k) {score+=(k+1)*(k+1);speed=leve+score/200; PRSCORE();}if(!p){k=getbox();if(!k) break;putbox(); //无法放出方块己方游戏结束}}}void Timer1_isr(void) interrupt 3 using 1{TH1=0x3c; //重新赋值TL1=0xb0;time++;if(time>100) time=0;}。
基于51单片机的俄罗斯方块游戏代码实现主要包括以下几个方面:
1. 数据结构:使用数据结构来表示游戏中的各种元素,如方块、矩阵等。
2. 导航键控制:通过键盘扫描代码,获取用户输入的导航键(上下左右)信息,以便控制方块的移动。
3. 方块生成:随机生成新的方块,或者根据游戏规则生成特定的方块。
4. 方块移动:根据用户输入的导航键信息,移动当前方块的位置。
5. 方块旋转:根据用户输入的导航键信息,旋转当前方块的角度。
6. 碰撞检测:检测方块与游戏区域边界、其他方块之间的碰撞,以及方块自身的碰撞。
7. 游戏规则:实现游戏的基本规则,如方块消除、得分、游戏结束等。
8. 用户界面:显示游戏界面,包括方块、游戏区域边界、得分等信息。
9. 延时与中断:通过延时函数和中断函数,实现游戏的实时性,如方块自动下落、响应用户输入等。
10. 代码优化:对代码进行优化,提高游戏运行效率和用户体验。
总之,基于51单片机的俄罗斯方块游戏代码实现涉及到数据结构、键盘扫描、方块生成与移动、碰撞检测、游戏规则、用户界面、延时与中断等多个方面。
====================程序说明=================== ;程序编写:超越夢想;联系方式:; QQ: 421965311; 邮箱:liwenkuicymx@;编写时间:2010年5月05号;实现功能:俄罗斯方块;转载请注明此部分;==============按键定义接口==============zyaj bit p3.4 ;左移按键;xzaj bit p3.3 ;旋转按键;jsaj bit p3.5 ;加速按键;ztaj bit p3.6 ;暂停按键;yyaj bit p3.7 ;右移按键;;============;列值移动区;===============xian00 equ 30Hxian01 equ 31Hxian10 equ 32Hxian11 equ 33Hxian20 equ 34Hxian21 equ 35Hxian30 equ 36Hxian31 equ 37Hxian40 equ 38Hxian41 equ 39Hxian50 equ 3aHxian51 equ 3bHxian60 equ 3cHxian61 equ 3dHxian70 equ 3eHxian71 equ 3fHxian80 equ 40Hxian81 equ 41Hxian91 equ 43H;==============背景区定义=================== bei00 equ 50Hbei01 equ 51Hbei10 equ 52Hbei11 equ 53Hbei20 equ 54Hbei21 equ 55Hbei30 equ 56Hbei31 equ 57Hbei40 equ 58Hbei41 equ 59Hbei50 equ 5aHbei51 equ 5bHbei60 equ 5cHbei61 equ 5dHbei70 equ 5eHbei71 equ 5fHbei80 equ 60Hbei81 equ 61Hbei90 equ 62Hbei91 equ 63H;==========旋转时存移动区数据============ yidong00 equ 65Hyidong01 equ 66Hyidong10 equ 67Hyidong11 equ 68Hyidong20 equ 69Hyidong21 equ 6aHyidong30 equ 6bHyidong31 equ 6cHyidong40 equ 6dHyidong41 equ 6eHyidong50 equ 6fHyidong60 equ 71H yidong61 equ 72H yidong70 equ 73H yidong71 equ 74H yidong80 equ 75H yidong81 equ 76H yidong90 equ 77H yidong91 equ 78Hxianshi00 equ 10h xianshi01 equ 11h xianshi10 equ 12h xianshi11 equ 13h xianshi20 equ 14h xianshi21 equ 15h xianshi30 equ 16h xianshi31 equ 17h xianshi40 equ 18h xianshi41 equ 19h xianshi50 equ 1ah xianshi51 equ 1bh tishicun1 equ 28h tishicun2 equ 29h tishicun3 equ 2ah tishicun4 equ 2bh yycishuzc equ 44h xuancun1 equ 45h xuancun2 equ 46h xuancun3 equ 47h xuancun4 equ 48h zycishu equ 49h yycishu equ 4ah zycishuzc equ 4bh zhancun equ 4ch xiayijishu equ 4dhxiayishuzc equ 4ehhang equ 4fhfeishu equ 08hfeishuge equ 09hfeishushi equ 0ahguanshu equ 0bhflag bit 20h.0ztf bit 20h.1ykbf bit 20h.2 ;右靠边标志位; zkbf bit 20h.3 ;左靠边标志位; xiacixyf bit 20h.4hechen bit 20h.5changfanf bit 20h.6ctuf bit 20h.7jiasu bit 25h.0jiasudu bit 25h.1anjian3 bit 25h.2jiashuf bit 25h.3 ;加速标志位; xuan0 bit 25h.4 ;xuan1 bit 25h.5cdf bit 25h.6xiaxiaof bit 25h.7yyf bit 26h.0 ;右移标志位; zyf bit 26h.1 ;左移标志位yiyou bit 26h.2 ;已右移标志位; yizuo bit 26h.3 ;已左移标志位; yiz bit 26h.4 ;已旋转标志位; xzf bit 26h.5 ;旋转标志位; ztkf bit 26h.6changtiaof bit 26h.7zfxingf bit 27h.0zting bit 27h.1anjian4 bit 27h.2diyici bit 27h.3suijishuf bit 27h.4tif bit 27h.5 shenglif bit 27h.6 tingzhif bit 27h.7date equ P0 weixuan equ p1latch_h equ p3.0latch_l equ p3.1 jiepaicshu equ 1chshijian equ 1dh zhancun0 equ 1fh zhancun1 equ 1ehorg 00hjmp startorg 0bhjmp time0org 30hstart:mov sp,#79hmov r0,#7fhkkk: mov @r0,#00djnz r0,kkkmov tmod,#01hmov th0, #0b1hmov tl0,,#0e0hsetb tr0setb et0setb easetb diyicisetb suijishufmov xian30,#07Hmov xian40,#04Hmov xian50,#00H mov xianshi00,#0ffhmov xianshi01,#0ffhmov xuancun1,xian30mov xuancun2,xian40mov xuancun3,xian50mov 1dh,#20mov jiepaicshu,1dhmov guanshu,#01hmov 0dh,#0mov 0eh,#0setb xuan0mov p0,#00mov p2,#00main: jnb flag,mainclr flagjnb xuan0,m60mov dptr,#tab5call xianshihanzi ;显示开机画面“俄罗斯方块”;jmp mainm60: jnb tingzhif,m26mov dptr,#tab4call xianshihanzi;显示"再来一次"jmp mainm26: jnb shenglif,m22mov dptr,#tab3call xianshihanzi; 显示"你通关啦!"jmp mainm22: call jiasuchuli ;加速判断子程序;jnb jiasu,mm10 ;jmp mm8mm10: call zantingchuli ;暂停判断子程序;jnb ztf,mm9jb ztkf,abcmm9: djnz jiepaicshu,abcmov jiepaicshu,shijianmm8: call xiayi ;下移子程序;abc: call xianshi ;显示子程序;call jianpan ;调用按键判断子程序;call jianzichuli;调用键值处理子程序;call suijishuchengxu;调用随机数产生子程序;jmp mainxianshihanzi:inc 0dhmov 0eh,r0mov a,0dhcjne a,#02,k1mov 0dh,#0inc 0ehinc 0ehmov a,0ehk1: cjne a,#0a0h,k5mov 0eh,#00jnb tingzhif,k0clr tingzhifmov feishu,#00hmov guanshu,#01hk0: jnb xuan0,k5clr xuan0k5: call xhcall xianshifenshuretxh:LOOP01: mov p2,#0mov date,#00Hclr latch_h ;下面的两个点阵不亮setb latch_l ;开上面的两个点阵mov weixuan,0cHmov a,r0movc a,@a+dptrmov date,acall delaymov date,#00clr latch_lsetb latch_hinc r0mov weixuan,0cHmov a,r0movc a,@a+dptrmov date,acall delaymov date,#00inc r0inc 0cHmov a,0cHcjne a,#16,LOOP01mov 0cH,#0mov r0,0ehret;=========随机数调用子程序============= suijishuchengxu:jnb suijishuf,c28clr suijishufjnb diyici,c28clr diyicicall suijishucall tishizcdjmp c26c28: jnb tif,c26clr tifmov xuancun1,tishicun1mov xuancun2,tishicun2mov xuancun3,tishicun3mov xuancun4,tishicun4mov xian30,tishicun1mov xian40,tishicun2mov xian50,tishicun3mov xian60,tishicun4mov a,xian40cjne a,#0fh,c32setb changtiaofjmp c34c32: mov a,xian30cjne a,#03,c34mov a,xian40cjne a,#03,c34setb zfxingfc34: mov tishicun4,#00hcall suijishucall tishizcdc26: rettishizcd:mov a,tishicun1rl amov xianshi20,amov a,tishicun2rl amov xianshi30,amov a,tishicun3rl amov xianshi40,aretjianpan:mov p3,#0ffhjb yyaj,di2setb yyf ;右移标志位置1;jmp tiaodi2: jb zyaj,di3setb zyf ;左移标志位置1;jmp tiaodi3: jb xzaj,tiaosetb xzfjmp tiaotiao: ret;============加速处理子程序================ jiasuchuli:jnb anjian3,panduan3;有按键按下,积木加速下移jnb jsaj,jiasuxiayiclr anjian3clr jiasudujmp haopanduan3:jb jsaj,haosetb anjian3jmp haojiasuxiayi:jb jiasudu,haosetb jiasudusetb jiasujnb ztkf,haoclr jiasuhao: retzantingchuli:jnb anjian4,panduan4;jnb ztaj,zantingclr anjian4clr ztingjmp hao1panduan4:jb ztaj,hao1setb anjian4jmp hao1zanting:jb zting,hao1setb ztingsetb ztfcpl ztkfhao1: retjianzichuli:jnb yyf,g0jmp g1g0: jnb zyf,g4jmp g3g4: jnb xzf,sdfjnb xzaj,f1clr xzfclr yizjmp sdfg1: jnb yyaj,ccclr yyfclr yiyoujmp sdfg3: jnb zyaj,g2clr zyfclr yizuojmp sdfg2: call zychenxujmp sdfcc: call yychenxujmp sdff1: call zhuang sdf: retzhuang:jnb yiz,f3jmp m0f3:call shifouchudijnb cdf,dmjmp m0dm: jnb zfxingf,fzfx zfx: jmp m0fzfx: call cunxiansetb yizcall qingpingmov 21h,xuancun1mov 22h,xuancun2mov 23h,xuancun3mov 24h,xuancun4jb changtiaof,ct call xuanzhuangjxct: cpl changfanfcall ctxzjxsf:mov xian30,21hmov xian40,22hmov xian50,23hmov xian60,24hcall zychuli ;左移处理;call yychuli ;右移处理;mov xuancun1,21hmov xuancun2,22hmov xuancun3,23hmov xuancun4,24hcall xiayichulicall shifoucbjcall shifouchubianm0:retctxzjx:jnb changfanf,cccmov 21h,#02hmov 22h,#02hmov 23h,#02hmov 24h,#02hjmp m20ccc: mov 21h,#00hmov 22h,#0fhmov 23h,#00hmov 24h,#00hm20: retshifouchudi:mov a,xiayijishusetb ccjne a,#13,dfdf: jc dcsetb cdfjmp dtdt: retshifouchubian:mov r0,#xian00mov a,@r0anl a,xian90cjne a,#0,fhmov r0,#xian01mov a,@r0anl a,xian91cjne a,#0,fhjmp wifh: call fangxianwi: retxiayichuli:mov xiayishuzc,xiayijishumov r0,xiayijishucjne r0,#0,loop2jmp m7loop2: call xydjnz xiayijishu,loop2 mov xiayijishu,xiayishuzc m7: retzychuli:mov zycishuzc,zycishu mov r5,zycishucjne r5,#00h,loop4retloop4: call zydjnz zycishu,loop4mov zycishu,zycishuzcretyychuli:mov yycishuzc,yycishumov r5,yycishucjne r5,#00h,loop5retloop5: call yydjnz yycishu,loop5m15: mov yycishu,yycishuzcretxuanzhuangjx:mov c,21h.2mov xuan0,cmov c,21h.0mov 21h.2,cmov c,23h.0mov 21h.0,cmov c,23h.2mov 23h.0,cmov c,xuan0mov 23h.2,cmov c,21h.1mov xuan1,cmov c,22h.0mov 21h.1,cmov c,23h.1mov 22h.0,cmov c,22h.2mov 23h.1,cmov c,xuan1mov 22h.2,cclr xuan0clr xuan1ret;===============左移子程序=============== zychenxu:jnb yizuo,ssretss: setb yizuocall kaozbiaojnb zkbf,d1retd1: call cunxiancall zyinc zycishucall shifoucbjjnb ctuf,d2dec zycishuclr ctufd2: retzy: mov zhancun0,xian00mov zhancun1,xian01mov r0,#xian00call zydongmov r0,#xian01call zydongmov xian90,zhancun0mov xian91,zhancun1retkaozbiao:mov a,xian00cjne a,#00,qwmov a,xian01cjne a,#00,qwclr zkbfjmp bbqw: setb zkbf ;置左靠边标志位; bb: retzydong:mov r3,#9loop44:inc r0inc r0mov a,@r0dec r0dec r0mov @r0,ainc r0inc r0djnz r3,loop44ret;=================右移子程序================ yychenxu:jnb yiyou,mmretmm: setb yiyoucall kaoybiao ;调用靠右边判断子程序;jnb ykbf,d0retd0: call cunxiancall yyinc yycishucall shifoucbjjnb ctuf,d4dec yycishuclr ctufd4: retyy: mov zhancun0,xian90mov zhancun1,xian91mov r0,#xian90call yydongmov r0,#xian91call yydongmov xian00,zhancun0mov xian01,zhancun1retkaoybiao:mov a,xian90cjne a,#00,qemov a,xian91clr ykbfjmp bcqe: setb ykbf ;置左靠边标志位;bc: retyydong:mov r3,#9loop45:dec r0dec r0mov a,@r0inc r0inc r0mov @r0,adec r0dec r0djnz r3,loop45retshifoucbj:mov r0,#xian00mov r1,#bei00mov r3,#20loop47:mov a,@r0anl a,@r1cjne a,#0,fhuiinc r0inc r1djnz r3,loop47clr ctufretfhui: setb ctufcall fangxianret;=================显示子程序===================== xianshi:mov r2,#10mov r0,#xian00mov r1,#bei00loop61: mov date,#00clr latch_l ;下面的两个点阵不亮setb latch_h ;开上面的两个点阵mov a,r3anl a,#0xffmov r3,amov weixuan,r3 ;片选mov a,@r1orl a,@r0 ;数据mov date,acall delay ;延时mov date,#00 ;关屏幕inc r0inc r1clr latch_hsetb latch_lmov a,r3anl a,#0xffmov r3,amov weixuan,r3mov a,@r1orl a,@r0mov date,a ;数据call delay ;延时mov date,#00 ;关屏幕inc r3inc r0inc r1djnz r2,loop61mov date,#00 ;显示左边10列;mov r3,#10mov r2,#6mov r0,#xianshi00loop3: mov date,#00clr latch_l ;下面的两个点阵不亮setb latch_h ;开上面的两个点阵mov weixuan,r3 ;片选mov date,@r0dst: call delay ;延时mov date,#00 ;关屏幕inc r0clr latch_hsetb latch_lmov weixuan,r3mov date,@r0 ;数据dsd: call delay ;延时mov date,#00 ;关屏幕inc r0inc r3djnz r2,loop3call xianshifenshucall cdguanshuretxianshifenshu:mov a,feishu ;显示分数;mov b,#10div abmov feishushi,amov feishuge,bmov a,feishushimov dptr,#tab1movc a,@a+dptrmov p2,#00mov p2,aclr p1.4setb p1.5call delaymov a,feishugemovc a,@a+dptrmov p2,#0mov p2,aclr p1.5setb p1.4call delaymov p2,#0ret;=================下移子程序================== xiayi:call cunxianjb xiacixyf,hccall xycall xiacinfouxyinc xiayijishucall shifoucbjjnb ctuf,wtddec xiayijishuclr ctufhc: call beijinghechenwtd: retcunxian:mov r0,#xian00mov r1,#YIDONG00mov r2,#20loop42:mov a,@r0mov @r1,ainc r0inc r1djnz r2,loop42retxiacinfouxy:mov r0,#xian01mov r1,#10loop41:mov a,@r0anl a,#80h ;判断是否触底;cjne a,#0,wtinc r0inc r0djnz r1,loop41clr xiacixyfjmp wywt: setb xiacixyfwy: retbeijinghechen: ; 背景合成;mov r0,#xian00mov r1,#bei00mov r2,#20loop21:mov a,@r1mov zhancun,@r0orl a,zhancunmov @r1,ainc r1inc r0djnz r2,loop21call xiaohang ;调用消行子程序;call qingping ;调用清屏子程序;call rst ;调用复位子程序;setb suijishufsetb tifretqingping:mov r0,#xian00mov r3,#20loop46:mov @r0,#0inc r0djnz r3,loop46retfangxian:mov r0,#xian00mov r1,#yidong00mov r2,#20loop43:mov a,@r1mov @r0,ainc r0inc r1djnz r2,loop43ret;***********复位子程序*************rst:mov xiayijishu,#0mov yycishu,#00mov zycishu,#00mov xuancun4,#0clr xiacixyfclr jiasuclr zfxingfclr ctufclr changfanfclr changtiaofsetb suijishufsetb tifretxiaohang:mov r4,#08mov r3,#01hk3: mov r1,#0mov r0,#bei00mov r2,#8call xh0 ;先判断左八列是否达到消行的要求1 d01: cjne r3,#01,afg ;判断第一行;cjne r1,#0,tzcmov a,@r0anl a,r3cjne a,#0,fghjmp abdfgh: inc r0inc r0mov a,@r0anl a,r3cjne a,#0,d01jmp abdafg: cjne r1,#0ffh,abdmov r2,#10inc hangmov r0,#bei00call xhxymov r3,zhancun0abd: mov a,r3rl amov r3,amov zhancun0,r3djnz r4,k3jmp ttytzc: setb tingzhif ;停止处;call qingbjrettty: mov r4,#08mov r3,#01hfor2:mov r1,#0mov r0,#bei01mov r2,#8call xh0mov a,@r0anl a,r3cjne a,#0,fgtjmp abtfgt: inc r0inc r0mov a,@r0anl a,r3cjne a,#0,aftjmp abtaft: cjne r1,#0ffh,abtinc hangsetb xiaxiaofmov r2,#10mov r0,#bei01call xhxycall shangmiaoxiyimov r3,zhancun0abt: mov a,r3rl amov r3,amov zhancun0,r3djnz r4,for2call jsfshgs ;计算所加的分数和处于的级别数;retxh0:for3:mov a,@r0anl a,r3orl a,r1mov r1,amov a,r1rl amov r1,ainc r0inc r0djnz r2,for3retxhxy:for4:mov r5,#0ffht2: clr cmov a,r5rlc amov r5,amov a,r5anl a,r3cjne a,#0,t2mov a,@r0mov zhancun,a ;最原始数据保存;mov 2eh,aanl a,r5mov 2dh,a ;最高有效位;clr cmov a,zhancunrlc amov zhancun1,a ;左移一次之后的数据;mov a,r5cpl aanl a,zhancun1mov 2ch,amov a,2chorl a,2dhmov @r0,ainc r0inc r0mov r3,zhancun0djnz r2,for4retcdguanshu:mov a,guanshucjne a,#01,g20mov xianshi21,#44hmov xianshi31,#7ehmov xianshi41,#40hjmp xw1g20: cjne a,#02,g30mov xianshi21,#64hmov xianshi31,#52hmov xianshi41,#4chjmp xw1g30: mov xianshi21,#49h mov xianshi31,#49h mov xianshi41,#36h xw1: retjsfshgs:mov r0,hangcjne r0,#00,u0mov hang,#0jmp sw2u0: cjne r0,#01,u1mov a,feishuadd a,#01mov feishu,ajmp sw2u1: cjne r0,#02,u2mov a,feishuadd a,#04mov feishu,ajmp sw2u2: cjne r0,#03,u3mov a,feishuadd a,#08mov feishu,ajmp sw2u3: cjne r0,#04,sw2mov a,feishuadd a,#16mov feishu,asw2: mov hang,#0sw3: mov a,feishusetb cycjne a,#5,s0s0: jnc gs2mov guanshu,#01mov shijian,#20jmp xwgs2: setb cycjne a,#10,s1s1: jnc gs3mov guanshu,#02mov shijian,#10 jmp xwgs3: setb cycjne a,#15,s3s3: jnc sl1mov guanshu,#03mov guanshu,#5 jmp xwsl1: setb shenglifcall qingbjxw: retqingbj:mov r0,#bei00mov r2,#20d8: mov @r0,#0inc r0djnz r2,d8mov r0,#xianshi10 mov r2,#11d9: mov @r0,#0inc r0djnz r2,d9retshangmiaoxiyi:mov r0,#bei00mov r1,#10for6:clr cmov a,@r0rlc amov @r0,ainc r0jmp kdkm: mov a,@r0orl a,#01hmov @r0,akd: inc r0djnz r1,for6ret;============================================= xy:mov r0,#xian00mov r1,#10for7:clr cmov a,@r0rlc amov @r0,ainc r0mov a,@r0rlc amov @r0,ainc r0djnz r1,for7ret;=============产生随机数=============suijishu:mov a,tl0anl a,#07Hrl amov dptr,#tabjmp @a+dptrtab: ajmp sub1ajmp sub2ajmp sub3ajmp sub4ajmp sub5ajmp sub6ajmp sub1sub1:mov tishicun1,#00H mov tishicun2,#07H mov tishicun3,#02Hretsub2:mov tishicun1,#03Hmov tishicun2,#06Hmov tishicun3,#00Hretsub3:mov tishicun1,#06Hmov tishicun2,#03Hmov tishicun3,#00Hretsub4:mov tishicun1,#07Hmov tishicun2,#04Hmov tishicun3,#00Hretsub5:mov tishicun1,#04Hmov tishicun2,#07Hmov tishicun3,#00Hretsub6:mov tishicun1,#00Hmov tishicun2,#0fHmov tishicun3,#00H mov tishicun4,#00hretsub7:mov tishicun1,#03Hmov tishicun2,#03Hmov tishicun3,#00Hretdelay:mov r6,#10mov r7,#50djnz r7,$djnz r6,$-4time0:mov th0,#0b1hmov tl0,#0e0hsetb flagretitab3:db 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00h;你db 00H,40H,00H,20H,0FFH,0F8H,00H,07H db 00H,40H,08H,20H,04H,18H,43H,0FHdb 80H,08H,7FH,0C8H,00H,08H,01H,08Hdb 06H,28H,0CH,18H,00H,00H,00H,00H;通db 00H,40H,40H,42H,20H,44H,1FH,0CCHdb 20H,00H,40H,00H,0BFH,0F1H,84H,91H db 84H,95H,0BFH,0F9H,94H,95H,0A4H,93H db 9FH,0F9H,0C0H,10H,40H,00H,00H,00H;关db 81H,00H,81H,10H,41H,10H,41H,11Hdb 21H,12H,11H,1CH,0DH,10H,03H,0F0Hdb 0DH,10H,11H,18H,21H,14H,21H,13Hdb 41H,1AH,0C1H,90H,41H,00H,00H,00H;啦db 00H,00H,01FH,0FCH,08H,04H, 1FH,0FCH db 42H,08H,82H, 08H, 7FH,0FFH,40H,88H db 40H,48H,43H, 0E8H,5CH,09H, 40H,0EH db 5EH,08H,41H, 0ECH,40H,08H, 00H,00Hdb 00H,00H,00H,00H,00H,00H,00H,00Hdb 00H,00H,00H,00H,30H,38H,33H,0FCH db 33H,0F8H,30H,18H,00H,00H,00H,00H db 00H,00H,00H,00H,00H,00H,00H,00Htab4:db 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00h;再db 04H,00H,04H,02H,04H,02H,0FFH,0F2H db 04H,92H,04H,92H,04H,92H,07H,0FEH db 04H,92H,44H,92H,84H,92H,7FH,0FAH db 04H,13H,06H,02H,04H,00H,00H,00H;玩db 10H,02H,30H,42H,10H,42H,1FH,0FEH db 08H,43H,88H,42H,40H,20H,30H,22Hdb 0FH,0E2H,00H,22H,00H,22H,3FH,0E2H db 40H,23H,40H,32H,70H,20H,00H,00H;一db 00H,80H,00H,80H,00H,80H,00H,80Hdb 00H,80H,00H,80H,00H,80H,00H,80Hdb 00H,80H,00H,80H,00H,80H,00H,80Hdb 00H,80H,00H,0C0H,00H,80H,00H,00H;次db 02H,00H,02H,02H,0FFH,04H,00H,8CH db 080H,40H,40H,00H,20H,20H,00H,18H db 0CH,17H,03H,0D0H,0CH,10H,10H,50Hdb 60H,38H,0C0H,10H,40H,00H,00H,00Hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00htab5:db 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00h;俄db 00H,80H,00H,40H,00H,20H,0FFH,0F8H db 04H,27H,44H,24H,82H,24H,7FH,0FEH db 21H,22H,10H,20H,09H,0FFH,0EH,20H db 32H,22H,41H,34H,0E0H,20H,00H,00H;罗db 80H,00H,88H,7EH,88H,22H,44H,22H db 42H,22H,25H,3EH,29H,0E2H,11H,22H db 09H,22H,09H,3EH,05H,22H,03H,22H db 00H,22H,00H,7FH,00H,02H,00H,00H;斯db 08H,00H,88H,04H,4FH,0FFH,29H,24H db 09H,24H,29H,24H,4FH,0FFH,28H,04H db 10H,00H,0FH,0FCH,00H,44H,00H,42H db 0FFH,0C3H,00H,42H,00H,40H,00H,00H;方db 00H,10H,80H,10H,40H,10H,20H,10H db 18H,10H,07H,0F1H,00H,92H,00H,96H db 40H,90H,80H,90H,40H,90H,3FH,0D0H db 00H,90H,00H,18H,00H,10H,00H,00H;db 08H,20H,18H,20H,08H,20H,0FH,0FFH db 84H,20H,46H,20H,22H,10H,1AH,10H db 07H,0FFH,0AH,10H,12H,10H,22H,10H db 43H,0F8H,0C2H,10H,42H,00H,00H,00Htab1:db 3fh,06h,5bh,4fh,66hdb 6dh,7dh,07h,7fh,6fhend。
************说明******************************此程序包含一个俄罗斯方块.c 文件和一个12864.h 文件********************俄罗斯方块.c文件**************************#include "reg51.h"#include "12864.h"#define uchar unsigned char#define uint unsigned intstatic unsigned long Seed = 1;#define A 48271L#define M 2147483647L#define Q (M / A)#define R (M % A)sbit K1=P3^4;sbit K2=P3^5;sbit K3=P3^6;sbit K4=P3^7;unsigned int idata num[19+2]={0xfff,//第1行,最下面0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,//第2行到第20行共19行0xfff//第21行,最上面};//定义共21行,其中num[0]为下墙壁行,num[20]为上墙壁行,每行12格,最左一格为左墙壁列,最右一格为右墙壁列unsigned char code Block[28][2]={/** 口口口口口口* 口口口口* 口口口口口口*/{0x88,0xc0},{0xe8,0x00},{0x62,0x20},{0x02,0xe0},/** 口口口口口口* 口口口口* 口口口口口口*/{0x22,0x60},{0x08,0xe0},{0xc8,0x80},{0xe2,0x00},/** 口* 口口口口* 口口口*/{0x8c,0x40},{0x6c,0x00},{0x8c,0x40},{0x6c,0x00},/** 口口口* 口口口口* 口*/{0x4c,0x80},{0xc6,0x00},{0x4c,0x80},{0xc6,0x00},/** 口口* 口口口口口口口口* 口口口口口口*/{0x04,0xe0},{0x8c,0x80},{0xe4,0x00},{0x26,0x20},/*口* 口* 口口口口口* 口*/{0x44,0x44},{0x0f,0x00},{0x44,0x44},{0x0f,0x00},/** 口口* 口口*/{0x06,0x60},{0x06,0x60},{0x06,0x60},{0x06,0x60}};#define PASSSCORE 20struct Jimu{unsigned int dat;char x;unsigned char y;unsigned char type;unsigned char change;}Sign[3];//积木结构体unsigned char SysFlag=0;#define NEWSIGNFLAG 0#define DEADFLAG 1#define PAUSEFLAG 2unsigned char Score=0;unsigned char Level=1;unsigned char DelayCnt=5;/*********************************************************/#define N 25/************************************伪随机数发生器*************************************/ double Random(void){long TmpSeed;TmpSeed=A*(Seed%Q)-R*(Seed/Q);if(TmpSeed>=0)Seed=TmpSeed;elseSeed=TmpSeed+M;return (double)Seed/M;}/************************************** 为伪随机数发生器播种***************************************/ void InitRandom(unsigned long InitVal){Seed=InitVal;}//延时子程序void Delay(unsigned int t){unsigned int i,j;for(i=0;i<t;i++)for(j=0;j<10;j++);}/*********************************初始化MPU**********************************/void InitCpu(void){TMOD=0x0;TH0=0;TL0=0;TR0=1;ET0=1;EX1=1;EA=1;TCON|=0x04;}/**************************** welcome 游戏选择界面/**********************/void welcome(){Lcd_WriteStr(0,0,"欢迎来玩");Lcd_WriteStr(0,1,"俄罗斯方块");Lcd_WriteStr(0,2,"设置按K1");Lcd_WriteStr(0,2,"开玩按K2");}/*************俄罗斯方块部分/******************************画墙壁,初始化界面*******************************/void DrawBoard(void){unsigned char n;for(n=0;n<12;n++){Lcd_Rectangle(3*n,0,3*n+2,2,1);Lcd_Rectangle(3*n,60,3*n+2,62,1);}for(n=0;n<20;n++){Lcd_Rectangle(0,3*n,2,3*n+2,1);Lcd_Rectangle(33,3*n,35,3*n+2,1);}Lcd_WriteStr(4,0,"经典游戏");Lcd_WriteStr(3,2,"Score:");Lcd_WriteStr(3,3,"Level:");}/*********************************** 游戏结束处理************************************/ void GameOver(void){if((SysFlag&(1<<DEADFLAG))!=0)Lcd_WriteStr(3,1,"You Fail");elseLcd_WriteStr(3,1,"You Pass");}unsigned int code MaskTab[16]={0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};/**********************************根据积木图标左下坐标X,Y来画出积木图标***********************************/void DrawSign(struct Jimu Temp,unsigned char DrawMode){unsigned char m,n;for(m=0;m<4;m++)for(n=0;n<4;n++){if((Temp.dat&MaskTab[4*m+n])!=0)Lcd_Rectangle(Temp.x+n*3,Temp.y-2-3*m,Temp.x+n*3+2,Temp.y-3*m,DrawMode);}}/********************************将积木图标值融入num数据中也即把积木图标固定,无法再下降*********************************/FixSign(void){unsigned char m,n;for(m=0;m<4;m++)//行循环for(n=0;n<4;n++)//列循环{if((Sign[0].dat&MaskTab[4*m+n])!=0){num[20-(Sign[0].y-2)/3+m]|=MaskTab[11-Sign[0].x/3-n];}}}/********************************判断积木图标中方块是否与障碍方块重合*********************************/unsigned char CheckIf(void){unsigned char m,n;for(m=0;m<4;m++)//行循环for(n=0;n<4;n++)//列循环{if((Sign[1].dat&MaskTab[4*m+n])!=0){if((num[20-(Sign[1].y-2)/3+m]&MaskTab[11-Sign[1].x/3-n])!=0)return 0;}}return 1;}/********************************判断积木图标是否可以继续下降一格********************************/unsigned char CheckIfDown(void){Sign[1]=Sign[0];//Sign[1].y+=3;//假设下降一格return CheckIf();}/********************************判断积木图标是否可以向左移动*********************************/unsigned char CheckIfLeft(void){Sign[1]=Sign[0];Sign[1].x-=3;return CheckIf();}/********************************判断积木图标是否可以向右移动*********************************/unsigned char CheckIfRight(void){Sign[1]=Sign[0];Sign[1].x+=3;return CheckIf();}/********************************判断是否可以旋转*********************************/unsigned char CheckIfRoll(void){unsigned char i;unsigned int Temp;Sign[1]=Sign[0];if(++Sign[1].change>3)Sign[1].change=0;i=Sign[1].type*4+Sign[1].change;Temp=(unsigned int)Block[i][0]<<8;Temp=Temp|Block[i][1];Sign[1].dat=Temp;return CheckIf();}/********************************寻找满格的行并做消除处理最多寻找4个满行并做消除*********************************/void DelFull(void){unsigned char m,n;unsigned char Temp;unsigned char Flag=0;Temp=(Sign[0].y-2)/3;if(Temp>=20)//防止越过了下边界Temp=1;elseTemp=20-Temp;for(n=Temp+3;n>=Temp;n--)//积木图标的最顶行开始寻找满行比较有利于运算{if(num[n]==0xfff){Flag=1;for(m=n+1;m<=19;m++){num[m-1]=num[m];}num[m]=0x801;Score++;//每找到一个满行,则分数加1}}if(Flag)//为加速而设置并判断的标志,有已固定的积木有满格消行变化则重画积木界面{for(m=Temp;m<=19;m++)//为加速,不必要重第一行重画起,只需要从积木图标最下行开始往上的重画for(n=1;n<=10;n++){if((num[m]&MaskTab[n])==0){if(Lcd_ReadPixel(30-(n-1)*3,57-(m-1)*3)!=0)//为加速而做的读象素操作{Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,0);}}else{if(Lcd_ReadPixel(30-(n-1)*3,57-(m-1)*3)==0)//为加速而做的读象素操作{Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,1);}}}}}/*******************************随机产生一个积木图标放到预产生区域并显示出来********************************/void CreatSign(void){unsigned char n;unsigned int Temp;DrawSign(Sign[2],0);//先清除n=Random()*28;Temp=(unsigned int)Block[n][0]<<8;Temp=Temp|Block[n][1];Sign[2].dat=Temp;Sign[2].x=45;Sign[2].y=4*3+2;Sign[2].type=n/4;Sign[2].change=n%4;DrawSign(Sign[2],1);//后画出}void PrintScore(void){unsigned char Str[3];Str[0]=(Score/10)|0x30;Str[1]=(Score%10)|0x30;Str[2]=0;Lcd_WriteStr(6,2,Str);}void PrintLevel(void){unsigned char Str[3];Str[0]=(Level/10)|0x30;Str[1]=(Level%10)|0x30;Str[2]=0;Lcd_WriteStr(6,3,Str);}/********************************游戏的具体过程,也是俄罗斯方块算法的关键部分*********************************/void GamePlay(void){unsigned char m,n;unsigned int Temp;SysFlag|=1<<NEWSIGNFLAG;//刚开始初始化为需要产生新的积木图标InitRandom(TL0);Lcd_WriteStr(3,1,"Playing");PrintScore();PrintLevel();CreatSign();while(1){if((SysFlag&(1<<NEWSIGNFLAG))==1)//判是否需要产生新的积木图标{SysFlag&=~(1<<NEWSIGNFLAG);Sign[0]=Sign[2];CreatSign();Sign[0].x=12;Sign[0].y=14;for(m=0;m<4;m++)//行循环{for(n=0;n<4;n++)//列循环{if((Sign[0].dat&MaskTab[15-m*4-n])==0)break;}if(n==4)Sign[0].y-=3;}//将积木图标出现置顶for(m=0;m<4;m++)//行循环for(n=0;n<4;n++)//列循环{if((Sign[0].dat&MaskTab[4*m+n])!=0){if((num[20-(Sign[0].y-2)/3+m]&MaskTab[11-Sign[0].x/3-n])!=0)SysFlag|=1<<DEADFLAG;}}if((SysFlag&(1<<DEADFLAG))!=0)break;//如果产生新的积木图标中的方块与已固定好的方块重合,则死亡。
题目:[单片机俄罗斯方块设计]摘要随着社会的不断的发展和进步,人们对娱乐产品的关注在不断的增加,特别是电子游戏产品在我们的生活中占据了很重要的地位。
俄罗斯方块游戏是一款风靡全球的经典游戏。
这款游戏之所以叫做俄罗斯方块,是因为发明这款游戏的人是俄罗斯人。
本次为了回顾经典设计了一款基于单片机的俄罗斯方块游戏机。
本次设计了一款基于单片机的俄罗斯方块游戏机,该游戏机可以丰富我们的业余生活。
在硬件设计上该游戏机以STC89C52单片机为基础、使用LCD12864图形液晶可以显示游戏的界面、通过按键实现游戏机的按钮的功能、并具有蜂鸣器可以实现声音提示的功能。
在软件设计上,使用C语言进行了俄罗斯方块游戏的控制程序的编写,并在keil软件上进行了调试。
最后在Proteus仿真软件上对俄罗斯方块游戏的功能进行了仿真,并焊接了实物电路板。
关键词:STC89C52单片机;俄罗斯方块;游戏机;LCD12864液晶AbstractWith the continuous development and progress of society, people pay more and more attention to entertainment products, especially video game products play a very important role in our life. The Tetris game is a classic game that is popular all over the world. The game is called the Tetris, because the people who invented the game were Russian. This time in order to review the classic design of a single chip based Tetris block game machine.The design of a single chip computer based Tetris game machine, which can enrich our amateur life. On the hardware design, the game machine is based on STC89C52 microcontroller, and it can display the interface of the game by using LCD12864 graphic LCD, realize the button function of the game machine by button, and has the function of voice prompt by buzzer. In the software design, the control program of Tetris game is written in C language and debugged on the keil software. Finally, the function of the Tetris game is simulated on the Proteus simulation software, and the physical circuit board is welded.Keywords:STC89C52 singlechip;Tetris block;game machine;LCD12864 liquid crystal目录摘要 (I)Abstract........................................................... I I 第1章绪论.. (1)1.1课题研究背景和意义 (1)1.2俄罗斯方块的发展状况及趋势 (1)1.3课题研究的主要内容 (1)1.4课题研究的主要内容 (2)第2章系统整体方案设计 (4)2.1系统的功能要求 (4)2.2系统总体方案框图设计 (4)2.3单片机模块的选择 (5)2.4液晶显示模块的选择 (6)2.5按键电路的选择 (7)第3章系统整体硬件设计 (9)3.1单片机电路设计 (9)3.1.1STC89C52单片机介绍 (9)3.1.2晶振电路设计 (10)3.1.3复位电路设计 (10)3.1.4单片机最小系统电路设计 (11)3.2 LCD12864液晶显示电路 (11)3.2.1点阵LCD的显示原理 (11)3.2.2LCD12864液晶的硬件连接 (12)3.3按键控制电路 (12)3.4声音提示电路设计 (13)3.5电源电路 (13)第4章系统软件设计 (15)4.1程语言的选择 (15)4.2软件介绍和工程建立 (15)4.3俄罗斯方块流程图设计 (16)4.3.1主程序流程图 (16)4.3.2游戏外观显示流程图 (18)4.3.3俄罗斯方块向左/右移动工作流程图 (19)4.3.4俄罗斯方块中按下键的流程图 (20)第5章系统的调试与制作 (21)5.1 KEIL软件介绍 (21)5.2程序调试 (21)5.3 proteus仿真步骤 (22)5.4实物综合调试 (23)结论 (26)参考文献 (27)附录 (28)致谢.............................................. 错误!未定义书签。
基于51单片机俄罗斯方块游戏设计作者:左厚臣前言闲得无事,想用单片机和LCD12864写一个俄罗斯方块游戏,培养培养兴趣,丰富一下业余生活,同时也熟练熟练单片机应用。
然后整理一下过程,本文没有什么专业的流程图,系统框图,随手画的。
希望各位大神勿喷,本菜鸟就献丑了。
关键字:51单片机LCD12864 俄罗斯方块游戏设计一、实物写真1、先展示一下实物效果呗,看能不能吸引到各位大神的眼球!!!!2、单片机选型IO口占用:7个程序存储器占用:6459Byte内部RAM:117.0Byte内部扩展RAM:1016ByteFosc = 24Mhz(也可选择12Mhz)中断使用状况:16位定时器溢出中断1个手头有一块STC12C5A60S2 51系列单片机,本实验也采用的此款单片机,或许有大神能用很节省资源的方法写出这款游戏,本菜鸟甘拜下风。
二、游戏算法整个游戏的算法也就是这样子的吧!下面就对每个步骤进说明吧!三、算法说明算法就捡重点的说吧,省得各位大神都闲啰嗦。
1、当前随机方块获取和下一回合游戏方块生成并显示此步骤拆解成如下流程图所示:(1)随机数生成51单片机需要调用库函数来产生随机数,如下:#include <stdlib.h>//调用库函数的头文件函数rand ()会生成一个int型的随机数,int型变量范围为-32768~32767占用2 字节。
我们使用时其实是可以把它当做一个unsigned int型变量的,取值范围0-65535 这个应该是很好理解的。
但是如果我们需要一个0-7的随机数怎么处理呢,没关系有办法,程序如下:u8 Random(u8 max){u16 temp;u8 a;max = max +1;temp=rand();//获取随机种子a = temp%max;return a;}其实也就是把得到随机数与想要得到数范围的最大数求余运算就可以了,即:a = temp%max;我们的游戏方块可以描述成2个要素:A、形状比如说形状有:■■■■■■■■■等,可用0-n来表示B、姿态比如说形状■■■姿态有4种如下:■■■■■■■■■■■■它们从左往右看可以看出规律分别旋转了0°,90°,180°,270°,也分别相对旋转了90°,可以用0-3来表示。
C语言程序#include <AT89X51.H>#define uchar unsigned char#define uint unsigned int#define DOWNTIME 30#define MAXHANG 20#define MAXLIE 16#define MAXPIX 3#define PUSHON 50#define LCD P2#define EN P3_0#define RW P3_1#define RS P3_2#define CS1 P3_3#define CS2 P3_4#define KEYLEFT P3_5#define KEYDOWN P3_6#define KEYRIGH P3_7#define KEYROTATION P1_0uchar gkey=0xff,keystate=0,t0ms1=0,t0ms=0,downtimegap=0; uchar miao=0,fen=0;uchar downok;bit keyflag,timeupdate,fashionupdate;uchar idata cubeMap[MAXHANG][2];typedef struct{uchar code * box;uchar cube : 4;uchar state : 4;char row;char column;} block;block this;uint score=0;uchar speed=1;uchar code bittable[8]={1,2,4,8,0x10,0x20,0x40,0x80}; uchar code cube[]={/* ■■■■*/0,4,0xe,0, 0,2,6,2, 0,7,2,0, 4,6,4,0,/*■■■■*/0,8,0xe,0, 0,4,4,0xc, 0,0,0xe,2, 0,6,4,4, /*■■■■*/0,0xe,8,0, 0,4,4,6, 0,1,7,0, 6,2,2,0, /*■■■■*/0,0xc,6,0, 0,2,6,4, 0,6,3,0, 2,6,4,0, /* ■■■■*/0,6,0xc,0, 0,4,6,2, 0,3,6,0, 4,6,2,0, /*■■■■*/0,0xf,0,0, 4,4,4,4, 0,0,0xf,0, 2,2,2,2, /*■■■■*/0,6,6,0, 0,6,6,0, 0,6,6,0, 0,6,6,0 };uchar code asii[]={0x3E,0x51,0x49,0x45,0x3E, // -0-0x00,0x42,0x7F,0x40,0x00, // -1-0x62,0x51,0x49,0x49,0x46, // -2-0x21,0x41,0x49,0x4D,0x33, // -3-0x18,0x14,0x12,0x7F,0x10, // -4-0x27,0x45,0x45,0x45,0x39, // -5-0x3C,0x4A,0x49,0x49,0x31, // -6-0x01,0x71,0x09,0x05,0x03, // -7-0x36,0x49,0x49,0x49,0x36, // -8-0x46,0x49,0x49,0x29,0x1E, // -9-0x00,0x36,0x36,0x00,0x00, // -:-10//next0x7F,0x04,0x08,0x10,0x7F, // -N-110x7F,0x49,0x49,0x49,0x41, // -E-120x63,0x14,0x08,0x14,0x63, // -X-130x01,0x01,0x7F,0x01,0x01, // -T-14//speed0x26,0x49,0x49,0x49,0x32, // -S-150x7F,0x09,0x09,0x09,0x06, // -P-160x7F,0x49,0x49,0x49,0x41, // -E-170x7F,0x41,0x41,0x41,0x3E, // -D-18//score0x3E,0x41,0x41,0x41,0x22, // -C-190x3E,0x41,0x41,0x41,0x3E, // -O-200x7F,0x09,0x19,0x29,0x46, // -R-210x00,0x00,0x00,0x00,0x00, // - -22//GAME OVER0x3E,0x41,0x51,0x51,0x72, // -G-230x7C,0x12,0x11,0x12,0x7C, // -A-240x7F,0x02,0x0C,0x02,0x7F, // -M-250x1F,0x20,0x40,0x20,0x1F, // -V-26//TIME// 0x00,0x41,0x7F,0x41,0x00 // -I-27};//////////////////////////////////////////////////////////////////////////////// void lcdCmd(uchar cmd){bit ea;ea=EA;EA=0;EN=0;RW=0;RS=0;LCD=cmd;EN=1;EN=1;EN=0;EA=ea;}//-------------------------------------------------------------------------------void lcdWriteByte(uchar ch){EN=0;RS=1;RW=0;LCD=ch;EN=1;EN=1;EN=0;}//--------------------------------------------------------------------------------void lcdSetPage(uchar page){page &=0x7;page +=0xb8;lcdCmd(page);}//-------------------------------------------------------------------------------- void lcdSetColumn(uchar column){column &=0x3f;column +=0x40;lcdCmd(column);}//-------------------------------------------------------------------------------- //character fron=5*8void lcdPlayChar(uchar index,uchar page,uchar colume){uchar i,temp;uint p;p=5*index;for(i=colume;i<colume+5;i++){if(i<64){CS1=1;CS2=0;temp=i;}else{CS1=0;CS2=1;temp=i-64;}lcdSetPage(page);lcdSetColumn(temp);lcdWriteByte(asii[p++]);}}//--------------------------------------------------------------------------------- //rectangle(3,0,50,60)void rectangle(void){uchar i,page;CS1=1;CS2=0;lcdSetPage(0); lcdSetColumn(2);EN=0;RS=1;RW=0;LCD=0xff;EN=1;EN=1;EN=0;for(i=3;i<51;i++){EN=0;RS=1;RW=0;LCD=0x1;EN=1;EN=1;EN=0;}EN=0;RS=1;RW=0;LCD=0xff;EN=1;EN=1;EN=0;//---------------------------for(page=1;page<7;page++) {lcdSetPage(page); lcdSetColumn(2);EN=0;RS=1;RW=0;LCD=0xff;EN=1;EN=1;EN=0;for(i=3;i<51;i++){EN=0;RS=1;RW=0;LCD=0x0;EN=1;EN=1;EN=0;}EN=0;RS=1;RW=0;LCD=0xff;EN=1;EN=1;EN=0;}//---------------------------lcdSetPage(7);lcdSetColumn(2);EN=0;RS=1;RW=0;LCD=0x1f;EN=1;EN=1;EN=0;for(i=3;i<51;i++){EN=0;RS=1;RW=0;LCD=0x10;EN=1;EN=1;EN=0;}EN=0;RS=1;RW=0;LCD=0x1f;EN=1;EN=1;EN=0;}//-------------------------------------------------------------------- //x:列;y行,页3*3void lcdPutPix(uchar x, uchar y,uchar flag) {uchar i,dat,bitmask,nextbit;bit bflag,pflag,ea;x=x*MAXPIX;y=y*MAXPIX;bflag=0;pflag=0;i=y%8;if(i==0)bitmask=0x7;else if(i==1)bitmask=0xe;else if(i==2)bitmask=0x1c;else if(i==3)bitmask=0x38;else if(i==4)bitmask=0x70;else if(i==5)bitmask=0xe0;else if(i==6){bflag=1;bitmask=0xc0;nextbit=1;}else if(i==7){bflag=1;bitmask=0x80;nextbit=3;}if(x<62){CS1=1;CS2=0;}else if(x>63){x-=64;CS1=0;CS2=1;}elsepflag=1;lcdSetPage(y/8);for(i=x;i<x+MAXPIX;i++) {if(pflag){if(i==62 || i==63){CS1=1;CS2=0;lcdSetPage(y/8);}else if(pflag && i==64){CS1=0;CS2=1;lcdSetPage(y/8);}}lcdSetColumn(i);ea=EA;EA=0;EN=0;LCD=0xff;RS=1;RW=1;EN=1;EN=0;EN=1;dat=LCD;EN=0;if(flag==1)dat|=bitmask;elsedat&=~bitmask;lcdSetColumn(i);EN=0;RW=0;RS=1;LCD=dat;EN=1;EN=0;EA=ea;}if(bflag){lcdSetPage(y/8+1);for(i=x;i<x+MAXPIX;i++) {if(pflag){if(i==62 || i==63){CS1=1;CS2=0;lcdSetPage(y/8+1);}else if(pflag && i==64){CS1=0;CS2=1;lcdSetPage(y/8+1);}}lcdSetColumn(i);ea=EA;EA=0;EN=0;LCD=0xff;RS=1;RW=1;EN=1;EN=0;EN=1;dat=LCD;EN=0;if(flag==1)dat|=nextbit;elsedat&=~nextbit;lcdSetColumn(i);EN=0;RS=1;LCD=dat;EN=1;EN=1;EN=0;EA=ea;}}}//------------------------------------------------------------------ void lcdClear(void){uchar i,page;CS1=1;CS2=0;for(page=0;page<8;page++){lcdSetPage(page);lcdSetColumn(0);for(i=0;i<64;i++)lcdWriteByte(0);}CS1=0;CS2=1;for(page=0;page<8;page++){lcdSetPage(page);lcdSetColumn(0);for(i=0;i<64;i++)lcdWriteByte(0);}}//----------------------------------------------------------------- #define STAR 53#define WIDE 6void lcdIni(void){lcdCmd(0x3f);lcdCmd(0xc0);lcdClear();rectangle();//NEXTlcdPlayChar(11,0,STAR);lcdPlayChar(12,0,STAR+1*WIDE);lcdPlayChar(13,0,STAR+2*WIDE);lcdPlayChar(14,0,STAR+3*WIDE);//SPEEDlcdPlayChar(15,3,STAR);lcdPlayChar(16,3,STAR+1*WIDE);lcdPlayChar(17,3,STAR+2*WIDE);lcdPlayChar(17,3,STAR+3*WIDE);lcdPlayChar(18,3,STAR+4*WIDE);//01lcdPlayChar(0,4,STAR+2*WIDE);lcdPlayChar(1,4,STAR+3*WIDE);//SCORElcdPlayChar(15,5,STAR);lcdPlayChar(19,5,STAR+1*WIDE);lcdPlayChar(20,5,STAR+2*WIDE);lcdPlayChar(21,5,STAR+3*WIDE);lcdPlayChar(12,5,STAR+4*WIDE);lcdPlayChar(0,6,STAR+1*WIDE);lcdPlayChar(0,6,STAR+2*WIDE);lcdPlayChar(0,6,STAR+3*WIDE);lcdPlayChar(0,6,STAR+4*WIDE);//TIMElcdPlayChar(0,7,STAR);lcdPlayChar(0,7,STAR+1*WIDE);lcdPlayChar(10,7,STAR+2*WIDE);lcdPlayChar(0,7,STAR+3*WIDE);lcdPlayChar(0,7,STAR+4*WIDE);}//----------------------------------------------------------------- void showScoreSpeed(void){uchar num[5];char i;uint temp;temp=score;for(i=0;i<5;i++){num[i]=temp%10;temp=temp/10;}for(i=4;i>0;i--)if(num[i]==0)num[i]=22;elsebreak;}for(i=4;i>-1;i--)lcdPlayChar(num[i],6,STAR+(4-i)*WIDE);lcdPlayChar(speed/10,4,STAR+2*WIDE);lcdPlayChar(speed%10,4,STAR+3*WIDE);}//-------------------------------------------------------------------void timeServer(void){if(timeupdate){timeupdate=0;lcdPlayChar(fen/10,7,STAR);lcdPlayChar(fen%10,7,STAR+1*WIDE);lcdPlayChar(10,7,STAR+2*WIDE);lcdPlayChar(miao/10,7,STAR+3*WIDE);lcdPlayChar(miao%10,7,STAR+4*WIDE);}if(fashionupdate){fashionupdate=0;lcdPlayChar(22,7,STAR+2*WIDE);}}//=================================================================== void t0isr(void) interrupt 1{uchar key;TH0=(65536-10000)/256;TL0=(65536-10000)%256;downtimegap++;t0ms=++t0ms%100;if(t0ms==0){timeupdate=1;miao=++miao%60;if(miao==0)fen=++fen%60;if(t0ms==50)fashionupdate=1;//----------------------------key=0xff;KEYLEFT=1;KEYRIGH=1;KEYROTATION=1;KEYDOWN=1;if(!KEYLEFT)key=0;if(!KEYRIGH)key=1;if(!KEYROTATION)key=2;if(!KEYDOWN)key=3;switch(keystate){case 0: if(key!=gkey){gkey=key;keystate=1;}break;case 1: if(key==gkey){t0ms1=0;keystate=2;if(key!=0xff)keyflag=1;}elsekeystate=0;break;case 2: if(key==gkey){if(t0ms1<PUSHON)t0ms1++;}else{keystate=0;keyflag=0;gkey=0xff;}break;}}//=================================================================== void showNextCube(uchar code * p,uchar x,uchar y){uchar i,j,temp;for(i=0;i<4;i++){temp=1;for(j=0;j<4;j++){if(p[i] & temp)lcdPutPix(x+j,y+i,1);elselcdPutPix(x+j,y+i,0);temp<<=1;}}}//------------------------------------------------------------------void createCube(void){static uchar next;this.cube=next;next=TL0%7;this.row=0;this.column=6;this.state=0;this.box=cube+16*this.cube;showNextCube(cube+16*next,19,3);}//------------------------------------------------------------------void showCubeMap(void){unsigned char hang,lie,temp;for(hang=MAXHANG-1;hang>0;hang--){if(cubeMap[hang][0]==0 && cubeMap[hang][1]==0)break;for(lie=0;lie<(MAXLIE/8);lie++){temp=8*lie;if(cubeMap[hang][lie]&0x01)lcdPutPix(temp+1,hang,1);if(cubeMap[hang][lie]&0x02)lcdPutPix(temp+2,hang,1);if(cubeMap[hang][lie]&0x04)lcdPutPix(temp+3,hang,1);if(cubeMap[hang][lie]&0x08)lcdPutPix(temp+4,hang,1);if(cubeMap[hang][lie]&0x10)lcdPutPix(temp+5,hang,1);if(cubeMap[hang][lie]&0x20)lcdPutPix(temp+6,hang,1);if(cubeMap[hang][lie]&0x40)lcdPutPix(temp+7,hang,1);if(cubeMap[hang][lie]&0x80)lcdPutPix(temp+8,hang,1);}}}//------------------------------------------------------------------- void writeCubeToMap(void){uchar row,column,temp;uchar hang,lie;for(row=0;row<4;row++){temp=1;for(column=0;column<4;column++){if(this.box[row] & temp){hang=this.row+row;lie=this.column+column;cubeMap[hang][lie/8] |=bittable[lie%8];lcdPutPix(lie+1,hang,1);}temp<<=1;}}}//-------------------------------------------------------------------void clearCubeFromMap(void){uchar row,column,temp;uchar hang,lie;for(row=0;row<4;row++){temp=1;for(column=0;column<4;column++){if(this.box[row] & temp){hang=this.row+row;lie=this.column+column;cubeMap[hang][lie/8] &=~bittable[lie%8];lcdPutPix(lie+1,hang,0);}temp<<=1;}}}//-------------------------------------------------------------------uchar checkBorder(void){if(this.box[3]!=0 && this.row>(MAXHANG-4))return 1;else if(this.box[2]!=0 && this.row>(MAXHANG-3))return 1;else if(this.box[1]!=0 && this.row>(MAXHANG-2))return 1;else if(this.box[0]!=0 && this.row>(MAXHANG-1))return 1;//---------------------if((this.box[0] & 0x01) || (this.box[1] & 0x01) || (this.box[2] & 0x01) ||(this.box[3] & 0x01) ) {if(this.column<0)return 1;else if((this.box[0] & 0x02) || (this.box[1] & 0x02) || (this.box[2] & 0x02) ||(this.box[3] & 0x02) ){if(this.column<-1)return 1;}else if((this.box[0] & 0x04) || (this.box[1] & 0x04) || (this.box[2] & 0x04) ||(this.box[3] & 0x04) ){if(this.column<-2)return 1;}else if((this.box[0] & 0x08) || (this.box[1] & 0x08) || (this.box[2] & 0x08) ||(this.box[3] & 0x08) ){if(this.column<-3)return 1;}//---------------------if((this.box[0] & 0x08) || (this.box[1] & 0x08) || (this.box[2] & 0x08) ||(this.box[3] & 0x08) ) {if(this.column>(MAXLIE-4))return 1;}else if((this.box[0] & 0x04) || (this.box[1] & 0x04) || (this.box[2] & 0x04) ||(this.box[3] & 0x04) ){if(this.column>(MAXLIE-3))return 1;}else if((this.box[0] & 0x02) || (this.box[1] & 0x02) || (this.box[2] & 0x02) ||(this.box[3] & 0x02) ){if(this.column>(MAXLIE-2))return 1;}else if((this.box[0] & 0x08) || (this.box[1] & 0x08) || (this.box[2] & 0x08) ||(this.box[3] & 0x08) ){if(this.column>(MAXLIE-1))return 1;}//--------------------}//------------------------------------------------------------------ uchar checkClask(void){uchar row,column,temp;uchar hang,lie;for(row=0;row<4;row++){temp=1;for(column=0;column<4;column++){if(this.box[row] & temp){hang=this.row+row;lie=this.column+column;if(cubeMap[hang][lie/8] & bittable[lie%8])return 1;}temp<<=1;}}return 0;}//------------------------------------------------------------------- void checkMap(void){uchar i,j,delete;bit full;full=0;delete=0;for(i=MAXHANG-1;i>0;i--){if(cubeMap[i][0]==0 && cubeMap[i][1]==0)break;if(cubeMap[i][0]==0xff && cubeMap[i][1]==0xff){delete++;full=1;for(j=i;j>0;j--){cubeMap[j][0]=cubeMap[j-1][0];cubeMap[j][1]=cubeMap[j-1][1];}i++;cubeMap[0][0]=0;cubeMap[0][1]=0;}}if(full){if(delete==1)score++;else if(delete==2)score+=4;else if(delete==3)score+=9;else if(delete==4)score+=16;rectangle();showCubeMap();if(score<50)speed=1;else if(score<100)speed=2;else if(score<500)speed=3;else if(score<1000)speed=4;else if(score<5000)speed=5;else if(score<10000)speed=6;else if(score<20000)speed=7;else if(score<30000)speed=8;else if(score<40000)speed=9;else if(score<50000)speed=10;else if(score<60000)speed=11;elsespeed=12;showScoreSpeed();}}//------------------------------------------------------------------- void moveLeft(void){clearCubeFromMap();this.column--;if(checkBorder() || checkClask())this.column++;writeCubeToMap();}//------------------------------------------------------------------- void moveRigh(void){clearCubeFromMap();this.column++;if(checkBorder() || checkClask())this.column--;writeCubeToMap();}//------------------------------------------------------------------- void moveDown(void){clearCubeFromMap();this.row++;if(checkBorder() || checkClask()){this.row--;downok=1;}elsedownok=0;writeCubeToMap();if(downok)checkMap();}//------------------------------------------------------------------ void cubeRotation(void){uchar temp;temp=this.state;clearCubeFromMap();this.state=++this.state%4;this.box=cube+16*this.cube+4*this.state;if(checkBorder() || checkClask()){this.state=temp;this.box=cube+16*this.cube+4*this.state;}writeCubeToMap();}///////////////////////////////////////////////////////////////////// void main(void){TMOD=0x1;TH0=(65536-10000)/256;TL0=(65536-10000)%256;EA=1;ET0=1;TR0=1;lcdIni();for(t0ms=0;t0ms<MAXHANG;t0ms++){cubeMap[t0ms][0]=0;cubeMap[t0ms][1]=0;}while(1){createCube();if(checkClask()){rectangle();#define SHOWSTAR 12#define GAP 8lcdPlayChar(23,2,SHOWSTAR); //GAMElcdPlayChar(24,2,SHOWSTAR+GAP);lcdPlayChar(25,2,SHOWSTAR+2*GAP);lcdPlayChar(12,2,SHOWSTAR+3*GAP);lcdPlayChar(20,4,SHOWSTAR); //OVERlcdPlayChar(26,4,SHOWSTAR+GAP);lcdPlayChar(12,4,SHOWSTAR+2*GAP);lcdPlayChar(21,4,SHOWSTAR+3*GAP);t0ms=0;while(t0ms<95);//延时2秒t0ms=0;while(t0ms<95);((void (code *) (void)) 0x0000) ( );}while(1)timeServer();if(keyflag){keyflag=0;t0ms1=0;if(gkey==0)moveLeft();if(gkey==1)moveRigh();if(gkey==2)cubeRotation();if(gkey==3)moveDown();}if(gkey==0 && t0ms1==PUSHON){t0ms1-=10;moveLeft();}if(gkey==1 && t0ms1==PUSHON){t0ms1-=10;moveRigh();}if(gkey==3 && t0ms1==PUSHON){t0ms1-=10;moveDown();}if(downtimegap>(DOWNTIME-speed)){moveDown();downtimegap=0;}if(downok){downok=0;break;}}}}。