基于80x86汇编的俄罗斯方块游戏

邱丑丑

发布日期: 2019-06-20 16:45:42 浏览量: 183
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

一、游戏背景介绍

1.1 背景知识

俄罗斯方块原本是前苏联科学家阿列克谢·帕基特诺夫所开发的教育用软件,之后开始提供授权给各个游戏公司,造成各平台上软件大量发行的现象。Game Boy 版的俄罗斯方块在日本卖出 424 万套,是 Game Boy 史上卖最好的游戏。海湾战争时,也是前线美军最常拿消磨时间的游戏之一。由于俄罗斯方块具有的数学性、动态性与知名度,也经常拿来作为游戏程序设计的练习题材。

俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由于上手简单、老少皆宜,从而 家喻户晓,风靡世界。俄罗斯方块原名是俄语Тетрис(英语是 Tetris),这个名字来 源于希腊语 tetra,意思是“四”,而游戏的作者最喜欢网球(tennis)。于是,他把两个词 tetra 和 tennis 合而为一,命名为 Tetris,这也就是俄罗斯方块名字的由来。自此俄罗斯方块游戏一直火热至今。在各种经典小游戏分区和分类,我们不难见其身影,经常被用来怀旧或是娱乐。

1.2 基本功能

部分游戏有单格方块,可以穿透固定的方块到达最下层空位。其他的改版中出现更多特别的造型。方块会从区域上方开始缓慢继续落下。玩家可以做的操作有:以 90 度为单位旋转方块,以格子为单位左右移动方块,让方块加速落下。本游戏中按 W 键可以旋转方块,控制方向。按 A 键可以左移,按 D 键可以右移,当左移或者右移到边界时,不能再移动整体的方块,按 q 键可以让方块加速下落,但不会直接下落,这种操作是为了让方块下落的更快,但不至于直接落下而失误导致游戏失误,按 S 键可以让方块直接落下,以此来节省玩家的时间。方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。每一行必须由所有行中所有列的当区域中某一列横向格子全部由方块填满,否则会一直累加直至方块行排满了所有的游戏界面,此游戏就会结束,并记录分数,如果某一行所有列都填满了方块,则该列会消失并成为玩家的得分。同时删除的列数越多,得分指数上升。当固定的方块堆到区域最上方而无法消除层数时,则游戏结束。

1.3 风靡全球的原因

俄罗斯方块风靡的原因在于,未完成的任务与潜在的解决方法并存——徐徐降临的每一 种方块都有各自的安插方式。俄罗斯方块是一个简单的可视世界,通过操纵五个按键(当然是向左、向右、左转、右转和降落)能够迅速地得出解决方案。对俄罗斯方块玩家的研究结果显示,人们普遍喜欢通过旋转方块来看它们是否匹配,而不是一边看着方便降落一边思考。当然这两种方法都可行,但在俄罗斯方块的世界里永远是动作领先——这是吸引人的关键。和生活中不太相同的是,俄罗斯方块将我们处理问题时的所见所想直接联系到了一起,我们能立即对问题采取行动。

1.4 作用

可以增强人们对图形的感性认识和对位置感的锻炼,日常生活压力大。用游戏来减轻压力。许多人无聊,来打发时间。在游戏世界中相当于另外一个你,在现实生活中做不到的在游戏看可以做到,得不到的在游戏中却可以得到,获得满足感和成就感。游戏的世界可以从侧面另外玩家的道德素质。思想素质,让你可以方面的接触各种各样的人。游戏玩家群体在社会中是各个行业,各个阶层的人。你可以在里面很方便的了解到其他东西。也可以学会许多东西。益智游戏可以锻炼你的脑力,敏捷游戏可以锻炼你的敏捷能力。策略游戏可以提高你的智力等。

进入界面后可以选择三种不同的游戏速度的游戏模式:

  • Fast 为最快速度,游戏难度最高,方块下落很快,很考验反应速度,同时游戏乐趣也最大

  • middle 为中等速度的模式

  • slow 为缓慢游戏模式,都比较适合新手练习和平时娱乐

选择任意一个速度的游戏模式后,游戏便进入了主界面,界面左边是游戏运行的游戏动画界面,右面有记分板和下一方块的提示,还有基本操作的提示,方便新手玩家操作。出现图形后,A 左移 D 右移 W 旋转 S 为直接下落,直至填满界面后会结束游戏。

最后如果方块累计触到上顶线,则游戏结束,退出主程序,如图 3。

二、核心算法思想

游戏区域由许多等面积的小方块构成,这些区域状态只有满或空两种。将空间以静态二维数组实现,并预先定义其状态值。满为 1,空为 0,以此来完成游戏地图区域的空间分配。

