软件测试项目的里程碑和关键路径
在软件测试项H的计划书中,都会制订一个明确的日程进度表。虫¨何对项目进行阶段划分、如何控制进度、如何控制风险等等,有一系列方法,但最成熟的技术足里程碑管理和关键路径的控制。
1里程碑(Milestone)的定义和控制
里程碑一般是项目中完成阶段性工作的标志,即将一个过程性的任务用一个结论性的标志米描述任务结束的、明确的起止点。一系列的起止点就构成引导整个项目进展的里程碑
(milestone)。一个里程碑标志着卜一个阶段结束、下一个阶段开始,也就是定义当前阶段完成的标准(entry criteria)和下个新阶段启动的条件或前提(entry criteria)a里程碑还有下列特征: . 里程碑也足有层次的,在个父里程碑下一个层次中定义子里程碑。
·不同类型的项目,里程碑可能不同。
. 不同规模项目的里程碑,其数量多少不一样,里程碑可以台并或分解。
在软件测试周期中,建议定义六个父里程碑、十几个子里程碑。
M1:需求分析和设计的审查
M11:市场/产品需求审查
M12:产品规格说明书的审查
M13:产品和技术知识传递
M14:系统/程序设计的审查
M2:测试计划和设计
M21:测试计划的制定
M22:测试计划的审查
M23:钡0试用例的段汁
M24:测试用例的审查
M25测试工具的设计和选择
M26:测试脚本的开发
M3:代码(包括单元测试)完成
M4:测试执行
M41:集成测试完成
M42:功能测试完成
M43:系统测试完成
M44:验收测试完成
M45:安装测试完成
M5:代码冻结
M6:测试结束
M61:为产品发布进行最后一轮测试
M62:写测试和质量报告
对每个子里程碑,还可以定义更小的里程碑——孙里程碑,见表17’1。
在一个里程碑到来之前,要进行检查,了解状态以确定是否能在预期的时间达到里程脾exit c,itefia(阶段完成的标准),如果存在较大差距,就要采取措施·争取达到里程碑的标准,即使不能,也要尽量减少这种差距。而每到一个里程碑t必须严格检查实际完成的情况是否符合已定义的标准,应及时对前一阶段的测试工作进行小结;如果需要,可以对后续测试工作计划进行调整,如增加资源、延长F一个里程碑的时间,以实现下一个里程碑的目标。
在项目管理进度跟踪的过程中,给予里程碑事件足够的重视,往往可以起到事半功倍的效用.只要能保证里程碑事件的按时完成,整个项目的进度也就有了保障。根据里程碑就比较容易确定软件测试进度表。
17.7测试项目的质量和配置管理
随着软件开发的规模越来越大,软件的质量问题显得越来越突出。软件质量的控制不中单是一个软件测试问题,在软件开发的所有阶段都应该引入软件质量管理和配置管理。 1质量管理的基本原则
· 控制所有过程的质量。
· 过程控制的出发点是预防不合格。
· 质量管理的中心任务足建立并实施文件化的质量体系。
·持续的质虽改进。
· 有效的质量体系应满足顾客和组织内部双方的需要和利益。
· 定期评价质量体系。
· 搞好质量管理关键在于领导和全员质量意识/文化。
2软件评审
软件评审并不是在软件开发完毕后进行评审,而是在软件开发的各个阶段都要进行评审.评审也可以看做是软件测试的一部分_L=作。因为在软件开发的各个阶段都可能产生错误,如果这些错误不及时发现并纠正,会不断地扩大,最后可能导致开发的失败。
(1)评审日标是更早地发现任何形式表现的软件功能、逻辑或实现方面的错误,审验证软件的需求,保证软件按预先定义的标准表示。
(2)评审过程,要经过准备(拟定主体和讨论项目)、反馈收集、会议并达成一致的 结论、结论执行跟踪等各个阶段。
(3)评审准则主要有下列内容:
· 评审产品,_『Ij不是评审设计者,不能使设计者有任何压力。
· 会场要有良好的气氛。
· 建立议事日程并维持它,会议不能脱离主题。
· 限制争论与反驳,评审会不是为了解决问题,而是为了发现问题。
·指明问题范围,而不是解决提到的问题。
· 展示记录(最好有黑板,将问题随时写在黑板上)。
· 限制会议人数和坚持会前准备工作。
· 对每个被评审的产品要尽力评审清单(帮助评审人员思考)
· 对每个正式技术评审分配资源和时间进度表。
· 对全部评审人员进行必要的培训。
·及早地对自己的评审做评审(对评审准则的评审)。
3配置管理
软件配置管理简称scM(soRwarecon矗gur眦ionM柚89ement的缩写),是在团队开发中.标识、控制和管理软件变更的一种管理,所以配置管理对软件测试和质量保证影响比较大.其影响程度取决于项目规模和复杂性、人员素质、流程、管理水平等。
软件配置管理分为版本管理、问题跟踪和建立管理三个部分,其中版本管理是基础。版本管理应完成以下主要任务:
·建立项目。
· 重构任何修订版的某一项或某一文件。
· 利用加锁技术防止覆盖。
· 当增加一个修订版时要求输入变更描述。
· 提供比较任意两个修订版的使用工具。
· 采用增量存储方式。
· 提供对修订版历史和锁定状态的报告功能。
· 提供归并功能。
· 允许在任何时候重构任何版本。
·权限的设置。
· 晋升模型的建立。
·提供各种报告。
第二篇:软件测试项目方案设计
俄罗斯方块Java语言设计
项目方案设计报告
2009 ~ 2010 学年 第 1 学期
教 学 单 位 计算机工程系
课 程 名 称 Java语言课程设计
课程设计题目 俄罗斯斯方块Java语言设计 指 导 教 师 熊伟平老师
学生姓名和学号: 关健驹(20094054034)
何伟添(20094054037)
邹杰霖(20094054032)
专 业 名 称 计算机应用技术
俄罗斯方块Java语言设计与实现
一、 项目需求分析:
主要是缓解学习压力过大的一个小游戏,非常益智,对小朋友的左脑开发具有很大的帮助。
二、 实验环境和要求:
系统:Microsoft Windows XP Professional
计算机:Intel(R) Core(TM) Duo COU
E4600 @ 2.40GHz 2.39GHz ,1.00GB的内存物理地址扩展 软件:JCreator Pro和JDK1.6
要求:
1) 面向对象程序设计的思想及编程方法的认识和掌握。
2) 熟悉java的编程环境J2SDK,掌握Application 和Applet的程序结构,并能熟练编写和调试两类程序。
3) 理解和掌握各种修饰符的用法。
4) 引入包,应用定时器,可变长数组,随机类,。
5) 熟练使用各种常用类库。
6) 理解JDK的事件处理机制,掌握java.awt 、javax.swing,javax.swing.event中的GUI标准组件的用法,学会合理运用布局策略、综合运用各种界面元素,编程构造满足应用需要的图形工作界面。
三、 程序设计和分析:
1、设计:
俄罗斯游戏的显示模块和控制模块由关健驹负责,框架结构由何伟添负责,代码输入、程序修改、测试和论文由邹杰霖负责完成。
2、分析:
主界面:
各个按钮的功能画面:
已进入游戏界面:
游戏程序代码:
/*
*按钮及键盘控制响应
*/
import java.awt.*;
import java.awt.event.*; import javax.swing.*;
import javax.swing.border.*;
public class ControlPanel extends JPanel
{
private TipBlockPanel tipBlockPanel;
private JPanel tipPanel,InfoPanel,buttonPanel;
private final JTextField levelField,scoreField;
private JButton playButton,pauseButton,stopButton,
turnHarderButton,turnEasilyButton;
private EtchedBorder border=new
EtchedBorder(EtchedBorder.RAISED,Color.WHITE, new Color(148, 145, 140)) ;
private RussiaBlocksGame game;
private Timer timer;
public ControlPanel(final RussiaBlocksGame game)
{
this.game = game;
/*
*图形界面部分
*/
setLayout(new GridLayout(3,1,0,4));
tipBlockPanel = new TipBlockPanel();
tipPanel = new JPanel( new BorderLayout() );
tipPanel.add( new JLabel("下一个方块:") , BorderLayout.NORTH ); tipPanel.add( tipBlockPanel , BorderLayout.CENTER );
tipPanel.setBorder(border);
InfoPanel = new JPanel( new GridLayout(4,1,0,0) );
levelField = new JTextField(""+RussiaBlocksGame.DEFAULT_LEVEL); levelField.setEditable(false);
scoreField = new JTextField("0");
scoreField.setEditable(false);
InfoPanel.add(new JLabel("难度:"));
InfoPanel.add(levelField);
InfoPanel.add(new JLabel("分数:"));
InfoPanel.add(scoreField);
InfoPanel.setBorder(border);
buttonPanel = new JPanel(new GridLayout(5,1,0,0)); playButton = new JButton("开始");
pauseButton = new JButton("暂停");
stopButton = new JButton("停止");
turnHarderButton = new JButton("更难");
turnEasilyButton = new JButton("更易");
buttonPanel.add(playButton);
buttonPanel.add(pauseButton);
buttonPanel.add(stopButton);
buttonPanel.add(turnHarderButton);
buttonPanel.add(turnEasilyButton);
buttonPanel.setBorder(border);
addKeyListener(new ControlKeyListener());//添加
add(tipPanel);
add(InfoPanel);
add(buttonPanel);
/*
*添加事件监听器
*/
playButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
game.playGame();
requestFocus();//让ControlPanel重新获得焦点以响应键盘事件 }
});
pauseButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if(pauseButton.getText().equals("暂停"))
game.pauseGame();
else
game.resumeGame();
requestFocus();//让ControlPanel重新获得焦点以响应键盘事件 }
}
);
stopButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
game.stopGame();
requestFocus();//让ControlPanel重新获得焦点以响应键盘事件 }
});
turnHarderButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
int level = 0;
try{
level = Integer.parseInt(levelField.getText()); setLevel(level + 1);
}catch(NumberFormatException e)
{
e.printStackTrace();
}
requestFocus();//让ControlPanel重新获得焦点以响应键盘事件
}
});
turnEasilyButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
int level = 0;
try{
level = Integer.parseInt(levelField.getText()); setLevel(level - 1);
}catch(NumberFormatException e)
{
e.printStackTrace();
}
requestFocus();//让ControlPanel重新获得焦点以响应键盘事件 }
});
/*
* 时间驱动程序,每格500毫秒对level,score值进行更新 */
timer = new Timer(500,
new ActionListener()
{
public void actionPerformed(ActionEvent event) {
scoreField.setText(""+game.getScore());
game.levelUpdate();
}
}
);
timer.start();
}
/*
* 设置预显方块的样式
*/
public void setBlockStyle(int style)
{
tipBlockPanel.setStyle(style);
tipBlockPanel.repaint();
}
/*
* 重置,将所有数据恢复到最初值
*/
public void reset()
{
levelField.setText(""+RussiaBlocksGame.DEFAULT_LEVEL); scoreField.setText("0");
setPlayButtonEnabled(true);
setPauseButtonLabel(true);
tipBlockPanel.setStyle(0);
}
/*
*设置playButton是否可用
*/
public void setPlayButtonEnabled(boolean enable)
{
playButton.setEnabled(enable);
}
/*
*设置pauseButton的文本
*/
public void setPauseButtonLabel(boolean pause)
{
pauseButton.setText( pause ? "暂停" : "继续" );
}
/*
*设置方块的大小,改变窗体大小时调用可自动调整方块到合适的尺寸 */
public void fanning()
{
tipBlockPanel.fanning();
}
/*
*根据level文本域的值返回当前的级别
*/
public int getLevel()
{
int level = 0;
try
{
level=Integer.parseInt(levelField.getText()); }catch(NumberFormatException e)
{
e.printStackTrace();
}
return level;
}
/*
* 设置level文本域的值
*/
public void setLevel(int level)
{
if(level > 0 && level <= RussiaBlocksGame.MAX_LEVEL) levelField.setText("" + level);
}
/*
* 内部类 为预显方块的显示区域
*/
private class TipBlockPanel extends JPanel
{
private Color bgColor = Color.darkGray,
blockColor = Color.lightGray; private RussiaBox [][]boxes = new
RussiaBox[RussiaBlock.ROWS][RussiaBlock.COLS];
private int boxWidth, boxHeight,style; private boolean isTiled = false;
/*
* 构造函数
*/
public TipBlockPanel()
{
for(int i = 0; i < boxes.length; i ++)
for(int j = 0; j < boxes[i].length; j ++) {
boxes[i][j]=new RussiaBox(false); }
style = 0x0000;
}
/*
* 构造函数
*/
public TipBlockPanel(Color bgColor, Color blockColor) {
this();
this.bgColor = bgColor;
this.blockColor = blockColor;
}
/*
* 设置方块的风格
*/
public void setStyle(int style)
{
this.style = style;
repaint();
}
/*
* 绘制预显方块
*/
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int key = 0x8000;
if(!isTiled)
fanning();
for(int i = 0; i < boxes.length; i ++)
for(int j = 0; j<boxes[i].length ;j ++)
{
Color color = (style & key) != 0 ? blockColor : bgColor; g.setColor(color);
g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight, true);
key >>=1;
}
}
/*
*设置方块的大小,改变窗体大小时调用可自动调整方块到合适的尺寸 */
public void fanning()
{
boxWidth = getSize().width / RussiaBlock.COLS;
boxHeight = getSize().height /RussiaBlock.ROWS;
isTiled=true;
}
}
/*
*内部类 键盘键听器,响应键盘事件
*/
class ControlKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent ke)
{
if (!game.isPlaying()) return;
RussiaBlock block = game.getCurBlock(); switch (ke.getKeyCode()) {
case KeyEvent.VK_DOWN:
block.moveDown();
break;
case KeyEvent.VK_LEFT:
block.moveLeft();
break;
case KeyEvent.VK_RIGHT:
block.moveRight();
break;
case KeyEvent.VK_UP:
block.turnNext();
break;
case KeyEvent.VK_SPACE://一键到底 while(block.moveDown())
{
}
break;
default:
break;
}
}
}
}
/*
*虚拟的单个方格类,控制方格的颜色
*/
public class RussiaBox implements Cloneable {
private boolean isColor;
public RussiaBox(boolean isColor) {
this.isColor = isColor;
}
/*
*设置颜色
*/
public void setColor(boolean isColor) {
this.isColor=isColor;
}
/*
*返回颜色
*/
public boolean isColorBox()
{
return isColor;
}
/*
* @see java.lang.Object#clone() */
public Object clone()
{
Object o = null;
try
{
o=super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
/*
* 主游戏类
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RussiaBlocksGame extends JFrame
{
public final static int PER_LINE_SCORE = 100;//消去一行得分
public final static int PER_LEVEL_SCORE = PER_LINE_SCORE*20;//升一级需要的分数
public final static int DEFAULT_LEVEL = 5;//默认级别
public final static int MAX_LEVEL = 10;//最高级别
private int score=0,curLevelScore = 0;//总分和本级得分
private GameCanvas canvas;
private ControlPanel controlPanel;
private RussiaBlock block;
private int style = 0;
boolean playing = false;
private JMenuBar bar;
private JMenu gameMenu,controlMenu,windowStyleMenu,informationMenu; private JMenuItem newGameItem,setBlockColorItem,setBgColorItem, turnHardItem,turnEasyItem,exitItem;
private JMenuItem playItem,pauseItem,resumeItem,stopItem; private JRadioButtonMenuItem
windowsRadioItem,motifRadioItem,metalRadioItem;
private JMenuItem authorItem,helpItem;
private ButtonGroup buttonGroup;
/*
* 构造函数
*/
public RussiaBlocksGame(String title)
{
super(title);
setSize(300,400);
Dimension scrSize=Toolkit.getDefaultToolkit().getScreenSize();
setLocation((scrSize.width-getSize().width)/2,(scrSize.height-getSize
().height)/2);
createMenu();
Container container=getContentPane();
container.setLayout(new BorderLayout());
canvas = GameCanvas.getCanvasInstance();
controlPanel = new ControlPanel(this);
container.add(canvas,BorderLayout.CENTER);
container.add(controlPanel,BorderLayout.EAST);
addWindowListener(
new WindowAdapter()
{
public void windowClosing(WindowEvent event) {
stopGame();
System.exit(0);
}
}
);
addComponentListener(
new ComponentAdapter()
{
public void componentResized(ComponentEvent event) {
canvas.fanning();
}
}
);
canvas.fanning();
setVisible(true);
}
/*
* 判断游戏是否正在进行
*/
public boolean isPlaying()
{
return playing;
}
/*
* 开始游戏并设置按钮和菜单项的可用性 */
public void playGame()
{
play();
controlPanel.setPlayButtonEnabled(false); playItem.setEnabled(false);
}
/*
* 暂停游戏
*/
public void pauseGame()
{
if(block != null) block.pauseMove(); controlPanel.setPauseButtonLabel(false); pauseItem.setEnabled(false);
resumeItem.setEnabled(true);
}
/*
* 从暂停中恢复游戏
*/
public void resumeGame()
{
if(block != null) block.resumeMove(); controlPanel.setPauseButtonLabel(true); pauseItem.setEnabled(true);
resumeItem.setEnabled(false);
}
/*
* 停止游戏
*/
public void stopGame()
{
if(block != null) block.stopMove(); playing = false;
controlPanel.setPlayButtonEnabled(true); controlPanel.setPauseButtonLabel(true); playItem.setEnabled(true); }
/*
* 得到当前级别
*/
public int getLevel()
{
return controlPanel.getLevel(); }
/*
* 设置当前级别,并更新控制面板的显示 */
public void setLevel(int level) {
if(level>0&&level<11)
controlPanel.setLevel(level); }
/*
* 得到当前总分数
*/
public int getScore()
{
if(canvas != null)
return score;
return 0;
}
/*
* 得到本级得分
*/
public int getCurLevelScore() {
if(canvas != null)
return curLevelScore; return 0;
}
/*
* 更新等级
*/
public void levelUpdate() {
int curLevel = getLevel();
if(curLevel < MAX_LEVEL && curLevelScore >= PER_LEVEL_SCORE) {
setLevel(curLevel + 1);
curLevelScore -= PER_LEVEL_SCORE;
}
}
/*
* 获得当前得方块
*/
public RussiaBlock getCurBlock() {
return block;
}
/*
* 开始游戏
*/
private void play()
{
playing=true;
Thread thread = new Thread(new Game()); thread.start();
reset();
}
/*
* 重置
*/
private void reset()
{
controlPanel.reset();
canvas.reset();
score = 0;
curLevelScore = 0; }
/*
* 宣告游戏结束
*/
private void reportGameOver()
{
JOptionPane.showMessageDialog(this,"Game over!"); }
/*
* 创建菜单
*/
private void createMenu()
{
gameMenu = new JMenu("游戏");
newGameItem = new JMenuItem("新游戏");
setBlockColorItem = new JMenuItem("设置方块颜色..."); setBgColorItem = new JMenuItem("设置背景颜色..."); turnHardItem = new JMenuItem("提高难度");
turnEasyItem = new JMenuItem("降低难度");
exitItem = new JMenuItem("退出");
gameMenu.add(newGameItem);
gameMenu.add(setBlockColorItem);
gameMenu.add(setBgColorItem);
gameMenu.add(turnHardItem);
gameMenu.add(turnEasyItem);
gameMenu.add(exitItem);
controlMenu = new JMenu("游戏控制"); playItem = new JMenuItem("开始"); pauseItem = new JMenuItem("暂停"); resumeItem = new JMenuItem("继续"); stopItem = new JMenuItem("停止"); controlMenu.add(playItem);
controlMenu.add(pauseItem);
controlMenu.add(resumeItem);
controlMenu.add(stopItem);
windowStyleMenu = new JMenu("窗口风格"); buttonGroup = new ButtonGroup();
windowsRadioItem = new JRadioButtonMenuItem("Windows");
motifRadioItem = new JRadioButtonMenuItem("Motif");
metalRadioItem = new JRadioButtonMenuItem("Mentel",true); windowStyleMenu.add(windowsRadioItem);
buttonGroup.add(windowsRadioItem);
windowStyleMenu.add(motifRadioItem);
buttonGroup.add(motifRadioItem);
windowStyleMenu.add(metalRadioItem);
buttonGroup.add(metalRadioItem);
/*informationMenu = new JMenu("信息");
authorItem = new JMenuItem("Author:Fuliang");
helpItem = new JMenuItem("Help");
informationMenu.add(authorItem);
informationMenu.add(helpItem);
*/
bar = new JMenuBar();
bar.add(gameMenu);
bar.add(controlMenu);
bar.add(windowStyleMenu);
//bar.add(informationMenu);
addActionListenerToMenu();
setJMenuBar(bar);
}
/*
* 添加菜单响应
*/
private void addActionListenerToMenu()
{
newGameItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { stopGame();
reset();
setLevel(DEFAULT_LEVEL);
}
});
setBlockColorItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) {
Color newBlockColor =
JColorChooser.showDialog(RussiaBlocksGame.this,
"Set color for block", canvas.getBlockColor()); if (newBlockColor != null)
canvas.setBlockColor(newBlockColor);
}
});
setBgColorItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
Color newBgColor =
JColorChooser.showDialog(RussiaBlocksGame.this,"Set color for block",
canvas.getBgColor());
if (newBgColor != null)
canvas.setBgColor(newBgColor);
}
});
turnHardItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { int curLevel = getLevel();
if (curLevel < MAX_LEVEL) setLevel(curLevel + 1); }
});
turnEasyItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { int curLevel = getLevel();
if (curLevel > 1) setLevel(curLevel - 1);
}
});
exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { System.exit(0);
}
});
playItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { playGame();
}
});
pauseItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { pauseGame();
}
});
resumeItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
resumeGame();
}
});
stopItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) {
stopGame();
}
});
windowsRadioItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) {
String plaf =
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; setWindowStyle(plaf);
canvas.fanning();
controlPanel.fanning();
}
});
motifRadioItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String plaf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel"; setWindowStyle(plaf);
canvas.fanning();
controlPanel.fanning();;
}
});
metalRadioItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) {
String plaf = "javax.swing.plaf.metal.MetalLookAndFeel"; setWindowStyle(plaf);
canvas.fanning();
controlPanel.fanning();
}
});
}
/*
* 设定窗口风格
*/
private void setWindowStyle(String plaf) {
try {
UIManager.setLookAndFeel(plaf);
SwingUtilities.updateComponentTreeUI(this); } catch (Exception e) {
e.printStackTrace();
}
}
private class Game implements Runnable
{
/*
* (non-Javadoc)
* @see java.lang.Runnable#run()
* 游戏线程的run函数
*/
public void run()
{
int col=(int)(Math.random()*(canvas.getCols()-3));
style=RussiaBlock.STYLES[(int)(Math.random()*RussiaBlock.BLOCK_KIND_NUMBER)][(int)(Math.random()*RussiaBlock.BLOCK_STATUS_NUMBER)];
while (playing) {
if (block != null) { //第一次循环时,block为空
if (block.isAlive()) {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
continue;
}
}
checkFullLine();
if (isGameOver()) { //检查游戏是否应该结束了 playItem.setEnabled(true);
pauseItem.setEnabled(true);
resumeItem.setEnabled(false);
controlPanel.setPlayButtonEnabled(true); controlPanel.setPauseButtonLabel(true);
reportGameOver();
return;
}
block = new RussiaBlock(-1, col, getLevel(),style);
block.start();
col=(int)(Math.random()*(canvas.getCols()-3));
style=RussiaBlock.STYLES[(int)(Math.random()*RussiaBlock.BLOCK_KIND_NUMBER)][(int)(Math.random()*RussiaBlock.BLOCK_STATUS_NUMBER)]; controlPanel.setBlockStyle(style);
}
}
/*
* 判断是否能消去整行
*/
public void checkFullLine()
{
for (int i = 0; i < canvas.getRows(); i++) {
int row = -1;
boolean fullLineColorBox = true;
for (int j = 0; j < canvas.getCols(); j++) {
if (!canvas.getBox(i, j).isColorBox()) { fullLineColorBox = false;
break;
}
}
if (fullLineColorBox) {
curLevelScore += PER_LINE_SCORE; score += PER_LINE_SCORE;
row = i--;
canvas.removeLine(row);
}
}
}
/*
* 判断游戏是否结束
*/
private boolean isGameOver() {
for (int i = 0; i < canvas.getCols(); i++) {
RussiaBox box = canvas.getBox(0, i); if (box.isColorBox()) return true; }
return false;
}
}
public static void main(String[] args) {
new RussiaBlocksGame("Russia Blocks Game"); }
}
/*
*方块状态控制
*/
public class RussiaBlock extends Thread
{
private int style,y,x,level;
private boolean moving,pausing;
private RussiaBox boxes[][];
private GameCanvas canvas;
public final static int ROWS = 4;
public final static int COLS = 4;
public final static int BLOCK_KIND_NUMBER = 7; public final static int BLOCK_STATUS_NUMBER = 4; public final static int BETWEEN_LEVELS_TIME = 50; public final static int LEVEL_FLATNESS_GENE = 3;
/*
*方块的所有风格及其不同的状态
*/
public final static int[][] STYLES = {// 共28种状态 {0x0f00, 0x4444, 0x0f00, 0x4444}, // 长条型的四种状态
{0x04e0, 0x0464, 0x00e4, 0x04c4}, // 'T'型的四种状态 {0x4620, 0x6c00, 0x4620, 0x6c00}, // 反'Z'型的四种状态 {0x2640, 0xc600, 0x2640, 0xc600}, // 'Z'型的四种状态 {0x6220, 0x1700, 0x2230, 0x0740}, // '7'型的四种状态 {0x6440, 0x0e20, 0x44c0, 0x8e00}, // 反'7'型的四种状态 {0x0660, 0x0660, 0x0660, 0x0660}, // 方块的四种状态 };
/*
*构造函数
*/
public RussiaBlock(int y,int x,int level,int style) {
this.y = y;
this.x = x;
this.level = level;
moving = true;
pausing = false;
this.style = style;
canvas = GameCanvas.getCanvasInstance();
boxes = new RussiaBox[ROWS][COLS];
int key = 0x8000;
for(int i = 0; i < boxes.length; i++)
for(int j = 0; j < boxes[i].length; j++) {
boolean isColor = ( (style & key) != 0 ); boxes[i][j] = new RussiaBox(isColor); key >>= 1;
}
display();
}
/*
*线程的 run方法控制放块的下落及下落速度 */
public void run()
{
while(moving)
{
try
{
sleep( BETWEEN_LEVELS_TIME * (RussiaBlocksGame.MAX_LEVEL - level + LEVEL_FLATNESS_GENE) );
if(!pausing)
moving = ( moveTo(y + 1,x) && moving );
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
/*
*暂停移动
*/
public void pauseMove() {
pausing = true; }
/*
*从暂停状态恢复 */
public void resumeMove() {
pausing = false; }
/*
*停止移动
*/
public void stopMove() {
moving = false; }
/*
*向左移一格
*/
public void moveLeft() {
moveTo(y , x - 1); }
/*
*向右移一格
*/
public void moveRight() {
moveTo(y , x + 1); }
/*
*向下移一格,返回与其他几个不同,为了一键到底
*/
public boolean moveDown()
{
if(moveTo(y + 1, x))
return true;
else
return false;
}
/*
*移到newRow,newCol位置
*/
public synchronized boolean moveTo(int newRow, int newCol) {
//erase();//必须在判断前进行擦除,否则isMoveable将产生错误行为
if(!moving || !isMoveable(newRow,newCol))
{
display();
return false;
}
y = newRow;
x = newCol;
display();
canvas.repaint();
return true;
}
/*
*判断能否移到newRow,newCol位置
*/
private boolean isMoveable(int newRow, int newCol) {
erase();
for(int i = 0; i < boxes.length; i ++) for(int j = 0; j< boxes[i].length; j ++ ) {
if( boxes[i][j].isColorBox() )
{
RussiaBox box = canvas.getBox(newRow + i, newCol + j); if(box == null || box.isColorBox())
return false;
}
}
return true;
}
/*
*通过旋转变为下一种状态
*/
public void turnNext()
{
int newStyle = 0;
for(int i = 0; i < STYLES.length; i ++)
for(int j = 0 ;j < STYLES[i].length; j++)
{
if(style == STYLES[i][j])
{
newStyle = STYLES[i][(j + 1)%BLOCK_STATUS_NUMBER]; break;
}
}
turnTo(newStyle);
}
/*
*通过旋转变能否变为newStyle状态
*/
private synchronized boolean turnTo(int newStyle)
{
//erase();//擦除之后在判断isTurnNextAble
if(!moving || !isTurnable(newStyle))
{
display();
return false;
}
style=newStyle;
int key = 0x8000;
for(int i = 0; i < boxes.length; i ++) for(int j = 0 ;j < boxes[i].length; j++) {
boolean isColor = ((key & style) != 0 ); boxes[i][j].setColor(isColor); key >>=1;
}
display();
canvas.repaint();
return true;
}
/*
*判断通过旋转能否变为下一种状态
*/
private boolean isTurnable(int newStyle)
{
erase();
int key = 0x8000;
for(int i = 0; i< boxes.length; i++)
for(int j=0; j<boxes[i].length; j++)
{
if((key & newStyle) != 0)
{
RussiaBox box = canvas.getBox(y + i, x + j); if(box == null || box.isColorBox()) return false;
}
key >>= 1;
}
return true;
}
/*
*擦除当前方块(只是设置isColor属性,颜色并没有清除,为了判断能否移动之用)
*/
private void erase()
{
for(int i = 0; i < boxes.length; i ++)
for(int j = 0; j< boxes[i].length; j ++ )
{
if( boxes[i][j].isColorBox() )
{
RussiaBox box = canvas.getBox( y + i, x + j); if(box != null)
box.setColor(false);
}
}
}
/*
*显示当前方块(其实只是设置Color属性,在调用repaint方法时才真正显示)
*/
private void display()
{
for(int i = 0; i < boxes.length; i ++)
for(int j = 0;j< boxes[i].length ; j ++) {
if(boxes[i][j].isColorBox())
{
RussiaBox box = canvas.getBox( y + i, x + j); if(box != null)
box.setColor( true );
}
}
}
}
/*
* 游戏中方块显示的画布类
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class GameCanvas extends JPanel
{
private RussiaBox [][]boxes;
private int rows = 20 , cols = 12;
private static GameCanvas canvas=null;
private int boxWidth, boxHeight;//默认为零需要调用fanning函数设置 private Color blockColor = Color.RED, bgColor = new Color(0,204,204); private EtchedBorder border=new
EtchedBorder(EtchedBorder.RAISED,Color.WHITE, new Color(148, 145, 140)) ;
/*
*采用单件模式,构造函数私有
*/
private GameCanvas()
{
boxes = new RussiaBox[rows][cols];
for(int i = 0; i < boxes.length; i ++)
for(int j = 0; j<boxes[i].length; j ++) boxes[i][j] = new RussiaBox(false);
setBorder(border);
}
/*
*获得GameCanvas实例
*/
public static GameCanvas getCanvasInstance() {
if(canvas == null)
canvas = new GameCanvas();
return canvas;
}
/*
*设置画布的背景色
*/
public void setBgColor(Color bgColor) {
this.bgColor = bgColor; }
/*
* 获得画布的背景色
*/
public Color getBgColor()
{
return bgColor;
}
/*
*设置方块的颜色
*/
public void setBlockColor(Color blockColor) {
this.blockColor = blockColor; }
/*
*方块的颜色
*/
public Color getBlockColor()
{
return blockColor;
}
/*
*设置画布中方块的行数
*/
public void setRows(int rows)
{
this.rows = rows; }
/*
*得到画布中方块的行数 */
public int getRows() {
return rows;
}
/*
*设置画布中方块的列数 */
public void setCols(int cols) {
this.cols = cols; }
/*
*得到画布中方块的列数
*/
public int getCols()
{
return cols;
}
/*
*得到row行,col列的方格
*/
public RussiaBox getBox(int row, int col)
{
if(row >= 0 && row < rows && col >= 0 && col < cols) return boxes[row][col];
else
return null;
}
/*
*在画布中绘制方块
*/
public void paintComponent(Graphics g)
{
super.paintComponent(g);
fanning();
for(int i = 0; i < boxes.length; i ++)
for(int j = 0; j < boxes[i].length; j ++)
{
Color color = boxes[i][j].isColorBox() ? blockColor : bgColor; g.setColor(color);
g.fill3DRect(j * boxWidth, i * boxHeight , boxWidth , boxHeight , true);
}
}
/*
*清除第row行
*/
public void removeLine(int row)
{
for(int i = row; i > 0; i --)
for(int j = 0; j < cols; j ++)
{
boxes[i][j] = (RussiaBox)boxes[i-1][j].clone(); }
}
/*
*重置 为初始时的状态
*/
public void reset()
{
for(int i = 0; i < boxes.length; i++)
for(int j = 0 ;j < boxes[i].length; j++)
{
boxes[i][j].setColor(false);
}
repaint();
}
/*
* 根据窗体的大小自动调整方格的大小
*/
public void fanning()
{
boxWidth = getSize().width / cols; boxHeight = getSize().height / rows; }
}
四、 实验总结和感想:
1、基本框架和游戏功能都能实现,界面效果都比较好
2、比较欠缺的是还不能插入音乐,缺少了不小享受的感觉。
3、实验完成后,觉得平常最重要的是要多实践,纸上谈兵是没用的。不过,还是学到了很多知识并得到了一定的编程经验。
4、实验过程中发现,团队合作是非常重要的,有些问题一个人解决不了,经过团队分析、讨论,解决的方案越多越简单。