传统的俄罗斯方块一共有七种形状,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。本节通过数组来定义这七种形状的相对虚拟坐标,并且每种形状 都有四个旋转状态,当然有的旋转状态都是一样...

    传统的俄罗斯方块一共有七种形状,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。本节通过数组来定义这七种形状的相对虚拟坐标,并且每种形状 都有四个旋转状态,当然有的旋转状态都是一样的,例如O形,四个旋转状态都是一个样子,尽管如此,也统一按四个状态来定。

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

    该版本是俄罗斯方块的第二个测试版本,该版本还没有建立任何可玩的游戏环节,运行俄罗斯方块版本2双击我运行.bat批处理文件,会从I,J,L,O,S,T,Z这七种形状中随机得到一种俄罗斯方块和随机的旋转状态,从顶部落到底部,到了底部后,就将俄罗斯方块重新初始化下落状态,并生成一个另外的随机形状继续下落,循环下去。可以按ESC键退出。如果要玩完整版,可以查看"zengl编程语言"栏目,其中的"zengl编程语言v1.0.5 编译,执行,源码调试一体化,开发俄罗斯方块"这篇文章里有俄罗斯方块正式发布版的下载地址。

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

    任何一种俄罗斯方块都是由四个小方块组成,每个俄罗斯方块也都有自己的整体虚拟坐标,而每个小方块的虚拟坐标是他的相对虚拟坐标加上整体虚拟坐标。

    例如上图的I形状(用蓝色边框标记起来的),整体坐标是蓝边框左上角的(3,2) ,而I形状在垂直旋转状态下四个小方块的相对虚拟坐标为(2,0),(2,1),(2,2),(2,3),那么第一个小方块的在游戏主区域中的虚拟坐标就 是(3+2,2+0) = (5,2),第二个就是(5,3),依此类推。其他所有形状的小方块也都是相对蓝色边框的左上角的,这个蓝色边框是一个虚拟的4 X 4的区域。之所以要这么做,是为了方便定义俄罗斯方块的各种形状,同时也便于计算俄罗斯方块的整体运动坐标。

    该版本tetris.zl的第167行的代码定义了所有形状和旋转状态的相对虚拟坐标:

tetris.members = array(
                    array(0,2),array(1,2),array(2,2),array(3,2)  ,  array(2,0),array(2,1),array(2,2),array(2,3),
                    array(0,2),array(1,2),array(2,2),array(3,2)  ,  array(2,0),array(2,1),array(2,2),array(2,3), //I形状的虚拟坐标

                    array(0,0),array(0,1),array(1,1),array(2,1)  ,  array(0,2),array(1,2),array(1,1),array(1,0),
                    array(0,1),array(1,1),array(2,1),array(2,2)  ,  array(2,0),array(1,0),array(1,1),array(1,2), //J形状的虚拟坐标

                    array(0,1),array(1,1),array(2,1),array(2,0)  ,  array(0,0),array(1,0),array(1,1),array(1,2),
                    array(0,2),array(0,1),array(1,1),array(2,1)  ,  array(1,0),array(1,1),array(1,2),array(2,2), //L形状的虚拟坐标

                    array(0,0),array(0,1),array(1,1),array(1,0)  ,  array(0,0),array(0,1),array(1,1),array(1,0),
                    array(0,0),array(0,1),array(1,1),array(1,0)  ,  array(0,0),array(0,1),array(1,1),array(1,0), //O形状的虚拟坐标

                    array(0,1),array(1,1),array(1,0),array(2,0)  ,  array(0,0),array(0,1),array(1,1),array(1,2),
                    array(0,1),array(1,1),array(1,0),array(2,0)  ,  array(0,0),array(0,1),array(1,1),array(1,2), //S形状的虚拟坐标

                    array(0,1),array(1,1),array(1,0),array(2,1)  ,  array(0,1),array(1,1),array(1,0),array(1,2),
                    array(0,1),array(1,1),array(1,2),array(2,1)  ,  array(1,0),array(1,1),array(1,2),array(2,1), //T形状的虚拟坐标

                    array(0,0),array(1,0),array(1,1),array(2,1)  ,  array(0,2),array(0,1),array(1,1),array(1,0),
                    array(0,0),array(1,0),array(1,1),array(2,1)  ,  array(0,2),array(0,1),array(1,1),array(1,0) //Z形状的虚拟坐标

    俄罗斯方块的每种形状都有特定的颜色值,在后面的版本中使用的是方块图片,在本版本中为了简化代码,就用颜色来填充小方块。

    下面的159行的代码设定了七种形状的颜色值:
tetris.color = array(array(0xf3,0x6c,0xe1) , //I形状的颜色值
                    array(0x37,0x33,0xe5) ,  //J形状的颜色值
                    array(0xde,0x9d,0x2b) ,  //L形状的颜色值
                    array(0xf1,0xf7,0x40) ,  //O形状的颜色值
                    array(0x33,0xf0,0x49) ,  //S形状的颜色值
                    array(0xd3,0x33,0xf0) ,  //T形状的颜色值
                    array(0xf6,0x10,0x36)    //Z形状的颜色值
                    );

    上面的两处代码需要注意的是array是一个函数,函数的参数中间以逗号隔开,最后一个参数后面不可以有逗号,这点和PHP不一样,所以需要特别注意,例如上面的array(0xf6,0x10,0x36)后面就没有逗号了。

    该版本还添加了碰撞检测的自定义函数:
/*
    对活动中的俄罗斯方块进行底部的碰撞检测,
*/

fun myCollisionDetect()
    global tetris;
    clsTetris tetris;
    start = tetris.startindex * 16 + tetris.state * 4; //得到方块样式的索引信息
    count = start + 4; //需要对四个方块都进行检测,所以加4
    for(i = start ; i<count ; i++) //循环对四个小方块进行检测。判断是否到了底部
        if(tetris.xy.vy + tetris.members[i].vy + 1 >= GameMainHeightNum)
            return TRUE;
        endif
    endfor
    return FALSE;
endfun

    下面是俄罗斯方块运动过程中的新的虚拟坐标计算函数:

/*
    计算运动中的方块的虚拟坐标,并判断是否下落到了主游戏区域的底部,如果到了底部就将俄罗斯方块重新初始化下落状态。
*/

fun myTetrisMove()
    global time,isneedDraw,tetris,isinStartDroping;
    clsTetris tetris;
    if(sdlGetTicks() - time > 1000) //每隔1000毫秒,就进行匀速自由落体运动。
        if(myCollisionDetect()) //先进行底部碰撞检测
            myGetRandomIndex(); //再随机生成下一次的方块形状。
            tetris.state = bltRandom()%TetrisStateNum; //设置下一次的方块旋转状态
            tetris.xy.vx = bltRandom()%(GameMainWidthNum - 3); //设置随机的水平初始虚拟坐标
            tetris.xy.vy = 0; //重置vy虚拟纵坐标
            isneedDraw = TRUE; //因为设置了新的俄罗斯方块坐标形状等信息,所以需要重新绘制。
            time = sdlGetTicks(); //重置time定时器
            return;
        endif
        tetris.xy.vy++; //如果没发生碰撞,就让俄罗斯方块的整体虚拟坐标加一
        isneedDraw = TRUE; //需要重新绘制
        time = sdlGetTicks(); //重置time定时器
    endif
endfun

    该版本的运行截图如下:

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

上下篇

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

上一篇: zengl俄罗斯方块v1 入门篇

相关文章

zengl俄罗斯方块v9 添加下一次出现方块的预览功能

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

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

zengl俄罗斯方块v4 堆砌碰撞过的方块

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

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