当前位置:文档之家› 俄罗斯方块作业设计讲解

俄罗斯方块作业设计讲解

xxxx学院信息工程学院课程设计报告设计名称:Java俄罗斯方块游戏设计设计题目:Java俄罗斯方块游戏设计学生学号:专业班级:2013级软件工程1班学生姓名:学生成绩:课题工作时间:2016.3.22 至2016.4.22说明:1、报告中的任务书、进度表由指导教师在课程设计开始前填写并发给每个学生。

2、学生成绩由指导教师根据学生的设计情况给出各项分值及总评成绩。

3、所有学生必须参加课程设计的答辩环节,凡不参加答辩者,其成绩一律按不及格处理。

答辩由指导教师实施。

4、报告正文字数一般应不少于3000字,也可由指导教师根据本门综合设计的情况另行规定。

5、平时表现成绩低于6分的学生,取消答辩资格,其本项综合设计成绩按不及格处理。

成绩评定表学生姓名:xxx 学号: 1402133 专业:软件工程班级: 2013级1班俄罗斯方块游戏设计与实现任务书一、用户需求及约束条件1、功能需求:实现游戏界面,能够通过按键移动、旋转、摆放游戏自动输出的各种方块,使之排列成完整的一行或多行,并消除得分。

具体需求:①游戏界面为一个用于摆放正方形格子的平面虚拟场地,其标准大小为20行、15列,以格子为单位计算即宽为15个格子,高为20个格子(每个格子大小为14×14)。

②一组由4个小型正方形格子组成的规则图形,颜色可根据自己的喜好设③不断输出单个方块到游戏区域顶部。

④玩家操作有:旋转方块;以格子为单位左、右移动方块;让方块加速落下。

⑤方块移到游戏区域最下方或是落到其它方块上导致无法移动时,就会固定在该处,而心的方块会出现在区域上方并开始下落。

⑥当游戏区域中某一行横向格子全部由方块填满时,该行会消失并成为玩家的得分。

同时删除的行数越多,得分指数越高。

⑦当固定的方块堆到游戏区域最上方且无法消除层数时,游戏结束。

⑧游戏会提示下一个要落下的方块,以便熟练的玩家根据下一个方块图形决定如何放置当前方块。

2、性能需求:①应用程序提供友好的图形用户界面。

②应用程序要具备健壮性、稳定性和好的可移植性。

3、应用程序开发要求:选用技术:不限。

二、设计要求、技术参数及设计规格1、图形用户界面设计。

2、功能实现:根据特定需求对游戏进行改进或者模拟,如增加游戏级别选择。

3、设计规格:请根据规范编写。

四、考核形式、考核时间、考核指标及成绩评定课程结束后,上交作品(电子版)、报告(打印版、电子版),考核指标、成绩评定见成绩评定表。

目录第一章绪论1.1.任务概述1.1.1.软件功能1.1.2.运行环境1.2.需求分析1.2.1.游戏界面1.2.2.菜单操作1.2.3.游戏操作1.2.4.游戏判定1.3.设计目的第二章相关技术与开发工具2.1.相关技术2.1.1.Java语言2.2.开发工具第三章概要设计3.1.程序流程3.1.1.程序主流程3.1.2.游戏控制流程3.2.模块说明3.2.1.游戏模块3.2.2.辅助模块3.3.重要数据第四章详细设计4.1.界面设计4.2.常量变量4.2.1.常量.4.2.2.变量.4.3.重要函数4.3.1.游戏状态4.3.2.游戏控制第五章调试与测试5.1.调试分析5.1.1.问题与解决5.1.2.性能分析5.1.3.程序不足5.2.测试结果5.2.1.游戏截图第六章总结与展望6.1.总结6.2.展望参考文献第一章绪论1.1任务概述用java编写一个俄罗斯方块游戏,要求程序运行之后出现一个游戏操作界面,并实现以下功能:(1) 实现各种方块的生产,包括形状和颜色等信息;(2) 实现各个方块的向下、向左、向右移动和旋转的功能;(3) 实现消行;(4) 实现开始、暂停、继续、结束等功能。

