采用STM32开发板制作俄罗斯方块小游戏

发布者:epsilon15最新更新时间:2024-06-06 来源: elecfans关键字:STM32  俄罗斯方块  小游戏 手机看文章 扫描二维码
随时随地手机看文章

《俄罗斯方块》(Tetris, 俄文:Тетрис)是一款由俄罗斯人阿列克谢·帕基特诺夫于1984年6月发明的休闲游戏。

该游戏曾经被多家公司代理过。经过多轮诉讼后,该游戏的代理权最终被任天堂获得。 [1] 任天堂对于俄罗斯方块来说意义重大,因为将它与GB搭配在一起后,获得了巨大的成功。

《俄罗斯方块》的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。

1.硬件平台

STM32开发板

3.5寸LCD屏(16位并口8080时序)

字库存储W25Q64(SPI)

4个按键

2.方块示例

本设计中方块种类共5种,根据方向的不同可分为19种可能性。

pYYBAGKSJKyADRpfAAm2yYHLuRg863.png

3.游戏效果图

1.游戏结束效果。当方块堆叠触碰到上顶端,则游戏结束。

pYYBAGKSJOeAZykbAApWvKh3oFU964.png

2.正常游戏和方块颜色分配,下一个方块提示,积分统计,按键操作说明。

pYYBAGKSJYCAeoYUAAWq-f7Fa7I160.png

3.消行效果展示,得分获取。

软件设计中,消除一行得1分,消除两行得2分,消除3行得4分,消除4行得8分。

poYBAGKSJZWABMUCAAo1jutCgew698.png

4.软件设计

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);

}

/******************消除一行*******************/

void Lcd_ClearOneLineDisplay(u16 y,u16 c)

