. . . . JAVA语言课程设计报告题目:扫雷小游戏设计者:专业班级:学号:指导教师:2011年 12月 12日计算机学院目录:1.设计容及要求 (1)1.1.扫雷小游戏的基本要求 (1)1.2 需求实现的主要功能 (1)2.需求分析 (1)2.1 扫雷区域的布局设计 (1)2.2 雷区的设计 (1)2.3 音效的设计 (1)3.总体设计 (2)3.1总体功能图 (2)3.2游戏设计流程图 (2)4.主要功能设计 (3)4.1 雷区设计流程图 (3)4.2 音效设计流程图 (4)4.3 排行榜设计流程图 (5)5.代码实现 (6)5.1 类之间的关系图 (6)5.2 各界面图及代码: (6)5.2.1 游戏菜单界面 (6)5.2.2 游戏登录界面(初级、中级、高级) (8)5.2.3自定义扫雷界面 (15)6.扫雷总结 (18)7.参考文献 (18)1·设计容及要求1.1·扫雷小游戏的基本要求扫雷小游戏主要采用Java语言编写,适合windows XP 以下的系统,以eclipse 为平台。
具体要求如下:<1> 扫雷小游戏分为初级、中级和高级三个级别,扫雷排行榜保存着每个级别的最好成绩,即挖出全部的地雷并且用时最少。
单机游戏菜单选择“初级”、“中级”和“高级”。
<2> 游戏默认的是初级级别,用户可以选择不同级别将出现对应级别的扫雷区域,单击扫雷区域任一方格以便启动计时器。
<3> 用户选择某个方格,单击它就行。
若所选择的放阁下有雷,这一局就结束了,若所选择方格下无雷,则会显示一个数字,该数字代表方格周围8个方格中共有几颗雷。
<4> 如果用户认为某个方格下有雷,单击右键可以在方格上标记一个用户认为是雷的图标(一个小旗子)。
<5> 用户可以选择标记为疑问的方格,可以选择游戏菜单下的标记,或者双击右键所选方格显示(?)图标。
<6> 扫雷完成后,程序弹出保存成绩的对话框,用户可以根据自身选择是否保存。
<7> 如果用户喜欢有提示音,可以选择游戏菜单中的声音选项,单击扫雷区域任一方格,就会听到吧嗒声。
当点中地雷时,将会有爆炸声音响起,胜利后,将播放凯旋的旋律。
1.2 需求实现的主要功能(1)该游戏具有计时功能,即扫完全部地雷所花费的时间。
(2)用户可以选择是否有音效。
(3)用户可以自定义级别,还可以输入任意地雷数。
(4)自动保存扫雷排行榜。
2·需求分析2.1 扫雷区域的布局设计系统的整体布局为:CardLayout 布局,采用菜单、按钮、面板……等组件,菜单项主要有开始,选择级别,自定义,标记,声音,扫雷排行榜,退出,按钮的功能是重新开始游戏(可以选择游戏菜单里的开局,也可以点击企鹅图标重新开始游戏)。
2.2 雷区的设计MineArea类是javax.swing 包中Jpanel容器的子类,实现了ActionListener和MouseListener接口,所创建的对象:mineArea是MineGame 类中最重要的成员之一,作为一个容器添加到MineGame窗口的中心。
2.3 音效的设计music类是java.awt包中Frame的子类,通过构造音效声音方法,在MainFrame主类中,通过ActionListener来监视是否已开始游戏,来决定播放计时声,之后又通过ActionListener来监视是否踩到雷和是否完成来决定,播放相应的音乐。
2.4 排行榜设计LogDialog是javax.swing包中Jdialog对话框的子类,并实现了ActiongListener接口。
LogDialog创建的对象dialog是MainFrame类(主类)的成员之一,当用户选择查看“英雄榜”菜单项时,该对话框可见,提供了查看扫雷的最好成绩的界面。
3·总体设计3.1总体功能图图1-1 总体功能图3.2游戏设计流程图图1-2 游戏设计流程图4·主要功能设计4.1 雷区设计流程图图1-3 雷区设计流程图4.2 音效设计流程图图1-4 音效设计流程图4.3 排行榜设计流程图N图 1-5 排行榜设计流程图5·代码实现5.1 类之间的关系图图1-6 类之间的关系图5.2 各界面图及代码:5.2.1 游戏菜单界面图1-7 游戏菜单界面其主要代码为:private void setMenuBar() {//设置菜单项JMenuBar menuBar = new JMenuBar();menuBar.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));JMenu gameMenu = new JMenu("游戏(G)");JMenu helpMenu = new JMenu("帮助(H)");gameMenu.setMnemonic('G');helpMenu.setMnemonic('H');声音=new Voice();startItem = new JMenuItem("开局(N)");startItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F2,0));logItem = new JMenuItem("扫雷英雄榜(T)...");markCheckItem = new JCheckBoxMenuItem("标记(?)(M)");soundItem=new JCheckBoxMenuItem("声音(S)");exitItem = new JMenuItem("退出(X)");aboutItem = new JMenuItem("关于扫雷(A)...");startItem.setMnemonic('N');exitItem.setMnemonic('X');aboutItem.setMnemonic('A');aboutItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1,0));logItem.setMnemonic('T');soundItem.setMnemonic('S');soundItem.setSelected(sound);markCheckItem.setMnemonic('M');markCheckItem.setSelected(markCheck);gameMenu.add(startItem);gameMenu.addSeparator();//radio grouplevelItem = new JRadioButtonMenuItem[4];ButtonGroup levelGroup = new ButtonGroup();levelItem[0] = new JRadioButtonMenuItem("初级(B)");levelItem[1] = new JRadioButtonMenuItem("中级(I)");levelItem[2] = new JRadioButtonMenuItem("高级(E)");levelItem[3] = new JRadioButtonMenuItem("自定义(C)...");levelItem[0].setMnemonic('B');levelItem[1].setMnemonic('I');levelItem[2].setMnemonic('E');levelItem[3].setMnemonic('C');for(int i=0;i<4;i++) {levelGroup.add(levelItem[i]);levelItem[i].addActionListener(this);gameMenu.add(levelItem[i]);}levelItem[currentLevel].setSelected(true);gameMenu.addSeparator();gameMenu.add(markCheckItem);gameMenu.addSeparator();gameMenu.add(soundItem);gameMenu.addSeparator();gameMenu.add(logItem);gameMenu.addSeparator();gameMenu.add(exitItem);helpMenu.add(aboutItem);startItem.addActionListener(this);markCheckItem.addActionListener(this);soundItem.addActionListener(this);logItem.addActionListener(this);exitItem.addActionListener(this);aboutItem.addActionListener(this);menuBar.add(gameMenu);menuBar.add(helpMenu);setJMenuBar(menuBar);}5.2.2 游戏登录界面(初级、中级、高级)图1-8 初级扫雷界面图1-9 中级扫雷界面图2.0 高级扫雷界面其主要代码为:private LevelLog levelLog[];private JTextArea logArea;private JButton resetButton;private JButton confirmButton;public LogDialog(JFrame frame, LevelLog log[]) {super(frame, "扫雷英雄榜", true);getContentPane().setLayout(null);levelLog = log;logArea = new JTextArea();logArea.setEditable(false);logArea.setBackground(UIManager.getColor("CheckBox.background"));logArea.setBounds(10,10,160,60);getContentPane().add(logArea, null);resetButton = new JButton("重新计分");resetButton.setBounds(10,70,90,25);resetButton.addActionListener(this);getContentPane().add(resetButton, null);setTextArea();confirmButton = new JButton("确定");confirmButton.setBounds(105,70,60,25);confirmButton.addActionListener(this);getContentPane().add(confirmButton, null);setSize(180,140);setLocationRelativeTo(frame);setResizable(false);show();}private void setTextArea() {logArea.setText("初级:" + levelLog[0].toString()+ "中级:" + levelLog[1].toString()+ "高级:" + levelLog[2].toString());}public void actionPerformed(ActionEvent e) {if(e.getSource()==resetButton) {for(int i=0;i<3;i++) {levelLog[i].setDefault();}setTextArea();} else {dispose();}}雷区界面设计代码:private Polygon segmentPolygon[];private int numberSegment[][] = {{0, 1, 2, 3, 4, 5 }, //0{1, 2 }, //1{0, 1, 3, 4, 6 }, //2{0, 1, 2, 3, 6 }, //3{1, 2, 5, 6 }, //4{0, 2, 3, 5, 6 }, //5{0, 2, 3, 4, 5, 6 }, //6{0, 1, 2 }, //7{0, 1, 2, 3, 4, 5, 6 }, //8{0, 1, 2, 3, 5, 6 } //9};private int div[] = {1,10,100,1000,10000,100000};private Image numberImage[];private Color fontColor = Color.red; //the color of numberprivate Color bgColor = Color.black;private Color maskColor = Color.darkGray;private int dWidth = 12;private int dHeight = 21;public LedNumber() {init();}public LedNumber(Color fc) {fontColor = fc;init();}public LedNumber(Color fc, Color bgc) {bgColor = bgc;fontColor = fc;init();}public LedNumber(Color fc,Color bgc,Color mc) {bgColor = bgc;fontColor = fc;maskColor = mc;init();}public Image getLedImage(int dg, int bound) {dg %= div[bound];Image image = new BufferedImage(dWidth*bound,dHeight,BufferedImage.TYPE_INT_RGB);Graphics g = image.getGraphics();bound--;for(int i = bound;i>=0;i--) {g.drawImage(numberImage[dg/div[i]],(bound-i)*dWidth,0,this); dg %= div[i];}return image;}public void init() {segmentPolygon = new Polygon[7];numberImage = new Image[10];//setup polygonssetNumberPolygon();setNumberImage();}public void setBackGround(Color bgc) {bgColor = bgc;}public void setFontColor(Color fc) {fontColor = fc;}public void setMaskColor(Color mkc) {maskColor = mkc;}public void setDigitWidth(int w) {dWidth = w;init();}public void setDigitHeight(int h) {dHeight = h;init();}public void setDigitSize(int w, int h) {dWidth = w;dHeight = h;init();}private void setNumberImage() {int i = 0;int j = 0;int k;Graphics g;while(i<10) {numberImage[i] = new BufferedImage(15,20,BufferedImage.TYPE_INT_RGB);g = numberImage[i].getGraphics();g.setColor(bgColor);g.fillRect(0,0,15,20);g.setColor(Color.DARK_GRAY);j = 0;while(j<numberSegment[8].length) {k = numberSegment[8][j];g.fillPolygon(segmentPolygon[k]);j++;}g.setColor(fontColor);j = 0;while(j<numberSegment[i].length) {k = numberSegment[i][j];g.fillPolygon(segmentPolygon[k]);j++;}i++;}}public void setNumberPolygon() {int mid = dHeight/2+1;segmentPolygon[0] = new Polygon();segmentPolygon[0].addPoint(2, 1);segmentPolygon[0].addPoint(dWidth-2,1);segmentPolygon[0].addPoint(dWidth-5,4);segmentPolygon[0].addPoint(4,4);segmentPolygon[1] = new Polygon();segmentPolygon[1].addPoint(dWidth-1, 1);segmentPolygon[1].addPoint(dWidth-1, mid-1);segmentPolygon[1].addPoint(dWidth-2, mid-1);segmentPolygon[1].addPoint(dWidth-4, mid-3);segmentPolygon[1].addPoint(dWidth-4, 4);segmentPolygon[2] = new Polygon();segmentPolygon[2].addPoint(dWidth-1, mid);segmentPolygon[2].addPoint(dWidth-1, dHeight-2);segmentPolygon[2].addPoint(dWidth-4, dHeight-5);segmentPolygon[2].addPoint(dWidth-4, mid+1);segmentPolygon[2].addPoint(dWidth-3, mid);segmentPolygon[3] = new Polygon();segmentPolygon[3].addPoint(dWidth-2, dHeight-1);segmentPolygon[3].addPoint(1, dHeight-1);segmentPolygon[3].addPoint(4, dHeight-4);segmentPolygon[3].addPoint(dWidth-4, dHeight-4);segmentPolygon[4] = new Polygon();segmentPolygon[4].addPoint(1, dHeight-2);segmentPolygon[4].addPoint(1, mid);segmentPolygon[4].addPoint(3, mid);segmentPolygon[4].addPoint(4, mid+1);segmentPolygon[4].addPoint(4, dHeight-5);segmentPolygon[5] = new Polygon();segmentPolygon[5].addPoint(1, mid-1);segmentPolygon[5].addPoint(1, 1);segmentPolygon[5].addPoint(4, 4);segmentPolygon[5].addPoint(4, mid-3);segmentPolygon[5].addPoint(2, mid-1);segmentPolygon[6] = new Polygon();segmentPolygon[6].addPoint(3, mid-1);segmentPolygon[6].addPoint(4, mid-2);segmentPolygon[6].addPoint(dWidth-4, mid-2);segmentPolygon[6].addPoint(dWidth-3, mid-1);segmentPolygon[6].addPoint(dWidth-5, mid+1);segmentPolygon[6].addPoint(4, mid+1);}5.2.3自定义扫雷界面图2-1 自定义扫雷界面其主要代码为:private JTextField widthField;private JTextField heightField;private JTextField mineField;private JButton confirmButton;private JButton cancelButton;private static LevelInfo level;public CustomDialog(Frame frame, LevelInfo levelInfo) {super(frame,"自定义雷区",true);getContentPane().setLayout(null);JLabel tempLabel = new JLabel("高度:");tempLabel.setBounds(10,10,30,20);heightField = new JTextField(""+levelInfo.getXBound());heightField.setBounds(50,10,40,20);getContentPane().add(tempLabel,null);getContentPane().add(heightField,null);tempLabel = new JLabel("宽度:");tempLabel.setBounds(10,40,30,20);widthField = new JTextField(""+levelInfo.getYBound());widthField.setBounds(50,40,40,20);getContentPane().add(tempLabel,null);getContentPane().add(widthField,null);tempLabel = new JLabel("雷数:");tempLabel.setBounds(10,70,30,20);mineField = new JTextField(""+levelInfo.getMineCount());mineField.setBounds(50,70,40,20);getContentPane().add(tempLabel,null);getContentPane().add(mineField,null);confirmButton = new JButton("确定");confirmButton.addActionListener(this);confirmButton.setBounds(100,10,60,25);getContentPane().add(confirmButton,null);cancelButton = new JButton("取消");cancelButton.addActionListener(this);cancelButton.setBounds(100,45,60,25);getContentPane().add(cancelButton,null);setSize(180,137);setLocationRelativeTo(frame);setResizable(false);show();}public void actionPerformed(ActionEvent e) {level = null;if(e.getSource()==confirmButton) {int x = Integer.parseInt(heightField.getText());int y = Integer.parseInt(widthField.getText());int m = Integer.parseInt(mineField.getText());level = new LevelInfo(x,y,m);}dispose();}public static LevelInfo getUserLevel(JFrame frame, LevelInfo levelInfo) { CustomDialog dialog = new CustomDialog(frame, levelInfo);return level;}5.2.4扫雷排行榜界面图2-2 扫雷排行榜界面其主要代码为:public LogDialog(JFrame frame, LevelLog log[]) {super(frame, "扫雷英雄榜", true);getContentPane().setLayout(null);levelLog = log;logArea = new JTextArea();logArea.setEditable(false);logArea.setBackground(UIManager.getColor("CheckBox.background"));logArea.setBounds(10,10,160,60);getContentPane().add(logArea, null);resetButton = new JButton("重新计分");resetButton.setBounds(10,70,90,25);resetButton.addActionListener(this);getContentPane().add(resetButton, null);setTextArea();confirmButton = new JButton("确定");confirmButton.setBounds(105,70,60,25);confirmButton.addActionListener(this);getContentPane().add(confirmButton, null);setSize(180,140);setLocationRelativeTo(frame);setResizable(false);show();}private void setTextArea() {logArea.setText("初级:" + levelLog[0].toString()+ "中级:" + levelLog[1].toString()+ "高级:" + levelLog[2].toString());}public void actionPerformed(ActionEvent e) {if(e.getSource()==resetButton) {for(int i=0;i<3;i++) {levelLog[i].setDefault();}setTextArea();} else {dispose();}}6·扫雷总结在编写扫雷这个游戏的过程中,让我注意到许多以前没有在意的细节,这些细节在编程的过程中必不可少。