《Java程序设计》实训报告 - 俄罗斯方块

更新时间:2024-01-24 19:32:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《Java程序设计》实训报告

——《俄罗斯方块》

一、实训任务及要求: 1.1、实训任务

1.运用Java实现小游戏的开发 2.了解Java开发项目的流程

3.掌握规划,设计,开发,测试的能力

1.2、实训要求

熟悉java的编程环境J2SDK,掌握Application 和Applet的程序结构,并能熟练编写和调试两类程序。熟练使用各种常用类库。理解JDK的事件处理机制,掌握java.awt 、javax.swing,javax.swing.event中的GUI标准组件的用法,学会合理运用布局策略、综合运用各种界面元素,编程构造满足应用需要的图形工作界面。

二、需求分析:

1.课程设计的目的和意义

俄罗斯方块游戏是一个经典的小游戏,由于它简单有趣,因而得到了广泛的流行,男女老幼都适合。而俄罗斯方块游戏的设计工作复杂且富有挑战性,它包含的内容多,涉及的知识广泛,与图形界面联系较大,包括界面的显示与更新、数据收集等,在设计的过程中,必将运用到各方面的知识,这对于visualbasi语言设计者而言,是个很好的锻炼机会。

2.系统功能设计

1. 本系统主要设计以下几种功能 2. 1、游戏难度选择功能

3. 游戏难度选择界面设置在程序运行开始时,一共有九种难度供玩家选择,每

选一级难度,都会相应地显示出代表该难度的图片。开始时不设置任何默认的难度,如果玩家不选难度直接按“Enter”进入,将会弹出提示框,提示其先选难度再进入。 4. 2、方块下落、变形功能

5. 在整个俄罗斯方块游戏中,方块的设计是核心。这里设计了一个方块类:

Square( ),用来生成方块以及实现块的左移、右移、向下、变形、重画、同步显示、初始化新块等。 6. 3、自动升级功能

7. 当分数累积到一定大小时,系统将自动为玩家提高难度。这里设置了每消除

10行方块,就增加一级难度。当难度增加的时候,方块会相应地改变颜色,以作为对玩家的提示。 8. 4、游戏音乐功能

9. 游戏开始音乐就自动播放,游戏暂停与结束时音乐相应消除。 10. 5、获取帮助功能

11. 这里设置了一个类,用来显示帮助,按F1键就能弹出窗口,显示游戏规则。

3.系统功能设计分析

1. 俄罗斯方块游戏根据功能的不同,设置了如下12个类:Square, Command,

GameArea, GameSetting, GameOver, Help, ImagePanel, JieMian, MyPanel, MyTimer, PlayMidi, WinListener,每个类的描述如下: 2.1、Square,方块类。这个类中定义了生成方块的方法,用二维数组int[][] pattern,存放7种方块的四种状态。在构造方法中以随机的形式生成方块,同时提供了以下几种方法:reset( ),leftTurn( ),leftMove( ),rightMove( ),fallDown( ),assertValid(int t,int s,int row,int col),dispBlock(int s)。分别实现方块的重画、翻转、左移、右移、下落、同步显示等功能。

2.2、Command,处理控制类。这是一个实现ActionListener接口的类,主要处理点击按钮事件。类中定义了三个int型变量:button_play,button_quit,button_pause,和一个boolean型的变量:pause_resume,并赋值。在GameArea类中通过事件响应,在按钮执行方法中调用其值,使用switch语句,根据不同按钮不同的值,来响应不同的事件。

2.3、GameArea,游戏界面类。GameArea继承了JFrame,是俄罗斯方块的主要游戏界面。这个类定义了GameSetting类的gameScr对象和ImagePanel类的imagepanel对象作为游戏区域面板和控制区域面板。在游戏区域,主要是根据相应格子的设置标志来显示相应的图形图片,这样就实现了俄罗斯方块的实时显示。