{

  u16 i=0;

  for(i=2;i;i+=10)>

2.绘制各个方块,设置方块颜色


 /*每一个种类的颜色*/

/*

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);

[1] [2] [3]
关键字:STM32  俄罗斯方块  小游戏 引用地址:采用STM32开发板制作俄罗斯方块小游戏

上一篇:如何用一个ESP8266加上STM32单片机做一个小产品?
下一篇:简述温度传感器DS18B20原理内附STM32例程代码

推荐阅读最新更新时间:2024-11-17 01:06

STM32入门学习笔记之基础定时器实验(上)
7.1 STM32定时器概述 STM32内部共有8个定时器,其中Timer1和Timer8属于高级定时器,Timer2~Timer5属于通用定时器,8个定时器的资源独立,互不影响。 STM32的通用定时器是一个通过可编程预分频器(PSC)驱动的16位自动装载计数器(CNT)构成。STM32的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)等。使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32的每个通用定时器都是完全独立的,没有互相共享的任何资源。 通用定时器的内部结构如下图所示。 7.2 相关寄存器 要使用通用定时器的基
[单片机]
<font color='red'>STM32</font>入门学习笔记之基础定时器实验(上)
[STM32] 关于USART接收中断的BUG和注意事项
今天在使用USART模块,遇到了一些问题并解决了,于是发贴共享。 问题描述: 在使用USART做串口通讯时,我只把接收中断打开,并设置抢占优先级为最低一个级别,而接收中断上一个优先级处理事情比较多,可能占用了2ms时间。当我使用9600波特率往下位机发送数据,速度非常快,就是一直按回车发!问题就出来,不到1分钟时间,通讯没有反应了。USART配置代码如下: void uart_config(void) { USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = UART_GetBaud(BaudRate); USART_In
[单片机]
基于STM32单片机和EM310的无线终端设计
0引言 在监测监控及数据采集系统(SCADA)系统中,采集数据的实时性和准确性对系统有很大的影响,合适的通信网络可以有效提高SCADA系统的效益,本文设计的GPRS无线终端在SCADA系统中的应用解决了上述问题,除满足数据实时性和准确性外,还具有建设成本低.结构简单.传输容量大.可远程控制等优势. 1 终端简介 1.1终端结构 无线终端由EM310GSM模块和STM32F103单片机构成,以STM32F103单片机为核心,STM32F103单片机有丰富的通信接口,用于连接EM310和现场仪表;还有丰富的I/O资源,可以扩展较大容量的RAM,一方面存储指令集,用于解读指令并作出相应的动作;另一方面用于暂时存储监测点采
[单片机]
基于<font color='red'>STM32</font>单片机和EM310的无线终端设计
基于stm32的HC-SR04超声波测距模块使用
1 工作原理 使用超声波模块之前,先了解其IO口和工作原理: 1.1 IO说明 VCC: 供5V电源 GND: 为地线 TRIG: 触发控制信号输入 ECHO: 回响信号输出 1.2 基本工作原理: 认真看好以下工作原理,后面的代码就是基于工作原理来实现的。 (1)采用IO口TRIG触发测距,给最少10us的高电平信号。 (2)模块自动发送8个40khz的方波,自动检测是否有信号返回; (3)有信号返回, 通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。 测试距离=(高电平时间*声速(340M/S))/2 时序图: 2 程序编写 2.1 外设配置 根据两个信号引脚来配置两个单片机的IO口
[单片机]
基于<font color='red'>stm32</font>的HC-SR04超声波测距模块使用
通用定时器-输入捕获实验
本节定时器PWM输出主要涉及到定时器框图左下方部分,即输入捕获部分 输入捕获工作过程(以通道1为例) 一个通道的框图: 作用:捕获TIMx_CH1通道信号的跳变,并触发捕获中断 我们将此过程拆分为4个部分 1,设置输入捕获滤波器 fDTS是根据TIMx_CR1-CKD 的设置确定的 如果TIMx_CR1-CKD 设置为00,则fTDS=fCK_INT = 72Mhz 如果TIMx_CR1-CKD 设置为10,则fTDS=fCK_INT / 4 = 18Mhz TIMx_CCMR1-ICF 输入捕获1滤波器,设置输入采样频率和数字滤波长度 如果TIMx_CCMR1-IC1F =0011,采样频率fSAMP
[单片机]
通用定时器-输入捕获实验
初学STM32及GPIO入门之流水灯
一.准备工作---建立一个keil工程 STEP1. 打开keil,选择project-new uvision project,建立一个LED工程 STEP2. 在工程文件保存的路径下新建以下文件夹,在官网上或其他渠道下载STM32的3.5版库,将inc 和scr文件夹放入fwlib中。将startup_stm32f10x_hd.s放入asm文件夹中。将库文件放入cmsis中。 STEP3. 在keil中分别新建 【startcode】【user】【fwlib】【cmsis】四个组,再按照下图所示将C文件加入组中。这里要注意的是组里面添加的都是汇编文件和C文件,头文件不需要添加。 STEP4. 为了更好的理清各项文
[单片机]
初学<font color='red'>STM32</font>及GPIO入门之流水灯
STM32/CPU地址映射的概念
1总线的由来 很多人对总线和地址映射的概念都是一头雾水,但是我们如果知道为何需要总线和地址映射,他们是在什么背景下被衍化出来的,自然而然对此概念就清清楚楚了。 我们知道CPU都是通过总线访问外设,例如STM32使用AMBA规范的总线和外设进行交互,那么在总线的概念没有被提出来的时候,外设是怎样被访问的呢? 其实在最早期还没有总线概念的时候,CPU设计者会直接把CPU内核和各种接口控制器设计到一起,如果要访问一个硬件,直接在内核里面对各种接口控制器进行操作,从而操作相应的硬件。我们看下图。 后来设计者发现如果每添加一个外设都要修改CPU内核,这样不具有很好的扩展性,为了使得外设的改变(增加、删除、修改)不影响CPU内核架
[单片机]
<font color='red'>STM32</font>/CPU地址映射的概念
意法STM32系列获ARM RealView微控制器开发工具包支持
ARM公司日前宣布RealView微控制器开发工具包将支持意法半导体基于ARM Cortex-M3处理器的全新STM32F1xx系列器件。 STM32F101(接入行)和STM32F103(性能行)将是意法半导体首个基于ARM Cortex-M3处理器的器件系列,兼具卓越的高性能和低功耗。该系列器件拥有高达72MHz的CPU时钟速度、128Kbyte片上闪存ROM及20Kbyte片上RAM,还包括A/D、CAN、USB、SPI、I2C等众多外设及多达80个GPIO。 RealView微控制器开发工具包3.1可为新器件提供支持。这一最新版本保留了Keil Vision 3集成开发环境(IDE)易于使用的特性,并增加了针对STM3
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved