基于LPC1788单片机俄罗斯方块
逻辑原理
俄罗斯方块的实现分为逻辑实现和显示屏显示两个层面。逻辑实现过程采用数组的方式实现。如下图所示。
图中被涂黑的方格用1表示,没有被涂黑的方格用0表示。每一行用一位十六进制数表示。因此上图所示方块抽象为十六进制数即0x0446。
明白了上述原理以后就可以表示出任意形状的方块了。俄罗斯方块游戏共有起种类型,分别为S、Z、L、J、I、O、T,每种类型又可以分为四种类别。因此可以创建一个二位数组来保存这些形状,在需要的时候从数组中直接调用即可。
同时为了增加游戏的乐趣需要在游戏运行的过程中对方块进行变形。所谓变形不是毫无规则胡乱改变,而是按照某一规则进行旋转,我采用的是顺时针旋转90度的方法,因此每个类别的方块有四种变形方式。所以同样可以创建一个二位数组用来保存方块旋转时所经过的路径。
方块的具体信息用结构体来进行封装。结构体中包含坐标、颜色、类型等具体信息。游戏开始运行时通过一个随机数来获取方块的各种信息,并在游戏中体现出来。
方块移动原理
每经过一个单位时间,界面会执行一次刷新动作以响应游戏的运行。每个动作只会改变局部的界面,因此只需要对改变的部分进行刷新即可。
需要注意的是每次动作之前都要进行冲突检测,以防止出界或与其它方块冲突。由于下一时刻的方块肯定会有一部分与当前时刻重叠,因此在执行冲突检测之前需要删除当前方块,单独对下一时刻的方块进行冲突检测,检测无误后在数组中绘制出来。
显示界面的刷新实现方式如下:创建两个数组,一个用来保存当前时刻的界面,另一个用来保存上一时刻的界面。每次刷新只需对两个数组进行比较,找到不同的部分。由于不同的部分包括新增的和删减的。所以需要在UI层绘制新增加的部分,并擦除应该删去的部分。
运行原理
游戏中的方块在没有任何按键操作的情况下依然可以自由下落。原理解释如下:
首先game_run()这个函数是放在一个无限循环的while()中的。在game_run()中有如下代码
Delay(25);
if (!pause)
time_count++;
if (time_count >= (12 - level))
{
time_count = 0;
refresh = true;
tetris_move(dire_down);
}
每次进入这个函数都会有一个Delay()函数,该函数直接决定了方块下落的速度。 if (time_count >= (12 - level))语句的作用是随着游戏级别的升高,运行速度会随之提升。满足if中的条件之后方块就会下落。由于游戏处于循环状态,因此每当时间到达之后方块即下落。
消行原理
当某一行被填充满之后需要消除该行。
由于数组中被填充的部分用1表示,没有被填充的部分用0表示。
因此消行原理如下:从顶端开始依次向下扫面,每检测到某一行全为1就认为该行已满,用上一行替换该行以消除满的那一行,并重新对最上面的第一行赋0值。
计分原理
依据所消的行数进行计分,所消行数每增加一定数值,游戏提高一个级别,并将游戏运行速度做相应提高。随着游戏级别的升高每消一行所得分数也做相应提高。
界面显示
上述原理是抽象化的实现,很显然还需要将上述实现过程映射到显示屏具体显示出来游戏才能进行。
编写者需要具备能够在显示屏任意位置显示任意颜色任意形状的能力。
然后通过回调函数将游戏的逻辑实现与实际显示连接起来