我是靠谱客的博主 紧张睫毛,最近开发中收集的这篇文章主要介绍【Proteus仿真】【51单片机】俄罗斯方块游戏设计-LCD12864一、功能简介二、软件设计三、实验现象联系作者,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
文章目录
- 一、功能简介
- 二、软件设计
- 三、实验现象
- 联系作者
一、功能简介
本项目使用Proteus8仿真51单片机控制器,使用LCD12864显示模块、按键模块。
主要功能:
系统运行后,LCD12864显示俄罗斯方块游戏界面并开始游戏,KEY1键用于方块方向旋转,KEY3、KEY4键控制左右方向移动,KEY2键控制方块下落速度。每消除1层分数递增1分,最大显示4位数分数。当游戏结束后,按下复位键重新开始游戏。能显示玩家时间。
二、软件设计
/*
作者:嗨小易(QQ:3443792007)
*/
//-----------------------------------------------------------------
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;
else
break;
}
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 //定时器中断0函数
{
uchar key;
TH0=(65536-20000)/256;
TL0=(65536-20000)%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;
}
else
keystate=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);
else
lcdPutPix(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;
}
//--------------------
return 0;
}
//------------------------------------------------------------------
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;
else
speed=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;
}
else
downok=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-20000)/256; //游戏速度定义
TL0=(65536-20000)%256; //10000
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 8
lcdPlayChar(23,2,SHOWSTAR); //GAME
lcdPlayChar(24,2,SHOWSTAR+GAP);
lcdPlayChar(25,2,SHOWSTAR+2*GAP);
lcdPlayChar(12,2,SHOWSTAR+3*GAP);
lcdPlayChar(20,4,SHOWSTAR); //OVER
lcdPlayChar(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;
}
}
}
}
三、实验现象
B站演示视频:https://space.bilibili.com/444388619
联系作者
专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。
最后
以上就是紧张睫毛为你收集整理的【Proteus仿真】【51单片机】俄罗斯方块游戏设计-LCD12864一、功能简介二、软件设计三、实验现象联系作者的全部内容,希望文章能够帮你解决【Proteus仿真】【51单片机】俄罗斯方块游戏设计-LCD12864一、功能简介二、软件设计三、实验现象联系作者所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复