java制作简单的坦克大战
详情请参照注释,这里就不多废话了,实现一下儿时的经典而已。
Blood.java
packagecom.hkm.TankWar; importjava.awt.*; /** *血块类,我方坦克吃了可回血; *@authorHekangmin * */ publicclassBlood{ privateintx,y,w,h;//血块的位置和宽度高度; privateTankWarClienttc; privateintstep=0;//纪录血块移动的步数; privatebooleanlive=true; publicbooleanisLive(){ returnlive; } publicvoidsetLive(booleanlive){ this.live=live; } /** *纪录血块的位置; */ privateint[][]pos={{400,300},{400,320},{420,320},{440,300},{440,330},{480,400},{520,400},{540,400}}; publicBlood() { x=pos[0][0]; y=pos[0][1]; w=h=18; } publicvoiddraw(Graphicsg) { if(!live)return; Colorc=g.getColor(); g.setColor(Color.CYAN); g.fillOval(x,y,w,h); g.setColor(c); move(); } /** *移动血块 */ publicvoidmove() { step++; if(step>=pos.length)step=0; else{ x=pos[step][0]; y=pos[step][1]; } } publicRectanglegetRect() { returnnewRectangle(x,y,w,h); } }
Explode.java
packagecom.hkm.TankWar; importjava.awt.*; /** *爆炸类 *@authorHekangmin * */ publicclassExplode{ privateintx,y;//爆炸发生的位置 privatebooleanLive=true; intdia[]={4,8,12,16,32,40,20,14,4};//用园模拟,代表圆的直径; intstep=0;//区别移到第几个直径 privateTankWarClienttc;//持有引用 publicExplode(intx,inty,TankWarClienttc) { this.x=x; this.y=y; this.tc=tc; } publicvoiddraw(Graphicsg) { if(!Live) { tc.explodes.remove(this); return; } if(step==dia.length)//如果到了最后一个直径爆炸死亡; { Live=false; step=0; return; } Colorc=g.getColor(); g.setColor(Color.YELLOW); g.fillOval(x,y,dia[step],dia[step]); g.setColor(c); step++; } }
Missile.java
packagecom.hkm.TankWar; importjava.awt.*; importjava.awt.Event.*; importjava.awt.event.KeyEvent; importjava.util.List; /** *子弹类 *@authorHekangmin * */ publicclassMissile{ privateintx,y;//子弹的位置 privateTank.Directiondir;//坦克方向 privatestaticfinalintXSPEED=10;//坦克x方向的移动速度, privatestaticfinalintYSPEED=10;//坦克y方向的移动速度, publicstaticfinalintWIDTH=10; publicstaticfinalintHEIGHT=10; privatebooleanLive=true;//判断子弹是否活着 privatebooleangood;//区分敌军子弹和我军子弹 privateTankWarClienttc; publicMissile(intx,inty,Tank.Directiondir){ this.x=x; this.y=y; this.dir=dir; } publicMissile(intx,inty,booleangood,Tank.Directiondir,TankWarClienttc) { this(x,y,dir); this.good=good;//将坦克好坏的属性与子弹还坏属性设为相同; this.tc=tc; } /** *画出子弹 *@paramg为画笔 */ publicvoiddraw(Graphicsg) { if(!Live) { tc.missiles.remove(this); return; } Colorc=g.getColor(); if(good) { g.setColor(Color.BLUE); } elseg.setColor(Color.ORANGE); g.fillOval(x,y,WIDTH,HEIGHT); g.setColor(c); move(); } /** *根据坦克的方向让子弹移动 */ privatevoidmove(){ switch(dir) { caseL: x-=XSPEED; break; caseLU: x-=XSPEED; y-=YSPEED; break; caseU: y-=YSPEED; break; caseRU: x+=XSPEED; y-=YSPEED; break; caseR: x+=XSPEED; break; caseRD: x+=XSPEED; y+=YSPEED; break; caseD: y+=YSPEED; break; caseLD: x-=XSPEED; y+=YSPEED; break; } if(x<0||y<0||x>TankWarClient.GAME_WIDTH||y>TankWarClient.GAME_HEIGHT)//子弹越界则让其死亡; { Live=false; } } publicbooleanisLive() { returnLive; } publicRectanglegetRect()//获取子弹的矩形区域; { returnnewRectangle(this.x,this.y,this.WIDTH,this.HEIGHT); } /** *判断子弹与坦克碰撞; *@paramt为坦克 *@return返回true则表示发生碰撞,否则没有碰撞; */ publicbooleanhitTank(Tankt) { if(this.Live&&this.getRect().intersects(t.getRect())&&t.isLive()&&this.good!=t.isGood()) { if(t.isGood()) { t.setLife(t.getLife()-10); if(t.getLife()<=0)t.setLive(false); }else{ t.setLive(false); } this.Live=false;///将子弹设为死亡; Explodee=newExplode(x,y,tc);//发生爆炸; tc.explodes.add(e); returntrue; } returnfalse; } /** *判断子弹与敌军坦克相撞; *@paramtanks敌军坦克 *@returntrue表示相撞,false没有相撞; */ publicbooleanhitTanks(List<Tank>tanks) { for(inti=0;i<tanks.size();i++) { if(hitTank(tc.tanks.get(i))) { returntrue; } } returnfalse; } /** *判断子弹是否撞墙 *@paramw墙 *@returntrue,撞上,false,未撞上; */ publicbooleanhitsWall(Wallw) { if(this.Live&&this.getRect().intersects(w.getRect())) { Live=false; returntrue; } returnfalse; } }
Tank.java
packagecom.hkm.TankWar; importjava.awt.*; importjava.awt.event.KeyEvent; importjava.util.*; /** *坦克类 *@authorHekangmin * */ publicclassTank{ publicstaticfinalintXSPEED=5;//坦克x方向速度 publicstaticfinalintYSPEED=5; publicstaticfinalintWIDTH=30; publicstaticfinalintHEIGHT=30; privateBloodBarbb=newBloodBar();//血条 privateintlife=100; publicintgetLife(){ returnlife; } publicvoidsetLife(intlife){ this.life=life; } privatestaticRandomr=newRandom(); privatestaticintstep=r.nextInt(12)+3;//定义一个数表示敌军坦克随机东的步数; privatebooleanbL=false,bU=false,bR=false,bD=false; enumDirection{L,LU,U,RU,R,RD,D,LD,STOP};//利用枚举类型定义坦克方向; privateintx,y; privateintoldX,oldY;//纪录上一步坦克的位置; privatebooleanlive=true;//判断是否活着 publicbooleanisLive(){ returnlive; } publicvoidsetLive(booleanlive){ this.live=live; } privatebooleangood;//坦克是好是坏 publicbooleanisGood(){ returngood; } privateDirectionptDir=Direction.D;//新增炮筒的方向; TankWarClienttc;//为了持有对方的引用以可以方便访问其成员变量; Directiondir=Direction.STOP;//一开始将坦克方向设为stop; publicTank(intx,inty,booleangood,Directiondir,TankWarClienttc) { this.x=x; this.y=y; this.oldX=x; this.oldY=y; this.good=good; this.dir=dir; this.tc=tc;//持有对方的引用; } publicvoiddraw(Graphicsg) { if(!live)//如果死亡则不再draw; { if(!good) { tc.tanks.remove(this); if(tc.tanks.size()<5)//少于5辆坦克时添加坦克; { for(inti=0;i<10;i++) { intposX=r.nextInt(800); intposY=r.nextInt(600); tc.tanks.add(newTank(posX,posY,false,Direction.D,tc));//使得坦克出现的位置随机 } } } return; } Colorc=g.getColor(); if(good) { g.setColor(Color.RED); bb.draw(g); } elseg.setColor(Color.BLACK); g.fillOval(x,y,WIDTH,HEIGHT); g.setColor(c); switch(ptDir)//画出炮筒的方向; { caseL: g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x-10,y+Tank.HEIGHT/2);//画出炮筒,画一条直线代替; break; caseLU: g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x-7,y-7); break; caseU: g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH/2,y-10); break; caseRU: g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH+7,y-7); break; caseR: g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH+10,y+Tank.HEIGHT/2); break; caseRD: g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH+7,y+Tank.HEIGHT+7); break; caseD: g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH/2,y+Tank.HEIGHT+10); break; caseLD: g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x-7,y+HEIGHT+7); break; } move(); } publicvoidmove() { oldX=x;//纪录坦克上一步的位置 oldY=y; switch(dir) { caseL: x-=XSPEED; break; caseLU: x-=XSPEED; y-=YSPEED; break; caseU: y-=YSPEED; break; caseRU: x+=XSPEED; y-=YSPEED; break; caseR: x+=XSPEED; break; caseRD: x+=XSPEED; y+=YSPEED; break; caseD: y+=YSPEED; break; caseLD: x-=XSPEED; y+=YSPEED; break; caseSTOP: break; } if(this.dir!=Direction.STOP) this.ptDir=this.dir; /** *防止坦克越界; */ if(x<0)x=0; if(y<25)y=25; if(x+Tank.WIDTH>TankWarClient.GAME_WIDTH)x=TankWarClient.GAME_WIDTH-30; if(y+Tank.HEIGHT>TankWarClient.GAME_HEIGHT)y=TankWarClient.GAME_HEIGHT-30; if(!good) { Direction[]dirs=Direction.values();//将枚举类型转化成数组; if(step==0) { step=r.nextInt(12)+3; intrn=r.nextInt(dirs.length);//产生length以内随机的整数; dir=dirs[rn]; } step--; if(r.nextInt(40)>20)this.fire();//使敌军坦克发射子弹; } } /** *处理按键 *@parame键盘事件; */ publicvoidKeyPressed(KeyEvente) { intkey=e.getKeyCode(); switch(key) { caseKeyEvent.VK_LEFT: bL=true; break; caseKeyEvent.VK_RIGHT: bR=true; break; caseKeyEvent.VK_UP: bU=true; break; caseKeyEvent.VK_DOWN: bD=true; break; } locationDir(); } publicvoidkeyReleased(KeyEvente){ intkey=e.getKeyCode(); switch(key) { caseKeyEvent.VK_CONTROL: fire(); break; caseKeyEvent.VK_LEFT: bL=false; break; caseKeyEvent.VK_RIGHT: bR=false; break; caseKeyEvent.VK_UP: bU=false; break; caseKeyEvent.VK_DOWN: bD=false; break; caseKeyEvent.VK_A: superFire(); break; caseKeyEvent.VK_F2: reBorn(); break; } locationDir(); } /** *发射子弹 *@return返回子弹类型 */ publicMissilefire(){ if(!live) returnnull; intmx=this.x+Tank.WIDTH/2-Missile.WIDTH/2;//计算子弹发射的位置; intmy=this.y+Tank.HEIGHT/2-Missile.HEIGHT/2; Missilem=newMissile(mx,my,good,ptDir,this.tc);////根据炮筒方向发射子弹 tc.missiles.add(m); returnm; } publicMissilefire(Directiondir) { if(!live) returnnull; intmx=this.x+Tank.WIDTH/2-Missile.WIDTH/2; intmy=this.y+Tank.HEIGHT/2-Missile.HEIGHT/2; Missilem=newMissile(mx,my,good,dir,this.tc);//根据坦克的方向发射子弹; tc.missiles.add(m); returnm; } publicvoidsuperFire() { Direction[]dirs=Direction.values(); for(inti=0;i<8;i++) { fire(dirs[i]); } } publicvoidlocationDir() { if(bL&&!bU&&!bR&&!bD) dir=Direction.L; elseif(bL&&bU&&!bR&&!bD) dir=Direction.LU; elseif(!bL&&bU&&!bR&&!bD) dir=Direction.U; elseif(!bL&&bU&&bR&&!bD) dir=Direction.RU; elseif(!bL&&!bU&&bR&&!bD) dir=Direction.R; elseif(!bL&&!bU&&bR&&bD) dir=Direction.RD; elseif(!bL&&!bU&&!bR&&bD) dir=Direction.D; elseif(bL&&!bU&&!bR&&bD) dir=Direction.LD; elseif(!bL&&!bU&&!bR&&!bD) dir=Direction.STOP; } publicRectanglegetRect()//获取tank的矩形区域 { returnnewRectangle(this.x,this.y,this.WIDTH,this.HEIGHT); } /** *坦克撞墙 *@paramw墙 *@returntrue撞上,false未撞上; */ publicbooleancolliedsWithWall(Wallw) { if(this.live&&this.getRect().intersects(w.getRect())) { this.stay(); returntrue; } returnfalse; } /** *处理坦克与坦克相撞,防止其互相穿越; *@paramtanks敌军坦克; *@returntrue撞上,false未撞上; */ publicbooleancolliedsWithTanks(java.util.List<Tank>tanks) { for(inti=0;i<tanks.size();i++) { Tankt=tanks.get(i); if(this!=t) { if(this.live&&this.isLive()&&this.getRect().intersects(t.getRect())) { this.stay();//返回上一步的位置; t.stay();////返回上一步的位置 returntrue; } } } returnfalse; } privatevoidstay() { x=oldX; y=oldY; } /** *为Tank的内部类;血条,显示在我方坦克的头顶上; *@authorHekangmin * */ privateclassBloodBar { publicvoiddraw(Graphicsg) { Colorc=g.getColor(); g.setColor(Color.RED); g.drawRect(x,y-10,WIDTH,10); intw=WIDTH*life/100; g.fillRect(x,y-10,w,10); } } /** *吃到血块加血; *@paramb血块 *@returntrue吃到,false未吃到; */ publicbooleaneat(Bloodb) { if(this.live&&b.isLive()&&this.getRect().intersects(b.getRect())) { this.life=100; b.setLive(false); returntrue; } returnfalse; } /** *我军坦克死后复活; */ publicvoidreBorn() { if(this.isGood()&&!this.isLive()) { this.setLive(true); this.setLife(100); } } }
TankWarClient.java
packagecom.hkm.TankWar; importjava.awt.*; importjava.awt.event.*; importjava.util.List; importjava.util.ArrayList; /** *这个是游戏的运行窗口; *@authorHekangmin * */ publicclassTankWarClientextendsFrame{ /** *游戏窗口的宽度; */ publicstaticfinalintGAME_WIDTH=800; /** *游戏窗口的高度; */ publicstaticfinalintGAME_HEIGHT=600; TankMyTank=newTank(700,400,true,Tank.Direction.STOP,this); List<Tank>tanks=newArrayList<Tank>(); List<Explode>explodes=newArrayList<Explode>(); List<Missile>missiles=newArrayList<Missile>(); Wallw1=newWall(300,200,20,200,this); Wallw2=newWall(600,300,30,150,this); Bloodb=newBlood(); /** *画一张虚拟图片; */ ImageOffScreenImage=null; publicTankWarClient(Stringname)//设置文字 { super(name); } /** *运行窗口; */ publicvoidlaunchFrame() { for(inti=0;i<10;i++)//添加十辆敌军坦克 { tanks.add(newTank(50+40*(i+1),50,false,Tank.Direction.D,this)); } this.setBounds(200,100,GAME_WIDTH,GAME_HEIGHT); this.setBackground(Color.GREEN); this.addWindowListener(newWindowAdapter()//匿名类 { publicvoidwindowClosing(WindowEvente) { System.exit(0); } }); this.addKeyListener(newKeyMonitor());//加入键盘监听器; this.setResizable(false);//不可改变窗口的大小; this.setVisible(true); newThread(newPaintThread()).start();//新建一个线程; } publicvoidpaint(Graphicsg) { g.drawString("Missilecount:"+missiles.size(),10,50);//显示字符串; g.drawString("Explodescount:"+explodes.size(),10,70); g.drawString("tankscount:"+tanks.size(),10,90); g.drawString("Mytanklife:"+MyTank.getLife(),10,110); /** *画出墙; */ w1.draw(g); w2.draw(g); /** *检测子弹与各类的事情; */ for(inti=0;i<missiles.size();i++) { Missilem=missiles.get(i); m.hitsWall(w1); m.hitsWall(w2); m.hitTanks(tanks); m.hitTank(MyTank); m.draw(g); //if(!m.isLive()) //missiles.remove(m); //elsem.draw(g); } /** *画出爆炸; */ for(inti=0;i<explodes.size();i++) { Explodee=explodes.get(i); e.draw(g); } for(inti=0;i<tanks.size();i++) { Tankt=tanks.get(i); t.colliedsWithWall(w1); t.colliedsWithWall(w2); t.colliedsWithTanks(tanks); t.draw(g); } b.draw(g); MyTank.eat(b); MyTank.draw(g); } /** *利用双缓冲技术消除坦克闪烁的现象; */ publicvoidupdate(Graphicsg)//g为画在屏幕上的画笔; { if(OffScreenImage==null) OffScreenImage=this.createImage(GAME_WIDTH,GAME_HEIGHT); GraphicsgOffScreen=OffScreenImage.getGraphics();//gOffScreen是OffScreenImage的画笔; Colorc=gOffScreen.getColor(); gOffScreen.setColor(Color.GREEN); gOffScreen.fillRect(0,0,GAME_WIDTH,GAME_HEIGHT); gOffScreen.setColor(c); paint(gOffScreen);//画在虚拟图片上; g.drawImage(OffScreenImage,0,0,null);//用g画笔将虚拟图片上的东西画在屏幕上 } privateclassPaintThreadimplementsRunnable{ publicvoidrun(){ while(true) { repaint();//这里的repaint方法是Frame类的 try{ Thread.sleep(100); }catch(InterruptedExceptione){ e.printStackTrace(); } } } } privateclassKeyMonitorextendsKeyAdapter { publicvoidkeyReleased(KeyEvente){ MyTank.keyReleased(e); } publicvoidkeyPressed(KeyEvente){ MyTank.KeyPressed(e); } } publicstaticvoidmain(String[]args){ newTankWarClient("MyTankWorld").launchFrame(); } }
Wall.java
packagecom.hkm.TankWar; importjava.awt.*; /** *生成阻碍物墙这个类; *@authorHekangmin * */ publicclassWall{ /** *x,y为墙的位置,w,h为宽度高度; */ intx,y,w,h; /** *持有引用 */ TankWarClienttc; publicWall(intx,inty,intw,inth,TankWarClienttc){ this.x=x; this.y=y; this.w=w; this.h=h; this.tc=tc; } publicvoiddraw(Graphicsg) { Colorc=g.getColor(); g.setColor(Color.GRAY); g.fillRect(x,y,w,h); g.setColor(c); } /** *得到墙的矩形区域; *@return */ publicRectanglegetRect() { returnnewRectangle(x,y,w,h); } }
以上所述就是本文的全部内容了,希望大家能够喜欢。