2.4、GameSetting, 游戏画布类。这个类生成的对象将作为游戏界面的方块下落区域,画布的设置为15行10列,当中的方格边长为30,类中还定义了一个二维数组int [][] scrArr作为屏幕数组,表示每一个方格。游戏区域中每一个方格是否存在游戏方块是由该方格的值来决定的,如果该方格的值为1,则表示该方格中存在游戏方块;如果该方格中的值为0,则表示该方格中不存在游戏方块,因此二维数组用于记录游戏区域中每个小方格的值。此外,类中还定义了画方块的方法,根据不同的难度画出不同颜色的方块。单击Play按钮时,系统调用initScr( )方法,初始化屏幕,将屏幕数组清零。当满足满行删除的条件时,系统调用deleteFullLine( )方法,进行删行加分,而且每删除十行,难度自动增加一级,方块颜色改变,并在难度显示框中相应显示。

2.5、GameOver,游戏结束弹出提示框类。当游戏结束时,系统弹出提示,包括玩家分数以及询问玩家要继续游戏还是退出。

2.6、Help,帮助类。在游戏界面,按F1键,弹出提示窗口,获取帮助。 2.7、ImagePanel,背景图片类。这个类继承了JPanel类,用来作为游戏界面中控制区域的容器,并添加图片。

2.8、JieMian,主界面类。这个类继承了JPanel类,作为游戏的第一个界面,也是难度选择界面。定义了9个单选按钮,当玩家未选任何难度就按Enter时,系统会弹出一个提示框,提示玩家先选难度再进入。 2.9、MyPanel,重写MyPanel类,使Panel的四周留空间。

2.10、MyTimer,定时线程类。类中定义了一个run()方法,用sleep()函数实现方块下落的快慢,即调节难度。

2.11、PlayMidi,添加音乐类。在游戏过程中添加背景音乐。 2.12、WinListener,关闭窗口类。

4.主要类的UML类图表示

1. Square 2. int[][] pattern 3. int SquareType 4. int SquareState 5. int blockState 6. int row,col 7. GameSetting scr 8. + void reset() 9. + void leftTurn() 10. + void leftMove() 11. + void rightMove() 12. + boolean fallDown() 13. boolean assertValid(int t,int s,int row,int col) 14. + synchronized void dispBlock(int s) 5.(Square类的UML类图表示)

15. GameSetting 16. int unitSize 17. int rowNum 18. int columnNum 19. int maxAllowRowNum 20. int SquareInitRo 21. int SquareInitCol 22. int [][] scrArr 23. Square b 24. initScr() 25. + void paint(Graphics g) 26. + void drawUnit(int row,int col,int type) 27. + Square getBlock() 28. + int getScrArrXY(int row,int col) 29. + int getInitRow() 30. + int getInitCol() 31. void deleteFullLine() 32. boolean isGameEnd() 33. + void keyPressed(KeyEvent e)

三、详细设计: 1模型层设计 1) 图形的产生

通过图形工厂类ShapeFactory的getShape(ShapeListener listener)方法随机产生方块的某种状态,这里运用了工厂设计模式,这种设计模式是为了实现高内聚低耦合而存在的,这种设计模式的通俗解释就是:你想要一个产品,你需要让工厂给你生产一个,你要告诉工厂你要生产什么产品,就把你需要生产的这个产品当做参数传给工厂类的生产产品的方法,然后根据你传进来的产品,而决定工厂人生产什么产品,产生出来产品后,最后要返回您要的这个东西。

随机产生一个数 随机数 1 2 3 反Z形 4 5 6 7 一字形 Z字形 7字形 反7形 倒T形 田字型

2) 图形数据结购

定义一个4x4方阵,共16个小格。用“0”和“1”来表示每个方格是绘制还是空白,由此可以组合出多种图形,如图所示:

