版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
面向对象课程设计潜艇大作战小游戏
目录1.需求分析 21.1需求分析: 21.2功能设计 22.概要设计 22.1程序设计思路 22.2程序运行界面 32.3流程图 33.各模块的功能及程序说明 43.1主界面代码 43.2潜艇对象的实现 83.3潜艇爆炸的实现 133.4游戏说明 143.5时间计时器 16计时产生潜艇 16计时产生鱼雷 183.6读取文件,记录分数 194.实验心得 261.需求分析1.1需求分析:本程序的要求为使用Java建立一个小游戏程序中用到Java课程中的重点知识1.2功能设计本游戏的功能有以下几个方面:首先绘制一个首页,首页包括开始、退出按钮,采用事件监听。进入游戏后使用,通过读取文件,读出以前的最好成绩,使用菜单按钮开始游戏通过方向键来控制潜艇的移动方向,空格键释放鱼雷击中敌人后加分,同时被敌人击中一次就扣除一次机会,共3次机会2.概要设计2.1程序设计思路此游戏的关键点是潜艇是否被击中的判断,整个屏幕是个二维坐标系,军舰在一个水平位置移动,当在某个位置发射鱼雷,判断鱼雷的图片与不断移动的潜艇图片是否有重合的地方,如果有发生爆炸,如果没有继续移动。2.2程序运行界面2.3流程图本游戏的基本运行流程是启动后把整个画布作为一个线程,随时准备响应用户按键操作的K响应,100ms扫描一次潜艇和水雷等物体的运行状态。在扫描潜艇和水雷运动时,执行各个物体画面的移动方法。程序并不为每隔新增潜艇和水雷开启一个新线程,太多线程会造成程序的性能直线下降;而是将每一个物体类型直接加入到画布中,每当一个新物体产生,将直接在画布上画出;当物体消除时,将直接在画布上被消除。这样就形成一种注册机制,所有游戏物体的产生和消除都需要画布注册,画布拥有不同类型物体的所有“名单”,所以,当执行移动命令是只需要遍历画布中所有游戏物体,依次执行每隔游戏物体中定义的移动方法即可。3.各模块的功能及程序说明3.1主界面代码主界面设计是使用坐标系,具体实现图如下:publicclassMainPanelextendsJPanel{privatestaticfinallongserialVersionUID=1L;privateMyButtonstartButton;privateMyButtonexitButton;privateJLabelhelpLabel;privateJLabelhelpLabel1;privateJLabelhelpLabel2;privateJLabelhelpLabel3;privateImageimage;privateJLabelcenterlabel;privatebooleanisStart;privatebooleanisExit;privateObservableobs;publicMainPanel(Observableob) {obs=ob;//初始化对象startButton=newMyButton("进入游戏");exitButton=newMyButton("退出游戏");helpLabel=newJLabel();helpLabel1=newJLabel();helpLabel2=newJLabel();helpLabel3=newJLabel();centerlabel=newJLabel();this.setLayout(newBorderLayout());this.helpLabel.setPreferredSize(newDimension(645,291));this.helpLabel1.setPreferredSize(newDimension(180,80));this.helpLabel2.setPreferredSize(newDimension(215,80));this.helpLabel3.setPreferredSize(newDimension(645,80));this.centerlabel.setPreferredSize(newDimension(460,80));centerlabel.setLayout(newGridLayout(2,1));centerlabel.add(this.startButton);centerlabel.add(this.exitButton);this.centerlabel.setBackground(newColor(255,255,0));this.add(helpLabel,BorderLayout.NORTH);this.add(helpLabel1,BorderLayout.EAST);this.add(helpLabel2,BorderLayout.WEST);this.add(helpLabel3,BorderLayout.SOUTH);this.add(centerlabel,BorderLayout.CENTER);//类中声明了游戏中需要的各种对象,并载入游戏中的图片image=Toolkit.getDefaultToolkit().getImage("imgs/主界面112.png");//image=newImageIcon(image).getImage();//对开始按钮的监听this.startButton.addActionListener(newActionListener() {publicvoidactionPerformed(ActionEvente) {booleanflag=true; MainPanel.this.setIsStart(flag);//System.out.println(MainPanel.this.getIsStart()); MainPanel.this.obs.notifyObservers(MainPanel.this);//System.out.println("isStart"); } } );//对结束事件的监听this.exitButton.addActionListener(newActionListener() {publicvoidactionPerformed(ActionEvente) { MainPanel.this.setExit(true); } } ); }publicvoidpaint(Graphicsg) {super.paint(g); Graphics2Dg2=(Graphics2D)g; g2.drawImage(image,0,0,this.getWidth(),this.getHeight(),this);super.paintComponents(g); }publicbooleangetIsStart() {returnthis.isStart; }publicvoidsetIsStart(booleanisStart) {this.isStart=isStart; }publicbooleanisExit(){returnisExit; }publicvoidsetExit(booleanisExit){this.isExit=isExit; }}3.2潜艇对象的实现publicclassSubmarineimplementsRunnable{privateintX;//位置x,yprivateintY;privateintdx;//移动距离privateintm;//方向:0代表向左1代表向右privateWarShipship;privateMyPanelpanel;privateintweight=65;//默认长度和宽度,数据来自图片大小privateintheight=20;publicbooleanflag=false;//运行标记privateImageimage;//图片对象//privatestaticintnum=0;publicSubmarine(WarShipship,MyPanelpanel) {this.ship=ship;this.panel=panel;this.dx=1;//随机产生潜艇图片和运动方向this.m=(int)(Math.random()*2);if(this.m==0) { Randomr=newRandom();intnum=r.nextInt(3);if(num==0) {image=Toolkit.getDefaultToolkit().getImage("imgs/潜艇1.png");//Toolkit.getDefaultToolkit().createImage("C:\\1.JPG"),用异步的方式创建图片。当线程执行到_img.getWidth(this)语句时,创建图片的线程还没准备好图片所以会返回-1。image=newImageIcon(image).getImage(); }elseif(num==1) {image=Toolkit.getDefaultToolkit().getImage("imgs/潜艇2.png");image=newImageIcon(image).getImage(); }elseif(num==2) {image=Toolkit.getDefaultToolkit().getImage("imgs/潜艇8.png");image=newImageIcon(image).getImage(); } }if(this.m==1) { Randomr1=newRandom();intnum=r1.nextInt(4);if(num==0) {image=Toolkit.getDefaultToolkit().getImage("imgs/潜艇3.png");image=newImageIcon(image).getImage(); }elseif(num==1) {image=Toolkit.getDefaultToolkit().getImage("imgs/潜艇4.png");image=newImageIcon(image).getImage(); }elseif(num==2) {image=Toolkit.getDefaultToolkit().getImage("imgs/潜艇6.png");image=newImageIcon(image).getImage(); }elseif(num==3) {image=Toolkit.getDefaultToolkit().getImage("imgs/潜艇7.png");image=newImageIcon(image).getImage(); } }this.weight=image.getWidth(panel);this.height=image.getHeight(panel);if(m==0) {this.X=this.panel.getWidth()-this.weight; }if(m==1) {this.X=0; } Randomry=newRandom();inty1=ry.nextInt(panel.getHeight())+180;while((y1+this.getHeight())>=panel.getHeight()) { y1=ry.nextInt(panel.getHeight())+180; }this.Y=y1;//计时器每隔一段时间产生鱼雷对象 TimeManager2tm2=newTimeManager2(this,this.panel,this.ship,this.panel.getTorpedoArray()); Threadt=newThread(tm2); t.start(); }publicvoiddrawSubmarine(Graphics2Dg) { g.drawImage(image,this.X,this.Y,panel); }publicvoidmoveLeft() {//System.out.println("潜水艇运动");this.X-=dx;//System.out.println(this.X);this.panel.repaint();if(this.X<0) {this.flag=true; } }publicvoidmoveright() {this.X+=dx;//this.panel.repaint();if(this.X>this.panel.getWidth()) {this.flag=true; } }publicvoidrun() {//System.out.println("线程激活");while(!flag) {//System.out.println("222");if(this.m==0) {this.moveLeft(); }if(this.m==1) {this.moveright(); }if(this.panel.isStop()) {synchronized(MyPanel.subLock) {try { MyPanel.subLock.wait(); }catch(Exceptione) { e.printStackTrace();this.flag=true; } } }try { Thread.sleep(10); }catch(Exceptione) { e.printStackTrace();this.flag=true; } } }publicintgetX(){returnX; }publicvoidsetX(intx){X=x; }publicintgetY(){returnY; }publicvoidsetY(inty){Y=y; }publicintgetDx(){returndx; }publicvoidsetDx(intdx){this.dx=dx; }publicintgetWeight(){returnweight; }publicvoidsetWeight(intweight){this.weight=weight; }publicintgetHeight(){returnheight; }publicvoidsetHeight(intheight){this.height=height; }3.3潜艇爆炸的实现/**潜艇被击中的爆炸效果,通过图片显示*/publicclassHitimplementsRunnable{privateMyPanelpanel;//主面板privateImageimage;//图片privateintliveTime=500;//爆炸效果显示的时间默认为500毫秒privateintbeginX=0;//位置xyprivateintbeginY=0;privatebooleanisRunning=false;//游戏是否正在运行标志publicHit(intx,inty,MyPanelpanel) {this.beginX=x;this.beginY=y;this.panel=panel;this.image=Toolkit.getDefaultToolkit().getImage("imgs/炸弹效果.png");this.image=newImageIcon(this.image).getImage(); }publicvoiddrawHitting(Graphics2Dg) { g.drawImage(this.image,this.beginX,this.beginY,this.panel); }publicvoidrun() {while(!this.isRunning) {try{ Thread.sleep(this.liveTime); }catch(InterruptedExceptione){//TODOAuto-generatedcatchblock e.printStackTrace(); }this.isRunning=true; } }publicbooleanisRunning(){returnisRunning; }publicvoidsetRunning(booleanisRunning){this.isRunning=isRunning; }}3.4游戏说明/***游戏规则的对话框,提示游戏规则信息*/publicclassHelpDialogextendsJDialogimplementsMouseMotionListener,MouseListener{privatestaticfinallongserialVersionUID=1L;protectedJFrameframe1;privateMyPanelpanel;privatebooleanflag=false;privatebooleanisDraw=false;privatebooleanisOutDraw=false;publicHelpDialog(Frameframe,booleanmodal,MyPanelpanel) {super(frame,modal);this.panel=panel;this.addMouseMotionListener(this);this.addMouseListener(this);this.setLocation(frame.getBounds().x+180,frame.getBounds().y+200);this.setSize(300,200);this.setUndecorated(true);this.setVisiableRigeon(this.getWidth(),this.getHeight());this.setVisible(true); }publicvoidpaint(Graphicsg) {super.paint(g); Graphics2Dg2=(Graphics2D)g;//g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); Point2Dstart=newPoint2D.Float(this.getWidth()/2,0); Point2Dend=newPoint2D.Float(this.getWidth()/2,this.getHeight());float[]dist={0.05f,1.0f}; Color[]colors={newColor(58,95,205),Color.CYAN}; LinearGradientPaintp=newLinearGradientPaint(start,end,dist,colors); g2.setPaint(p); g2.fillRect(0,0,this.getWidth(),this.getHeight()); Stringtitle=newString("游戏规则"); g2.setFont(newFont("华文行楷",Font.BOLD,25)); g2.setColor(Color.yellow); BasicGraphicsUtils.drawString(g2,title,100,90,50); Stringcontext=newString("按<-或A键控制军舰向左"); g2.setFont(newFont("华文行楷",Font.BOLD,15)); g2.setColor(Color.yellow); BasicGraphicsUtils.drawString(g2,context,100,50,100); Stringcontext1=newString("按->或D键控制军舰向右"); g2.setFont(newFont("华文行楷",Font.BOLD,15)); g2.setColor(Color.yellow); BasicGraphicsUtils.drawString(g2,context1,100,50,120); Stringcontext2=newString("按空格键扔炸弹"); g2.setFont(newFont("华文行楷",Font.BOLD,15)); g2.setColor(Color.yellow); BasicGraphicsUtils.drawString(g2,context2,100,50,140);//g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);this.repaintShape(); }3.5时间计时器计时产生潜艇publicclassTimeManagerimplementsRunnable{privateWarShipship;privateMyPanelpanel;privateintspeed=1000;publicTimeManager(WarShipship,MyPanelpanel) {this.ship=ship;this.panel=panel; }publicvoidrun() { Randomr=newRandom();while(this.panel.isRunning()) {if(this.panel.isStop()==true) {//System.out.println("777");synchronized(MyPanel.subLock) {try { MyPanel.subLock.wait(); }catch(Exceptione) { e.printStackTrace();//this.flag=true;this.panel.endGame(); } } } Submarinesm=newSubmarine(this.ship,this.panel);this.panel.getSubmarineArray().add(sm); Threadt=newThread(sm); t.start();try { Thread.sleep(this.speed+r.nextInt(this.speed*3)); }catch(Exceptione) { e.printStackTrace(); } } }publicintgetSpeed(){returnspeed; }publicvoidsetSpeed(intspeed){this.speed=speed; }}计时产生鱼雷publicclassTimeManager2implementsRunnable{privateWarShipship;privateArrayList<Torpedo>torpedoArray;privateMyPanelpanel;privateSubmarinesm;publicTimeManager2(Submarinesm,MyPanelpanel,WarShipship,ArrayList<Torpedo>torpedoArray) {this.sm=sm;this.torpedoArray=torpedoArray;this.panel=panel;this.ship=ship; }publicvoidrun() { Randomr=newRandom();while(!this.sm.flag) {//System.out.println("333");if(this.panel.isStop()==true) {synchronized(MyPanel.subLock) {//System.out.println("stop");try { MyPanel.subLock.wait(); }catch(Exceptione) { e.printStackTrace();//this.flag=true;this.panel.endGame(); } } } Torpedotp=newTorpedo(this.panel,this.ship,this.sm);this.torpedoArray.add(tp); Threadt=newThread(tp); t.start();try {inttime=r.nextInt(4000)+2000; Thread.sleep(time); }catch(Exceptione) { e.printStackTrace(); } } }}3.6读取文件,记录分数publicclassInputDialogextendsJDialog{/** * */privatestaticfinallongserialVersionUID=1L;privateJButtonsubmit;//提交按钮privateJLabeltext1;privateJLabeltext2;privateJLabeltext3;privateJTextFieldfield;privateMyPanelpanel;privateJPanelcenterPanel;privateJPanelnorthPanel;privateJPanelsouthPanel;publicInputDialog(Frameframe,booleanmodal,MyPanelpanel) {super(frame,modal);this.panel=panel;this.submit=newJButton("提交");this.text1=newJLabel("恭喜您进入前十!");this.text1.setFont(newFont("楷体",Font.BOLD,15));this.text1.setHorizontalAlignment(JLabel.CENTER);this.text1.setVerticalAlignment(JLabel.BOTTOM);this.text1.setPreferredSize(newDimension(300,90));this.text2=newJLabel("请输入您的姓名:");this.text2.setFont(newFont("楷体",Font.BOLD,12));this.text2.setHorizontalAlignment(JLabel.CENTER);this.text2.setPreferredSize(newDimension(130,20));this.text3=newJLabel("总分:"+this.panel.getScore());this.text3.setFont(newFont("楷体",Font.BOLD,12));this.text3.setHorizontalAlignment(JLabel.CENTER);this.text3.setPreferredSize(newDimension(300,30));this.field=newJTextField();this.field.setFont(newFont("楷体",Font.BOLD,15));this.field.setHorizontalAlignment(JLabel.CENTER);this.field.setPreferredSize(newDimension(70,20));this.submit.setBackground(Color.orange);this.submit.setHorizontalAlignment(JLabel.CENTER);this.submit.setPreferredSize(newDimension(80,30));this.submit.setForeground(newColor(61,145,64));this.submit.setFont(newFont("",0,20));this.centerPanel=newJPanel(newFlowLayout(5));this.centerPanel.setPreferredSize(newDimension(200,50));this.centerPanel.add(this.text2);this.centerPanel.add(this.field);this.northPanel=newJPanel(newGridLayout(2,1));this.northPanel.setPreferredSize(newDimension(300,90));this.northPanel.add(this.text1);this.northPanel.add(this.text3); JLabelsouthHelp1=newJLabel(); southHelp1.setPreferredSize(newDimension(100,50)); JLabelsouthHelp2=newJLabel(); southHelp2.setPreferredSize(newDimension(100,50));this.southPanel=newJPanel();this.southPanel.setPreferredSize(newDimension(300,70));this.southPanel.add(southHelp1);this.southPanel.add(this.submit);this.southPanel.add(southHelp2); JLabeleast=newJLabel(); east.setPreferredSize(newDimension(20,30)); JLabelwest=newJLabel(); west.setPreferredSize(newDimension(60,20)); Containerc=this.getContentPane(); c.add(this.northPanel,BorderLayout.NORTH); c.add(this.centerPanel,BorderLayout.CENTER); c.add(this.southPanel,BorderLayout.SOUTH); c.add(east,BorderLayout.EAST); c.add(west,BorderLayout.WEST);this.setContentPane(c);this.setLocation(frame.getBounds().x+180,frame.getBounds().y+200);this.setUndecorated(true); AWTUtilities.setWindowOpacity(this,0.7F);this.setSize(300,200);this.submit.addActionListener(newActionListener() {publicvoidactionPerformed(ActionEventarg0) {//得到用户信息 Stringname=InputDialog.this.field.getText().trim(); Stringscore=Integer.toString(InputDialog.this.panel.getScore()); Stringpass=Integer.toString(InputDialog.this.panel.getPass()); SimpleDateFormatdf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");//设置日期格式 Stringdate=df.format(newDate());//newDate()为获取当前系统时间 Stringargs[]=date.split(""); Stringtime=args[0]; Stringuser=name+""+score+""+pass+""+time;//将数据文件中的用户信息取出,去掉最后一名,加入玩家信息,并按降序排序 ArrayList<String>userList=newArrayList<String>(); BufferedReaderbr=null; BufferedWriterbw=null;try { br=newBufferedReader(newFileReader("userInfo/user")); Stringtemp=null;intcount=0;while((temp=br.readLine())!=null) {//System.out.println(temp); userList.add(temp); count++; }for(inti=1;i<userList.size();i++) { String[]arg=userList.get(i).split("");intvalue=Integer.parseInt(arg[1]);for(intposition=i;position>0;position--) { String[]indexScore=userList.get(position-1).split("");inttempScore=Integer.parseInt(indexScore[1]);if(tempScore<value) { Stringtemp1=(String)userList.get(position); userList.set(position,(String)userList.get(position-1)); userList.set(position-1,temp1); }
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论