之前的版本,俄罗斯方块都是使用的颜色来填充,这节开始,为俄罗斯方块设置背景图片,同时为其添加上下左右键的操作功能。 下载地址为:http://pan.baidu.com/share/...
之前的版本,俄罗斯方块都是使用的颜色来填充,这节开始,为俄罗斯方块设置背景图片,同时为其添加上下左右键的操作功能。
下载地址为:http://pan.baidu.com/share/link?shareid=396056&uk=940392313 (百度盘共享链接地址),进入zengl俄罗斯方块共享文件夹,在该文件夹中有个version_3_tetris.rar的压缩包就是v3版本的代码包,里面有个版本3说明.txt文件,包含了该版本的相关说明:
该版本是俄罗斯方块的第三个测试版本,该版本具备基本的上下左右控制功能,运行俄罗斯方块版本3双击我运行.bat批 处理文件,会从I,J,L,O,S,T,Z这七种形状中随机得到一种俄罗斯方块和随机的旋转状态,从顶部落到底部,在下落过程中可以按左右键进行左右位 移,按上键来切换旋转状态,按下键来加速下落,到了底部后,就将俄罗斯方块重新初始化下落状态,并生成一个另外的随机形状继续下落,循环下去。可以按 ESC键退出。如果要玩完整版,可以查看"zengl编程语言"栏目,其中的"zengl编程语言v1.0.5 编译,执行,源码调试一体化,开发俄罗斯方块"这篇文章里有俄罗斯方块正式发布版的下载地址。
如果是linux用户,在成功编译了zengl v1.0.5或更高版本的程序后(注意编译需要root权限,因为需要将.so动态链接库拷贝到/usr/lib中),可以将 version_3_tetris.rar里的version_3_tetris文件夹拷贝到zengl根目录中,最后运行./zenglrun version_3_tetris/tetris.zl -n 即可,如果要调试脚本,可以加个-d参数(参数的含义请参考上面提到的zengl v1.0.5的文章,或者通过-h参数来查看帮助)。
在version_3_tetris目录中多了个tetris.png的俄罗斯方块背景图片资源:
上图就是俄罗斯方块七种形状的小方块背景图片集合。在游戏脚本中要加载这个图片资源,需要使用到sdlLoadBmp函数,该函数原型如下:
sdlLoadBmp(picname,red[option],green[option],blue[option]); 第一个参数picname是位图的文件名,如果有四个参数,则使用后面的三个参数来设置位图colorkey的r,g,b值,colorkey可以过滤掉不要的颜色,产生透明背景效果。返回值为加载的位图表面指针。
例如该版本的tetris.zl脚本文件的第132行:
tetris.bgimg = sdlLoadBmp("tetris.png"); //俄罗斯方块背景图片
要将加载的位图绘制到游戏窗口中,需要使用到sdlBlitImg函数,该函数的原型如下:
sdlBlitImg(src surface,src rect,dest surface,dest rect); 第一个参数src surface是要绘制的原位图表面指针,第二个参数src rect是原位图要绘制的矩形区域,如果是0,则表示将原位图的所有区域都绘制到目标表面中,如果是数组或类,则读取该数组中的前四项分别代表矩形区域的 坐标和宽高。第三个参数dest surface是要绘制的目标位图表面指针,第四个参数dest rect是要绘制的目标矩形区域,如果是0,则表示要绘制目标表面的所有区域,如果是数组或类,则表示目标矩形区域的坐标和宽高。
例如tetris.zl脚本的myDrawTetris自定义函数的第12行:
sdlBlitImg(tetris.bgimg,
array(tetris.startindex * TetrisWidth,0,TetrisWidth,TetrisHeight),
screen,
array(TetrisWidth * (tetris.members[i].vx + tetris.xy.vx) + gameMainBg.pos.x,
TetrisHeight * (tetris.members[i].vy + tetris.xy.vy) + gameMainBg.pos.y,
TetrisWidth , TetrisHeight)
);
从该版本开始,所有宏定义,类定义等都放在了tetris_def.zl脚本中。在宏定义部分,有和SDL按键事件相关的宏:
//sdl event def SDL游戏引擎事件相关的宏定义
def NoEvent 0;
def EvKeyDown 2;
def EvKeyUp 3;
def KeyEsc 27;
def KeyUp 273;
def KeyDown 274;
def KeyLeft 276;
def KeyRight 275;
def EvQuit 12;
//sdl event def end
上面就定义了上下左右等按键的SDL值,这些值可以在SDL库的C头文件中找到,例如在windows vs2008的代码压缩包里包含了SDL-1.2.15目录,该目录中include目录下有个SDL_keysym.h头文件,里面有所有SDL按键事 件的值定义:
例如上图中的SDLK_UP按上键的值为273,对应zengl脚本中的KeyUp宏值。其他的按键宏值也是类似的定义方法。
为了处理这些按键事件,在游戏脚本中添加了myCalculateMove自定义函数:
/*
如果按了上下左右方向键,则计算将要显示的位置和样式等信息
*/
fun myCalculateMove()
global tetris,isneedDraw,time;
clsTetris tetris;
switch(tetris.direct)
case KeyLeft:
start = tetris.startindex * 16 + tetris.state * 4;
if(tetris.xy.vx + tetris.members[start + 0].vx - 1 >= 0) //如果最左侧的小方块没到达主游戏区域的左边界,则将整体虚拟坐标减一
tetris.xy.vx--;
endif
break;
case KeyRight:
start = tetris.startindex * 16 + tetris.state * 4;
if(tetris.xy.vx + tetris.members[start + 3].vx + 1 < GameMainWidthNum) //如果最右侧的小方块没到达主游戏区域的右边界,则将整体虚拟坐标加一
tetris.xy.vx++;
endif
break;
case KeyUp:
orig_state = tetris.state;
tetris.state = (tetris.state + 1)%4; //按上键时,得到下一次的旋转状态
start = tetris.startindex * 16 + tetris.state * 4;
if((tetris.xy.vx + tetris.members[start + 0].vx < 0) ||
(tetris.xy.vx + tetris.members[start + 3].vx >= GameMainWidthNum) ||
myCollisionDetect()) //判断旋转后的状态是否超出左右边界,或者是否会发生底部碰撞,如果发生了这些情况,则将旋转状态恢复为原来的值。
tetris.state = orig_state;
endif
break;
case KeyDown:
if(!myCollisionDetect()) //如果按了下方向键,则进行碰撞检测,并在其中设置方块的下落速度。
tetris.xy.vy += tetris.speed;
endif
break;
default: //其他按键,直接返回
return;
endswt
isneedDraw = TRUE; //设置需要绘制标记
time = sdlGetTicks(); //重置定时器
endfun
至于脚本中的其他代码都在重要的部分加了注释,可以结合注释和调试器进行分析,该版本的运行界面如下:
OK,下节介绍v4的版本,休息,休息一下 O(∩_∩)O~