小方块的实现是由一个 4*2 的小数组表示,用四个存储单位空间存储当前下坠物的每一个子 块的位置来对整个下坠物件的位置进行标识,每个存储空间的大小就是一个点的坐标。每个 方块都有其对应的编号,编号按由上到下,由左到右的顺序编排。有了这些编号,方块的变 换实现起来就方便多了。再由一个宏去标识下坠物的位置。

游戏进程需要定时器的驱动,所以很有必要在程序当中加入一个定时器机制。方块随着时间的自动下落需要一个定时器来计算时间下落,若下落速度小于屏幕时间的刷新速度,则会出现屏幕的闪动等问题,因此我们只需定义一个时间类,设置好时间间隔即可。同时,也需要控制屏幕的刷新速度,而刷新速度必须比方块下落时间间隔快。而且计时器可以对游 戏运行时间进行如此对游戏的开始,暂停,结束控制便能够得到实现。

游戏开始后便开始掉落方块,并且会在游戏区域上方出现下一个下坠物的形态,因此有随机物件产生这个操作。此时用户可根据需要来变换方块,向左或向右移动来调整方块位置,然后通过按下使方块加速下落。这就涉及到了四个主要操作。当方块向左或向右移动时,需要判定方块是否达到了游戏区域的边界;当方块下落时需要判定方块是否到了游戏区域的底部,或是碰到了别的方块。开始后便可用键盘上的“上下左右”来对方块进行操作。方块移动之前,要对方块的横纵坐标计算,我们在核心算法中,用两次嵌套的循环来实现横纵坐标的计算,外层对横坐标进行判断和计算,内层对纵坐标进行判断和计算,首先用大循环去计算横坐标的增减,因为横坐标要考虑的问题较多,而纵坐标比较容易实现,纵坐标只需考虑图形是否撞到了底线或者其他方块,出现触碰底线和触碰其他方块的问题后,用中断保存改变后的值即可跳出循环。首先设置一个栈,数据先入栈,中断保存信息,x 轴和 y 轴的坐标分别进各自对应的寄存器,与之前中断值作比较,纵坐标自增,此处有一个循环,若 DX 寄存器值小于 b 的纵坐标,则继续调用中断 INT 10H;用循环来实现整个纵坐标增长或减少的计算,跳出循环后 CX 寄存器值加一,进入第二个循环,该循环包括上一个循环体,判断 CX 值是否小于纵坐标,若小于,将新的纵坐标数据放入 DX 寄存器中。方块的实现七种下物都有一个共同点,就是它们占据的空间一样,都是由四个等面积的小方块构成,因此用一个整型的数组来存储每个下坠物的四个小方块的坐标位置。每个下坠物中的方块都有编号,编号按从左到右,从上到下的顺序排列。从代码中可以看出程序首先获取了当前下坠物的四个小方块坐标,然后所有纵坐标递减一格,由函数计算出改变数据的区域。这样便可完成左移命令。右移和下移的道理也是一样。但是这里涉及到一个问题,就是要对移动是否到达游戏区域的边界做出判断。左、右移的限制原理是一样的,只是方向和坐标数据有点区别。根据各种不同形态的下坠物最左边的小方块的正左(右)方区域是否为非被占用状态来判断它是否可以移动。

界面绘制,定时器任务的发生,用户的输入(如开始,暂停,结束,级别设置,左移,右移,旋转,快速下移)的命令的响应需要用到多线程。在屏幕的绘制中,首先应该修改屏幕的颜色,其次要定义一个方块类,将生成的小方块放入其中。将前景色和背景色设置为同一种颜色,一个字符显示在屏幕上就是一个小方块。控制方块的下落速度是设计中必须实现 的功能,方块的下落速度也就是时间间隔,因此我们只需定义一个时间类,设置好时间间隔即可。同时,也需要控制屏幕的刷新速度,而刷新速度必须比方块下落时间间隔快。因此,如何在一个程序中体现两种不同的时间控制是此模块的一个难点我们需要对键盘中上、下、 左、右键的读取实现对方块的变形、下落、右移和右移的功能。

三、核心算法流程图

进入程序后先进行屏幕初始化,之后显示调用显示边框函数,再显示新方块。检测按键状态,之后再度检测键盘状态。为了保证整个程序结构性能良好,不会出现与其他函数体同时用一个寄存器而使得程序跑飞。其中分别四个主要操作按键 WASD 都对应不同的操作,W 旋转,A 左移 D 右移,S 下落,如果键盘输入的对应寄存器的值,则输出对应的操作的值,否则便进入下一个判断条件进行判断,否则操作失效。在进入程序后先将几个主要寄存器推入堆栈,当程序退出时,又将寄存器值从堆栈中送回。堆栈采用的是先进后出的算法,所以应当注意顺序。这样接口,便于向后兼容,使用起来方便。如下,图 4。

