俄罗斯方块就像堆积木一样,将所有下落碰撞后的方块堆砌起来,越堆越高,本节的版本就来实现这种堆砌功能。     下载地址:http://pan.baidu.com/share/link?shareid=396...

    俄罗斯方块就像堆积木一样,将所有下落碰撞后的方块堆砌起来,越堆越高,本节的版本就来实现这种堆砌功能。

    下载地址:http://pan.baidu.com/share/link?shareid=396056&uk=940392313 (百度盘的共享链接地址),进入zengl俄罗斯方块共享文件夹,在该文件夹中有个version_4_tetris.rar的压缩包就是v4版本的代码包,里面有个版本4说明.txt文件,包含了该版本的相关说明:

    该版本是俄罗斯方块的第四个测试版本,该版本会将所有发生过底部碰撞的俄罗斯方块固定在主游戏区域中,但是还不具备消行积分的功能,只是将俄罗斯方块进行简单堆砌,运行俄罗斯方块版本4双击我运行.bat批 处理文件,会从I,J,L,O,S,T,Z这七种形状中随机得到一种俄罗斯方块和随机的旋转状态,从顶部落下,在下落过程中可以按左右键进行左右位移,按 上键来切换旋转状态,按下键来加速下落,到了底部后或者和其他主游戏区域的固定方块发生碰撞后,就会固定在主游戏区域中,并重新在顶部生成另一个俄罗斯方 块,继续下落,循环下去。可以按ESC键退出。如果要玩完整版,可以查看"zengl编程语言"栏目,其中的"zengl编程语言v1.0.5 编译,执行,源码调试一体化,开发俄罗斯方块"这篇文章里有俄罗斯方块正式发布版的下载地址。

    如果是linux用户,在成功编译了zengl v1.0.5或更高版本的程序后(注意编译需要root权限,因为需要将.so动态链接库拷贝到/usr/lib中),可以将 version_4_tetris.rar里的version_4_tetris文件夹拷贝到zengl根目录中,最后运行./zenglrun version_4_tetris/tetris.zl -n 即可,如果要调试脚本,可以加个-d参数(参数的含义请参考上面提到的zengl v1.0.5的文章,或者通过-h参数来查看帮助)。

    在游戏脚本中,俄罗斯方块的主游戏区域是由10 X 20的一个200个小方格组成的区域,发生碰撞后的小方块将遗留在这些小方格中,所以需要一个数组来记录下所有小方格的占用状态,存放的方块类型等信息, 在tetris_def.zl脚本中对clsGameMainBg类做了扩展:

class clsGameMainBg
    clsPosition pos; //游戏主区域的主屏幕的坐标,宽高信息
    clsColor bgcolor; //主区域背景色
    clsFixTetris fix_tetris; //存放主游戏区域固定方块信息的数组
    count; //主游戏区域的总方格数
endcls

    上面类中的fix_tetris成员就是一个存放所有小方格状态的数组。该数组和小方格的对应关系如下图所示:

    从上图可以看出,fix_tetris的数组元素索引在主游戏区域是从左往右,从上到下依次增大的,其中虚拟坐标(0,0)对应 fix_tetris[0]元素,(1,0)对应fix_tetris[1]元素,(0,1)对应fix_tetris[10]元素等,以此类推。

    fix_tetris里的每个元素又是一个clsFixTetris类型,如下:

class clsFixTetris
    startindex; //该元素对应方格里存放的方块的形状样式索引,由该索引可以得到方块的背景图片等信息
    occupy; //判断对应的方格里是否有小方块。
endcls

    在tetris.zl脚本中,增加了myFillMainGg自定义函数,通过该函数将每次碰撞后的方块对应的fix_tetris数组元素设为占用状态,并设置该方格对应的方块样式信息,从而将方块固定到主游戏区域中去:

/*
    如果发生底部碰撞,则将主游戏区对应的格子设为占用状态。
*/

