龙空技术网

教你用三菱PLC+HMI仿真制作《俄罗斯方块》

PLC程序猿 4715

前言:

而今朋友们对“c俄罗斯方块旋转算法”大约比较关心,咱们都需要剖析一些“c俄罗斯方块旋转算法”的相关内容。那么小编在网络上收集了一些关于“c俄罗斯方块旋转算法””的相关资讯,希望小伙伴们能喜欢,大家一起来了解一下吧!

很多人刚学过plc编程都想自己编程实现一个小功能或者小游戏来检验自己的学习成果,如果你学过ST(结构化)语言,那我们可以用PLC实现一个更为复杂的游戏,比如《俄罗斯方块》!本文将详细介绍如何使用三菱的ST语言来编写,在此过程中我们也可以体会ST语言的特点,感兴趣的同学可以一起探讨。

我们先看一下成品视频。

视频加载中...

需要的软件

1.GX Work2。用于编辑PLC程序。

2.GT Designer3。用于构建HMI画面。

选择三菱产品的原因有两个。一是三菱的PLC与HMI的仿真可以通讯,无需硬件;二是虽然三菱的ST支持的内容比较少,但是比较正规,上手也快。

制作HMI画面

我们先画出我们要控制的内容,规定好控制的具体变量以便于我们后面的编程。按照以下几步制作HMI画面。

1.打开GT Designer3,在弹出的窗口选择新建,随便选择一个型号的设备都可以,这里选择的是2000系列的800x600分辨率的机器,点击确定后弹出连接机器设置窗口,选择三菱的Q系列,因为我们后面要用Q系列的plc进行编程,也可以选择其他的。

选择触摸屏型号

2.在“基本画面”中新建一个画面,设置一个背景色如黑色,创建一个位指示灯作为游戏的一个像素,设定指示灯在off和on状态下的颜色和形状。可以将off状态的颜色设置为背景色,这样在off状态下这个像素就“隐身”了。

设置位指示灯

设定指示灯关联的PLC软元件,文中设定的是D0.b0,D0是一个16位的字类型软元件,我们用它的第一位来控制灯的状态。当然,既然是位指示灯你完全可以用M0等位软元件。

3.右键点击指示灯,点击“连续复制”,设置XY方向的复制的数量,勾选软元件号增量,选择复制的方向。一般俄罗斯方块的像素是20x10,这里稍微设置大一些30x16。确定后生成游戏的主屏幕,横向为X+,竖向为Y+。

连续复制

4.用上方面的方法制作一个4*4像素的预览小屏幕,再画几个控制方向和开始复位等按钮,制作完成。

控制流程

开始写一个程序时我们要先确定整个逻辑的框架,正式的项目一般还要画一个流程图,我们这里就省略流程图用文本的形式确定整个流程。

1.随机生成一个图形,缓存在预览窗口,跳转至2;

2.将预览窗口缓存的图形在主窗口的最上方显示,随机生成一个新的图形在预览窗口显示,跳转至3;

3.判断主窗口的图形是否可以下降,yes跳转至4,no判断游戏是否结束,yes跳转至100,no跳转至6;

4.将主屏幕的图形向下(Y+方向)挪动一格;跳转至5;

5.延时等待,延时结束时跳转至3。此时可以使用按钮控制图形移动和旋转;

6.此时图形无法继续向下,判断是否有一行摆满需要消除,如果有消除计算得分。跳转至2;

100.游戏结束。

整个流程可以用一个case of 语句来编写,这样程序就十分清晰可读,plc资源占用也少。

流程1,生成图形

在开始逻辑编程前我们要先将触摸屏的一维软元件(D0.b0-D29.b15)转化为我们方便操作的二维的标签(X0,Y0-X15,Y29),这样我们想要点亮一个像素只要给出一个坐标(X,Y)就可以了,要实现这个目的我们要先建立一个结构体变量“iY”,里面包含容量为16的位数组“iX”:

坐标结构体

图里面的type用于区别像素的状态,后面会讲。

然后在全局标签将这个结构体声明成容量为30的数组,起个名字为“Main_iY”,这两个数字正好与HMI里面指示灯的横向纵向数量相等,然后进行标签与软元件的关联,如下图:

