STM32之俄罗斯方块
1.硬件平台
2.示例效果
3.软件设计
?3.1 绘制单个方块函数
void Lcd_DrawDiamond(u16 x,u16 y,u16 c)
{
u16 i;
LcdWriteReg(0x2A);
LcdWriteData((x>>8)&0xff);
LcdWriteData(x&0xff);
LcdWriteData(((x+8)>>8)&0xff);
LcdWriteData((x+8)&0xff);
LcdWriteReg(0x2B);
LcdWriteData((y>>8)&0xff);
LcdWriteData(y&0xff);
LcdWriteData(((y+8)>>8)&0xff);
LcdWriteData((y+8)&0xff);
LcdWriteReg(0x2C);
for(i=0;i<9*9;i++)LcdWriteData(c);
}
?3.2 清空一行显示
void Lcd_ClearOneLineDisplay(u16 y,u16 c)
{
u16 i=0;
for(i=2;i<LCD_WIDTH-98;i+=10)
{
Lcd_DrawDiamond(i,y,c);
}
}
?3.3 定义屏幕大小数组,保存方块图形掉落位置状态信息,显示区域宽度为220,高度为480
u8 shape_place_stat[49][24]=
{
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,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,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,1,1,1,1,1,1,1,1},
};
?3.4 更新当前状态到二维数组中
void Lcd_Refreshbuff(u16 x,u16 y,u8 stat)
{
shape_place_stat[y/10][x/10+1]=(stat&0x01);
}
?3.5 设置每个方块种类颜色,绘制各个方块
const u16 Drawshape_color[]={DARKBLUE,BRRED,BLUE,GRAY,BLACK};
void Lcd_Drawshape(u16 x,u16 y,u8 what,u16 c,u8 stat)
{
switch (what)
{
case 1:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
}
break;
case 2:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x+20,y,c);
Lcd_DrawDiamond(x+30,y,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x+20,y,stat);
Lcd_Refreshbuff(x+30,y,stat);
}
break;
case 3:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x,y+20,c);
Lcd_DrawDiamond(x,y+30,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x,y+20,stat);
Lcd_Refreshbuff(x,y+30,stat);
}
break;
case 4:
{
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x+20,y+10,c);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x+20,y+10,stat);
}
break;
case 5:
{
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x,y+20,c);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x,y+20,stat);
}
break;
case 6:
{
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x+10,y+20,c);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x+10,y+20,stat);
}
break;
case 7:
{
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x+20,y,c);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x+20,y,stat);
}
break;
case 8:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x,y+20,c);
Lcd_DrawDiamond(x+10,y+20,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x,y+20,stat);
Lcd_Refreshbuff(x+10,y+20,stat);
}
break;
case 9:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x+20,y,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x+20,y,stat);
}
break;
case 10:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x+10,y+20,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x+10,y+20,stat);
}
break;
case 11:
{
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x+20,y+10,c);
Lcd_DrawDiamond(x+20,y,c);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x+20,y+10,stat);
Lcd_Refreshbuff(x+20,y,stat);
}
break;
case 12:
{
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x+10,y+20,c);
Lcd_DrawDiamond(x,y+20,c);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x+10,y+20,stat);
Lcd_Refreshbuff(x,y+20,stat);
}
break;
case 13:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x+20,y,c);
Lcd_DrawDiamond(x+20,y+10,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x+20,y,stat);
Lcd_Refreshbuff(x+20,y+10,stat);
}
break;
case 14:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x,y+20,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x,y+20,stat);
}
break;
case 15:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x+20,y+10,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x+20,y+10,stat);
}
break;
case 16:
{
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x,y+20,c);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x,y+20,stat);
}
break;
case 17:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x+20,y+10,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x+20,y+10,stat);
}
break;
case 18:
{
Lcd_DrawDiamond(x,y,c);
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x+10,y+20,c);
Lcd_Refreshbuff(x,y,stat);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x+10,y+20,stat);
}
break;
case 19:
{
Lcd_DrawDiamond(x,y+10,c);
Lcd_DrawDiamond(x+10,y+10,c);
Lcd_DrawDiamond(x+10,y,c);
Lcd_DrawDiamond(x+20,y,c);
Lcd_Refreshbuff(x,y+10,stat);
Lcd_Refreshbuff(x+10,y+10,stat);
Lcd_Refreshbuff(x+10,y,stat);
Lcd_Refreshbuff(x+20,y,stat);
}
break;
}
}
?3.6 方块移动和切换方向
int Lcd_DownMove(u16 x,u16 y,u16 what,u16 c)
{
Lcd_Drawshape(x,y,what,WHITE,0);
Lcd_Drawshape(x,y+10,what,c,1);
return y+10;
}
int Lcd_LeftMove(u16 x,u16 y,u16 what,u16 c)
{
Lcd_Drawshape(x,y,what,WHITE,0);
Lcd_Drawshape(x-10,y,what,c,1);
return x-10;
}
int Lcd_RightMove(u16 x,u16 y,u16 what,u16 c)
{
Lcd_Drawshape(x,y,what,WHITE,0);
Lcd_Drawshape(x+10,y,what,c,1);
return x+10;
}
u8 Lcd_Changshape(u16 x,u16 y,u16 what,u16 c)
{
u8 stat;
switch(what)
{
case 1:stat=1;break;
case 2:
{
if(shape_place_stat[(y+40)/10][x/10] || shape_place_stat[(y+30)/10][x/10] || shape_place_stat[(y+20)/10][x/10] || shape_place_stat[(y+10)/10][x/10])
{
stat=2;
break;
}
Lcd_Drawshape(x,y,2,WHITE,0);Lcd_Drawshape(x,y,3,c,1);stat=3;break;
}
case 3:
{
if(shape_place_stat[(y+40)/10][(x+40)/10])
{
stat=3;
break;
}
Lcd_Drawshape(x,y,3,WHITE,0);Lcd_Drawshape(x,y,2,c,1);stat=2;break;
}
case 4:
{
Lcd_Drawshape(x,y,4,WHITE,0);Lcd_Drawshape(x,y,5,c,1);stat=5;break;
}
case 5:
{
Lcd_Drawshape(x,y,5,WHITE,0);Lcd_Drawshape(x,y,6,c,1);stat=6;break;
}
case 6:
{
if(shape_place_stat[y/10][(x+30)/10])
{
stat=6;
break;
}
Lcd_Drawshape(x,y,6,WHITE,0);Lcd_Drawshape(x,y,7,c,1);stat=7;break;
}
case 7:Lcd_Drawshape(x,y,7,WHITE,0);Lcd_Drawshape(x,y,4,c,1);stat=4;break;
case 8:
{
if(shape_place_stat[y/10][(x+30)/10])
{
stat=8;
break;
}
Lcd_Drawshape(x,y,8,WHITE,0);Lcd_Drawshape(x,y,9,c,1);stat=9;break;
}
case 9:
{
if(shape_place_stat[(y+30)/10][x/10])
{
stat=9;
break;
}
Lcd_Drawshape(x,y,9,WHITE,0);Lcd_Drawshape(x,y,10,c,1);stat=10;break;
}
case 10:
{
if(shape_place_stat[y/10][(x+30)/10])
{
stat=10;
break;
}
Lcd_Drawshape(x,y,10,WHITE,0);Lcd_Drawshape(x,y,11,c,1);stat=11;break;
}
case 11:
{
if(shape_place_stat[(y+30)/10][x/10])
{
stat=11;
break;
}
Lcd_Drawshape(x,y,11,WHITE,0);Lcd_Drawshape(x,y,8,c,1);stat=8;break;
}
case 12:
{
if(shape_place_stat[(y)/10][(x+30)/10] || shape_place_stat[(y+20)/10][x/10] || shape_place_stat[(y+20)/10][(x+30)/10])
{
stat=12;
break;
}
Lcd_Drawshape(x,y,12,WHITE,0);Lcd_Drawshape(x,y,13,c,1);stat=13;break;
}
case 13:
{
if(shape_place_stat[(y+30)/10][x/10])
{
stat=13;
break;
}
Lcd_Drawshape(x,y,13,WHITE,0);Lcd_Drawshape(x,y,14,c,1);stat=14;break;
}
case 14:
{
if(shape_place_stat[y/10][(x+30)/10])
{
stat=14;
break;
}
Lcd_Drawshape(x,y,14,WHITE,0);Lcd_Drawshape(x,y,15,c,1);stat=15;break;
}
case 15:
{
if(shape_place_stat[(y+30)/10][x/10])
{
stat=15;
break;
}
Lcd_Drawshape(x,y,15,WHITE,0);Lcd_Drawshape(x,y,12,c,1);stat=12;break;
}
case 16:
{
if(shape_place_stat[y/10][(x+30)/10])
{
stat=16;
break;
}
Lcd_Drawshape(x,y,16,WHITE,0);Lcd_Drawshape(x,y,17,c,1);stat=17;break;
}
case 17:
{
Lcd_Drawshape(x,y,17,WHITE,0);Lcd_Drawshape(x,y,16,c,1);stat=16;break;
}
case 18:
{
if(shape_place_stat[y/10][(x+30)/10])
{
stat=18;
break;
}
Lcd_Drawshape(x,y,18,WHITE,0);Lcd_Drawshape(x,y,19,c,1);stat=19;break;
}
case 19:
{
Lcd_Drawshape(x,y,19,WHITE,0);Lcd_Drawshape(x,y,18,c,1);stat=18;break;
}
}
return stat;
}
?3.7 判断是否到达边界
u8 Lcd_Shape_GetStat(u16 x,u16 y)
{
if(shape_place_stat[y/10][x/10+1])return 1;
else return 0;
}
const u8 shape_high[19]={2,1,4,2,3,3,2,3,2,3,2,3,2,3,2,3,2,3,2};
const u8 shape_widht[19]={2,4,1,3,2,2,3,2,3,2,3,2,3,2,3,2,3,2,3};
u8 Lcd_Shape_GetLowerBoundary(u16 x,u16 y,u8 cnt)
{
switch (cnt)
{
case 1:
{
if(shape_place_stat[(y+20)/10][x/10+1])return 1;
else if(shape_place_stat[(y+20)/10][(x+10)/10+1])return 2;
}
break;
case 2:
{
if(shape_place_stat[(y+10)/10][x/10+1])return 1;
else if(shape_place_stat[(y+10)/10][(x+10)/10+1])return 2;
else if(shape_place_stat[(y+10)/10][(x+20)/10+1])return 3;
else if(shape_place_stat[(y+10)/10][(x+30)/10+1])return 4;
}
break;
case 3:
{
if(shape_place_stat[(y+40)/10][x/10+1])return 1;
}
break;
case 4:
{
if(shape_place_stat[(y+20)/10][x/10+1])return 1;
else if(shape_place_stat[(y+20)/10][(x+10)/10+1])return 2;
else if(shape_place_stat[(y+20)/10][(x+20)/10+1])return 3;
}
break;
case 5:
{
if(shape_place_stat[(y+30)/10][x/10+1])return 1;
else if(shape_place_stat[(y+20)/10][(x+10)/10+1])return 2;
}
break;
case 6:
{
if(shape_place_stat[(y+20)/10][x/10+1])return 1;
else if(shape_place_stat[(y+30)/10][(x+10)/10+1])return 2;
}
break;
case 7:
{
if(shape_place_stat[(y+10)/10][x/10+1])return 1;
else if(shape_place_stat[(y+20)/10][(x+10)/10+1])return 2;
else if(shape_place_stat[(y+10)/10][(x+20)/10+1])return 3;
}
break;
case 8:
{
if(shape_place_stat[(y+30)/10][x/10+1])return 1;
if(shape_place_stat[(y+30)/10][(x+10)/10+1])return 1;
}
break;
case 9:
{
if(shape_place_stat[(y+20)/10][x/10+1])return 1;
else if(shape_place_stat[(y+10)/10][(x+10)/10+1])return 2;
else if(shape_place_stat[(y+10)/10][(x+20)/10+1])return 3;
}
break;
case 10:
{
if(shape_place_stat[(y+10)/10][x/10+1])return 1;
else if(shape_place_stat[(y+30)/10][(x+10)/10+1])return 2;
}
break;
case 11:
{
if(shape_place_stat[(y+20)/10][x/10+1])return 1;
else if(shape_place_stat[(y+20)/10][(x+10)/10+1])return 2;
else if(shape_place_stat[(y+20)/10][(x+20)/10+1])return 3;
}
break;
case 12:
{
if(shape_place_stat[(y+30)/10][x/10+1])return 1;
else if(shape_place_stat[(y+30)/10][(x+10)/10+1])return 2;
}
break;
case 13:
{
if(shape_place_stat[(y+10)/10][x/10+1])return 1;
else if(shape_place_stat[(y+10)/10][(x+10)/10+1])return 2;
else if(shape_place_stat[(y+20)/10][(x+20)/10+1])return 3;
}
break;
case 14:
{
if(shape_place_stat[(y+30)/10][x/10+1])return 1;
else if(shape_place_stat[(y+10)/10][(x+10)/10+1])return 2;
}
break;
case 15:
{
if(shape_place_stat[(y+20)/10][x/10+1])return 1;
else if(shape_place_stat[(y+20)/10][(x+10)/10+1])return 2;
else if(shape_place_stat[(y+20)/10][(x+20)/10+1])return 3;
}
break;
case 16:
{
if(shape_place_stat[(y+30)/10][x/10+1])return 1;
else if(shape_place_stat[(y+20)/10][(x+10)/10+1])return 2;
}
break;
case 17:
{
if(shape_place_stat[(y+10)/10][x/10+1])return 1;
else if(shape_place_stat[(y+20)/10][(x+10)/10+1])return 2;
else if(shape_place_stat[(y+20)/10][(x+20)/10+1])return 2;
}
break;
case 18:
{
if(shape_place_stat[(y+20)/10][x/10+1])return 1;
else if(shape_place_stat[(y+30)/10][(x+10)/10+1])return 2;
}
break;
case 19:
{
if(shape_place_stat[(y+20)/10][x/10+1])return 1;
else if(shape_place_stat[(y+20)/10][(x+10)/10+1])return 2;
else if(shape_place_stat[(y+10)/10][(x+20)/10+1])return 3;
}
break;
}
return 0;
}
?3.8 将上一行方块放到当前行
static void Lcd_ClearOneLine(u8 line)
{
u8 i=1;
for(i=1;i<23;i++)
{
if(shape_place_stat[line][i])Lcd_DrawDiamond((i-1)*10+2,line*10,BLACK);
else Lcd_DrawDiamond((i-1)*10+2,line*10,WHITE);
}
}
?3.9 判断得分,消行,清除方块在二维数组状态
u8 Lcd_GetMark(u8 *buff)
{
int i,j,k;
u8 cnt=0;
int line=0;
for(i=47;i>=0;i--)
{
for(j=1;j<23;j++)
{
if(shape_place_stat[i][j])break;
}
if(j==23)
{
line=i;
break;
}
}
if(line<=1)return 0xff;
for(i=47;i>line;i--)
{
for(j=0;j<24;j++)
{
if(shape_place_stat[i][j]==0)break;
}
if(j==24)buff[cnt++]=i;
}
if(cnt)
{
for(i=0;i<cnt;i++)
{
Lcd_ClearOneLineDisplay(buff[i]*10,RED);
}
Delay_Ms(500);
for(i=0;i<cnt;i++)
{
Lcd_ClearOneLineDisplay(buff[i]*10,WHITE);
}
for(k=cnt-1;k>=0;k--)
{
for(j=buff[k];j>=line;j--)
{
for(i=0;i<24;i++)
{
shape_place_stat[j][i]=shape_place_stat[j-1][i];
}
}
line--;
}
for(i=buff[0];i>=line;i--)
{
Lcd_ClearOneLine(i);
}
}
if(cnt==0)cnt=0;
else if(cnt==1)cnt=1;
else if(cnt==2)cnt=4;
else if(cnt==3)cnt=8;
else if(cnt==4)cnt=16;
return cnt;
}
void Lcd_Clearshape(void)
{
int i,j;
for(i=0;i<48;i++)
{
for(j=1;j<23;j++)
{
shape_place_stat[i][j]=0;
}
}
}
?3.10 窗口绘制
void Lcd_TetrisShowWind(void)
{
LCD_DrawLine(LCD_WIDTH-97, 0, LCD_WIDTH-97, LCD_HIGHT,BLACK);
LCD_DrawLine(LCD_WIDTH-96, 0, LCD_WIDTH-96, LCD_HIGHT,BLACK);
LCD_DrawLine(LCD_WIDTH-96, 170, LCD_WIDTH-1, 170,BLACK);
LCD_DrawLine(LCD_WIDTH-96, 171, LCD_WIDTH-1, 171,BLACK);
LCD_Display_Str(LCD_WIDTH-96+25,30,24,(u8 *)"NEXT",DARKBLUE);
LCD_Display_Str(LCD_WIDTH-96+25,200,16,(u8 *)"得 分",DARKBLUE);
LCD_Display_Str(LCD_WIDTH-96+96/2-12,200+30,24,(u8 *)"0",RED);
LCD_Display_Str(LCD_WIDTH-96+10,320,16,(u8 *)"旋转 KEYUP ",DARKBLUE);
LCD_Display_Str(LCD_WIDTH-96+10,360,16,(u8 *)"暂停 KEY1",DARKBLUE);
LCD_Display_Str(LCD_WIDTH-96+10,400,16,(u8 *)"左 KEY2 ",DARKBLUE);
LCD_Display_Str(LCD_WIDTH-96+10,440,16,(u8 *)"右 KEY0",DARKBLUE);
}
4.主函数
#include "stm32f10x.h"
#include "beep.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
#include "w25q64.h"
#include "timer.h"
#include <string.h>
#include "nt35310.h"
#include "tetris_game.h"
#include <stdlib.h>
int main()
{
u8 buff[49];
u8 stat=1;
int x0=112,y0=0;
u16 cnt=1,cnt2=0;
u8 key;
u16 mark=0,res,mark2=0;
u16 color;
u16 i=200;
Beep_Init();
Led_Init();
Key_Init();
TIMx_Init(TIM4,7200,65535);
Usartx_Init(USART1,115200,72);
printf("串口初始化完成\r\n");
W25Q64_Init();
LCD_Init();
AA:
LCD_Clear(WHITE);
Lcd_TetrisShowWind();
cnt=rand()%20;
if(cnt==0)cnt=1;
cnt2=rand()%20;
if(cnt2==0)cnt2=1;
Lcd_Drawshape(LCD_WIDTH-96+35,80,cnt2,BLACK,0);
while(1)
{
key=Key_Getval();
if(key==3)
{
stat=!stat;
}
else if((key==1) && stat)
{
i=0;
if(cnt==1)color=Drawshape_color[0];
else if(cnt>=2 && cnt<=3)color=Drawshape_color[1];
else if(cnt>=4 && cnt<=7)color=Drawshape_color[2];
else if(cnt>=8 && cnt<=15)color=Drawshape_color[3];
else if(cnt>=16 && cnt<=19)color=Drawshape_color[4];
cnt=Lcd_Changshape(x0,y0,cnt,color);
}
else if((key==2) && stat)
{
if(Lcd_Shape_GetStat(x0+shape_widht[cnt-1]*10,y0)==0)
{
if(cnt==1)color=Drawshape_color[0];
else if(cnt>=2 && cnt<=3)color=Drawshape_color[1];
else if(cnt>=4 && cnt<=7)color=Drawshape_color[2];
else if(cnt>=8 && cnt<=15)color=Drawshape_color[3];
else if(cnt>=16 && cnt<=19)color=Drawshape_color[4];
x0=Lcd_RightMove(x0,y0,cnt,color);
}
}
else if((key==4) && stat)
{
if(x0>=10)
{
if(Lcd_Shape_GetStat(x0-10,y0)==0)
{
if(cnt==1)color=Drawshape_color[0];
else if(cnt>=2 && cnt<=3)color=Drawshape_color[1];
else if(cnt>=4 && cnt<=7)color=Drawshape_color[2];
else if(cnt>=8 && cnt<=15)color=Drawshape_color[3];
else if(cnt>=16 && cnt<=19)color=Drawshape_color[4];
x0=Lcd_LeftMove(x0,y0,cnt,color);
}
}
}
if(i>=100 && stat)
{
i=0;
if(cnt==1)color=Drawshape_color[0];
else if(cnt>=2 && cnt<=3)color=Drawshape_color[1];
else if(cnt>=4 && cnt<=7)color=Drawshape_color[2];
else if(cnt>=8 && cnt<=15)color=Drawshape_color[3];
else if(cnt>=16 && cnt<=19)color=Drawshape_color[4];
y0=Lcd_DownMove(x0,y0,cnt,color);
if(Lcd_Shape_GetLowerBoundary(x0,y0,cnt))
{
res=Lcd_GetMark(buff);
if(res==0xff)
{
mark=0;
res=0;
LCD_Display_Str(LCD_WIDTH/2-9*12,230,24,(u8 *)"GAME OVER",RED);
LCD_Display_Str(LCD_WIDTH/2-9*12-20,265,16,(u8 *)"请按任意键重新开始!",RED);
while(1)
{
key=Key_Getval();
if(key)
{
Lcd_Clearshape();
goto AA;
}
}
}
mark+=res;
if(mark2!=mark)
{
mark2=mark;
snprintf((char *)buff,sizeof(buff),"%02d",mark2);
LCD_Display_Str(LCD_WIDTH-94,230,24,(u8 *)" ",WHITE);
LCD_Display_Str(LCD_WIDTH-94+96/2-strlen((char *)buff)*12,230,24,buff,RED);
}
x0=112,y0=0;
Lcd_Drawshape(LCD_WIDTH-96+35,80,cnt2,WHITE,0);
cnt=cnt2;
cnt2=rand()%20;
if(cnt2==0)cnt2=1;
Lcd_Drawshape(LCD_WIDTH-96+35,80,cnt2,BLACK,0);
}
}
Delay_Ms(1);
i++;
}
}
5.完整工程
完整工程示例:https://download.csdn.net/download/weixin_44453694/84079602
|