1.1.1. 游戏简介俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。

俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。

由于上手简单、老少皆宜,从而家喻户晓,风靡世界。

俄罗斯方块曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事,它看似简单但却变化无穷,令人上瘾。

相信大多数用户都还记得为它痴迷得茶不思饭不想的那个俄罗斯方块时代。

俄罗斯方块上手极其简单,但是要熟练地掌握其中的操作与摆放技巧,难度却不低。

作为家喻户晓老少皆宜的大众游戏,其普及程度可以说是史上任何一款游戏都无法相比的。

但是,谁知道这么优秀的娱乐工具,出自哪位神人之手呢?顾名思义,俄罗斯方块自然是俄罗斯人发明的。

这位伟人叫做阿列克谢·帕基特诺夫。

俄罗斯方块原名是俄语Тетрис(英语是Tetris),这个名字来源于希腊语tetra,意思是“四”,而游戏的作者最喜欢网球(tennis)。

于是,他把两个词tetra和tennis合而为一,命名为Tetris,这也就是俄罗斯方块名字的由来啦。

1.1.2. 软件功能俄罗斯方块是游戏随机产生不同形状的7种规则图形,用户通过上下左右键控制方块的左移、右移、旋转和快速下降,当方块无间隙的堆满一层时消除堆满的这一层,当方块堆积高度等于游戏规定高度时,游戏失败。

1.1.3. 运行环境操作环境为:Windows 7以上,运行环境为:MyEclipse。

1.2. 需求分析1.2.1. 游戏界面游戏界面为一个用于摆放正方形格子的平面虚拟场地,其标准大小为20行、15列.如图1-1所示。

图1-11.2.2. 菜单操作菜单操作包括游戏的开始、停止、暂停、继续以及形状的移动(左、右控制键)、自动下落、加速下落(下键控制)、旋转(上控制键)、形状一落到底(空格键)、颜色设置、恢复默认设置。

1.2.3. 游戏操作游戏的按键处理:开始新游戏、暂停/继续、方块向左移动(左控制键)、方块向右移动(右控制键)、方块旋转(上控制键)、形状向下移动(下控制键)、形状一落到底(空格键)。

1.2.4. 游戏判定当游戏区域中某一行横向格子全部由方块填满时,该行会消失。

当固定的方块堆到游戏区域最上方且无法消除层数时,游戏结束。

1.3. 设计目的综合运用在校期间所学理论知识和技能,设计开发俄罗斯方块,使自己熟悉应用系统的开发过程,培养独立思考能力,检验学习效果和动手能力,提高工程实践能力,为将来实际工作打下坚实的基础。

第二章相关技术与开发工具2.1. 相关技术2.1.1.Java语言Java语言是当今流行的网络编程语言,它具有面向对象、跨平台、分布应用等特点。

Java广泛应用于PC,数据中心,游戏控制台,科学超级计算机,移动电话和互联网,同时拥有全球最大的开发者专业群体。

2.2. 开发工具MyEclipse,是基于Eclipse开发的功能强大的企业级集成开发环境,主要用于Java、Java EE以及移动应用的开发。

MyEclipse提供了对UML、Ajax、Web、Web Services、J2EE、JSP、XML、Struts、JSF、Java Persistence、EJB、扩展数据库以及各种应用服务器的集成支持。

MyEclipse也全面支持各种主流的第三方框架,让你能够快速高效地进行开发工作。

此外,MyEclipse还全面支持各种基于Eclipse平台的插件,允许你自由定制或扩展个性化功能。

第三章概要设计3.1. 程序流程俄罗斯方块游戏的程序主流程包括游戏的界面管理设置,游戏的图形管理设置,关于游戏的说明设置,游戏控制管理设置,游戏的配置管理设置,游戏的监听管理设置等几个方面。

如图3-1-1所示。

图3-1-13.1.1. 程序主流程程序主流程主要由玩家来操纵实现,如图3-1-2所示。