标签与软元件关联

预览小屏同理。

想要显示一个图形我们需要知道这个图形对应哪些坐标,这里我们使用excel列出所有图形的坐标值:

所有图形

可以看到一共有7个图形,每个图形有4个方向,所有图形显示的像素个数都是4,这样我们可以用两个容量为4的字数组存储这个4个XY坐标,想要在预览窗口中显示图形可以直接将这4个坐标依次显示出来就可以了。而给XY一个偏移值,就可以实现主窗口显示,各个方向的移动。

想随机生成一个图形需要用到随机数指令RND生成两个随机数,在通过数学计算将这两个数一个控制在0-6,作为图形的种类;一个控制在0-3,作为图形的方向。

生成两个随机数

通过两个数字变量确定一个数组的程序我们可以写成一个Function(功能、指令),因为后面我们还要用到这个程序,减少程序篇幅。我们把所有图形的坐标写到这个FC里面,FC的返回值设为结构体,便于起名字。

生成图形指令

在主程序中调用FC:

流程1完整程序

流程2,预览图形更新

将上一步生成的OBJ数组(图形坐标)传给临时变量tempObj,然后再重新生成新的图形,并在预览窗口显示。显示方法为使用for循环,赋值4个X,Y坐标对应的像素。

生成新预览图形并显示

这里面offsetX,offsetY为坐标偏移,我给定一个初始值,图形坐标加上offset值后在主屏幕上方还没有进入,所以先不用显示。

流程3,下降判断

判断图形能不能下降,方法为将图形的所有Y坐标+1,然后再判断Y坐标是否满足两个条件的其中之一,也就是“或”关系(or),第一个条件是至少1个Y坐标=30,意味着图形到了主屏幕的最底部;第二个条件是再主屏幕内的图形像素的iType为2,这里的iType就是前面建立像素结构体时增加的数字变量,我定义运动中的图形像素iType=1,固定的iType=2。

两个条件都不满足则可以下降,满足其一则意味着图形是不能下降的,这时将图形的像素类型更改为2(iType=2)。

图形不能下降我们还要判断游戏是不是结束了,方法是判断图形所有的像素当前Y坐标是否存

在<0的情况。

下降判断

流程4,移动一格

这里比较简单,将数组对应的像素置为false,Y坐标+1,再将数组对应的像素置为true。

移动一格

这里也是主屏幕能够显示出图形原因,主屏幕的像素指示灯已经关联到“Main_iY”全局变量中,只要将上一步生成的数组对应的像素置true就可以显示了,但是超过屏幕范围外的坐标不要赋值,否则会引起数组超限报错。

流程5,延时等待,按钮操作

延时的时间可以根据分数来设定,这里直接指定1000ms。

在这个流程中还要编辑左,右,下和旋转4个按钮的动作,“左右下”动作比较容易实现,只要将图形的所有坐标+1或者-1就行了,参考流程4的写法;需要注意移动后的图形不能超过边界,不能穿越已经降落固定的图形,判断方法参考流程3。

向左移动

“旋转”功能需要将找到当前这个图形的类型和方向,也就是流程2里面记录的ObjType和ObjDirection,然后将这个方向ObjDirection进行+1或者-1操作,使用FC生成新的图形坐标,将旧的图形删除,将新的图形显示。

图形旋转

这里我们在真正的旋转前仍然要先判断,旋转后的图形是否超边界或与固定图形重合,我这里的逻辑是与固定图形重合的不允许旋转,超左右边界的移动一格坐标后进行旋转。这里实际上存在bug,但是很难出现我懒得改了。。。

流程6,判断消除

在流程3里面判断图形无法下降并固定的时候进入此流程,图形固定后我们要判断是否存在需要消除的行,方法为逐行判断是否全部显示,消除后记得将消除行上方的图形下降,记录得分。

运行调试

消除所有的错误和bug,添加必要的启动复位按钮程序,将程序段拉入PLC循环扫描任务中,编译后启动仿真,然后启动HMI的仿真,就可以愉快的玩耍啦~

标签: #c俄罗斯方块旋转算法