版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于JAVA的扫雷小游戏引言本次课程设计目的在于设计开发一个类似windows自带扫雷游戏的小游戏,实现基本的扫雷面板及扫雷的游戏功能、游戏数据存储、游戏计时等功能。设计采用Windows下的eclipse开发工具由本人独立完成。系统设计本游戏采用快速原型模型的软件开发方法设计,总共经历了八个版本的修改最终完成设计要求。在第一个版本中,实现如下功能:基于JFrame的扫雷框架的建立:使用JFrame建立起如图的所示的程序框架,雷区为12*12,添加JPanel和JButton,采用setBounds的布局方式而非内置的布局方法。基于Random方法的虚拟雷盘的建立和动态修改:通过Random产生出一个14*14的数组,其中,二维数组边缘对应边框标记值为2,产生的雷点标记为1,普通点标记为0。再次建立一个12*12的数组对应实际的游戏面板,初始值为0,遍历14*14的数组中非边缘的元素,将每个格子周围的地雷数目赋值给对应的12*12数组,地雷仍然用-1来表示,最后遍历12*12的数组同时把数组中非0非-1的数绘制到JPanel上,值为-1的元素向面板对应位置添加一个地雷的图片(注:地雷图片来自Windows7自带扫雷游戏的截图)。基于Button的雷区覆盖面板建立以及虚拟雷盘的ActionListener的连接:将生成好的底板覆盖上12*12的Button并且为每个Button添加ActionListener,实现点击后隐藏对应的Button功能。结果如下图:重新开始及其按键功能的实现:通过“重新开始”按键重新生成雷区以及重新覆盖Button到所有格子。关于按键及其功能:通过“关于”按键弹出一个MessageDialog。在第二个版本中,实现如下功能:新增利用递归算法实现的一次点开一片区域功能:通过数据结构中的走迷宫算法在按键监听中加入了连锁点亮的算法,点亮该格,然后依次遍历12*12表的周围9格,发现为空格即递归调用遍历算法,发现数字即点亮该格并return,初步实现了如图所示的功能:新增虚拟访问判定表的建立和刷新及修改:即通过查找已标记的正确的雷并且计数,如果达到了设定了雷的最大值即执行游戏结束的方法。新增失败提示框和自动刷新功能:即点亮了地雷的区域后,自动弹出对话框提示失败并且执行游戏结束的方法。对原boom表进行了改动,解决了虚拟表和实际表的下标错位问题将原12*12的数组扩充到14*14。在第三个版本中,实现如下功能:修复了一个导致重新开始后第一行雷点位置不变的BUG:重写游戏结束的算法,改变循环的起始点,使其可以正确生成虚拟的雷点。新增了右键标记、取消雷点的功能:为每个Button添加了MouseListener从而实现了当点击鼠标右键时可以修改Button上文字,显示为雷,并且当该Button已经显示了雷的时候再次右键该Button可以取消文字显示。在第四个版本中,实现如下功能:调整了按键监听的点亮区域算法,当且仅当点击处周围没有地雷时才会触发openButton()算法,否则仅显示当前区域,提高了游戏性:重写了Button的ActionListener,按条件区分是否执行递归点亮算法,当且仅当单击区域为空的时候才执行点亮算法,否则仅点亮该区域。新增了基于System.currentTimeMillis()的计时器功能,计时器与重新开始游戏对应同步更新:通过在游戏开始时获取一个currentTimeMillis()以及实时监控并刷新计时器窗口的值为当前时间减去初始时间除以1000,为节约内存,单独为计时器开辟了一个线程,每工作一次该线程休息0.5秒。在第五个版本中,实现如下功能:更改了获胜和失败后的提示信息:将本次游戏时间加入了游戏结束时的提示窗口。新增了“记录”窗体的框架和面板:增加了一个新的JFrame,对应“记录”按钮。在第六个版本中,实现如下功能:再次改进了按键监听的点亮区域算法:进行递归遍历时将正相邻和斜相邻两种情况分开,使斜相邻的地雷值为0的格子不再会被自动点亮,提高了游戏性,至此版本为止,该算法已经完全符合预期要求。游戏后台新加入了recordlist类,用来存储和处理光荣榜的数据:该类拥有10条记录以及插入新数据到对应位置的功能。对记录窗体的改动:通过取消设定recordFrame类的mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);以及设定recFrame.hide();方法解决了关闭窗口时导致的程序异常终止的错误。在第七个版本中,实现如下功能:记录的读取与存储:通过ObjectOutputStream和ObjectInputStream成功实现了对光荣榜文件的存取功能。并且重新定义了上一版本的光荣榜信息控件,增加了获胜时修改光荣榜并且自动保存文件的功能,同时新增nameInput窗口类到游戏结束时并且成绩足以进入光荣榜时调用的方法中,用于输入获取进入光荣榜的玩家信息。在最终版本中,实现如下功能:记录与游戏的同步措施:通过更改FileOutputStream的实现位置到nameInputer中的actionListener中并且将recordlist和usedTime以参数形式通过构造函数传入nameInputer类中成功实现了光荣榜数据文件的存取。系统实现Sweeper类:importjava.awt.event.*;importjavax.swing.*;importjava.awt.*;importjava.util.Random;importjava.io.*;publicclasssweeper{Buttonboom[][]=newButton[14][14]; intvisualBoom[][]=newint[14][14]; intvisitTest[][]=newint[14][14]; intnumOfBoom=0; LabeltimeLabel=newLabel(); timeRunnablerunnable=newtimeRunnable(); ThreadtimeThread=newThread(runnable); longstartTime; longusedTime; JFramemainframe; myPanelpanel; ImageboomImage=newImageIcon("boom.jpg").getImage(); recordlistlist=newrecordlist(); JButtonstartButton; JButtonaboutButton; JButtonrecordButton; //类的属性 voidcreateWindow(){ //创建基础框架 mainframe=newJFrame("扫雷"); panel=newmyPanel(); //框架及面板 startButton=newJButton(); startButton.setText("重新开始"); startButton.setFont(newFont("楷书",Font.ITALIC,15)); startButton.setFocusPainted(false); startButton.addActionListener(newstartListener()); aboutButton=newJButton(); aboutButton.setText("关于"); aboutButton.setFont(newFont("楷书",Font.ITALIC,15)); aboutButton.setFocusPainted(false); aboutButton.addActionListener(newaboutListener()); recordButton=newJButton(); recordButton.setText("记录"); recordButton.setFont(newFont("楷书",Font.ITALIC,15)); recordButton.addActionListener(newrecordListener()); recordButton.setFocusPainted(false); //按钮 timeLabel.setBounds(350,220,30,30); timeLabel.setBackground(Color.white); startTime=System.currentTimeMillis(); timeThread.start(); panel.setLayout(null); panel.setBackground(Color.BLACK); startButton.setBounds(320,40,100,30); panel.add(startButton); recordButton.setBounds(320,100,100,30); panel.add(recordButton); aboutButton.setBounds(320,160,100,30); panel.add(aboutButton); panel.add(timeLabel); mainframe.setSize(450,340); mainframe.setVisible(true); mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainframe.add(panel); //框架布局 } voidsetBoom() //生成虚拟雷盘的雷区 { for(introw=0;row<14;row++) for(intcol=0;col<14;col++) { boom[row][col]=newButton(); visualBoom[row][col]=0; } //初始化雷区 for(inti=0;i<14;i++) { visualBoom[0][i]=-2; visualBoom[i][0]=-2; visualBoom[i][13]=-2; visualBoom[13][i]=-2; } //虚拟雷盘封边 intx,y; Randomr=newRandom(); for(intcount=0;count<16;) { x=r.nextInt(12); y=r.nextInt(12); if(visualBoom[x+1][y+1]==0) { visualBoom[x+1][y+1]=-1; count++; } } } //生成地雷,边缘:-2雷点:-1正常点:0 voidhandleBoom(){ //炸弹信息转化 inttemp[][]=newint[14][14]; for(introw=0;row<14;row++) for(intcol=0;col<14;col++) { temp[row][col]=visualBoom[row][col]; } for(introw=1;row<13;row++) for(intcol=1;col<13;col++) { temp[row][col]=countBoom(row,col); } numOfBoom=0; visualBoom=temp; } intcountBoom(intx,inty){ //周围炸弹计数器 intcount=0; if(visualBoom[x][y]!=-1) { if(visualBoom[x-1][y-1]==-1) count++; if(visualBoom[x][y-1]==-1) count++; if(visualBoom[x+1][y-1]==-1) count++; if(visualBoom[x+1][y]==-1) count++; if(visualBoom[x+1][y+1]==-1) count++; if(visualBoom[x][y+1]==-1) count++; if(visualBoom[x-1][y+1]==-1) count++; if(visualBoom[x-1][y]==-1) count++; }else count=-1; returncount; } //雷:-1雷数:(int) voidshowButton() //加入雷区按钮到面板上 { for(introw=1;row<13;row++) for(intcol=1;col<13;col++) { boom[row][col].setBounds((row-1)*25,(col-1)*25,25,25); boom[row][col].setFocusable(false); boom[row][col].addActionListener(newbuttomListener(row,col)); boom[row][col].addMouseListener(newrightClick(row,col)); panel.add(boom[row][col]); } } classmyPanelextendsJPanel{ //面板内部类 publicvoidpaintComponent(Graphicsg) { g.setColor(Color.gray); g.fillRect(0,0,300,300); g.setColor(Color.black); for(intline=0;line<=300;line+=25) g.drawLine(line,0,line,300); for(introw=0;row<=300;row+=25) g.drawLine(0,row,300,row); //绘制基本格 g.setFont(newFont("楷书",Font.ITALIC,13)); g.drawString("MineSweeperVer3.0",305,20); //绘制版本信息 g.drawString("时间",310,240); for(introw=1;row<13;row++) for(intcol=1;col<13;col++) { if(visualBoom[row][col]!=-1&&visualBoom[row][col]!=0) g.drawString(Integer.toString(visualBoom[row][col]),(row-1)*25+8,(col-1)*25+20); elseif(visualBoom[row][col]==-1) { g.drawImage(boomImage,(row-1)*25,(col-1)*25,25,25,this); } } } } //面板绘图 classbuttomListenerimplementsActionListener{ //各种监听器 introw,col; buttomListener(intx,inty) { row=x; col=y; } publicvoidactionPerformed(ActionEvente){ if(visualBoom[row][col]==0) { refreshVisitTest(); openButton(row,col); }elseif(visualBoom[row][col]!=-1) { boom[row][col].setVisible(false); }else { boom[row][col].setVisible(false); gameOver(0); } numOfBoom=0; for(introw=1;row<13;row++) for(intcol=1;col<13;col++) if(boom[row][col].getLabel()=="雷") numOfBoom++; if(numOfBoom==16) gameOver(1); } } classrightClickimplementsMouseListener{ introw,col; rightClick(intx,inty) { row=x; col=y; } @Override publicvoidmouseClicked(MouseEvente){ //TODOAuto-generatedmethodstub if(e.getButton()==MouseEvent.BUTTON3) { if(boom[row][col].getLabel()!="雷") { boom[row][col].setLabel("雷"); numOfBoom=0; for(introw=1;row<13;row++) for(intcol=1;col<13;col++) if(boom[row][col].getLabel()=="雷") numOfBoom++; if(numOfBoom==16) gameOver(1); } else boom[row][col].setLabel(""); } } @Override publicvoidmouseEntered(MouseEvente){ //TODOAuto-generatedmethodstub } @Override publicvoidmouseExited(MouseEvente){ //TODOAuto-generatedmethodstub } @Override publicvoidmousePressed(MouseEvente){ //TODOAuto-generatedmethodstub } @Override publicvoidmouseReleased(MouseEvente){ //TODOAuto-generatedmethodstub } } voidrefreshVisitTest(){ //重置访问标记表 for(introw=1;row<13;row++) for(intcol=1;col<13;col++) { visitTest[row][col]=0; } //访问标记置0 for(inti=0;i<14;i++) { visualBoom[0][i]=1; visualBoom[i][0]=1; visualBoom[i][13]=1; visualBoom[13][i]=1; } //边缘访问标记置1 } classstartListenerimplementsActionListener{ publicvoidactionPerformed(ActionEvente){ for(introw=1;row<13;row++) for(intcol=1;col<13;col++) { boom[row][col].setVisible(true); boom[row][col].setLabel(""); visualBoom[row][col]=0; } intx,y; Randomr=newRandom(); for(intcount=0;count<16;) { x=r.nextInt(12); y=r.nextInt(12); if(visualBoom[x+1][y+1]==0) { visualBoom[x+1][y+1]=-1; count++; } } handleBoom(); startTime=System.currentTimeMillis(); panel.repaint(); System.out.println(""); System.out.println(""); System.out.println(""); System.out.println(""); for(introw=1;row<13;row++) { System.out.println(""); for(intcol=1;col<13;col++) { if(visualBoom[col][row]!=-1) System.out.print(visualBoom[col][row]+""); else System.out.print("*"); } } } } classrecordListenerimplementsActionListener{ @Override publicvoidactionPerformed(ActionEventarg0){ recordFramerec=newrecordFrame(); rec.createWindow(); } } classaboutListenerimplementsActionListener{ publicvoidactionPerformed(ActionEvente){ JOptionPane.showMessageDialog(mainframe.getContentPane(),"制作人:滨江学院2021级软件工程1班王琢","关于",JOptionPane.INFORMATION_MESSAGE); } } voidopenButton(intx,inty){ //响应鼠标事件 visitTest[x][y]=1; //访问标记置1 boom[x][y].setVisible(false); if(visualBoom[x][y]!=-1) { if(visualBoom[x-1][y-1]!=-1) boom[x-1][y-1].setVisible(false); if(visualBoom[x][y-1]==0&&visitTest[x][y-1]==0) openButton(x,y-1); elseif(visualBoom[x][y-1]!=-1) boom[x][y-1].setVisible(false); if(visualBoom[x+1][y-1]!=-1) boom[x+1][y-1].setVisible(false); if(visualBoom[x+1][y]==0&&visitTest[x+1][y]==0) openButton(x+1,y); elseif(visualBoom[x+1][y]!=-1) boom[x+1][y].setVisible(false); if(visualBoom[x+1][y+1]!=-1) boom[x+1][y+1].setVisible(false); if(visualBoom[x][y+1]==0&&visitTest[x][y+1]==0) openButton(x,y+1); elseif(visualBoom[x][y+1]!=-1) boom[x][y+1].setVisible(false); if(visualBoom[x-1][y+1]!=-1) boom[x-1][y+1].setVisible(false); if(visualBoom[x-1][y]==0&&visitTest[x-1][y]==0) openButton(x-1,y); elseif(visualBoom[x-1][y]!=-1) boom[x-1][y].setVisible(false); }else{ gameOver(0); } } classtimeRunnableimplementsRunnable{ //计时器专用线程 @Override publicvoidrun(){ while(true) { timeLabel.setText(Long.toString((System.currentTimeMillis()-startTime)/1000)); usedTime=(System.currentTimeMillis()-startTime)/1000+1; try{ Thread.sleep(500); }catch(Exceptionex){ } } } } voidgameOver(intisWin){ //游戏结束 if(isWin==0) { JOptionPane.showMessageDialog(mainframe.getContentPane(),"胜败乃兵家常事,大侠请重新来过!\n本次游戏用时:"+usedTime+"秒","YouLose!",JOptionPane.INFORMATION_MESSAGE); startButton.doClick(); }else{ JOptionPane.showMessageDialog(mainframe.getContentPane(),"恭喜您!没有什么地雷能逃过您的火眼金睛\n本次游戏用时:"+usedTime+"秒","YouWin!",JOptionPane.INFORMATION_MESSAGE); try { ObjectInputStreamin=newObjectInputStream(newFileInputStream("record.wz")); list=(recordlist)in.readObject(); in.close(); if(usedTime<=list.getLowestScore()); nameInputernameinputer=newnameInputer(list,usedTime); }catch(Exceptione) { } startButton.doClick(); } } publicstaticvoidmain(String[]args){ sweepermain=newsweeper(); main.setBoom(); main.handleBoom(); main.createWindow(); main.showButton(); for(introw=1;row<13;row++) { System.out.println(""); for(intcol=1;col<13;col++) { if(main.visualBoom[col][row]!=-1) System.out.print(main.visualBoom[col][row]+""); else System.out.print("*"); } } }}recordFrame类:importjava.awt.Graphics;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.*;importjavax.swing.*;publicclassrecordFrameimplementsSerializable{ JFramerecFrame; recPanelrecpanel; JButtonclose=newJButton("关闭"); recordlistlist; voidcreateWindow(){ recFrame=newJFrame("光荣榜"); recpanel=newrecPanel(); recpanel.setLayout(null); close.addActionListener(newcloseListener()); close.setBounds(50,230,80,20); recpanel.add(close); recFrame.setSize(200,300); recFrame.setVisible(true); recFrame.add(recpanel); } classcloseListenerimplementsActionListener{ @Override publicvoidactionPerformed(ActionEventarg0){ recFrame.hide(); } } classrecPanelextendsJPanel{ publicvoidpaintComponent(Graphicsg){ g.drawString("姓名",25,20); g.drawString("耗时",125,20); try{ ObjectInputStreamin=newObjectInputStream(newFileInputStream("record.wz")); list=(recordlist)in.readObject(); in.close(); for(intpos=0;pos<10;pos++) { g.drawString([pos],25,20*(pos+2)); g.drawString(Long.toString(list.score[pos]),125,20*(pos+2)); } }catch(Exceptione){ e.printStackTrace(); } } }}recordList类:importjava.io.*;publicclassrecordlistimplementsSerializable{ //光荣榜存储类 publicStringname[]; publiclongscore[]; publicrecordlist(){ //构造函数 name=newString[10]; score=newlong[10]; for(inti=0;i<10;i++) { name[i]="王琢"; score[i]=999; } } longgetLowestScore(){ //返回榜内最长时间 returnscore[9]; } longgetHighestScore(){ returnscore[0]; } voidinsertValue(Stringn,longs){ //插入新元素 inti=0; longtemp; Stringntemp; while(s>score[i]){ i++; } do{ temp=score[i]; ntemp=name[i]; score[i]=s; name[i]=n; s=temp; n=ntemp; i++; }while(i<10); }}nameInputer类:importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.FileOutputStream;importjava.io.ObjectOutputStream;importjavax.swing.*;publicclassnameInputer{ JFrameframe; JPanelpanel; JTextFieldtext; JButtonbutton; JLabellabel; Stringname; recordlistmylist; longusedtime; nameInputer(recordlistlist,longtime){ frame=newJFrame("新纪录"); frame.setSize(300,180); panel=newJPanel(); text=newJTextField(); text.setBounds(145,30,60,20); button=newJButton("确定"); button.addActionListener(newbuttonlistener()); button.setBounds(80,70,100,20); label=newJLabel("请留下您的尊姓大名:"); label.setBounds(20,30,120,20); panel.setLayout(null); panel.add(text); panel.add(button); panel.add(label); frame.add(panel); frame.setVisible(true); mylist=list; usedtime=time; } StringgetName(){ return; } recordlistgetList(recordlistlist){ returnlist; } classbuttonlistenerimplementsActionListener{publicvoidactionPerformed(ActionEvente) { name=text.getText(); mylist.insertValue(name,usedtime); try{ ObjectOutputStreamout=newObjectOutputStream(newFileOutputStream("record.wz")); out.writeObject(mylist); out.close(); }catch(Exceptionex){ } frame.hide(); } }}软件截图:结束语经过了近一周的不断努力和改进,终于完成了这个扫雷的小游戏,通过这次程序设计我深切体会了JAVA相对于C语言的便捷性以及多态与封装的优越性,同时也深深体会到软件工程基础知识对软件开发的重要性,亲身体会了一次从策划到初步实施到不断完善的开发程序过程,为今后的程序开发积累的宝贵的经验。另外,我也深深体会到数据结构的重要性,一个好的数据结构可以提高算法效率,节省大量宝贵的资源,提升程序运行效率。这次课程设计提高了我对程序开发的兴趣,体会到了在开发过程中发现问题,解决问题的乐趣,为今后的学习树立了信心。
教师见习报告总结期待已久的见习已经结束了,在龙岩三中高中部见习听课,虽然只是短短的两个星期,但感触还是蛮深的,以前作为一名学生坐在课室听课,和现在作为一名准教师坐在课室听课是完全不同的感受,感觉自己学到了一些在平时课堂上学不到的东西。在这里,我获得的不仅是经验上的收获,更多是教学管理,课堂教学等的理念,以及他们带给我的种种思考。教育见习实践过程:听课。教育见习的主要目的是让学生在指导教师的引导下,观摩教师上课方法、技巧等。听课是教育见习的主要内容。我院规定在一周的见习中需完成至少6课的见习任务。我在教师的安排指导下,分别对高一、高二物理专业课型为主,其他课型齐头的方式,积极主动的完成了听课任务,收到良好的效果。我听的第一节课是高二(8)班,这是一个平衡班,水平不如实验班高。在上课前。科任老师已经跟我说了这个班的纪律是比较差的,而且成绩也不是很好。在我听课期间,确实有几个学生在课堂上说话,但是我发现了一个有趣的现象,这个现象我在往后的几个班都发现了,就是绝大部分的学生的学习热情都好高涨,积极举手发言,积极参与课堂活动。我跟老师们提起这个现象的时候,科任老师就跟我说,一个班里不可能所有的学生都能HYPERLINK"/search?word=%E5%85%A8%E7%A5%9E%E8%B4%AF%E6%B3%A8&fr=qb_search_ex
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年RISC-VPWM生成器设计考核试卷
- 不用协议书盒
- 2025初级商业人像摄影师布光附件创意应用效果考核试卷
- 偿还协议书的描述
- 2025年被害人承诺辩护公诉应对考核试卷
- 2025年航空航天行业航空航天创新技术与航天探索研究报告及未来发展趋势预测
- 2025年民宿节能设备采购与投资回报分析考核试卷
- 2025年农业无人机作业安全规范考核试卷
- 2025年科技行业医疗AI影像标注转化科技成果转化考核试卷
- 2025年公路工程监理实务(考核评价监理)考核试卷
- 全球及中国核药(核素药物)行业发展动态与需求前景分析报告2025-2030年
- 皮草购货合同协议
- 品管圈-提高心血管介入术后患者肢体活动有效率
- 模切行业的应用与发展
- 酒店管理职业规划分析
- 去冰岛旅游景点
- 2025【英文合同】英文版国际租房合同模板
- 2025届湖南省“一起考”大联考高三下学期一模物理试题(原卷版+解析版)
- 银河航天卫星在轨服务技术的可行性研究
- 2025年入团积极分子培训考试题库及答案
- 大学生心理健康教育(第三版)教案:第五章 人际和谐 协调利益
评论
0/150
提交评论