首先设置一个栈,数据先入栈,中断保存信息,x 轴和 y 轴的坐标分别进各自对应的寄存器,与之前中断值作比较,纵坐标自增,此处有一个循环,若 DX 寄存器值小于 b 的纵坐标,则继续调用中断 INT 10H;用循环来实现整个纵坐标增长或减少的计算,跳出循环后 CX 寄存器值加一,进入第二个循环,判断 CX 值是否小于纵坐标,若小于,将新的纵坐标数据放入 DX 寄存器中,再将坐标计算得得值传回寄存器,完成方块的消除和累积。如下,图 5。

四、开发中遇到的问题

如何能够让下落的方块在检测到下方有原先掉下来的方块或者已经到达游戏界面的底部从而停下来呢?

建立一个静态数据二维表与游戏界面映射。栅格部分初始化为1,之后不对该静态数据位置操作。栅格部分是不会显示在屏幕上,只是在静态数据表中存在,以此方便对方块的出界,叠加等的判断。

当一格中的方块堆满后如何实现消除?

解决此问题的方法是用消行算法,当有出现方块不可动作,即 NOTDONECAN 对应值的为 1 时,先将 QUANOW 对应的值当前位置在静态数据表中的映射数值置为1,之后判断静态数据表 中是否有一整行为1,是则将该行以上数据整体下移一行,之后刷新显示,即通过判断静态数据表中的各个位置是否为1,为1则刷新为洋红色否则刷为黑色;如若该行有0存在,则进行下一行的判断。

当一个或几个方块出界、叠加时候,如何判断这种情况?

先将 QUANOW 对应的传送给与寄存器,等长的一维数据表 QUATEMP。当再将 QUATEMP 进行 一次操作,比如向下操作:将 QUATEMP 对应的中的Y 轴坐标加1,X 轴坐标不变,再调用NOTDONE 函数分别找到 QUATEMP 中四个方块位置在静态数据表中的映射,判断该位置数据是否为1,如若有一个1则,将NOTDONECAN 标志位置为1,即不可动作,否则将其置为0。

DOWNGOON则 通过判断 NOTDONECAN 标志位来选择是否将 QUATEMP 的值传送给 QUANOW,如若NOTDONECAN为 0,即可以动作,则传送数据,同时刷新显示。否则不可动作,则将 QUANOW 当前位置在静态数 据表中的映射数据置为1,即跟新静态数据二维表。其他判断依此类推。

如何控制下落的时间?

一开始做游戏界面的时候,设置的默认下落时间间隔和屏幕刷新时间不合适,游戏界面消除和下落方块的时候,总是会出现闪屏的情况,对游戏影响不大,但是对玩家游戏体验影响很大,经过查阅资料和研究,我们发现屏幕的刷新速度必须快于方块的下落速度,否则会出现上述情况。控制方块的下落速度是设计中必须实现的功能,方块的下落速度也就是时间间隔,因此 我们只需定义一个时间类,设置好时间间隔即可。同时,也需要控制屏幕的刷新速度,而刷新速度必须比方块下落时间间隔快。因此,如何在一个程序中体现两种不同的时间 控制是此模块的一个难点。

如何控制按键不重复按下向下的按键时,下落速度会加快,即放置间隔的运行间隔会减小存在问题:无论是在放置间隔外部还是内部更改速度值,都只能在清除间隔之后,才能生效,无法满足需求解决方式:将放置间隔更改为放置时间,在放置时间里调用自身,形成递归,即可实现需求, 如何检测方块位置?

没有方块存在时,直接下落到界面底部。有方块阻挡时,停在方块上面。存在问题:如何记录已有方块的位置解决方式:获取每一个方块的 top 和left 位置,拼接成字符串,存入数组。每一次掉落时,都检测每一个方块的下一个位置是否已经存在在数组中,如果没有,就允许下落。否则停止下落,生成下一个方块。按键按下时,如何禁止重复触发?按键按下时,速度在当前值的基础上减少300,速度减少300存在问题:按键一直按住不放时,速度就会一直持续执行减法。解决方式:设置一个 flag,按键按下,flag 值就改变,当事件触发时,flag 才会变回原值。

如何让玩家适当操作?

