基于Java的俄罗斯方块游戏的设计与实现
2017-05-22高成珍
高成珍
摘要:俄罗斯方块是一款简单有趣的益智类小游戏,通过对游戏中包含的元素及其关系的分析,抽象出相应的类和接口,通过对游戏过程的分析,抽象出关键的流程,并通过Java语言编程实现。
关键词:俄罗斯方块;Java
0引言
俄罗斯方块是一款经久不衰的益智类小游戏,游戏规则简单、有趣,老少皆宜。对于Java初学者来说是一个不错的练习项目,难度适中,不仅可以检验知识的综合运用,提升开发技能,培养面向对象编程思维,同时还可以激发学习兴趣,增强自我效能感。
1俄罗斯方块游戏中核心元素
游戏中核心元素包括3个:各种形状的方块、底部障碍物以及游戏面板。游戏主要是控制方块在面板上的移动与变化以及障碍物的增加和消除。
1.1方块
经典的俄罗斯方块游戏中方块主要有7种类型,如图1所示,每一种类型又有若干种变形,如图2所示。
根据图2形状的分析可以得出,所有的方块都可以用一个4*4的格子表示,格子有两种状态:空白和填充。对于不同的形状,填充部分不同而已,所以可以用一个包含16个整型元素的一维数组来表示一种具体的形状。当需要填充时,对应的位置上的数字为1,否则位置上的数字为0。采用二维数组存储一种类型的方块,第一维表示的是第几种变体,第二维表示具体形状的数值。采用三维数组存储所有的方块,第一维表示哪一种类型,第二维表示该类型的第几种变体,第三维表示具体形状的数值。对于方块来说除了要知道它的形状以外,还需要知道它的位置,并且能够根据需要进行移动和变形,所以方块类(Shape)的设计如图3所示。
1.2障碍物
障碍物实际上就是不能移动的方块组合,障碍物会随着游戏执行过程而不断增加或减少。与方块类似可以采用一个二维数组来保存障碍物,数组的大小即为整个面板中横向和纵向上格子的个数,对于需要填充的格子数值标记为1,空白格子对应的数值为0。障碍物添加后需要判断是否超出边界,如果超出则游戏结束,同时需要判断是否有满行,有则需要删除等等,障碍物类(Ground)的关键属性和方法如图4所示。
1.3游戏面板
游戏面板主要用于显示方块以及障碍物,需要指定宽度和高度,为了使程序更为灵活,面板的宽度和高度不指定为具体的数值,而是以格子为单位,指定包含多少个格子,通过静态常量指定格子个数以及格子的边长。游戏面板类的关键属性和方法如图5所示。
2俄罗斯方块游戏关键流程
俄罗斯方块游戏的主要流程为:游戏开始后,随机生成方块,启动线程让方块定时下落,监听用户的按键操作控制方块的移动和变形,及时刷新方块位置,方块位置变化后需重新判断是否可以继续移动,如果不能移动则将其转换成障碍物。转换后需判断是否可以消除障碍物,以及是否游戏结束。具体流程如图6所示,程序运行效果如图7所示。
3關键功能分析与设计
3.1如何实现方块的移动
方块移动有两种类型:一种是定时自由下落;另一种是根据用户的按键操作进行变化,如左移、右移、下移或者旋转。对于第一种移动类型,通过单独启动一个线程来完成,线程每隔一定的时间,执行Shape的下移方法,下移后需通知面板及时刷新。因为Shape类和GamePanel面板类不在同一个文件,二者之间不能直接通信,可借助于中介一控制器Controller。为Shape对象添加一个监听变化的监听器ShapeListener,而Controller实现了该接口,在创建Controller对象时传递GamePanel对象,形状发生变化时,会调用Controller的相应方法,在该方法内可调用GamePanel的显示方法。对于第二种移动类型,主要是通过监听用户按键的操作,然后根据所按的键,执行相应的操作(←表示左移,↓表示右移,↓表示下移,↑表示旋转),最后同样调用GamePanel的显示方法,刷新界面。
3.2方块与障碍物的转换及消除障碍物
障碍物实际上就是不能移动的方块,当方块不能向下移动时,就需要将其转换成障碍物,只需获取方块的位置,然后将障碍物中该位置对应的值设置为1,然后重新绘制即可。转换成障碍物后,循环遍历每一行数据,如果一行中所有的数据都为1,则表明这一行为满格,需要消除,只需要将该行上面的所有数据集体向下移动即可。
4总结
本文从面向对象编程思想出发,分析俄罗斯方块游戏中主要的元素及其关系,抽象出相应的类和接口,整体采用MVC模式,通过控制器控制对象间的通信与数据传递,具有较好的扩展性和灵活性。对于提升初学者综合运用Java知识设计简单的系统具有一定的借鉴意义。