fun myFillMainGg()
    global gameMainBg,tetris;
    clsGameMainBg gameMainBg; clsTetris tetris;
    start = tetris.startindex * 16 + tetris.state * 4;
    count = start + 4;
    for(i = start ; i<count ; i++) //对四个小方块循环设置占用状态
        vx = tetris.xy.vx + tetris.members[i].vx;
        vy = tetris.xy.vy + tetris.members[i].vy;
        index = vx + vy * GameMainWidthNum;
        gameMainBg.fix_tetris[index].occupy = 1; //将主游戏区对应方格设为占用状态。
        gameMainBg.fix_tetris[index].startindex = tetris.startindex; //设置形状样式的索引值,每个样式都有自己的背景图片信息
    endfor
endfun

    在绘制游戏窗口时,通过myDrawFixTetris自定义函数将上面设为占用状态的固定方块给绘制出来:

/*
    绘制主游戏区域由于碰撞而固定下来的方块,如果主游戏区域横排有10格,竖排有20格,那么一共可以存放200个小方块。
    那么gameMainBg.fix_tetris就是一个含有200个元素的数组,每个元素对应主游戏区域中的一个小格子,gameMainBg.fix_tetris[i].occupy成员用于判断
    某个格子里是否含有小方块。如果含有方块,就根据该方块的样式和状态将其绘制出来。这样做个循环就可以将200个格子里含有方块的格子都绘制出来。
*/

fun myDrawFixTetris()
    global tetris,screen,gameMainBg;
    clsTetris tetris; clsGameMainBg gameMainBg;
    for(i=0;i<gameMainBg.count;i++) //循环所有的主游戏区域的格子
        if(gameMainBg.fix_tetris[i].occupy) //如果某个格子里有方块,则将其绘制出来
            vx = i % GameMainWidthNum; //根据索引值计算虚拟坐标的x值。
            vy = bltConvToInt(i / GameMainWidthNum); //根据索引值计算虚拟坐标的y值。因为除法得出的默认结果是一个浮点数,而下面的sdlBlitImg绘制时需要整数格式的坐标数据,所以需要通过bltConvToInt将除得的浮点数转为整数。
            sdlBlitImg(tetris.bgimg,
                    array(gameMainBg.fix_tetris[i].startindex * TetrisWidth,0,TetrisWidth,TetrisHeight),
                    screen,
                    array(TetrisWidth * vx + gameMainBg.pos.x,
                            TetrisHeight * vy + gameMainBg.pos.y,
                            TetrisWidth , TetrisHeight)
                    );
        endif
    endfor
endfun

    上面棕色的注释是这里额外添加的需要注意的地方。

    在tetris.zl中还添加了一个myEdgeDetect边界检测的自定义函数,和myCollisionDetect碰撞检测自定义函数的不同之处 在于,边界检测是用来限制俄罗斯方块的左右位移的,当玩家按下左右键时,通过myEdgeDetect函 数来判断其左右两边是否会超出边界,或者在左右两边是否有其他的固定的小方块挡住了去路,如果有则不能再左右位移,而碰撞检测主要是判断运动中的俄罗斯方 块底部是否和其他的小方块发生接触,或者是否到了主游戏区域的底部,如果是则将运动方块固定下来,并在顶部重新生成另一个随机的方块继续下落。

    至于脚本中的其他代码都在重要的部分加了注释,可以结合注释和调试器进行分析,该版本的运行界面如下:

    前面提到过,因为该版本还不具备消行积分功能,所以上图中的最底行即使满了一行,也不会消行,该版本还只是简单的堆砌方块,在后面的版本中将逐步加入消行积分等功能。

    OK,下节介绍v5的版本,休息,休息一下 O(∩_∩)O~

上下篇

下一篇: zengl俄罗斯方块v5 简单消行法

上一篇: zengl俄罗斯方块v3 添加按键功能

相关文章

zengl俄罗斯方块v5 简单消行法

zengl俄罗斯方块v11 使用zengl v1.0.6新语法

zengl俄罗斯方块v1 入门篇

zengl俄罗斯方块v8 修复消行BUG

zengl俄罗斯方块v6 传统消行法

zengl俄罗斯方块v7 添加暂停功能