根据相应的提示进行一些功能上的选择,如修改音乐,方块颜色和游戏难度。当游戏开始时,计算机将随机抽取方块的放到方格上。此游戏允许玩家旋转方块,左右移动,加速向下。程序要实现对满行的消除并记录得分以及对游戏的结束判断。

如何更便利玩家体验该游戏?

在 windows 环境下建立一个简单的用户界面,用户可以进行功能性的菜单选择,我们选择了fast,middle,solw 三种游戏速度模式,由难到易三种游戏模式选择。简单明了,不需要玩家输入多余命令,仅输入 1,2,3,4 即可控制界面的选择以及退出游戏。

游戏开始后,通过指定的功能键控制方块,方块可以左右移动、落下、旋转。AD 分别为左移和右移,W 为旋转当前的方块,S 为使方块快速落下,方便于玩家的技巧性游戏。此操作在游戏运行界面右方记分板的下方显示出,方便玩家的操作。

界面上要显示分数和游戏已经开始的时间和游戏的难度,并且预显示出下一个方块的形状,使玩家可以通过下一步的形势推断现在进行的操作,以此来增加游戏的难度和趣味性,让游戏有更多的技巧可言,游戏方式多元化,否则游戏便很枯燥单调,不会很好的吸引其他玩家。

能进行简单的参数设置:修改音乐,改变方块颜色和难度等。

对三个主要游戏数据的处理方块的下落,相应键盘:需要判断下键是否按下,并加快时钟周期。完成下落后,还原到原来的时钟周期形状的下落, 实现旋转:不同旋转角度显示不同方向的方块来完成的。 消去主游戏区底部填满的行:查看主游戏区底部的每行是否填满的方式是,在游戏区图 形框可以看成是由许多的小方块组成,方块运动的过程就是造型里方块显示或者隐藏,就像现在的霓虹灯效果一样,由时钟控件控制改变的速度,上一层的消失,下一层的显示,这样, 从视觉效果可以看到方块的下落运动效果方块在下落的过程中会自动判断每一行方块的属性,如果此行方块属性全部为是时,就会将这一行小方块的 visible 属性全部变成否, 同时消去此行,在将上面的小方块向下移动,利用循环语句进行判断,将所有这样情况的行改变小方块属性。当有多行同时出现这样情况时使用递归调用,实现连续消行。

六、心得体会

在这本次编写俄罗斯方块汇编游戏的中,在收获知识的同时,还收获了阅历,收获了成熟, 在此过程中,我们通过查找大量资料,请教老师和同学。使我再专业知识和动手实践方面都得了到很好的提升。在此次程序设计中,接触到了我们熟知的网络,在设计过程中总觉得好难实现,但在实现过程中,发现只要用心探索,一切皆有可能。通过课程设计,我对汇编语言有了更深一 步的了解,发现其用起来不是十分的方便,但确实是比较适合我们初学者学习的语言。这次课程设计我对游戏编程有了一定的了解,虽然自己只用了汇编,但在实际操作的过程中,也和同学们交流探讨了好多其他语言关于游戏设计的思想,集思广益,拓宽了自己的眼界。增强了自己的实际动手能力,增加了学习计算机语言的兴趣,另外在课程设计中也得到了一定的成就感。决定再今后的学习中,多看一些这类方面的书籍,来进一步的了解相关的游戏编程知识,为以后的应用做准备。

经过本次汇编语言的学习与实践,体验了之前没有尝试过的学习模式,这种自学加上老师辅导,并和同学一组独立做出课程作业的模式,让我丛中收获到许多。首先,经过在课本上学习、在图书馆中查阅资料和在互联网上查询,我学习了不少汇编语言的基础知识和一些小技巧与应 用,与此同时,因为汇编语言这门语言更接近于硬件,它直接面向机器,我也学习和了解到不少关于计算机硬件的一些知识。其次,我们在开发过程中,先设计框架和思路,然后一起查阅相关的资料,一边学习一边测试部分的小程序,检测代码功能和编译器环境问题,虽然有不少的小麻烦和一些棘手的问题,但是经过和同学一起调试交流,成功解决了这些问题。一开始认为开发程序很简单,但在制作的过程中,感受到做一个完整完善的小程序原来也是很不容易,有很多问题要面对和解决,通过本次项目我们学习到了一种临危不乱,顽强渐进的精神,为以后的学习和 工作积累了经验,打下了良好的基础。

上传的附件 cloud_download 俄罗斯方块.zip ( 767.89kb, 1次下载 )
error_outline 下载需要8点积分

发送私信

精品资源尽在此

57
文章数
0
评论数
最近文章
eject