该项目gitee地址:https://gitee.com/lsy_loren/loren-tetris.git
一、游戏概述
本游戏是一款经典的俄罗斯方块游戏,使用Java语言开发,具有图形用户界面(GUI)。玩家通过操作方块的移动、旋转和下落,使其填满一行或多行来消除得分,并随着得分的增加提升等级。游戏还具备暂停、阴影显示、本地记录保存等功能。
二、游戏架构
(一)总体架构
游戏采用了MVC(Model-View-Controller)架构模式,将游戏的数据、界面显示和用户交互逻辑分离。
- Model(模型层):由
GameData
类及其相关的数据实体类(如Block
和BlockShape
)组成,负责存储游戏的状态信息,包括游戏地图、当前方块、下一个方块、得分、等级、游戏时间等。 - View(视图层):主要由
GameFrame
、GamePanel
以及各种Box
类(如BoxExplain
、BoxGrade
等)构成,负责游戏的图形界面显示,包括游戏窗口的创建、游戏区域的绘制、各种信息框(如操作说明、等级显示、分数统计等)的呈现。 - Controller(控制层):
GameService
类作为控制器,负责处理用户的输入操作(键盘事件),并根据操作更新游戏模型的状态,同时协调视图层的更新。
(二)模块详细介绍
1. 模型层
GameData
类- 包含游戏地图(
gameMap
),是一个二维数组,用于存储方块在游戏区域中的位置和状态。 - 记录当前方块(
current
)和下一个方块(next
)的形状和位置信息。 - 维护游戏的各种状态,如游戏是否结束(
gameOver
)、是否显示阴影(enableShadow
)、是否暂停(gamePause
)等。 - 管理游戏的得分(
gameScore
)、消行数量(gameRemoveCount
)、等级(gameGrade
)以及游戏时间(gameTimeHour
、gameTimeMinute
、gameTimeSecond
)。 - 提供方法用于获取和设置上述各种属性,并实现了本地记录的读取和保存功能。
- 包含游戏地图(
Block
类- 表示游戏中的单个方块,具有位置信息(
x
和y
坐标)、大小(size
)、颜色(color
)以及是否冻结(frozen
)的属性。 - 提供方法用于获取和设置方块的属性,以及创建冻结方块的静态方法。
- 表示游戏中的单个方块,具有位置信息(
BlockShape
类- 定义方块的形状,由多个
Block
组成一个形状。 - 包含各种预定义的方块形状(如左7形状、右7形状、左Z形状等)的静态方法,以及随机生成方块形状的方法。
- 提供方法用于移动(
blockShapeMove
)和旋转(blockShapeRotate
)方块形状,以及拷贝方块形状(copyBlockShape
)的功能。
- 定义方块的形状,由多个
2. 视图层
GameFrame
类- 继承自
JFrame
,是游戏的主窗口。 - 设置窗口的标题、大小、可调整性等属性,并将
GamePanel
设置为内容面板,最后显示窗口。
- 继承自
GamePanel
类- 继承自
JPanel
,是游戏的主要绘制区域。 - 初始化游戏按钮(
btnGameStart
),设置其属性和位置,并添加点击事件监听器,用于开始游戏。 - 初始化游戏数据(
initGameData
)和加载游戏边框(loadGameBoxList
),包括各种信息框的创建和添加到列表中。 - 重写
paintComponent
方法,用于绘制游戏界面,遍历gameBoxList
并调用每个Box
的paint
方法进行绘制。
- 继承自
Box
类及其子类(如BoxExplain
、BoxGrade
等)Box
类是一个抽象类,定义了基本的属性(如位置和大小)和方法(如paint
方法)。- 各个子类继承自
Box
类,并重写gameAction
方法,用于在特定的区域绘制不同的游戏信息。例如:BoxExplain
类用于绘制操作说明,包括旋转、移动、速落、阴影、暂停等操作的按键提示。BoxGrade
类用于绘制当前游戏等级。BoxBlock
类用于绘制游戏地图中的方块,包括冻结方块和非冻结方块的不同绘制方式,以及在启用阴影时绘制当前方块的阴影。BoxCount
类用于绘制游戏的分数、消行数量、游戏时间以及下一级所需分数的进度条。
3. 控制层
GameService
类- 继承自
KeyAdapter
,用于处理键盘事件。 - 在构造函数中初始化游戏面板(
gamePanel
)、游戏结束帧(gameOverFrame
)和游戏数据(gameData
),并启动游戏相关的线程(方块下落线程和游戏时间线程)。 - 重写
keyPressed
方法,根据用户按下的不同按键执行相应的操作,如旋转方块、移动方块、速落、暂停、显示阴影等,并在操作后调用gamePanel.repaint
方法更新界面。 - 提供一系列私有方法用于处理方块的业务逻辑,包括方块的旋转、移动、冻结、消行等操作,以及游戏的统计功能(如更新得分、等级等)和消行闪烁效果的实现。
- 提供
saveDiskRecord
方法用于保存本地记录,更新游戏按钮状态并重新绘制游戏面板。
- 继承自
三、游戏流程
(一)游戏启动
- 程序启动后,
GameFrame
被创建并显示,其中包含GamePanel
。 GamePanel
初始化游戏按钮和游戏数据,并加载游戏边框信息框。- 玩家点击“开始游戏”按钮,触发按钮的点击事件监听器。
(二)游戏进行
- 在按钮点击事件中,重新初始化游戏数据,设置游戏未结束,禁用开始按钮,并添加
GameService
作为键盘事件监听器,然后调用repaint
方法更新界面。 GameService
中的方块下落线程和游戏时间线程开始运行。- 方块下落线程:根据游戏是否暂停和当前等级计算方块下落的时间间隔,不断调用
doBlockShapeDown
方法使方块下落,并更新界面。 - 游戏时间线程:每秒更新一次游戏时间,并更新界面。
- 方块下落线程:根据游戏是否暂停和当前等级计算方块下落的时间间隔,不断调用
- 玩家通过键盘操作方块,
GameService
的keyPressed
方法根据按键执行相应的方块操作,如旋转、移动等,并更新游戏数据和界面。
(三)游戏结束
- 当方块无法再下落时,如果方块到达了游戏区域的顶部,游戏结束。
GameService
设置游戏结束状态,移除键盘事件监听器,并显示GameOverFrame
。GameOverFrame
提示玩家输入姓名,玩家输入后点击“确定”按钮,GameService
调用saveDiskRecord
方法保存本地记录,更新游戏按钮状态并重新绘制游戏面板。
四、游戏规则
- 方块从游戏区域顶部开始下落,玩家可以通过键盘操作旋转、左右移动和加速下落方块。
- 当方块填满一行或多行时,这些行将被消除,玩家获得相应的分数,并且上方的方块会自动下落填充空缺。
- 随着得分的增加,玩家的等级会提升,方块下落的速度也会加快。
- 玩家可以通过按下特定按键暂停游戏、显示当前方块的阴影。
五、数据存储
- 游戏使用
Serializable
接口实现本地记录的保存和读取。 - 本地记录文件(
data/record.dat
)存储了玩家的得分和姓名信息,最多保存5条记录。 - 在
GameData
类中,通过getDiskRecordList
方法读取记录文件,通过saveDiskRecordList
方法保存记录。
六、界面设计
- 游戏主窗口包含游戏区域和各种信息框,整体布局简洁明了。
- 游戏区域绘制方块和阴影,信息框分别显示操作说明、等级、分数、消行数量、游戏时间以及下一级所需分数的进度条等信息。
- 游戏结束帧提示玩家输入姓名,并显示得分信息。