IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32之俄罗斯方块 -> 正文阅读

[嵌入式]STM32之俄罗斯方块

STM32之俄罗斯方块

1.硬件平台

  • STM32开发板
  • 3.5寸LCD屏(16位并口8080时序)
  • 字库存储W25Q64(SPI)
  • 4个按键

2.示例效果

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.软件设计

?3.1 绘制单个方块函数

/*************绘制单个方块**************/
void Lcd_DrawDiamond(u16 x,u16 y,u16 c)
{
  u16 i;
  LcdWriteReg(0x2A);//设置x坐标
  LcdWriteData((x>>8)&0xff);//x坐标高8位
  LcdWriteData(x&0xff);//x坐标低8位
  LcdWriteData(((x+8)>>8)&0xff);//x坐标高8位
  LcdWriteData((x+8)&0xff);//x坐标低8位
  LcdWriteReg(0x2B);//设置Y坐标
  LcdWriteData((y>>8)&0xff);//Y坐标高8位
  LcdWriteData(y&0xff);//Y坐标低8位
  LcdWriteData(((y+8)>>8)&0xff);//Y坐标高8位
  LcdWriteData((y+8)&0xff);//Y坐标低8位
  LcdWriteReg(0x2C);//设置x坐标
  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},//第一行y=0的状态信息
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},//第二行y=10的状态信息
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},//y=20
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},//y=30
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},//y=40 
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},//y=50
  {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},//y=200
  {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},//y=300
  {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},//y=400
  {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},//y=460
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},//y=470  
  {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 设置每个方块种类颜色,绘制各个方块

 /*每一个种类的颜色*/
/*
		1  -- DARKBLUE --Drawshape_color[0]
		2,3 -- BRRED  --Drawshape_color[1]
		4,5,6,7 -- BLUE --Drawshape_color[2]
		8,9,10,11,12,13,14,15 -- GRAY --Drawshape_color[3]
		16,17,18,19  --BLACK -- Drawshape_color[4]
*/
const u16 Drawshape_color[]={DARKBLUE,BRRED,BLUE,GRAY,BLACK};
/*******************绘制一个俄罗斯方块***************************
**形参:x,y -- 要显示的位置
**			what  --要绘制的方块序号(1~19)
**      c   --方块颜色
**			stat  --更新到二维数组中的状态(0表示清除,1表示写入状态)
*******************************************************************/
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)
{
	//printf("x=%d,y=%d\r\n",x,y);
	//printf("stat=%d\r\n",shape_place_stat[y/10][x/10+1]);
  if(shape_place_stat[y/10][x/10+1])return 1;
  else return 0;  
}
//每个方块高度         //1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
const u8 shape_high[19]={2,1,4,2,3,3,2,3,2,3,2,3,2,3,2,3,2,3,2};
//保存每个方块宽度      //1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
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);
		//shape_place_stat[line][i]=shape_place_stat[line-1][i];
  }
}

?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;
    }
  }
//	printf("line=%d\r\n",line);
	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;//消除1行得1分
	else if(cnt==2)cnt=4;//消除2行得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);
	/*俄罗斯方块示例图*/
//  for(i=1;i<=19;i++)
//  {
//		if(i==1)color=Drawshape_color[0];
//		else if(i>=2 && i<=3)color=Drawshape_color[1];
//		else if(i>=4 && i<=7)color=Drawshape_color[2];
//		else if(i>=8 && i<=15)color=Drawshape_color[3];
//		else if(i>=16 && i<=19)color=Drawshape_color[4];
//    Lcd_Drawshape(x0,y0,i,color,0);//绘制图形
//    x0+=50;
//    if(x0>=260)
//    {
//      x0=50;
//      y0+=50;
//    }
//  }
  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);//显示字符串
				}
       // printf("得分:%d\r\n",mark);
        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

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 21:59:21  更:2022-03-13 22:00:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:19:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码