其中图一表示为{0,0,0,0, 1,1,1,1 , 0,0,0,0, 0,0,0,0} 其中图二表示为{0,0,0,0, 0,1,1,0 , 0,1,1,0, 0,0,0,0} 其中图三表示为{0,0,0,0, 0,1,0,0 , 0,1,1,1, 0,0,0,0} 其中图四表示为{0,0,0,0, 0,1,0,1 , 0,1,1,0, 0,0,1,0}

方块的旋转是通过绘制4个方向的方块,在不同旋转角度显示不同方向的方块来完成的。所以程序要控制方块的旋转方向,只要控制显示哪副图就可以了。

本游戏是用一个三维数组int[][][] shapes = new int[][][];作为存储方块的数据结构来保存方块的28种状态的。代码如下:

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();

以下这段代码是3个子模块的代码,通过实例化按钮,标签,文本域,图形面板等,用add方法进行添加等,具体解释在代码中有体现

public ControlPanel(final RussiaBlocksGame game) {

this.game = game; /*

* 图形界面部分 */

setLayout(new GridLayout(3, 1, 0, 4));// 设置控制面板布局方

式为网格状布局

tipBlockPanel = new TipBlockPanel();// 新建一个图形界面面板

中的子面板

方式

tipPanel.add(new

JLabel(\

Block:\

tipPanel = new JPanel(new BorderLayout());// 设置为位置布局

BorderLayout.NORTH);// 添加新的标签在子面板中,设置布局在北部

tipPanel.add(tipBlockPanel, BorderLayout.CENTER);// 添加

tipblockpanel面板在子面板中

tipPanel.setBorder(border); // 显示统计面板模块

InfoPanel = new JPanel(new GridLayout(4, 1, 0, 0));// 新建

一个显示面板

// 设置4行1

列的网格状布局

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(3, 1, 0, 0));// 新

建一个按钮面板

// 设置布

局方式为网格状布局

1列

playButton = new JButton(\开始\添加开始按钮 pauseButton = new JButton(\暂停\添加暂停按钮 stopButton = new JButton(\停止\添加停止按钮

turnHarderButton = new JButton(\难一级\添加难一级按钮

// 为3行

按钮功能未实现

turnEasilyButton = new JButton(\简单一级\添加简单一级

按钮 按钮功能未实现

// 按钮面板添加功能按钮

buttonPanel.add(playButton);// 按钮面板添加开始按钮 buttonPanel.add(pauseButton);// 按钮面板添加暂停按钮

未实现

buttonPanel.add(stopButton);// 按钮面板添加 停止按钮 // buttonPanel.add(turnHarderButton); 添加难一级按钮 该功能

// buttonPanel.add(turnEasilyButton); 添加简单一级按钮 该功

能未实现

add(tipPanel); add(InfoPanel); add(buttonPanel);

buttonPanel.setBorder(border);

addKeyListener(new ControlKeyListener());// 添加键盘监听事

四、运行调试与分析讨论: 4.1游戏演示

4.1游戏界面演示,如7

图7

4.2开始和结束控制菜单,如图8

图8

4.3游戏窗口控制菜单,如图9

图9

4.2系统测试

4.2.1快捷键测试

1.键盘按“Ctrl+N” 效果:游戏开始 结果:正常 2. 键盘按“Ctrl+E” 效果:游戏退出 结果:正常

4.2.2右侧快捷按钮测试

1.点击“开始” 按钮 效果:游戏开始 结果:正常

2.点击“暂停” 按钮 效果:游戏暂停 结果:正常

3.点击“停止” 按钮 效果:游戏重置 结果正常

4.2.3界面菜单选项的功能测试 1.“游戏”菜单的测试 点击“游戏” ? “新游戏” 效果:游戏正常开始 结果:正常

2.点击“游戏”?“Exit” 效果:游戏退出

结果:正常

3. “窗口样式”菜单测试

1.点击“窗口样式”?“Windows” 效果:切换为Wingdows模式 结果:正常

2.点击“窗口样式”?“Motif” 效果:切换为Motif样式 结果:正常

3. 点击“窗口样式”?“Mentel” 效果:切换为Mentel模式 结果:正常

4.2.4 按键事件的功能测试 (1) 方块移动测试

游戏过程中,点击“左、右、下”方向键

输出:方块正常移动,不会移出边界 结果:正常 (2) 方块反转测试

游戏过程中,点击向上方向键

输出:方块无边界和障碍物阻挡的情况下可反转 结果:正常

4.2.5方块堆砌与消行测试

(1) 当方块下落到最底面或与障碍物接触时 输出:方块成功堆砌在底部 结果:正常 (2) 当出现满行现象时

输出:所有满行被消除,方块依次下移 结果:正常

4.2.6 测试结果分析

经过测试,本游戏实现了基本的功能,不过整体功能还不是很强大,作为开发的第一个版本,游戏在很多方面还需要进一步完善。

五、设计体会与小结:

课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程. 回顾起课程设计,至今我仍感慨颇多,的确,在这一星期的日子里,可以说得是苦多于甜,但是可以学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。通过课程设计之后,把以前所学过的知识重新温故。

这次课程设计终于顺利完成了,在设计中遇到了很多编程问题,最后在老师的指导下,终于迎刃而解。在此我表示感谢!同时,对给过我帮助的所有同学和各位指导老师再次表示忠心的感谢

六、附录:

1、小组成员及分工情况

系 (部): 信息工程系 专业班级: 软件(1)班 学生姓名: 陈学烽 学 号: 1011302101012 完成日期: 2011年12月28日

2、源代码

ControlPanel.java /*

*虚拟的单个方格类,控制方格的颜色 */

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; } public Object clone() { Object o = null; try { o = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; } }

GameCanvas.java

//游戏中方块显示的画布类

import java.awt.*;

import java.awt.event.*; import javax.swing.*;

import javax.swing.border.*;

class GameCanvas extends JPanel { private RussiaBox[][] boxes;//定义小方块 private int rows = 20, cols = 12;//定义20行 12列 private static GameCanvas canvas = null; private int boxWidth, boxHeight;// 默认为零需要调用fanning函数设置 private Color blockColor = Color.RED, bgColor = Color.LIGHT_GRAY;//定义方块色为红色,背景为浅灰色 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; } /* * 获得画布的背景色 */

}

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;//y为新的行 x = newCol;//x为新的列 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); } } } }

RussiaBlocksGame.java import java.awt.*;

import java.awt.event.*; import javax.swing.*;

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 = 1;// 默认级别 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,//3种样式风格选项卡 metalRadioItem; private JMenuItem authorItem, helpItem;//作者选项卡 帮助选项卡 private ButtonGroup buttonGroup;//按钮组 /* * 构造函数 */ public RussiaBlocksGame(String title) { super(title); setSize(300, 400);//设置游戏大小为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, \最终成绩:\ + curLevelScore + \等级:\ } /* * 创建菜单 */ private void createMenu() { gameMenu = new JMenu(\游戏\新建一个jmenu游戏菜单 newGameItem = new JMenuItem(\新游戏\新建一个新游戏选项卡 并命名新游戏 ,设快捷键为N newGameItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));//设置新游戏选项卡快捷键 setBlockColorItem = new JMenuItem(\Block Color...\新建一个设置游戏方块颜色选项卡 并命名(未实现) setBgColorItem = new JMenuItem(\新建一个设置游戏背景色选项卡 并命名(未实现) turnHardItem = new JMenuItem(\难一级\新建一个难一级选项卡(未实现) turnEasyItem = new JMenuItem(\简单一级\新建一个简单一级选项卡(未实现) exitItem = new JMenuItem(\KeyEvent.VK_E);//新建一个退出选项卡 并命名 设快捷键E exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, ActionEvent.CTRL_MASK));//设置退出选项卡快捷键 gameMenu.add(newGameItem);//游戏菜单添加新游戏选项卡 // gameMenu.add(setBlockColorItem);//游戏菜单添加设置游戏方块颜色选项卡(未实现) // gameMenu.add(setBgColorItem);//游戏菜单添加设置游戏背景色选项卡(未实现) // gameMenu.add(turnHardItem);//游戏菜单添加难一级选项卡(未实现) // gameMenu.add(turnEasyItem);//游戏菜单添加简单一级选项卡(未实现) gameMenu.add(exitItem);//游戏菜单添加退出选项卡

controlMenu = new JMenu(\控制\添加控制菜单 并命名(未实现) playItem = new JMenuItem(\开始\KeyEvent.VK_B);//添加开始选项卡 并命名 设快捷b(未实现) playItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, ActionEvent.CTRL_MASK));//设置快捷键(未实现) pauseItem = new JMenuItem(\暂停\添加暂停选项卡 并命名 设快捷p(未实现) pauseItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK));//设置快捷键(未实现) resumeItem = new JMenuItem(\重新开始\KeyEvent.VK_R);//添加重新开始选项卡 并命名 设快捷r(未实现) resumeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK));//设置快捷键(未实现) stopItem = new JMenuItem(\停止\KeyEvent.VK_S);//添加停止选项卡 并命名 设快捷s(未实现) stopItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));//设置快捷键(未实现) 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样式选项卡 并命名 设置为默认使用状态 windowStyleMenu.add(windowsRadioItem);//窗口风格菜单添加windows菜单样式选项卡 buttonGroup.add(windowsRadioItem);//单选按钮组添加windows样式菜单选项卡 windowStyleMenu.add(motifRadioItem);//窗口风格菜单添加motif菜单样式选项卡 buttonGroup.add(motifRadioItem);//单选按钮组添加motif样式菜单选项卡 windowStyleMenu.add(metalRadioItem);//窗口风格菜单添加metal菜单样式选项卡 buttonGroup.add(metalRadioItem);//单选按钮组添加metal样式菜单选项卡 informationMenu = new JMenu(\游戏说明\新建一个信息菜单 并命名 authorItem = new JMenuItem(\作者\新建一个作者选项卡 并命名 helpItem = new JMenuItem(\帮助\新建一个帮助选项卡 并命名 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, \ canvas.getBlockColor()); if (newBlockColor != null) canvas.setBlockColor(newBlockColor); } });

setBgColorItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { Color newBgColor = JColorChooser.showDialog( RussiaBlocksGame.this, \ 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 = \ setWindowStyle(plaf); canvas.fanning(); controlPanel.fanning(); } }); motifRadioItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { String plaf = \ setWindowStyle(plaf); canvas.fanning(); controlPanel.fanning(); ; } }); metalRadioItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { String plaf = \ setWindowStyle(plaf); canvas.fanning(); controlPanel.fanning(); } }); authorItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { if (ae.getSource() == authorItem) { JOptionPane.showMessageDialog(null, \俄罗斯方块\\n\\n\作者: 117寝室\\n\\n\ + \联系方式:软件G091班\ } } }); helpItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { if (ae.getSource() == helpItem) { JOptionPane.showMessageDialog(null, \俄罗斯方块\\n\\n\游戏简介\\n\\n\ + \:每消除掉20行,提升一个等级,并增加游戏难度(提高游戏速度)\\n\

+ \游戏等级由最初的1级到最高等级10级\\n\ + \游戏窗口风格为3种,玩家可自由选择适合自己的游戏样式风格\\n\ + \此游戏仅为娱乐,如用于商业,概不负责\\n\ } } }); } /* * 设定窗口风格 */ 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(\ } }

RussiaBox.java import java.awt.*;

import java.awt.event.*; import javax.swing.*;

import javax.swing.border.*; /*

*虚拟的单个方格类,控制方格的颜色 */

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; }

public Object clone() { Object o = null; try { o = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; }

}

* 返回颜色 */

public boolean isColorBox() { return isColor; }

public Object clone() { Object o = null; try { o = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; }

本文来源:https://www.bwwdw.com/article/feyw.html

Top