进入游戏点击开始游戏操作游戏退出游戏点击停止游戏结束图3-1-23.1.2. 游戏控制流程游戏的控制流程由游戏控制器、颜色控制器,游戏的控制流程控制游戏的操作和颜色的显示效果。

如图3-1-3所示。

图3-1-33.2. 模块说明3.2.1. 游戏模块游戏模块层功能模块用28种状态的数据结构生成7种图形:Z字形、反Z 字形、田字形、7字形、反7字形、T字形,各个方块能实现自己的变形。

游戏模块主要由游戏主界面(TetrisFrame)、游戏控制器(GameCoutroller)、游戏控制键(HotKeySetDialog)、游戏监听器(ConfigListener)以及配置类(Config)等组成游戏的正常运行。

如图3-2-1所示。

图3-2-13.2.2. 辅助模块辅助功能包括游戏界面、游戏的地形、形状工厂、游戏配置、监听器、控制器、关于游戏对话框、游戏显示设置对话框等:1. 游戏界面里面包含游戏主界面、网格背景、游戏预览界面。

2. 游戏的地形里面含有障碍物,它是由一个一个的点构成,点的x,y 坐标标明该障碍区位于地形的位置。

3. 形状工厂产生用28种状态的数据结构生成7种图形:Z字形、反Z 字形、田字形、7字形、反7字形、T字形。

4. 游戏配置包含当前用户配置和默认配置。

5. 监听器由游戏监听器、游戏显示监听器、游戏预览监听器以及只读监听器等部分组成。

6. 控制器由游戏控制器、颜色控制器组成。

3.3. 重要数据当方块的横坐标等于0,方块就不能移动,方块数组也就不能再移动,因此方块数组的第一列至少有一个值为1。

当方块数组的第一列全部为0时,也就是说,当方块数组有1的那一列碰到边界时,方块才不能移动,这时候,首次出现1的那一列横坐标肯定小于0了,假定我们以x记录方块数组的横坐标,以y记录方块不能移动时,方块数组中首次出现1的那一列,当方块不能移动时,x + y 的值必定是等于0的。

同理当方块到达右边界不能移动时。

我们可以从方块数组的右边开始检测,记录下首次出现1的那列的值,这时候,x + y 一定是等于15.第四章详细设计4.1. 界面设计import java.awt.Color;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.FocusAdapter;import java.awt.event.FocusEvent;import javax.swing.JColorChooser;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextArea;import javax.swing.border.EtchedBorder;import javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;import cn.itcast.tetris.controller.Controller;import cn.itcast.tetris.entities.Ground;import cn.itcast.tetris.entities.ShapeFactory;import cn.itcast.tetris.listener.GameListener;import cn.itcast.tetris.util.Global;import cn.itcast.tetris.view.GamePanel;/*** 主界面, 实现了GameListener 接口** @version 1.0, 01/01/08** @author 杨旭强**/public class MainFrame extends JFrame implements GameListener { /****/private static final long serialVersionUID = 1L;/**** @param args*/public static void main(String args[]) {try {Controller controller = new Controller(new ShapeFactory(),new Ground(), new GamePanel());MainFrame frame = new MainFrame(controller);/* 显示窗口*/frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}}private final Controller controller;private final GameOptionPanel gameOptionPanel;private final GamePanel gamePanel;private final Ground ground;private final ShapeFactory shapeFactory;public MainFrame(Controller c) {super();this.setTitle("俄罗斯方块");this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setLayout(null);this.setResizable(false);if(c.getGameInfoLabel() == null)c.setGameInfoLabel(new JLabel());this.controller = c;this.shapeFactory = c.getShapeFactory();this.ground = c.getGround();this.gamePanel = c.getGamePanel();this.gameOptionPanel = new GameOptionPanel();final JLabel infoLabel = c.getGameInfoLabel();/* 监听器*/MyGroundListener mgl = new MyGroundListener();ground.addGroundListener(mgl);/* 控制器*/// controller = new Controller(shapeFactory, ground, gamePanel,// infoLabel);gameOptionPanel.getNewGameButton().setEnabled(true);gameOptionPanel.getStopGameButton().setEnabled(false);this.addFocusListener(new FocusAdapter() {public void focusGained(FocusEvent arg0) {// controller.continueGame();}public void focusLost(FocusEvent arg0) {controller.pauseGame();if (gameOptionPanel.getPauseButton().isEnabled())gameOptionPanel.getPauseButton().setText("继续游戏");}});gamePanel.addFocusListener(new FocusAdapter() {public void focusGained(FocusEvent arg0) {// controller.continueGame();}public void focusLost(FocusEvent arg0) {controller.pauseGame();if (gameOptionPanel.getPauseButton().isEnabled())gameOptionPanel.getPauseButton().setText("继续游戏");}});gameOptionPanel.getNewGameButton().addActionListener(new ActionListener() {/*** 开始游戏的按钮*/public void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif (controller.isPlaying()) {return;}int lineNum = gameOptionPanel.getLineNum();int obstacleNum =gameOptionPanel.getObstacleNum();controller.newGame();/* 放到后面*/ground.generateSomeStochasticObstacle(obstacleNum,lineNum);}});gameOptionPanel.getStopGameButton().addActionListener(new ActionListener() {/*** 停止游戏的按钮*/public void actionPerformed(ActionEvent e) {controller.stopGame();}});gameOptionPanel.getPauseButton().setEnabled(false);gameOptionPanel.getPauseButton().addActionListener(new ActionListener() {/*** 暂停/继续游戏的按钮*/public void actionPerformed(ActionEvent e) {if (controller.isPausingGame()) {controller.continueGame();} else {controller.pauseGame();}if (controller.isPausingGame())gameOptionPanel.getPauseButton().setText("继续游戏");elsegameOptionPanel.getPauseButton().setText("暂停游戏");}});gameOptionPanel.getCheckBox_drawGridding().addChangeListener(new ChangeListener() {public void stateChanged(ChangeEvent arg0) { gameOptionPanel.getButton_griddingColor().setVisible(gameOptionPanel.getCheckBox_drawGridding().isSelected());MainFrame.this.refreshOption();}});gameOptionPanel.getCheckBox_colorfulShape().addChangeListener(new ChangeListener() {public void stateChanged(ChangeEvent arg0) { gameOptionPanel.getButton_shapeColor().setVisible(gameOptionPanel.getCheckBox_colorfulShape().isSelected());MainFrame.this.refreshOption();}});gameOptionPanel.getCheckBox_colorfulObstacle().addChangeListener(new ChangeListener() {public void stateChanged(ChangeEvent arg0) { gameOptionPanel.getButton_obstacleColor().setVisible(gameOptionPanel.getCheckBox_colorfulObstacle().isSelected());MainFrame.this.refreshOption();}});gameOptionPanel.getButton_shapeColor().addActionListener(new ActionListener() {public void actionPerformed(ActionEvent arg0) {Color shapeColor = JColorChooser.showDialog(MainFrame.this, "请选择图形的颜色",new Color(0xFF4500));if (shapeColor != null)shapeFactory.setDefaultShapeColor(shapeColor);}});gameOptionPanel.getButton_griddingColor().addActionListener(new ActionListener() {public void actionPerformed(ActionEvent arg0) {Color griddingColor =JColorChooser.showDialog(MainFrame.this, "请选择网格的颜色",Color.LIGHT_GRAY);if (griddingColor != null)ground.setGriddingColor(griddingColor);}});gameOptionPanel.getButton_obstacleColor().addActionListener(new ActionListener() {public void actionPerformed(ActionEvent arg0) {Color obstacleColor = JColorChooser.showDialog(MainFrame.this, "请选择障碍物的颜色", Color.DARK_GRAY);if (obstacleColor != null)ground.setObstacleColor(obstacleColor);}});gameOptionPanel.getButton_fullLineColor().addActionListener(new ActionListener() {public void actionPerformed(ActionEvent arg0) {Color fullLineColor = JColorChooser.showDialog(MainFrame.this, "请选择满行的效果的颜色", Color.DARK_GRAY);if (fullLineColor != null) {ground.setFullLineColor(fullLineColor);}}});gameOptionPanel.getButtonBackgroundColor().addActionListener(new ActionListener() {public void actionPerformed(ActionEvent arg0) {Color backgroundColor = JColorChooser.showDialog(MainFrame.this, "请选择背景的颜色" new Color(0xcfcfcf));if (backgroundColor != null)gamePanel.setBackgroundColor(backgroundColor);}});gameOptionPanel.getButton_default().addActionListener(new ActionListener() {/*** 恢复默认设置的按钮*/public void actionPerformed(ActionEvent e) {gamePanel.setBackgroundColor(GamePanel.DEFAULT_BACKGROUND_COLOR);gameOptionPanel.getCheckBox_drawGridding().setSelected(false);ground.setGriddingColor(Ground.DEFAULT_GRIDDING_COLOR);gameOptionPanel.getCheckBox_colorfulShape().setSelected(true);shapeFactory.setDefaultShapeColor(ShapeFactory.DEFAULT_SHAPE_COLOR);gameOptionPanel.getCheckBox_colorfulObstacle().setSelected(true);ground.setObstacleColor(Ground.DEFAULT_OBSTACLE_COLOR);gameOptionPanel.getTextField_obstacleNum().setText("30");gameOptionPanel.getTextField_lineNum().setText("0");gameOptionPanel.getTextField_stayTime().setText("300");ground.setFullLineColor(Ground.DEFAULT_FULL_LINE_COLOR);}});/*** subPanel*/JPanel subPanel = new JPanel();subPanel.setLayout(null);subPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED));subPanel.setSize(gamePanel.getSize().width + 3,infoLabel.getSize().height + gamePanel.getSize().height + 2);infoLabel.setBounds(5, 0, infoLabel.getSize().width - 5, infoLabel.getSize().height);gamePanel.setBounds(1, infoLabel.getSize().height,gamePanel.getSize().width, gamePanel.getSize().height);subPanel.add(infoLabel);subPanel.add(gamePanel);int left = 10, left2 = 5;gameOptionPanel.setBounds(left, 21,gameOptionPanel.getSize().width,gameOptionPanel.getSize().height);subPanel.setBounds(left + left2 + gameOptionPanel.getSize().width, 1,subPanel.getSize().width, subPanel.getSize().height);/*** 说明*/JPanel infoPanel = new JPanel();infoPanel.setBorder(newEtchedBorder(EtchedBorder.LOWERED));infoPanel.setLayout(null);infoPanel.setBounds(10, 25 + gameOptionPanel.getSize().height,gameOptionPanel.getSize().width,subPanel.getSize().height- gameOptionPanel.getSize().height - 25);final JLabel infoTitleLable = new JLabel();infoTitleLable.setFont(new Font("宋体", Font.PLAIN, 12));infoTitleLable.setText(Global.TITLE_LABEL_TEXT);infoTitleLable.setBounds(10, 5, infoPanel.getSize().width - 10, 20);final JTextArea InfoTextArea = new JTextArea();InfoTextArea.setFont(new Font("宋体", Font.PLAIN, 12));InfoTextArea.setText(_LABEL_TEXT);InfoTextArea.setFocusable(false);InfoTextArea.setBackground(this.getBackground());InfoTextArea.setBounds(10, 25, infoPanel.getSize().width - 20,infoPanel.getSize().height - 50);infoPanel.add(infoTitleLable);infoPanel.add(InfoTextArea);gameOptionPanel.getCheckBox_colorfulObstacle().setFocusable(false);gameOptionPanel.getCheckBox_colorfulShape().setFocusable(false);gameOptionPanel.getCheckBox_drawGridding().setFocusable(false);/* 设置主界面大小*/this.setSize(gameOptionPanel.getSize().width+ gamePanel.getSize().width + left + left2 + 15,gamePanel.getSize().height > gameOptionPanel.getSize().height + 20 ? gamePanel.getSize().height + 60: gameOptionPanel.getSize().height + 60);// this.pack();/* 让窗口居中*/this.setLocation(this.getToolkit().getScreenSize().width / 2- this.getWidth() / 2,this.getToolkit().getScreenSize().height/ 2 - this.getHeight() / 2);/*** 添加监听器*/gamePanel.addKeyListener(controller);gameOptionPanel.addKeyListener(controller);this.addKeyListener(controller);controller.addGameListener(this);subPanel.addKeyListener(controller);this.getContentPane().add(gameOptionPanel);this.getContentPane().add(infoPanel);this.getContentPane().add(subPanel);}public void gameOver() {// TODO Auto-generated method stubgameOptionPanel.getTextField_lineNum().setFocusable(true);gameOptionPanel.getTextField_stayTime().setFocusable(true);gameOptionPanel.getTextField_obstacleNum().setFocusable(true);gameOptionPanel.getPauseButton().setEnabled(false);gameOptionPanel.getStopGameButton().setEnabled(false);gameOptionPanel.getNewGameButton().setEnabled(true);gameOptionPanel.getPauseButton().setText("暂停/继续");}public void gameStart() {// TODO Auto-generated method stubgameOptionPanel.getTextField_lineNum().setFocusable(false);gameOptionPanel.getTextField_stayTime().setFocusable(false);gameOptionPanel.getTextField_obstacleNum().setFocusable(false);gameOptionPanel.getPauseButton().setEnabled(true);gameOptionPanel.getNewGameButton().setEnabled(false);gameOptionPanel.getStopGameButton().setEnabled(true);}public void gameContinue() {// TODO Auto-generated method stubgameOptionPanel.getPauseButton().setText("暂停游戏");}public void gamePause() {// TODO Auto-generated method stubgameOptionPanel.getPauseButton().setText("继续游戏");}private void refreshOption() {int stayTime = gameOptionPanel.getStayTime();ground.setDrawGridding(gameOptionPanel.isDrawGridding());shapeFactory.setColorfulShape(!gameOptionPanel.isColorfulShape());ground.setColorfulSupport(!gameOptionPanel.isColorfulObstacle());Global.STAY_TIME = stayTime;}}4.2. 常量变量4.2.1. 常量.private static Properties properties = new Properties();/*** 配置文件的路径(默认为当前目录下的 snake.ini文件)*/private static String CONFIG_FILE = "tetris.ini";/*** 一个格子的宽度, 单位:像素<BR>* 对应的配置文件中的关键字为: cell_width, 或用 cell_size 指定<BR>* 范围1 至 100<BR>* 缺省值为 23*/public static final int CELL_WIDTH;/*** 一个格子的高度, 单位:像素<BR>* 对应的配置文件中的关键字为: cell_width, 或用 cell_size 指定<BR>* 范围1 至 100<BR>* 缺省值为 23*/public static final int CELL_HEIGHT;/*** 用格子表示的宽度, (宽度为多少个格子) 单位:格<BR>* 对应的配置文件中的关键字为: width<BR>* 范围10 至 80<BR>* 缺省值为 15*/public static final int WIDTH;/*** 用格子表示的高度, (高度为多少个格子), 单位:格<BR>* 对应的配置文件中的关键字为: height<BR>* 范围10 至 60<BR>* 缺省值为20*/public static final int HEIGHT;/*** 图形下落的初始速度 (单位: 毫秒/格)<BR>* 对应的配置文件中的关键字为: speed<BR>* 范围10 至无限大<BR>* 缺省值为 200*/public static final int DEFAULT_SPEED;/*** 保存当前游戏中图形的下落速度*/public static int CURRENT_SPEED;/*** 图形快速下落的速度 (单位: 毫秒/格)<BR>* 对应的配置文件中的关键字为: swift_speed<BR> * 范围0 至无限大<BR>* 缺省值为 15*/public static final int SWIFT_SPEED;/*** 每次加速或减速的幅度 (单位: 毫秒/格)<BR>* 对应的配置文件的关键字为: speed_step<BR>* 范围1 至无限大<BR>* 缺省值为 25*/public static final int SPEED_STEP;/*** 消除满行前暂停效果的时间(单位: 毫秒)<BR>* 对应的配置文件的关键字为: stay_time<BR>* 范围0 至无限大<BR>* 缺省值为 200*/public static final int DEFAULT_STAY_TIME;/*** 消除满行前暂停效果的时间*/public static int STAY_TIME;private static Random random = new Random();public static final String TITLE_LABEL_TEXT;public static final String INFO_LABEL_TEXT;private static final Color[] DEFAULT_COLORS = new Color[] {new Color(0x990066), new Color(0x990099), new Color(0x330099),new Color(0x663300), new Color(0x009966), new Color(0x003333) };4.2.2. 变量./***旋转*/public static final int ROTATE = 5;/*** 上移*/public static final int UP = 1;/*** 下落*/public static final int DOWN = 2;* 左移*/public static final int LEFT = 3; /*** 右移*/public static final int RIGHT = 4;/*** 监听器组*/protected ShapeListener listener;/****/protected int[][] body;/*** 当前显示的状态*/protected int status;/*** 图形的真实高度*/protected int height;/*** 左上角的位置*/protected int left;/*** 左上角的位置*/protected int top;* 下落的速度*/protected int speed;/*** 生命*/protected boolean life;/*** 暂停状态*/protected boolean pause;protected boolean swift;protected int swiftSpeed = Global.SWIFT_SPEED;protected Thread shapeThread, swiftThread;/*** 颜色*/protected Color color = Color.BLUE;4.3. 重要函数4.3.1. 游戏状态/*** 开始游戏*/void gameStart();/*** 结束游戏*/void gameOver();/*** 暂停游戏*/void gamePause();/*** 继续游戏*/void gameContinue();4.3.2. 游戏控制@Overridepublic void keyPressed(KeyEvent e) {if (e.getKeyCode() != KeyEvent.VK_Y && !playing) return;switch (e.getKeyCode()) {/*** 方向左*/case KeyEvent.VK_LEFT:if (isPausingGame()) {this.continueGame();}shape.setSwift(false);if (isPlaying() && ground.isMoveable(shape, Shape.LEFT))shape.moveLeft();break;/*** 方向右*/case KeyEvent.VK_RIGHT:if (isPausingGame()) {this.continueGame();}shape.setSwift(false);if (isPlaying() && ground.isMoveable(shape, Shape.RIGHT))shape.moveRight();break;/*** 方向上*/case KeyEvent.VK_UP:if (isPlaying()) {if (!shape.isPause()) {if (ground.isMoveable(shape,Shape.ROTATE)) {shape.setSwift(false);shape.rotate();}} else {if (ground.isMoveable(shape, Shape.UP))shape.moveUp();else {shape.die();shape = shapeFactory.getShape(this);}}}break;/*** 方向下*/case KeyEvent.VK_DOWN:if (isPausingGame()) {this.continueGame();}if (isPlaying() && isShapeMoveDownable(shape)) shape.moveDown();break;/*** PAGE UP*/case KeyEvent.VK_PAGE_UP:shape.speedUp();break;/*** PAGE DOWN*/case KeyEvent.VK_PAGE_DOWN:shape.speedDown();break;/*** 反引号,换一个图形*/case KeyEvent.VK_BACK_QUOTE:if (isPlaying()) {shape.die();shape = shapeFactory.getShape(this);}break;case KeyEvent.VK_ENTER:if (isPausingGame())this.continueGame();elsethis.pauseGame();break;case KeyEvent.VK_Y:if (!isPlaying())newGame();break;case KeyEvent.VK_SPACE:if (isPlaying() && !isPausingGame())shape.setSwift(true);break;}/*** 重新显示*/gamePanel.redisplay(ground, shape);if (gameInfoLabel != null)gameInfoLabel.setText(this.getNewInfo());}/*** 询问一下图形是否可以下落,如果不能下落了,就会让图形变成障碍物<BR>* 这个方法是同步的*/public synchronized boolean isShapeMoveDownable(Shape s) {if (shape == null)return true;if (!playing || shape != s)return false;if (ground.isMoveable(shape, Shape.DOWN))return true;shape.die();ground.accept(shape);if (playing && !ground.isFull()) {shape = shapeFactory.getShape(this);}gamePanel.redisplay(ground, shape);if (gameInfoLabel != null)gameInfoLabel.setText(this.getNewInfo());return false;}/*** 处理图形触发的 shapeMovedDown (图形下落) 事件<BR>* 将会重新显示*/public void shapeMovedDown(Shape s) {// TODO Auto-generated method stubif (playing && ground != null && shape != null) gamePanel.redisplay(ground, shape);}/*** 开始一个新游戏*/public void newGame() {playing = true;ground.init();ground.addGroundListener(this);Global.CURRENT_SPEED = Global.DEFAULT_SPEED;shape = shapeFactory.getShape(this);if (playing)gamePanel.redisplay(ground, shape);if (gameInfoLabel != null)gameInfoLabel.setText(this.getNewInfo());for (GameListener l : listeners)l.gameStart();}/*** 停止当前游戏*/public void stopGame() {if (shape == null)return;playing = false;for (GameListener l : listeners)l.gameOver();}/*** 暂停游戏*/public void pauseGame() {if (shape == null)return;shape.setPause(true);for (GameListener l : listeners)l.gamePause();}/*** 继续游戏*/public void continueGame() {shape.setPause(false);for (GameListener l : listeners)l.gameContinue();}/*** 游戏是否是在暂停状态*/public boolean isPausingGame() {return shape.isPause();}/*** 获得游戏的最新提示信息** @return*/public String getNewInfo() {if (!playing || ground.isFull())return" ";// "提示: 按 Y 开始新游戏";elsereturn new StringBuffer().append("提示:").append(" 速度 ").append(shape.getSpeed()).append("毫秒/格").toString();}public ShapeFactory getShapeFactory() {return shapeFactory;}public void setShapeFactory(ShapeFactory shapeFactory) {this.shapeFactory = shapeFactory;}public Ground getGround() {return ground;}public void setGround(Ground ground) {this.ground = ground;}public GamePanel getGamePanel() {return gamePanel;}public void setGamePanel(GamePanel gamePanel) { this.gamePanel = gamePanel;}/*** 处理Ground 触发的 beforeDeleteFullLine 事件将会改变满行的颜色并暂停一段时间*/public void beforeDeleteFullLine(Ground ground, int lineNum) {// TODO Auto-generated method stubground.changeFullLineColor(lineNum);gamePanel.redisplay(ground, shape);try {Thread.sleep(Global.STAY_TIME);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** 处理Ground 触发的 fullLineDeleted 事件, 这个方法什么也没做, 只是打印了一句话*/public void fullLineDeleted(Ground ground, int deletedLineCount) {// TODO Auto-generated method stubSystem.out.println("消了 "+ deletedLineCount + " 行");}/*** 是否正在游戏中** @return*/public boolean isPlaying() {if (playing && !ground.isFull())return true;return false;}/*** 得到显示提示信息的组件** @return*/public JLabel getGameInfoLabel() {return gameInfoLabel;}/*** 设置** @param gameInfoLabel*/public void setGameInfoLabel(JLabel gameInfoLabel) { this.gameInfoLabel = gameInfoLabel;this.gameInfoLabel.setSize(Global.WIDTH *Global.CELL_WIDTH, 20);this.gameInfoLabel.setFont(new Font("宋体",Font.PLAIN, 12));gameInfoLabel.setText(this.getNewInfo());}/*** 处理Ground 的 groundIsFull() 事件, 将触发游戏结束事件 */public void groundIsFull(Ground ground) {// TODO Auto-generated method stubif (playing) {playing = false;for (GameListener l : listeners)l.gameOver();}}/*** 添加监听器, 可添加多个** @param l*/public void addGameListener(GameListener l) { if (l != null)this.listeners.add(l);/*** 移除监听器** @param l*/public void removeGameListener(GameListener l) { if (l != null)this.listeners.remove(l);}}第五章调试与测试5.1. 调试分析5.1.1. 问题与解决1.语法错误:编程过程中总是避免不了一些语法错误,例如上下变量名不统一、函数格式错误等。

相关主题