java写的坦克大战简易版
- 格式:docx
- 大小:68.67 KB
- 文档页数:26
package com.cwj.tankGame;import javax.sound.sampled.*;import java.io*;import java.awt.*;import java.io.IOException;import java.util.*;import javax.swing,*;import javax.imageio.ImageIO;import javax.swing.*;class AePlayWave extends Thread {private String filename;public AePlayWave(String wavfile) {filename = wavfile;}public void run() {File soundFile = new File(filename);AudioInputStream audioInputStream = null;try {audioInputStream = AudioSystem.getAudioInputStream(soundFile);} catch (Exception e1) {e1.printStackTrace();return;}AudioFormat format = audioInputStream.getFormat(); SourceDataLine auline = null; info = new (SourceDataLine.class, format); try {auline = (SourceDataLine) AudioSystem.getLine(info);auline.open(format);} catch (Exception e) {e.printStackTrace();return;}auline.start();int nBytesRead = 0;//这是缓冲byte[] abData = new byte[512];try {while (nBytesRead != -1) {nBytesRead = audioInputStream.read(abData, 0, abData.length); if (nBytesRead >= 0)auline.write(abData, 0, nBytesRead);}} catch (IOException e) {e.printStackTrace();return;} finally {auline.drain();auline.close();}}}class Bomb{int x;int y;int lifeTime = 10;boolean isLive=true;public Bomb(int x,int y){this.x=x;this.y=y;}public void lifeDown(){if(lifeTime>0){lifeTime--;}else{this.isLive=false;}}}class EnemyTank extends Tank implements Runnable{int n=1;//敌方坦克转弯n次发射一颗子弹int MaxShot = 10;int runDistance = 10;//变一次方向前进的距离//定义一个向量可以访问MyPanel上所有地方坦克Vector<EnemyTank> ets =new Vector<EnemyTank>();Vector<Shot> ss = new Vector<Shot>();public void setEts(Vector<EnemyTank> v){this.ets=v;}public int abs(int x){if(x>0)return x;elsereturn -x;}public boolean isTouchOther(){switch(this.direction){case 0://上for(int i=0;i<ets.size();i++){EnemyTank t = ets.get(i);if(t!=this)//不是自己这辆坦克{if(abs(this.x-t.x)<=40&&this.y>t.y&&this.y-t.y<=40) {return true;}}}break;case 2://下for(int i=0;i<ets.size();i++){EnemyTank t = ets.get(i);if(t!=this)//不是自己这辆坦克{if(abs(this.x-t.x)<=40&&t.y>this.y&&t.y-this.y<=40) {return true;}}}break;case 1://左for(int i=0;i<ets.size();i++){EnemyTank t = ets.get(i);if(t!=this)//不是自己这辆坦克{if(abs(this.y-t.y)<=40&&this.x>t.x&&this.x-t.x<=40) {return true;}}}break;case 3://右for(int i=0;i<ets.size();i++){EnemyTank t = ets.get(i);if(t!=this)//不是自己这辆坦克{if(abs(this.y-t.y)<=40&&this.x<t.x&&t.x-this.x<=40) {return true;}}}break;}return false;}public EnemyTank(int x,int y){super(x,y);}int time=0;public void sleep(){try{Thread.sleep(50);}catch(Exception e){e.printStackTrace();}}public void run() {while(true){switch(direction){case 0:for(int i =0;i<this.runDistance;i++){if(y>20&&!this.isTouchOther())y-=speed;this.sleep();}break; case 1:for(int i =0;i<this.runDistance;i++){if(x>20&&!this.isTouchOther())x-=speed;this.sleep();}break; case 2:for(int i =0;i<this.runDistance;i++){if(y<580&&!this.isTouchOther())y+=speed;this.sleep();}break; case 3:for(int i =0;i<this.runDistance;i++){if(x<780&&!this.isTouchOther())x+=speed;this.sleep();}break; }this.direction=(int)(Math.random()*4);if(this.isLive==false){break;}else{time++;if(time%n==0)if(ss.size()<MaxShot){Shot s = new Shot(x,y);s.setDirection(direction);ss.add(s);Thread t = new Thread(s);t.start();}}}}}class MyTank extends Tank{int MAXSHOT=20;public int getMAXSHOT() {return MAXSHOT;}public void setMAXSHOT(int mAXSHOT) { MAXSHOT = mAXSHOT;}Shot shot=null;Vector<Shot> ss = new Vector<Shot>(); public MyTank(int x,int y){super(x,y);}public void fire(){if(this.isLive==true){shot = new Shot(x,y);ss.add(shot);Thread t = new Thread(shot);t.start();shot.setDirection(this.direction);}}public void moveUp(){if(y>20)y-=speed;}public void moveLeft(){if(x>20)x-=speed;}public void moveDown(){if(y<580)y+=speed;}public void moveRight(){if(x<780)x+=speed;}class Node {int x;public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public int getDirection() {return direction;}public void setDirection(int direction) { this.direction = direction;}int y;int direction;public Node(int x,int y){this.x=x;this.y=y;}}class Record {//记录每关有多少敌人private static int etNum=20;private static int sum = 0;private static FileWriter fw=null;private static BufferedWriter bw = null; private static FileReader fr = null; private static BufferedReader br = null; private static Vector<Node> nodes=null; public static Vector<Node> getNodes() { return nodes;public static void setNodes(Vector<Node> nodes) { Record.nodes = nodes;}public static Vector<EnemyTank> ets = null;public static Vector<EnemyTank> getEts() {return ets;}public static void setEts(Vector<EnemyTank> ets) { Record.ets = ets;}public static void restoreRecord(){try {nodes = new Vector<Node>();File file = new File("e:\\tankGame.txt");if(!file.isDirectory()){if(file.createNewFile())System.out.println("成功创建文件e:\\tankGame.txt"); }fr = new FileReader("e:\\tankGame.txt");br = new BufferedReader(fr);String strSum = br.readLine();if(strSum!=null)sum = Integer.parseInt(strSum);else return;String str="";while((str=br.readLine())!=null){String []xyd=str.split(" ");int x,y,direction;x = Integer.parseInt(xyd[0]);y = Integer.parseInt(xyd[1]);direction = Integer.parseInt(xyd[2]);Node node = new Node(x,y);node.setDirection(direction);nodes.add(node);}for(int i=0;i<nodes.size();i++){System.out.println(nodes.get(i).x+" "+nodes.get(i).y+" "+nodes.get(i).direction); }} catch (Exception e) {e.printStackTrace();}finally{try {if(br!=null)br.close();if(fr!=null)fr.close();} catch (IOException e) {e.printStackTrace();}}}public static void keepRecord(){try {fw = new FileWriter("e:\\tankGame.txt");bw = new BufferedWriter(fw);bw.write(sum+"\r\n");for(int i =0;i<ets.size();i++){EnemyTank et = ets.get(i);if(et.isLive==true){String record = et.x+" "+et.y+" "+et.getDirection()+"\r\n";bw.write(record);}}} catch (Exception e) {e.printStackTrace();}finally{try {if(bw!=null)bw.close();if(fw!=null)fw.close();} catch (IOException e) {e.printStackTrace();}}}public static int getSum() {return sum;}public static void setSum(int sum) { Record.sum = sum;}public static void addSum(){sum++;}public static int getEtNum() {return etNum;}public static void setEtNum(int etNum) { Record.etNum = etNum;}public static int getMyLife() {return myLife;}public static void setMyLife(int myLise) { Record.myLife = myLise;}//生命数private static int myLife=3;public static void reduceEtNum(){etNum--;}public static void reduceMyLife(){myLife--;}}class Shot implements Runnable{int x;int speed=5;int y;int direction;boolean isLive=true;public void run(){while(true){try{Thread.sleep(100);}catch(Exception e){e.printStackTrace();}switch(this.direction){case 0:y-=speed;break;case 1:x-=speed;break;case 2:y+=speed;break;case 3:x+=speed;break;}if(x<0||x>800||y<0||y>600){this.isLive=false;break;}}//while}public int getSpeed() {return speed;}public void setSpeed(int speed) { this.speed = speed;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public int getDirection() {return direction;}public void setDirection(int direction) { this.direction = direction;}public Shot(int x,int y){this.x=x;this.y=y;}}class Tank{boolean isLive=true;int x=0;int y=0;int color;public int getColor() {return color;}public void setColor(int color) {this.color = color;}int speed=3;int direction=0;//0上1左2下3右public int getSpeed() {return speed;}public void setSpeed(int speed) { this.speed = speed;}public int getDirection() {return direction;}public void setDirection(int direction) { this.direction = direction;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public Tank(int x,int y){this.x=x;this.y=y;}}public class TankGame extends JFrame implements ActionListener{ MyPanel mp=null;MyStartPanel msp = null;JMenuBar jmb =null;JMenu jm1=null;JMenuItem jmi11 =null;JMenuItem jmi12 = null;JMenuItem jmi13 = null;JMenuItem jmi14 = null;public static void main(String[]args){TankGame t = new TankGame();}public TankGame(){/*mp=new MyPanel();this.add(mp);Thread t = new Thread(mp);t.start();this.addKeyListener(mp);*/jmb = new JMenuBar();jm1 = new JMenu("游戏(G)");jm1.setMnemonic('G');jmi11 = new JMenuItem("开始游戏(N)");jmi11.addActionListener(this);jmi11.setActionCommand("newgame");jmi11.setMnemonic('N');jmi12 = new JMenuItem("退出游戏(E)");jmi12.addActionListener(this);jmi12.setActionCommand("exitgame");jmi12.setMnemonic('E');jmi13 = new JMenuItem("退出并保存(O)");jmi13.addActionListener(this);jmi13.setActionCommand("exitandsave");jmi13.setMnemonic('O');jmi14 = new JMenuItem("继续游戏(S)");jmi14.addActionListener(this);jmi14.setActionCommand("continue");jmi14.setMnemonic('S');jm1.add(jmi11);jm1.add(jmi13);jm1.add(jmi14);jm1.add(jmi12);jmb.add(jm1);this.setJMenuBar(jmb);msp = new MyStartPanel();Thread t = new Thread(msp);t.start();this.add(msp);this.setSize(900, 700);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setTitle("坦克大战欢迎加qq1036624975交流学习编程爱好者学习交流群294787264");this.setVisible(true);}public void actionPerformed(ActionEvent e) {if(e.getActionCommand().equals("newgame")){if(mp!=null)this.remove(mp);mp = new MyPanel("newGame");Thread t = new Thread(mp);t.start();this.remove(msp);this.add(mp);this.addKeyListener(mp);this.setVisible(true);AePlayWave apw = new AePlayWave("e://tank.wav"); new Thread(apw).start();}else if(e.getActionCommand().equals("exitgame")){System.exit(0);}else if(e.getActionCommand().equals("exitandsave")) {Record.setEts(mp.et);Record.keepRecord();System.exit(0);}else if(e.getActionCommand().equals("continue")){Record.restoreRecord();if(mp!=null)this.remove(mp);mp = new MyPanel("oldGame");Thread t = new Thread(mp);t.start();this.remove(msp);this.add(mp);this.addKeyListener(mp);this.setVisible(true);}}}class MyStartPanel extends JPanel implements Runnable {int count=0;public void paint(Graphics g){super.paint(g);g.fillRect(0, 0, 800, 600);if(count%6==0)g.setColor(Color.YELLOW);else if(count%6==1)g.setColor(Color.BLUE);else if(count%6==2)g.setColor(Color.CYAN);else if(count%6==3)g.setColor(Color.GREEN);else if(count%6==4)g.setColor(Color.ORANGE);else if(count%6==5)g.setColor(Color.PINK);g.setFont(new Font("黑体",Font.PLAIN,100));g.drawString("第一关",250,300);g.setFont(new Font("黑体",Font.PLAIN,20));g.drawString("w上s下a左d右j发射子弹", 0, 20);if(count>20000)count=0;}public void run() {while(true){try {Thread.sleep(300);} catch (Exception e) {e.printStackTrace();}count++;this.repaint();}}}class MyPanel extends JPanel implements KeyListener,Runnable {Image bomb1=null;Image bomb2=null;Image bomb3=null;MyTank mt = null;//我的坦克Vector<EnemyTank>et=new Vector<EnemyTank>();Vector<Bomb>bombs = new Vector<Bomb>();Vector<Node>nodes =null;int enemyTankNum=20;public MyPanel(String ifNew){Record.restoreRecord();mt = new MyTank(300,570);mt.setSpeed(7);mt.setColor(0);//初始化敌人的坦克if(ifNew.equals("newGame")){for(int i =0;i<enemyTankNum;i++){EnemyTank tank = null;if(i<10){tank=new EnemyTank((i+1)*70,20);}else{tank = new EnemyTank(((i-9))*70,80);}tank.setDirection(2);Thread t = new Thread(tank);t.start();Shot s = new Shot(tank.x,tank.y);s.setDirection(tank.direction);new Thread(s).start();tank.ss.add(s);tank.setColor(1);et.add(tank);tank.setEts(et);}}else if(ifNew.equals("oldGame")){nodes=Record.getNodes();for(int i =0;i<nodes.size();i++){Node node = nodes.get(i);EnemyTank tank = null;tank = new EnemyTank(node.getX(),node.getY()); tank.setDirection(node.getDirection());Thread t = new Thread(tank);t.start();Shot s = new Shot(tank.x,tank.y);s.setDirection(tank.direction);new Thread(s).start();tank.ss.add(s);tank.setColor(1);et.add(tank);tank.setEts(et);}}//三张图片,组成一颗炸弹try {bomb1=ImageIO.read(new File("image/bomb_1.gif"));bomb2=ImageIO.read(new File("image/bomb_2.gif"));bomb3=ImageIO.read(new File("image/bomb_3.gif"));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//以下方式加载图片第一次爆炸效果不明显/*bomb1=Toolkit.getDefaultToolkit().getImage("image/bomb_1.gif"); bomb2=Toolkit.getDefaultToolkit().getImage("image/bomb_2.gif"); bomb3=Toolkit.getDefaultToolkit().getImage("image/bomb_3.gif");*/ }public void showMessage(Graphics g){this.paintTank(825, 20, g, 0, 1);this.paintTank(825, 80, g, 0, 0);g.setColor(Color.BLACK);g.drawString("x"+Record.getEtNum(),850,20);g.drawString("x"+Record.getMyLife(), 850, 80);g.setFont(new Font("华文彩云",Font.BOLD,20));g.drawString("总成绩", 2, 620);g.drawString(""+Record.getSum(), 76, 620);}public void paint(Graphics g){super.paint(g);g.fillRect(0, 0, 800, 600);this.showMessage(g);if(mt.isLive==true)paintTank(mt.getX(),mt.getY(),g,mt.getDirection(),mt.getColor());//画敌人坦克for(int i=0;i<et.size();i++){EnemyTank t = et.get(i);if(t.isLive==true){paintTank(t.getX(),t.getY(),g,t.getDirection(),t.getColor());for(int j = 0;j<t.ss.size();j++)//画子弹{if(s.isLive==true){g.setColor(Color.RED);g.fillRect(s.getX(), s.getY(), 5,5);}else{t.ss.remove(s);}}}else{et.remove(t);}}//爆炸效果for(int i=0;i<bombs.size();i++){Bomb b = bombs.get(i);if(b.lifeTime>6){g.drawImage(bomb1,b.x,b.y,40,40,this);}else if(b.lifeTime>3){g.drawImage(bomb2,b.x,b.y,40,40,this);}else{g.drawImage(bomb3,b.x,b.y,40,40,this);}b.lifeDown();if(b.lifeTime==0){bombs.remove(b);}}for(int i =0;i<mt.ss.size();i++)//我的画子弹{Shot s = mt.ss.get(i);if(s!=null&&s.isLive==true){g.setColor(Color.YELLOW);g.fillRect(s.getX(), s.getY(),5, 5);}if(s.isLive==false) //子弹清空,才能打下一发子弹{}}}//被攻击public void hitMyTank(){for(int i=0;i<et.size();i++){EnemyTank e=et.get(i);for(int j=0;j<e.ss.size();j++){Shot enemyShot = e.ss.get(j); boolean res=false;res = this.isHitTank(enemyShot, mt); if(res==true)Record.reduceMyLife();}}}//攻击敌方坦克public void hitEnemyTank(){for(int i=0;i<mt.ss.size();i++){Shot shot = mt.ss.get(i);if(shot.isLive==true){for(int j =0;j<et.size();j++){EnemyTank etank = et.get(j);if(etank.isLive==true){boolean res=false;res=this.isHitTank(shot, etank);if(res==true){Record.reduceEtNum();Record.addSum();}}}}}}//判断子弹是否击中坦克public boolean isHitTank(Shot shot,Tank etank){boolean res=false;if(shot.x>etank.x-20&&shot.x<etank.x+20&&shot.y>etank.y-20&&shot.y<etank.y+20&&et ank.isLive==true)//子弹击中{shot.isLive=false;etank.isLive=false;Bomb bomb = new Bomb(etank.getX()-20,etank.getY()-20);bombs.add(bomb);res = true;}return res;}public void paintTank(int x,int y,Graphics g,int direction,int type){switch(type)//判断坦克类型{case 0:g.setColor(Color.yellow);//自己的break;case 1:g.setColor(Color.RED);//敌人的break;}switch(direction){case 0://上g.fillRect(x-20, y-20, 40, 40);g.fill3DRect(x-5, y-20, 10, 20,false);break;case 1://左g.fillRect(x-20, y-20, 40, 40);g.fill3DRect(x-20, y-5, 20, 10,false);break;case 2://下g.fillRect(x-20, y-20, 40, 40);g.fill3DRect(x-5, y, 10, 20,false);break;case 3://右g.fillRect(x-20, y-20, 40, 40);g.fill3DRect(x, y-5, 20, 10,false);break;}}@Overridepublic void keyTyped(KeyEvent e) {// TODO Auto-generated method stub}@Overridepublic void keyPressed(KeyEvent e) {// TODO Auto-generated method stubif(e.getKeyCode()==KeyEvent.VK_J)//发射子弹{if(this.mt.ss.size()<this.mt.getMAXSHOT()) {this.mt.fire();}}if(e.getKeyCode()==KeyEvent.VK_W){mt.setDirection(0);this.mt.moveUp();}else if(e.getKeyCode()==KeyEvent.VK_A) {mt.setDirection(1);this.mt.moveLeft();}else if(e.getKeyCode()==KeyEvent.VK_S) {mt.setDirection(2);this.mt.moveDown();}else if(e.getKeyCode()==KeyEvent.VK_D) {mt.setDirection(3);this.mt.moveRight();}this.repaint();}@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){try {Thread.sleep(50);//50毫秒重绘一次} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.hitEnemyTank();//判断己方坦克是否击中敌方坦克this.hitMyTank();//判断敌方坦克是否击中己方坦克this.repaint();}}}。
importjava.awt.*;importjavax.swing.*;importimportclassfextendsJFrame{f(Stringtitle){this.setTitle(title);this.setSize(608,630);this.setLocation(300,100);this.setBackground(Color.BLACK); MyTankmp=newMyTank();this.add(mp);this.addKeyListener(mp); newThread(mp).start();}publicstaticvoidmain(String[]args){ fh=newf("坦克大战(版本1.0)");h.setVisible(true);}}//主战坦克//子弹intdx=295,dy=295;intdx1=295,dy1=-10;intdx2=600,dy2=295;intdx3=295,dy3=600;intdx4=-10,dy4=295;//敌军坦克intnum=10;//敌军坦克数量,不能修改int[]xf=newint[num];int[]yf=newint[num];int[]opf=newint[num];int[]dxf=newint[num];int[]dyf=newint[num];int[]dxf1=newint[num];int[]dyf2=newint[num];int[]dxf3=newint[num];int[]dyf3=newint[num];int[]dxf4=newint[num];int[]dyf4=newint[num];//构造函数,初始化敌军坦克的位置和状态MyTank(){for(inti=0;i<num;i++){xf[i]=(int)(Math.random()*560);yf[i]=(int)(Math.random()*560);dxf[i]=xf[i]+15;dyf[i]=yf[i]+15;}for(inti=0;i<num;i++){dxf1[i]=295;dyf1[i]=-10;dxf2[i]=600;dyf2[i]=295;dxf3[i]=295;dyf3[i]=600;dxf4[i]=-10;dyf4[i]=295;}}//主面版publicvoidpaint(Graphicsg){switch(color%6){case0:g.setColor(Color.blue);break; case1:g.setColor(Color.yellow);break; case2:g.setColor(Color.red);break; case3:g.setColor(Color.orange);break; case4:g.setColor(Color.green);break; case5:g.setColor(Color.black);break; }g.fillOval(x-5,y-5,10,10);g.fillOval(x-5,y+5,10,10);g.fillOval(x-5,y+15,10,10);g.fillOval(x-5,y+25,10,10);g.fillOval(x-5,y+35,10,10);g.fillOval(x+35,y+35,10,10);g.setColor(Color.black);g.fillRect(x+15,y-20,10,40);switch(color%20){case0:g.setColor(Color.white);break; case1:g.setColor(Color.white);break; case2:g.setColor(Color.white);break; case3:g.setColor(Color.white);break; case4:g.setColor(Color.white);break; case5:g.setColor(Color.white);break; case6:g.setColor(Color.white);break; case7:g.setColor(Color.white);break; case8:g.setColor(Color.white);break; case9:g.setColor(Color.white);break;case10:g.setColor(Color.black);break; case11:g.setColor(Color.black);break; case12:g.setColor(Color.black);break; case13:g.setColor(Color.black);break; case14:g.setColor(Color.black);break; case15:g.setColor(Color.black);break;}}g.fillRect(x,y,40,40);switch(color%6){case0:g.setColor(Color.blue);break; case1:g.setColor(Color.yellow);break; case2:g.setColor(Color.red);break; case3:g.setColor(Color.orange);break; case4:g.setColor(Color.green);break; case5:g.setColor(Color.black);break; }g.fillOval(x-5,y-5,10,10);g.fillOval(x+5,y-5,10,10);g.fillOval(x+15,y-5,10,10);g.fillOval(x+25,y-5,10,10);g.fillOval(x+25,y+35,10,10);g.fillOval(x+35,y+35,10,10);g.setColor(Color.black);g.fillRect(x+20,y+15,40,10);switch(color%20){case0:g.setColor(Color.white);break; case1:g.setColor(Color.white);break; case2:g.setColor(Color.white);break; case3:g.setColor(Color.white);break; case4:g.setColor(Color.white);break; case5:g.setColor(Color.white);break; case6:g.setColor(Color.white);break; case7:g.setColor(Color.white);break; case8:g.setColor(Color.white);break;case9:g.setColor(Color.white);break; case10:g.setColor(Color.black);break; case11:g.setColor(Color.black);break; case12:g.setColor(Color.black);break; case13:g.setColor(Color.black);break; case14:g.setColor(Color.black);break;}}g.setColor(Color.blue);g.fillRect(x,y,40,40);switch(color%6){case0:g.setColor(Color.blue);break; case1:g.setColor(Color.yellow);break; case2:g.setColor(Color.red);break; case3:g.setColor(Color.orange);break; case4:g.setColor(Color.green);break; case5:g.setColor(Color.black);break; }g.fillOval(x-5,y-5,10,10);g.fillOval(x-5,y+5,10,10);g.fillOval(x-5,y+15,10,10);g.fillOval(x+35,y+15,10,10);g.fillOval(x+35,y+25,10,10);g.fillOval(x+35,y+35,10,10);g.setColor(Color.black);g.fillRect(x+15,y+20,10,40);switch(color%20){case0:g.setColor(Color.white);break; case1:g.setColor(Color.white);break; case2:g.setColor(Color.white);break; case3:g.setColor(Color.white);break; case4:g.setColor(Color.white);break; case5:g.setColor(Color.white);break; case6:g.setColor(Color.white);break; case7:g.setColor(Color.white);break;case8:g.setColor(Color.white);break; case9:g.setColor(Color.white);break; case10:g.setColor(Color.black);break; case11:g.setColor(Color.black);break; case12:g.setColor(Color.black);break; case13:g.setColor(Color.black);break;}}if(op==4){g.setColor(Color.yellow);g.fillRect(x,y,40,40);switch(color%6){case0:g.setColor(Color.blue);break; case1:g.setColor(Color.yellow);break; case2:g.setColor(Color.red);break; case3:g.setColor(Color.orange);break; case4:g.setColor(Color.green);break; case5:g.setColor(Color.black);break; }g.fillOval(x-5,y-5,10,10);g.fillOval(x+5,y-5,10,10);g.fillOval(x+5,y+35,10,10);g.fillOval(x+15,y+35,10,10);g.fillOval(x+25,y+35,10,10);g.fillOval(x+35,y+35,10,10);g.setColor(Color.black);g.fillRect(x-20,y+15,40,10);switch(color%20){case0:g.setColor(Color.white);break; case1:g.setColor(Color.white);break; case2:g.setColor(Color.white);break; case3:g.setColor(Color.white);break; case4:g.setColor(Color.white);break; case5:g.setColor(Color.white);break; case6:g.setColor(Color.white);break;case7:g.setColor(Color.white);break; case8:g.setColor(Color.white);break; case9:g.setColor(Color.white);break; case10:g.setColor(Color.black);break; case11:g.setColor(Color.black);break; case12:g.setColor(Color.black);break;}}g.setColor(Color.black);g.fillOval(dx,dy,10,10);g.fillOval(dx1,dy1,10,10);g.fillOval(dx2,dy2,10,10);g.fillOval(dx3,dy3,10,10);g.fillOval(dx4,dy4,10,10);for(inti=0;i<num;i++){if(opf[i]==1){g.fillRect(xf[i],yf[i],40,40);g.fillOval(xf[i]-5,yf[i]-5,10,10); g.fillOval(xf[i]-5,yf[i]+5,10,10); g.fillOval(xf[i]-5,yf[i]+15,10,10);g.fillOval(xf[i]+35,yf[i]+15,10,10);g.fillOval(xf[i]+35,yf[i]+25,10,10);g.fillOval(xf[i]+35,yf[i]+35,10,10);g.fillRect(xf[i]+15,yf[i]-20,10,40);g.fillOval(xf[i]+5,yf[i]+30,10,10);g.fillOval(xf[i]+25,yf[i]+30,10,10); }if(opf[i]==2){g.fillRect(xf[i],yf[i],40,40);g.fillOval(xf[i]-5,yf[i]-5,10,10); g.fillOval(xf[i]+5,yf[i]-5,10,10); g.fillOval(xf[i]+15,yf[i]-5,10,10);g.fillOval(xf[i]+25,yf[i]-5,10,10);g.fillOval(xf[i]+35,yf[i]-5,10,10);g.fillOval(xf[i]-5,yf[i]+35,10,10);g.fillOval(xf[i]+5,yf[i]+35,10,10);g.fillOval(xf[i]+15,yf[i]+35,10,10);g.fillOval(xf[i]+25,yf[i]+35,10,10);g.fillOval(xf[i]+35,yf[i]+35,10,10);g.fillRect(xf[i]+20,yf[i]+15,40,10);}g.fillOval(xf[i]+35,yf[i]-5,10,10);g.fillOval(xf[i]+35,yf[i]+5,10,10);g.fillOval(xf[i]+35,yf[i]+15,10,10);g.fillOval(xf[i]+35,yf[i]+25,10,10);g.fillOval(xf[i]+35,yf[i]+35,10,10);g.fillRect(xf[i]+15,yf[i]+20,10,40);g.fillOval(xf[i]+5,yf[i],10,10);g.fillOval(xf[i]+25,yf[i],10,10);}if(opf[i]==4){g.fillRect(xf[i],yf[i],40,40);g.fillOval(xf[i]-5,yf[i]-5,10,10); g.fillOval(xf[i]+5,yf[i]-5,10,10);g.fillOval(xf[i]+5,yf[i]+35,10,10); g.fillOval(xf[i]+15,yf[i]+35,10,10);g.fillOval(xf[i]+25,yf[i]+35,10,10);g.fillOval(xf[i]+35,yf[i]+35,10,10);g.fillRect(xf[i]-20,yf[i]+15,40,10);g.fillOval(xf[i]+30,yf[i]+5,10,10); g.fillOval(xf[i]+30,yf[i]+25,10,10); }g.fillOval(dxf1[i],dyf1[i],10,10); g.fillOval(dxf2[i],dyf2[i],10,10); g.fillOval(dxf3[i],dyf3[i],10,10); g.fillOval(dxf4[i],dyf4[i],10,10);}}publicvoidkeyTyped(KeyEvente){}//键盘控制坦克的移动,发弹publicvoidkeyPressed(KeyEvente){ color++;if(e.getKeyCode()==KeyEvent.VK_UP){}}x=x+tankspeed;dx=dx+tankspeed;if(x>=560){x=x-tankspeed;dx=dx-tankspeed;}}if(e.getKeyCode()==KeyEvent.VK_DOWN){ op=3;y=y+tankspeed;dy=dy+tankspeed;if(y>=560){y=y-tankspeed;}if(e.getKeyCode()==KeyEvent.VK_LEFT){op=4;x=x-tankspeed;dx=dx-tankspeed;if(x<=0){x=x+tankspeed;dx=dx+tankspeed;}}if(e.getKeyCode()==KeyEvent.VK_SPACE){if(op==1){dx1=dx;dy1=dy;}if(op==2){dx2=dx;dy2=dy;}if(op==3){dx3=dx;dy3=dy;}if(op==4){dx4=dx;dy4=dy;}}}}dy3=dy3+tankbullet;dx4=dx4-tankbullet;for(inti=0;i<num;i++){dyf1[i]=dyf1[i]-tankfbullet;dxf2[i]=dxf2[i]+tankfbullet;dyf3[i]=dyf3[i]+tankfbullet;dxf4[i]=dxf4[i]-tankfbullet;}//判断是否被击中for(inti=0;i<num;i++){if(dyf1[i]<y+38&&dyf1[i]>y+8&&dxf1[i]-x>-10&&dxf1[i]-x<40){ ("被1击中");dxf1[i]=dxf[i];dyf1[i]=dyf[i];if(dxf2[i]>x+2&&dxf2[i]<x+32&&dyf2[i]-y>-10&&dyf2[i]-y<40){ ("被2击中");dxf2[i]=dxf[i];dyf2[i]=dyf[i];shengming=shengming-nandu;}if(dyf3[i]>y+2&&dyf3[i]<y+32&&dxf3[i]-x>-10&&dxf3[i]-x<40){ ("被3击中");dxf3[i]=dxf[i];dyf3[i]=dyf[i];shengming=shengming-nandu;}if(dxf4[i]>x+8&&dxf4[i]<x+38&&dyf4[i]-y>-10&&dyf4[i]-y<40){ ("被4击中");dxf4[i]=dxf[i];dyf4[i]=dyf[i];shengming=shengming-nandu;}}//判断是否击中敌军for(inti=0;i<num;i++){S("1击中");fenshu=fenshu+100;xf[i]=(int)(Math.random()*560);}}fenshu=fenshu+100;xf[i]=(int)(Math.random()*560);yf[i]=(int)(Math.random()*560);}if(dx4>xf[i]+8&&dx4<xf[i]+38&&dy4-yf[i]>-10&&dy4-yf[i]<40){ ("4击中");fenshu=fenshu+100;xf[i]=(int)(Math.random()*560);yf[i]=(int)(Math.random()*560);}dxf[i]=xf[i]+15;dyf[i]=yf[i]+15;}switch(opf[i]){case1:{yf[i]--;dyf[i]--;for(ints=0;s<num;s++){ if(yf[i]<=0){yf[i]++;dyf[i]++;}}break;}case2:{xf[i]++;dxf[i]++;for(ints=0;s<num;s++){if(xf[i]>=560){xf[i]--;dxf[i]--;}}break;}}}break;}case4:{xf[i]--;dxf[i]--;for(ints=0;s<num;s++){ if(xf[i]<=0){xf[i]++;dxf[i]++;}}break;}}try{Thread.sleep(20);}catch(Exceptione){e.printStackTrace();}//坦克的开火if(a%50==5){if(Math.random()>0.5){for(inti=0;i<2;i++){if(opf[i]==1){dxf1[i]=dxf[i];dyf1[i]=dyf[i]; }if(opf[i]==2){dxf2[i]=dxf[i];dyf2[i]=dyf[i]; }if(opf[i]==3){dxf3[i]=dxf[i];dyf3[i]=dyf[i]; }if(opf[i]==4){dxf4[i]=dxf[i];dyf4[i]=dyf[i]; }}}}}}if(opf[i]==3){dxf3[i]=dxf[i];dyf3[i]=dyf[i]; }if(opf[i]==4){dxf4[i]=dxf[i];dyf4[i]=dyf[i]; }}}}if(a%50==25){if(Math.random()>0.5){for(inti=4;i<6;i++){if(opf[i]==1){if(opf[i]==2){dxf2[i]=dxf[i];dyf2[i]=dyf[i]; }if(opf[i]==3){dxf3[i]=dxf[i];dyf3[i]=dyf[i]; }if(opf[i]==4){dxf4[i]=dxf[i];dyf4[i]=dyf[i]; }}}}if(a%50==35){if(Math.random()>0.5){for(inti=6;i<8;i++){if(opf[i]==1){dxf1[i]=dxf[i];dyf1[i]=dyf[i]; }if(opf[i]==2){dxf2[i]=dxf[i];dyf2[i]=dyf[i]; }}}}}}if(Math.random()>0.5){for(inti=8;i<10;i++){if(opf[i]==1){dxf1[i]=dxf[i];dyf1[i]=dyf[i]; }if(opf[i]==2){dxf2[i]=dxf[i];dyf2[i]=dyf[i]; }if(opf[i]==3){dxf3[i]=dxf[i];dyf3[i]=dyf[i]; }if(opf[i]==4){dxf4[i]=dxf[i];dyf4[i]=dyf[i]; }}//坦克的随机移动if(a%50==1){for(inti=0;i<2;i++){ if(Math.random()>0.5){ if(Math.random()>0.5){ opf[i]=1;}else{opf[i]=2;}}else{if(Math.random()>0.5){ opf[i]=3;}else{opf[i]=4;}}}}if(a%50==11){//坦克的随机移动}}else{opf[i]=4;}}}}if(a%50==21){//坦克的随机移动for(inti=4;i<6;i++){if(Math.random()>0.5){ if(Math.random()>0.5){ opf[i]=1;}else{opf[i]=2;}else{if(Math.random()>0.5){ opf[i]=3;}else{opf[i]=4;}}}}if(a%50==31){//坦克的随机移动for(inti=6;i<8;i++){if(Math.random()>0.5){ if(Math.random()>0.5){ opf[i]=1;}else{opf[i]=2;}}else{if(Math.random()>0.5){ opf[i]=3;}else{}}}}//opf[i]=1;}else{opf[i]=2;}}else{if(Math.random()>0.5){ opf[i]=3;}else{opf[i]=4;}}}}//重画//弹出player1胜利对话框JOptionPane.showMessageDialog(null, "你结束了!!!","GameOver!",JOptionPane.ERROR_MESSAGE); //结束游戏System.exit(0);}this.repaint();}}}。
Java课程设计任务书简单电子游戏坦克大战的设计1、主要内容:设计一个简单的坦克大战电子游戏,可以允许多位玩家在局域网中同时对战2、系统要求:游戏具有图形游戏界面,能让用户看到游戏所给出的反馈。
有人机交互功能,使用户操作指定的游戏元素,并且坦克具有生命值,能攻击敌方,无法攻击友方,而且坦克的攻击具有视觉效果!3、具体要求(包括技术要求等):1.需要有图形游戏界面,让用户能看到游戏给出的反馈2.有人机交互功能,使用户能操作指定的游戏元素3.不同队伍的坦克,须显示不同外观,已分辨敌我4.坦克能够开火,攻击敌方,但不能攻击队友5需要有不可被子弹穿透的墙6.坦克有生命值,并非被击中一次就会爆炸7游戏结束后可重新开始学习并掌握以下技术:Java、JavaBean 等熟练使用以下开发工具:Myeclipse 等实现系统上述的功能。
4、进度安排:12月28日~ 12月29日:课程设计选题,查找参考资料12月30日~ 1月1日:完成系统设计和数据库设计1月2日~ 1月4日:完成程序代码的编写1月4日~ 1月5日:系统测试与完善1月5日~ 1月6日:完成课程设计报告,准备答辩分工:随着计算机的普及以及对电子游戏的认识,电子游戏已被越来越多的人选作放松、娱乐的休闲方式;电子游戏既不需要专门购买游戏器材,也不需要宽阔的游戏场地,只需要一台能独立完成任务的计算机即可,它可以是人们工作、学习时用的计算机,并不需要另行配置,这比起传统休闲游戏即省钱又省事。
局域网游戏更是可以将现实空间中零散的计算机,组织起来,使其在逻辑空间中集中起来,使游戏的组织、开展变得轻松。
如此轻松而又安逸的休闲方式,使得越来越多的人尝试,甚至已经将电子游戏作为主要休闲方式,既然有如此多的人使用,那其中必然存在巨大的商机,即使人们不愿意为一个小小的休闲游戏花费金钱,但在游戏中添加广告、游戏相关服务也包藏了巨大的财富;当然电子游戏的制作如今已是空前的火爆,大大小小的游戏公司横空出世,都想在电子游戏制作这个行业里占据一席之地,而一款成功的电子游戏需要精心的策划、分析、设计,只有这样才能获得游戏中包藏的财富,以及做出一款真正能够让玩家娱乐、放松的游戏,而不是骗取玩家钱财的工具。
JAVA实现经典游戏坦克⼤战的⽰例代码⽬录前⾔主要设计功能截图代码实现总结前⾔⼩时候⼤家都玩过坦克⼤战吧,熟悉的旋律和丰富的关卡陪伴了我们⼀整个寒暑假,还记得传说中的经典坦克⼤战吗?那些怀旧的记忆,伴随着我们⼀起⾛过来的经典坦克⼤战,刚开始那战战兢兢,屡屡被敌⼈坦克击毁的情景历历在⽬。
现在好了,再也不⽤担⼼敌⼈坦克了,可以横冲直撞,横扫敌⼈坦克了。
快哉《坦克⼤战》游戏以坦克战⽃为主题,⽤java语⾔实现,采⽤了swing技术进⾏了界⾯化处理,设计思路⽤了⾯向对象思想。
主要需求可以⽣成不同的地图,消灭地图上的所有坦克为胜利;可以设置关卡地图,不断增加难度。
主要设计1、要有难度关卡:第⼀关,第⼆关,第三关,第四关,第五关;第⼀关地图最简单,第五关地图最难;2、坦克要有⾎条,打多次才会死3、地图要我有我⽅坦克四辆(相当于4条命)和多辆敌⽅坦克4、我⽅坦克的炮弹数量是固定的,设置为5005、地图右边显⽰基本信息6、地图上要在砖块,铁块,河流功能截图游戏开始页⾯代码实现窗⼝布局public class GameFrame extends JFrame {/*** serialVersionUID*/private static final long serialVersionUID = -1176914786963603304L;public GameFrame() {super();this.setSize(800, 700);this.setTitle("坦克⼤战");this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);this.setResizable(false);// 显⽰器屏幕⼤⼩Dimension screenSizeInfo = Toolkit.getDefaultToolkit().getScreenSize();int leftTopX = ((int) screenSizeInfo.getWidth() - this.getWidth()) / 2;int leftTopY = ((int) screenSizeInfo.getHeight() - this.getHeight()) / 2;// 设置显⽰的位置在屏幕中间this.setLocation(leftTopX, leftTopY);}}地图渲染核⼼算法@Servicepublic class PaintService {@Autowiredprivate GameContext context;private Brick rightBrick = new Brick(700, 50);private Iron rightIron = new Iron(700, 50);private Water rightWater = new Water(700, 50);/*** 画出东西(包括坦克、障碍物。
java简单坦克⼤战制作代码利⽤Java语⾔中的集合、Swing、线程等知识点编写⼀个坦克⼤战游戏。
(1)画出敌我坦克的原理:在坦克类⾥⾯有⼀个布尔类型变量good。
⽤于判断坦克的阵营,在创建坦克对象时在Tank类的构造⽅法中传⼊good的值。
在画坦克的时候判断good的值,区分敌我坦克的颜⾊;(2)坦克运动的原理:在坦克类⾥写⼊了监听键盘摁键的响应事件,对监听到的上下左右键进⾏记录,并合成坦克移动的⼋个⽅向的变量。
之后对应每个⽅向的不同对坦克坐标x,y的值做响应的更改实现我⽅坦克的移动。
⽽敌⽅坦克则⾃动移动,通过随机数对敌⽅坦克移动⽅向的随机,并且随机出每次移动的次数。
两个随机值相结合即实现了敌⽅坦克的移动。
(3)坦克发射⼦弹的原理:通过键盘监听,检测到发射⼦弹命令后将主类的⼦弹类集合中添加⼀个⼦弹类。
将炮筒的⽅向以及坦克的位置以及坦克的阵营传⼊给⼦弹类,在主类paint画⽅法中⼀直循环⼦弹类集合,如果集合内有⼦弹,就画出来。
这样就实现了发射⼦弹。
(4)坦克、⼦弹、墙的碰撞原理:在坦克类⼦弹类墙类中分别getRect⽅法获取⾃⾝的范围,然后在每次画坦克、⼦弹时都会进⾏相应的碰撞检测(在坦克类⾥有与墙和出⾃⼰外的坦克相撞的处理⽅法、在⼦弹类⾥有与墙和坦克相碰撞的处理⽅法。
),如果⾃⾝与不该碰撞的物体的范围相重合,则代表两物体相撞。
(5)坦克加⾎的原理:在⾎块类中有⾎块与我⽅坦克相碰撞的处理⽅法,如果⾎块范围与坦克范围重合则⾎块类死亡,并且坦克类的⾎量回复置满。
(6)坦克复活的原理:通过键盘监听,检测到我⽅坦克复活命令后,如果我⽅坦克处于死亡状态,则将我⽅坦克存货状态改为活着并且将我⽅坦克⾎量回置满⾎。
编程思想:坦克⼤战的编程思想在主类开启⼀个线程,没50毫秒循环⼀次画⽅法(绘制整个界⾯内的所有东西)。
画的东西有敌我坦克(颜⾊区分)、⼦弹、墙、⾎块、爆炸。
所以总共写出了⼏个类:Tank坦克类、Missile⼦弹类、Wall墙类、Blood ⾎块类、TankClient主类。
坦克⼤战【java项⽬】坦克⼤战(JAVA项⽬)1.项⽬简介复刻童年经典⼩游戏——坦克⼤战:⽤户进⼊游戏界⾯后,通过键盘上的数字1,2键选择游戏模式,选择1并按回车键进⼊单⼈模式;选择2并按回车键进⼊双⼈模式。
玩家1可通过按键WASD控制坦克⽅向及移动,并且按空格发射⼦弹。
玩家2通过⽅向键控制坦克⽅向移动,并且按K键发射⼦弹。
⼦弹碰到围墙后消失,⼦弹碰到坦克后产⽣爆炸特效。
左上⾓记录敌⽅坦克的实时数量。
玩家击败所有敌⽅坦克,游戏胜利;若所有我⽅坦克被击败,或者我⽅基地被摧毁,则游戏失败。
2.⼩组成员及分⼯成员负责任务组长黄抒鸿博客撰写,游戏规则的制定,碰撞检测,爆炸特效的实现,随机事件的编写组员雷正伟前期调研,⾯向对象设计,窗体绘制,闪动问题的解决,键盘事件的编写3.项⽬功能架构图与主要功能流程图3.1项⽬功能架构图3.2主要功能流程图3.3⾯向对象类设计图4.功能详解4.1 窗体绘制及添加键盘事件4.1.1 创建窗⼝·创建类继承JFrame·创建启动⽅法launch()4.1.2 为窗⼝上⾊·重写paint()⽅法,设置图形颜⾊和⼤⼩4.1.3 添加选项⽂字4.1.4 为窗⼝添加键盘事件添加内部类,实现KeyAdapter类,重写keyPressed⽅法,写⼊键盘事件,1选择单⼈模式,2选择双⼈模式窗⼝添加键盘监视器添加指针图⽚在项⽬⽂件夹下创建⽂件夹images,关于项⽬的图⽚,插件都放在这个⽂件夹内创建图⽚对象在launch()⽅法中重绘图形4.2双缓冲解决闪动问题创建⼀个图⽚Image offScreemImage = null;重写paint()⽅法创建⼀个和弹出窗⼝宽⾼相同的图⽚,获取该图⽚的图形对象,把所有内容添加到该图⽚中//创建和容器⼀样⼤⼩的Image图⽚if(offScreemImage == null) {offScreemImage = this.createImage(width,height);}//获的该图⽚的图形Graphics gImage = offScreemImage.getGraphics();gImage.setColor(Color.GRAY);gImage.fillRect(0, 0, width, height);//添加游戏选项gImage.setColor(Color.BLUE);gImage.setFont(new Font("仿宋", Font.BOLD, 50));if (state == 0 ) {gImage.drawString("选择游戏模式", 220, 100);gImage.drawString("单⼈模式", 220, 200);gImage.drawString("双⼈模式", 220, 300);//绘制指针gImage.drawImage(select, 160, y, null);} else if (state ==1 || state ==2) {gImage.drawString("游戏开始", 220, 100);if (state ==1) {gImage.drawString("单⼈模式", 220, 200);} else if(state ==2) {gImage.drawString("双⼈模式", 220, 200);}}4.3⾯向对象设计游戏⽗类:坦克类:玩家⼀和玩家⼆玩家2和玩家1的⽅法都是⼀样的,只需要修改键盘事件。
MyTankGame2.javapackage test;import javax.swing.*;import java.awt.*;import java.awt.event.*;//import java.io.*;import java.util.*;class MyTankGame2 extends JFrame implements ActionListener {MyPanel mp=null;//定义一个开始的面板MyStartPanel msp=null;//做出我需要的菜单JMenuBar jmb=null;//开始游戏JMenu jm1=null;JMenuItem jmi1=null;//退出系统JMenuItem jmi2=null;//存盘退出JMenuItem jmi3=null;JMenuItem jmi4=null;public static void main(String[] args){//System.out.println("Hello World!");MyTankGame2 mtg=new MyTankGame2();}//构造方法public MyTankGame2(){//创建菜单及菜单选项jmb=new JMenuBar();jm1=new JMenu("游戏(G)");//设置助记符jm1.setMnemonic('G');jmi1=new JMenuItem("开始新游戏(N)");jmi2=new JMenuItem("退出游戏(E)");jmi3=new JMenuItem("存盘退出游戏");jmi4=new JMenuItem("继续上局游戏");jmi4.addActionListener(this);jmi4.setActionCommand("continueGame");jmi3.addActionListener(this);jmi3.setActionCommand("saveExit");jmi2.setMnemonic('E');//对jmi1进行响应jmi1.addActionListener(this);jmi1.setActionCommand("newGame");jmi2.addActionListener(this);jmi2.setActionCommand("exit");jm1.add(jmi1);jm1.add(jmi2);jm1.add(jmi3);jm1.add(jmi4);jmb.add(jm1);msp=new MyStartPanel();Thread t=new Thread(msp);t.start();this.setJMenuBar(jmb);this.add(msp);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setSize(600,450);this.setVisible(true);}@Overridepublic void actionPerformed(ActionEvent e) {//对用户不同的点击进行不同的处理if(e.getActionCommand().equals("newGame")){mp=new MyPanel("newGame");Thread t=new Thread(mp);t.start();//先删除旧的面板this.remove(msp);this.add(mp);//注册监听this.addKeyListener(mp);//显示this.setVisible(true);}else if(e.getActionCommand().equals("exit")){//保存击毁敌人的数量Recorder.keepRecording();System.exit(0);}//对存盘退出做处理else if(e.getActionCommand().equals("saveExit")){//工作Recorder re=new Recorder();re.setEts(mp.ets);//保存击毁敌人的数量和敌人的坐标re.keepRecAndEnemyTank();//退出System.exit(0);}else if(e.getActionCommand().equals("continueGame")){ //mp=new MyPanel("con");//mp.flag=;Thread t=new Thread(mp);t.start();//先删除旧的面板this.remove(msp);this.add(mp);//注册监听this.addKeyListener(mp);//显示this.setVisible(true);}}}class MyStartPanel extends JPanel implements Runnable{ int times=0;public void paint(Graphics g){super.paint(g);g.fillRect(0, 0, 400, 300);//提示信息if(times%2==0){g.setColor(Color.yellow);//开关信息的字体Font myFont=new Font("华文新魏",Font.BOLD,30);g.setFont(myFont);g.drawString("stage:1", 150, 140);}}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){//休眠try {Thread.sleep(100);} catch (Exception e) {// TODO: handle exception}times++;//重画this.repaint();}}}//我的面板class MyPanel extends JPanel implements KeyListener,Runnable {//定义我的坦克Hero hero=null;//判断继续上局还是新游戏//定义敌人的坦克组Vector<EnemyTank> ets=new Vector<EnemyTank>();Vector<Node> nodes=new Vector<Node>();//定义炸弹集合Vector<Bomb> bombs=new Vector<Bomb>();int enSize=5;//定义三张图片Image image1=null;Image image2=null;Image image3=null;//构造方法public MyPanel(String flag){//恢复记录Recorder.getRecording();hero=new Hero(30,231);if(flag.equals("newGame")){//初始化敌人的坦克for(int i=0;i<enSize;i++){//创建一辆敌人的坦克对象EnemyTank et=new EnemyTank((i+1)*50,0);et.setColor(0);et.setDirect(2);//将MyPanel的敌人坦克向量交给该敌人坦克et.setEts(ets);//启动敌人的坦克Thread t=new Thread(et);t.start();//给敌人的坦克添加一颗子弹Shot s=new Shot(et.x+10, et.y+30, 2,1);et.ss.add(s);new Thread(s).start();ets.add(et);//加入}}else{nodes=new Recorder().getNodesAndEnNums();//初始化敌人的坦克for(int i=0;i<nodes.size();i++){Node node=nodes.get(i);//创建一辆敌人的坦克对象EnemyTank et=new EnemyTank(node.x,node.y);et.setColor(0);et.setDirect(node.direct);//将MyPanel的敌人坦克向量交给该敌人坦克et.setEts(ets);//启动敌人的坦克Thread t=new Thread(et);t.start();//给敌人的坦克添加一颗子弹Shot s=new Shot(et.x+10, et.y+30, 2,1);et.ss.add(s);new Thread(s).start();ets.add(et);//加入}}/*try {image1=ImageIO.read(new File("/bomb_1.gif"));image2=ImageIO.read(new File("/bomb_2.gif"));image3=ImageIO.read(new File("/bomb_3.gif"));} catch (Exception e) {e.printStackTrace();// TODO: handle exception}*///播放开战声音AePlayWave apw=new AePlayWave("F:\\myjava\\day9\\坦克大战\\TankGamae13\\src\\111.wav");apw.start();//初始化图片image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource( "/bomb_1.gif"));image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource( "/bomb_2.gif"));image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource( "/bomb_3.gif"));}//画出提示信息public void showInfo(Graphics g){//画出提示信息坦克(该坦克不参与战斗)this.drawTank(100, 320, g, 0, 0);g.setColor(Color.black);g.drawString(Recorder.getEnNum()+"", 128, 343);this.drawTank(165, 320, g, 0, 1);g.setColor(Color.black);g.drawString(Recorder.getMyLife()+"", 195, 343);//画出玩家的总成绩g.setColor(Color.black);Font f=new Font("宋体",Font.BOLD,20);g.setFont(f);g.drawString("您的总成绩", 410, 25);this.drawTank(420, 60, g, 0, 0);g.setColor(Color.black);g.drawString(Recorder.getAllEnNum()+"", 455, 80);}//重写paint函数public void paint(Graphics g){super.paint(g);g.fillRect(0,0,400,300);//画出提示信息this.showInfo(g);//画出自己的坦克if(hero.isLive){this.drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),1);}//从ss中取出每一颗子弹并绘制for(int i=0;i<hero.ss.size();i++){Shot myShot =hero.ss.get(i);//画出子弹if(myShot!=null&&myShot.isLive==true){g.draw3DRect(myShot.x, myShot.y, 1, 1, false);}if(myShot.isLive==false){//从ss中删除掉该子弹hero.ss.remove(myShot);}}//画出炸弹for(int i=0;i<bombs.size();i++){Bomb b=bombs.get(i);if(b.life>6){g.drawImage(image1, b.x, b.y, 30, 30,this);}else if(b.life>3){g.drawImage(image2, b.x, b.y, 30, 30,this);}else{g.drawImage(image3, b.x, b.y, 30, 30,this);}//让b的生命值减小b.lifeDown();if(b.life==0){//把炸弹从向量中去掉bombs.remove(b);}}//画出敌人的坦克for(int i=0;i<ets.size();i++){ EnemyTank et=ets.get(i);if(et.isLive){this.drawTank(et.getX(),et.getY(), g, et.getDirect(), 0);//顺便画出敌人的子弹for(int j=0;j<et.ss.size();j++){//取出子弹Shot enemyShot=et.ss.get(j);if(enemyShot.isLive){g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);}else{//如果死亡了,就从Vextor中删除掉et.ss.remove(enemyShot);}}}}}//判断我的子弹是否会击中敌人的坦克public void hitEnemyTank(){//判断是否会击中for(int i=0;i<hero.ss.size();i++){//取出子弹Shot myShot=hero.ss.get(i);//判断子弹是否有效if(myShot.isLive){//取出每一个敌人坦克与之匹配for(int j=0;j<ets.size();j++){//取出坦克EnemyTank et=ets.get(j);if(et.isLive){if(this.hitTank(myShot, et)){ //减少敌人数量Recorder.reduceEnNum();//增加我的记录Recorder.addEnEnum();}}}}}}//我是否被击中public void hitMe(){//取出每一个敌人的坦克for(int i=0;i<this.ets.size();i++){//取出坦克EnemyTank et=ets.get(i);//取出每颗子弹for(int j=0;j<et.ss.size();j++){//取出子弹Shot enemyShot=et.ss.get(j);if(hero.isLive){if(this.hitTank(enemyShot, hero)){//待写}}}}}//画出一个专门判断子弹是否击中敌人坦克的函数public boolean hitTank(Shot s ,Tank et){boolean b2=false;//判断该坦克的方向switch(et.direct){//敌人坦克的方向是向上或者向下case 0:case 2:if(s.x>et.x&&s.x<et.x+20&&s.y>et.y&&s.y<et.y+30){//击中//子弹死亡s.isLive=false;//敌人坦克死亡et.isLive=false;b2=true;//System.out.println("hytfyfrujyg");//创建一颗炸弹放入VectorBomb b=new Bomb(et.x, et.y);bombs.add(b);}break;case 1:case 3:if(s.x>et.x&&s.x<et.x+30&&s.y>et.y&&s.y<et.y+20){//击中//子弹死亡s.isLive=false;//敌人坦克死亡et.isLive=false;b2=true;Bomb b=new Bomb(et.x, et.y);bombs.add(b);}break;}return b2;}//画出坦克的函数(扩展)public void drawTank(int x,int y,Graphics g,int direction,int type) {//判断类型switch(type){case 0:g.setColor(Color.CYAN);break;case 1:g.setColor(Color.yellow);break;}//判断方向switch(direction){//向上走case 0://g.setColor(Color.CYAN);//画出我的坦克(到时再封装成一个函数)//1.画出左边的矩形g.fill3DRect(x,y,5,30,false);//2.画出右边边的矩形g.fill3DRect(x+15,y,5,30,false);//3画出中间的矩形g.fill3DRect(x+5,y+5,10,20,false);//4画圆形g.fillOval(x+5,y+10,10,10);//5.画出线g.drawLine(x+10,y+15,x+10,y);break;case 1://向右g.fill3DRect(x, y, 30,5, false);g.fill3DRect(x, y+15, 30,5 ,false);g.fill3DRect(x+5, y+5, 20, 10, false);g.fillOval(x+10, y+5, 10, 10);g.drawLine(x+15, y+10, x+30, y+10);break;case 2://向下g.fill3DRect(x,y,5,30,false);//2.画出右边边的矩形g.fill3DRect(x+15,y,5,30,false);//3画出中间的矩形g.fill3DRect(x+5,y+5,10,20,false);//4画圆形g.fillOval(x+5,y+10,10,10);//5.画出线g.drawLine(x+10,y+15,x+10,y+30);break;case 3://向左g.fill3DRect(x, y, 30,5, false);g.fill3DRect(x, y+15, 30,5 ,false);g.fill3DRect(x+5, y+5, 20, 10, false);g.fillOval(x+10, y+5, 10, 10);g.drawLine(x+15, y+10, x, y+10);break;}}@Overridepublic void keyTyped(KeyEvent e) {// TODO Auto-generated method stub}@Override//w上,s下,a左,右边public void keyPressed(KeyEvent e) {// TODO Auto-generated method stubif(e.getKeyCode()==KeyEvent.VK_W){//设置我的坦克的方向上this.hero.setDirect(0);if(this.hero.y>0){this.hero.moveUp();}}else if(e.getKeyCode()==KeyEvent.VK_D){//设置我的坦克的方向右边this.hero.setDirect(1);if(this.hero.x<370){this.hero.moveRight();}}else if(e.getKeyCode()==KeyEvent.VK_S){//设置我的坦克的方向 xia边this.hero.setDirect(2);if(this.hero.y<=271){this.hero.moveDown();}}else if(e.getKeyCode()==KeyEvent.VK_A){//设置我的坦克的方向左边this.hero.setDirect(3);if(this.hero.x>0){this.hero.moveLeft();}}if(e.getKeyCode()==KeyEvent.VK_K){//玩家按了一个k键,开火if(this.hero.ss.size()<=5){this.hero.shotEnemy();}}//必须用repaintPanelthis.repaint();}@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub }@Overridepublic void run() {// TODO Auto-generated method stub//每隔100毫秒去重画while(true){try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.hitEnemyTank();this.hitMe();//重绘this.repaint();}}}Members.javapackage test;import java.io.*;import java.util.Vector;import javax.sound.sampled.AudioFormat;import javax.sound.sampled.AudioInputStream;import javax.sound.sampled.AudioSystem;import javax.sound.sampled.DataLine;import javax.sound.sampled.SourceDataLine;class AePlayWave extends Thread {private String filename;public AePlayWave(String wavfile) {filename = wavfile;}public void run() {File soundFile = new File(filename);AudioInputStream audioInputStream = null;try {audioInputStream = AudioSystem.getAudioInputStream(soundFile);} catch (Exception e1) {e1.printStackTrace();return;}AudioFormat format = audioInputStream.getFormat();SourceDataLine auline = null; info = new (SourceDataLine.class, format);try {auline = (SourceDataLine) AudioSystem.getLine(info);auline.open(format);} catch (Exception e) {e.printStackTrace();return;}auline.start();int nBytesRead = 0;byte[] abData = new byte[512];try {while (nBytesRead != -1) {nBytesRead = audioInputStream.read(abData, 0, abData.length);if (nBytesRead >= 0)auline.write(abData, 0, nBytesRead);}} catch (IOException e) {e.printStackTrace();return;} finally {auline.drain();auline.close();}}}class Node//恢复点{int x,y,direct;public Node(int x,int y,int direct){this.x=x;this.y=y;this.direct=direct;}}//记录类,同时也可以保存一些设置class Recorder{//记录每关有多少敌人private static int enNum=5;//设置我有多少可用的人private static int myLife=3;//记录总共消灭了多少敌人private static int allEnNum=0;//从文件中恢复记录点static Vector<Node> nodes=new Vector<Node>();private static FileWriter fw=null;private static BufferedWriter bw=null;private static FileReader fr=null;private static BufferedReader br=null;private Vector <EnemyTank> ets=new Vector<EnemyTank>();public Vector<EnemyTank> getEts() {return ets;}public void setEts(Vector<EnemyTank> ets) {this.ets = ets;}//完成读取任务public Vector<Node> getNodesAndEnNums(){try {fr=new FileReader("F:\\myRecording.txt");br=new BufferedReader(fr);String n="";//先读取第一行n=br.readLine();allEnNum=Integer.parseInt(n);while((n=br.readLine())!=null){String []xyz=n.split(" ");Node node=new Node(Integer.parseInt(xyz[0]),Integer.parseInt(xyz[1]),Integer.parseInt(xyz[2]));nodes.add(node);}} catch (Exception e) {e.printStackTrace();// TODO: handle exception}finally{try {br.close();fr.close();} catch (Exception e2) {// TODO: handle exception}}return nodes;}//保存击毁敌人坦克的数量和敌人坦克的坐标,方向public void keepRecAndEnemyTank(){try {//创建fw=new FileWriter("F:\\myRecording.txt");bw=new BufferedWriter(fw);bw.write(allEnNum+"\r\n");//保存当前还活着的坐标和方向for(int i=0;i<ets.size();i++){//取出第一个坦克EnemyTank et=ets.get(i);if(et.isLive){String record=et.x+" "+et.y+" "+et.direct;//写入到文件bw.write(record+"\r\n");}}} catch (Exception e) {// TODO: handle exception}finally{//关闭流try {bw.close();fw.close();} catch (Exception e2) {// TODO: handle exception}}}//从文件中读取记录public static void getRecording(){try {fr=new FileReader("F:\\myRecording.txt");br=new BufferedReader(fr);String n=br.readLine();allEnNum=Integer.parseInt(n);} catch (Exception e) {e.printStackTrace();// TODO: handle exception}finally{try {br.close();fr.close();} catch (Exception e2) {// TODO: handle exception}}}//把玩家击毁敌人的坦克数量保存到文件中public static void keepRecording(){try {//创建fw=new FileWriter("F:\\myRecording.txt");bw=new BufferedWriter(fw);bw.write(allEnNum+"\r\n");} catch (Exception e) {// TODO: handle exception}finally{//关闭流try {bw.close();fw.close();} catch (Exception e2) {// TODO: handle exception}}}public static int getAllEnNum() {return allEnNum;}public static void setAllEnNum(int allEnNum) { Recorder.allEnNum = allEnNum;}public static int getEnNum() {return enNum;}public static void setEnNum(int enNum) {Recorder.enNum = enNum;}public static int getMyLife() {return myLife;}public static void setMyLife(int myLife) { Recorder.myLife = myLife;}//减少敌人数public static void reduceEnNum(){enNum--;}//消灭敌人public static void addEnEnum(){allEnNum++;}}//炸弹类class Bomb{int x,y;//炸弹的生命int life=9;boolean isLive=true;public Bomb(int x,int y){this.x=x;this.y=y;}//减少生命值public void lifeDown(){if(life>0){life--;}else{this.isLive=false;}}}//子弹类class Shot implements Runnable{int x,y;int direct;int speed=1;//是否还活着boolean isLive=true;public Shot(int x,int y,int direct,int speed) {this.x=x;this.y=y;this.direct=direct;this.speed=speed;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}switch(direct){case 0://向上y-=speed;break;case 1://向右x+=speed;break;case 2://下y+=speed;break;case 3:x-=speed;break;}//子弹何时死亡if(x<0||x>400||y<0||y>300){this.isLive=false;break;}//System.out.println(x+""+y);}}}//坦克类class Tank{int x=0;int y=0;//定义方向的值0上,右2,下3,左int direct=0;//坦克的速度int speed=1;int color=0;boolean isLive=true;public int getColor() {return color;}public void setColor(int color) {this.color = color;}public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}public int getDirect() {return direct;}public void setDirect(int direct) {this.direct = direct;}public Tank(int x,int y){this.x=x;this.y=y;}public int getX(){return x;}public int getY(){return y;}public void setX(int x){this.x=x;}public void setY(int y){this.y=y;}}//敌人的坦克 ,做成线程class EnemyTank extends Tank implements Runnable {//boolean isLive=true;int times=0;//定义一个向量,可以访问到MyPanel上所有敌人的坦克Vector<EnemyTank> ets=new Vector<EnemyTank>();//定义一个向量,可以存放敌人的子弹Vector <Shot> ss=new Vector<Shot>();//敌人添加子弹应当在刚刚创建坦克和敌人的坦克子弹死亡之后public EnemyTank(int x, int y){super(x, y);}//得到MyPanel的敌人坦克向量public void setEts(Vector<EnemyTank>vv){this.ets=vv;}//判断是否碰到了别人的敌人的坦克public boolean isTouchOtherEnemy(){boolean b=false;//..。
陕西国防学院《Java语言》课程期末实训题目坦克大战学院电子信息学院专业软件技术班别软件3132班学号3531323X姓名小智2015年3月6日一、课程题目坦克大战(Java版本)实现一个java版本的坦克大战游戏【功能提示】1.游戏要有图形用户界面,界面能够反映游戏所有的细节。
2.界面中要有坦克,墙,树林,河流。
3.界面中要有一个“家”,“家”被攻击中则输了游戏。
4.坦克分两种,敌方和我方。
5.墙也分为两种,可以穿透的普通墙,不可以穿透的铁墙。
6.树和河流均只有一种,树林坦克可以通过。
7.坦克可以发射子弹,敌我方的子弹属性一样。
8.我方子弹可以杀死敌方坦克,敌方子弹也可以杀死我方坦克,但需要多枪子弹才可以杀死。
9.敌方之间不可以杀死对方。
10.子弹击中坦克要有爆炸,但击中墙不能爆炸。
11.我方可以吃血包增加生命。
12.游戏可以暂停,重新开始,游戏帮助等功能。
具体如下图:13.二、题目分析与设计需求分析1.设计一个图形用户界面,将所有游戏的元素都能在此用于界面上表现出来,界面能够接受用户的操作,具有人机交互功能。
用户可以选择重新开始游戏,退出游戏,暂停游戏和查找游戏帮助。
2.界面中包含坦克,树,河流,阻挡墙和游戏用户所要保护的“家”。
3.坦克:坦克分为两种,敌方坦克和用户控制的坦克。
用户方和敌方坦克均可以发射子弹,可以改变路径的行走,且在行走过程中遇到墙等阻碍物和游戏边界时要改变方向,而不能一直顶着障碍物不放。
坦克之间不能穿越,碰撞到后自动调换方向。
4.树:界面中要包括树林,作为遮掩物体和修饰物体,以便增加游戏的元素,使得游戏更加贴切人性化。
树的数目不限,以游戏整体界面清晰美观来决定数目。
5.河流:界面中要包括河流,河流作用与树林相同,同样河流的数目不限,以游戏界面整体美观度来决定数目。
6.墙:墙体分为两种,普通的墙和铁墙,普通的墙在受到子弹袭击时会损坏,而铁墙可以阻碍子弹的穿越。
两方的坦克均不能穿越两种墙体,但都可以摧毁普通墙体。
Java程序课程设计任务书项目名称:坦克大战游戏的设计与开发英文名:Tank Battle1、主要内容:1、基于java的游戏开发与设计的分析;2、坦克大战游戏的架构搭建与设计实现;3、游戏可以通过用户可以注册新用户,修改自己的密码、个人资料。
2、具体要求1、系统的功能要求:(一)实现玩家试玩游戏功能,屏蔽用户注册和登陆功能(空功能)(二)玩家具备一个或者两个备选坦克战车(三)玩家可以选择一个到两个关卡进行作战(四)玩家可以选择两个敌对阵营中的一个加入,与其他AI战车坦克并肩作战(五)胜利判定条件为:时间制、全杀制(可选)(六)至少提供两个可以自由切换的视角(七)至少提供一种炮弹类型(八)假定项目:如果用户注册,登陆功能能够顺利做好,则提供一个玩家分数上传和排行榜功能。
2、学习并掌握以下技术:数据库的JDBC连接,JA V A编程语言,MySQL数据库的应用;JSP的开发与运用3、熟练使用以下开发工具:JCreator,Myeclipse ,MySQL ,PowerDesigner 等3、进度安排:12月28日~ 12 月29 日:查阅资料,完成文献综述,任务书;12月29 日~ 12月31日:进行系统的需求分析与设计;1月1日~ 1月3日:根据分析进行各个模块程序的设计与创建;1月4日~ 1 月6日:完成各个模块的程序编写;1月7 日~ 1 月8 日:完成全部程序的编写及系统测试;1月9日~ 1 月10日:完成课程设计报告的编写,答辩;摘要随着Java语言的不断发展和壮大,现在的Java已经广泛的应用于各个领域,包括医药,汽车工业,手机行业,游戏,等等地方。
Java游戏的开发为满足人们娱乐所需而设计。
本游戏为坦克大战游戏,是基于Java的图形用户界面而开发的,可以放松心情的小游戏。
游戏从系统操作简便、界面友好、灵活、上手即会的基本要求出发,完成整款游戏的开发。
游戏更设置了暂停、计分、音乐、速度,用户信息保存等功能,可以根据自己的爱好,挑战更高难度,为用户带来愉悦的体验。
陕西国防学院《Java语言》课程期末实训题目坦克大战学院电子信息学院专业软件技术班别软件3132班学号 3531323X姓名小智2015年3月6日一、课程题目坦克大战(Java版本)实现一个java版本的坦克大战游戏【功能提示】1.游戏要有图形用户界面,界面能够反映游戏所有的细节。
2.界面中要有坦克,墙,树林,河流。
3.界面中要有一个“家”,“家”被攻击中则输了游戏。
4.坦克分两种,敌方和我方。
5.墙也分为两种,可以穿透的普通墙,不可以穿透的铁墙。
6.树和河流均只有一种,树林坦克可以通过。
7.坦克可以发射子弹,敌我方的子弹属性一样。
8.我方子弹可以杀死敌方坦克,敌方子弹也可以杀死我方坦克,但需要多枪子弹才可以杀死。
9.敌方之间不可以杀死对方。
10.子弹击中坦克要有爆炸,但击中墙不能爆炸。
11.我方可以吃血包增加生命。
12.游戏可以暂停,重新开始,游戏帮助等功能。
具体如下图:二、题目分析与设计需求分析1.设计一个图形用户界面,将所有游戏的元素都能在此用于界面上表现出来,界面能够接受用户的操作,具有人机交互功能。
用户可以选择重新开始游戏,退出游戏,暂停游戏和查找游戏帮助。
2.界面中包含坦克,树,河流,阻挡墙和游戏用户所要保护的“家”。
3.坦克:坦克分为两种,敌方坦克和用户控制的坦克。
用户方和敌方坦克均可以发射子弹,可以改变路径的行走,且在行走过程中遇到墙等阻碍物和游戏边界时要改变方向,而不能一直顶着障碍物不放。
坦克之间不能穿越,碰撞到后自动调换方向。
4.树:界面中要包括树林,作为遮掩物体和修饰物体,以便增加游戏的元素,使得游戏更加贴切人性化。
树的数目不限,以游戏整体界面清晰美观来决定数目。
5.河流:界面中要包括河流,河流作用与树林相同,同样河流的数目不限,以游戏界面整体美观度来决定数目。
6.墙:墙体分为两种,普通的墙和铁墙,普通的墙在受到子弹袭击时会损坏,而铁墙可以阻碍子弹的穿越。
两方的坦克均不能穿越两种墙体,但都可以摧毁普通墙体。
import java.awt.*;//血块类public class Blood {int x, y, w, h;//定义血块坐标变量,宽度、高度变量TankClient tc; //生命坦克客户端变量int step = 0;private boolean live = true;//初始生命为true//定义5个血块数组private int[][] pos = {{350, 300}, {360, 300}, {375, 275}, {400, 200}, {360, 270}, {365, 290}, {340, 280}};//血块构造函数public Blood() {x = pos[0][0];y = pos[0][1];w = h = 15;}//画出血块public void draw(Graphics g) {if(!live) return;Color c = g.getColor();//对象c获取当前颜色g.setColor(Color.MAGENTA);//设定血块颜色为洋红色g.fillRect(x, y, w, h);//用洋红色填充矩形g.setColor(c);move();//调用move方法}//血块移动方法private void move() {step ++;if(step == pos.length){step = 0;}x = pos[step][0];y = pos[step][1];}//看是否和子弹相碰撞public Rectangle getRect() {return new Rectangle(x, y, w , h);}//判断生存状态public boolean isLive() {return live;//返回生存状态}//设定生死状态public void setLive(boolean live) {this.live = live;}}import java.awt.*;//爆炸类public class Explode {int x, y; //定义爆炸坐标变量private boolean live = true;//初始化生命为true//引用坦克客户端对象private TankClient tc ;//定义并初始化半径数组int[] diameter = {4, 7, 12, 18, 26, 32, 49, 30, 14, 6};int step = 0;//根据碰撞位置创建爆炸public Explode(int x, int y, TankClient tc) {this.x = x;this.y = y;this.tc = tc;}//用一个圆来表示模拟爆炸public void draw(Graphics g) {if(!live) {tc.explodes.remove(this);return;}if(step == diameter.length) {live = false;step = 0;return;}Color c = g.getColor();//对象c用来获取颜色g.setColor(Color.ORANGE);//设定爆炸颜色为桔黄色g.fillOval(x, y, diameter[step], diameter[step]);//用桔黄色填充圆g.setColor(c);step ++;}}import java.awt.*;import java.util.List;//子弹类public class Missile {public static final int XSPEED = 10; //子弹水平速度public static final int YSPEED = 10; //子弹垂直速度public static final int WIDTH = 10; //子弹宽度变量public static final int HEIGHT = 10;//子弹高度变量int x, y;//子弹坐标Tank.Direction dir;//子弹方向//子弹生死状态变量private boolean good;//设定敌我双方判断标志private boolean live = true;//判断是否存活//坦克客户对象private TankClient tc;//子弹构造函数public Missile(int x, int y, Tank.Direction dir) {this.x = x;this.y = y;this.dir = dir;}//重写构造函数public Missile(int x, int y, boolean good, Tank.Direction dir, TankClient tc) { this(x, y, dir);this.good = good;this.tc = tc;}//在窗体上画出子弹public void draw(Graphics g) {if(!live) {tc.missiles.remove(this);return;}//如果子弹死了,则不画出Color c = g.getColor();//获取颜色g.setColor(Color.BLACK);//设置子弹颜色为黑色g.fillOval(x, y, WIDTH, HEIGHT);//用黑色填充圆g.setColor(c);move();//子弹移动方法}//子弹移动函数private void move() {//根据子弹的方向确定下一步的移动switch(dir) {case L:x -= XSPEED;break;case LU:x -= XSPEED;y -= YSPEED;break;case U:y -= YSPEED;break;case RU:x += XSPEED;y -= YSPEED;break;case R:x += XSPEED;break;case RD:x += XSPEED;y += YSPEED;break;case D:y += YSPEED;break;case LD:x -= XSPEED;y += YSPEED;break;case STOP:break;}//判断子弹是否出界,若出则去掉if(x < 0 || y < 0 || x > TankClient.GAME_WIDTH || y > TankClient.GAME_HEIGHT) {live = false;}}//判断子弹生存状态public boolean isLive() {return live;//返回子弹生存状态}//获取子弹外围坐标public Rectangle getRect() {return new Rectangle(x, y, WIDTH, HEIGHT);}//打坦克函数public boolean hitTank(Tank t) {if(this.live && this.getRect().intersects(t.getRect()) && t.isLive() && this.good != t.isGood()) { //每中一次弹生命值减少20if(t.isGood()) {t.setLife(t.getLife()-20);if(t.getLife() <= 0) t.setLive(false);//坦克没血了则没生命} else {t.setLive(false);}this.live = false;Explode e = new Explode(x, y, tc);//创建一个爆炸e对象tc.explodes.add(e);//添加到爆炸容器中return true;}return false;}//依次判断所有敌方坦克是否被子弹击中public boolean hitTanks(List<Tank> tanks) {for(int i=0; i<tanks.size(); i++) {if(hitTank(tanks.get(i))) {return true;}}return false;}//判断子弹是否击中墙public boolean hitWall(Wall w) {if(this.live && this.getRect().intersects(w.getRect())) {this.live = false;return true;}return false;}}import java.awt.*;import java.awt.event.*;import java.util.*;//定义坦克类public class Tank {public static final int XSPEED = 5; //坦克水平速度public static final int YSPEED = 5; //坦克垂直速度public static final int WIDTH = 30; //坦克宽度public static final int HEIGHT = 30; //坦克高度private boolean live = true; //初始化生命为trueprivate BloodBar bb = new BloodBar();//声明血块变量private int life = 100; //初始化生命值为100TankClient tc;//生命坦克客户端变量private boolean good;//设置区分敌我两方标志private int x, y; //声明两个整型私有变量x,y坐标private int oldX, oldY;//记录上一步的坐标private static Random r = new Random(); //创建一个随机数r对象//声明方向变量private boolean bL=false, bU=false, bR=false, bD = false;enum Direction {L, LU, U, RU, R, RD, D, LD, STOP};/*坦克的八个方向和一个stop状态*/private Direction dir = Direction.STOP;private Direction ptDir = Direction.D;private int step = r.nextInt(12) + 3;//整数step在[3,14]间随机取值//构造方法public Tank(int x, int y, boolean good) {this.x = x;this.y = y;this.oldX = x;this.oldY = y;this.good = good;}//重写构造方法public Tank(int x, int y, boolean good, Direction dir, TankClient tc) { this(x, y, good);this.dir = dir;this.tc = tc;}//画出坦克public void draw(Graphics g) {if(!live) {if(!good) {tc.tanks.remove(this);}return;}Color c = g.getColor();//获取颜色if(good) g.setColor(Color.RED);//我方坦克颜色设置为红色else g.setColor(Color.BLUE);g.fillOval(x, y, WIDTH, HEIGHT);g.setColor(c);//画出子弹if(good) bb.draw(g);switch(ptDir) {case L:g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT/2);break;case LU:g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y);break;case U:g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y);break;case RU:g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y);break;case R:g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT/2);break;case RD:g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT);break;case D:g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y + Tank.HEIGHT);break;case LD:g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT);break;}move();}//移动方法void move() {//记录上一次坐标this.oldX = x;this.oldY = y;switch(dir) {case L:x -= XSPEED;break;case LU:x -= XSPEED;y -= YSPEED;break;case U:y -= YSPEED;break;case RU:x += XSPEED;y -= YSPEED;break;case R:x += XSPEED;break;case RD:x += XSPEED;y += YSPEED;break;case D:y += YSPEED;break;case LD:x -= XSPEED;y += YSPEED;break;case STOP:break;}if(this.dir != Direction.STOP) {this.ptDir = this.dir;}//控制坦克不出界if(x < 0) x = 0;if(y < 30) y = 30;if(x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH;if(y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT;if(!good) {Direction[] dirs = Direction.values();if(step == 0) {step = r.nextInt(12) + 3;int rn = r.nextInt(dirs.length);//改变方向dir = dirs[rn];}step --;if(r.nextInt(40) > 38) this.fire();}}private void stay() {x = oldX;y = oldY;}//键按下的消息处理public void keyPressed(KeyEvent e) {int key = e.getKeyCode();switch(key) {case KeyEvent.VK_Q :if(!this.live) {this.live = true;this.life = 100;}break;case KeyEvent.VK_LEFT :bL = true;break;case KeyEvent.VK_UP :bU = true;break;case KeyEvent.VK_RIGHT :bR = true;break;case KeyEvent.VK_DOWN :bD = true;break;}locateDirection();}//设定方向void locateDirection() {if(bL && !bU && !bR && !bD) dir = Direction.L;else if(bL && bU && !bR && !bD) dir = Direction.LU;else if(!bL && bU && !bR && !bD) dir = Direction.U;else if(!bL && bU && bR && !bD) dir = Direction.RU;else if(!bL && !bU && bR && !bD) dir = Direction.R;else if(!bL && !bU && bR && bD) dir = Direction.RD;else if(!bL && !bU && !bR && bD) dir = Direction.D;else if(bL && !bU && !bR && bD) dir = Direction.LD;else if(!bL && !bU && !bR && !bD) dir = Direction.STOP;}//键抬起的消息处理public void keyReleased(KeyEvent e) {int key = e.getKeyCode();switch(key) {case KeyEvent.VK_CONTROL:fire();break;case KeyEvent.VK_LEFT :bL =true;break;case KeyEvent.VK_UP :bU = true;break;case KeyEvent.VK_RIGHT :bR = true;break;case KeyEvent.VK_DOWN :bD = true;break;case KeyEvent.VK_A ://按下A开火superFire();break;}locateDirection();}//开火发射方法public Missile fire() {if(!live) return null;int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;Missile m = new Missile(x, y, good, ptDir, this.tc);tc.missiles.add(m);return m;}public Missile fire(Direction dir) {if(!live) return null;int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;Missile m = new Missile(x, y, good, dir, this.tc);tc.missiles.add(m);return m;}//看坦克是否与子弹碰撞public Rectangle getRect() {return new Rectangle(x, y, WIDTH, HEIGHT);}//判断坦克是否还活着public boolean isLive() {return live;}//设定坦克的生死状态public void setLive(boolean live) {this.live = live;}//判断坦克状态是否良好public boolean isGood() {return good;}//坦克与墙相撞public boolean collidesWithWall(Wall w) {if(this.live && this.getRect().intersects(w.getRect())) {this.stay();return true;}return false;}//坦克与坦克相撞public boolean collidesWithTanks(java.util.List<Tank> tanks) {for(int i=0; i<tanks.size(); i++) {Tank t = tanks.get(i);if(this != t) {if(this.live && t.isLive() && this.getRect().intersects(t.getRect())) {this.stay();t.stay();return true;}}}return false;}//发射超级子弹private void superFire() {Direction[] dirs = Direction.values();for(int i=0; i<8; i++) {fire(dirs[i]);}}//返回坦克的生命值public int getLife() {return life;}//设置坦克的生命值public void setLife(int life) {this.life = life;}//创建生命值private class BloodBar {//在坦克上方画出生命条public void draw(Graphics g) {Color c = g.getColor();g.setColor(Color.RED);g.drawRect(x, y-10, WIDTH, 10);int w = WIDTH * life/100 ;g.fillRect(x, y-10, w, 10);g.setColor(c);}}//判断坦克是否吃到东西public boolean eat(Blood b) {if(this.live && b.isLive() && this.getRect().intersects(b.getRect())) { this.life = 100;b.setLive(false);return true;}return false;}}import java.awt.*;import java.awt.event.*;import java.util.List;import java.util.ArrayList;//坦克游戏的窗体类public class TankClient extends Frame {//定义窗口宽高public static final int GAME_WIDTH = 800;public static final int GAME_HEIGHT = 600;//声明一个自己坦克的对象Tank myTank = new Tank(50, 50, true, Tank.Direction.STOP, this);//声明两个墙变量Wall w1 = new Wall(100, 200, 20, 150, this), w2 = new Wall(300, 100, 300, 20, this);List<Explode> explodes = new ArrayList<Explode>();//创建一个存放爆炸的容器List<Missile> missiles = new ArrayList<Missile>();//创建一个存放子弹的容器List<Tank> tanks = new ArrayList<Tank>();//创建一个存放坦克的容器Image offScreenImage = null;Blood b = new Blood();//创建一个血块对象//画方法public void paint(Graphics g) {//左上角显示的有关游戏的相关信息g.drawString("missiles count:" + missiles.size(), 10, 50);//子弹数g.drawString("explodes count:" + explodes.size(), 10, 70);//爆炸数g.drawString("tanks count:" + tanks.size(), 10, 90);//坦克数g.drawString("tanks life:" + myTank.getLife(), 10, 110);//坦克生命//画出爆炸if(tanks.size() <= 0) {for(int i=0; i<5; i++) {tanks.add(new Tank(50 + 40*(i+1), 50, false, Tank.Direction.D, this));}}//画出子弹for(int i=0; i<missiles.size(); i++) {Missile m = missiles.get(i);m.hitTanks(tanks);//打敌人m.hitTank(myTank);//被敌人打m.hitWall(w1);//撞墙m.hitWall(w2);m.draw(g);//if(!m.isLive()) missiles.remove(m);//else m.draw(g);}for(int i=0; i<explodes.size(); i++) {Explode e = explodes.get(i);e.draw(g);}for(int i=0; i<tanks.size(); i++) {Tank t = tanks.get(i);t.collidesWithWall(w1);t.collidesWithWall(w2);//坦克撞到墙t.collidesWithTanks(tanks);//坦克相撞t.draw(g);}myTank.draw(g);//画出坦克myTank.eat(b);w1.draw(g);//画出墙w2.draw(g);b.draw(g);}//双缓存消除闪烁public void update(Graphics g) {if(offScreenImage == null) {offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT);}Graphics gOffScreen = offScreenImage.getGraphics();Color c = 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);}//启动窗口public void lauchFrame() {//画出坦克for(int i=0; i<10; i++) {tanks.add(new Tank(50 + 40*(i+1), 50, false, Tank.Direction.D, this));}//this.setLocation(400, 300);this.setSize(GAME_WIDTH, GAME_HEIGHT);this.setTitle("TankWar");this.addWindowListener(new WindowAdapter() //处理窗口的关闭{public void windowClosing(WindowEvent e) {System.exit(0);}});this.setResizable(false);//设置窗口大小固定this.setBackground(Color.GREEN);//窗口背景颜色为绿色this.addKeyListener(new KeyMonitor());setVisible(true);new Thread(new PaintThread()).start();}public static void main(String[] args) {TankClient tc = new TankClient();//创建一个窗体uchFrame();}//内部类新起一线程控制坦克移动private class PaintThread implements Runnable {public void run() {while(true) {repaint();try {Thread.sleep(50);//每隔50ms,坦克移动一下(重画一下)} catch (InterruptedException e) {e.printStackTrace();}}}}//增加键盘监听private class KeyMonitor extends KeyAdapter {//键盘抬起public void keyReleased(KeyEvent e) {myTank.keyReleased(e);}//键盘按下public void keyPressed(KeyEvent e) {myTank.keyPressed(e);}}}import java.awt.*;//墙类public class Wall {int x, y, w, h;//坐标,长,宽TankClient tc ;//坦克客户对象//根据墙左上角坐标,宽度,高度创建墙public Wall(int x, int y, int w, int h, TankClient tc) {this.x = x;this.y = y;this.w = w;this.h = h;this.tc = tc;}//在窗体中画出墙public void draw(Graphics g) {g.fillRect(x, y, w, h);}//返回墙的矩形碰撞区域public Rectangle getRect() {return new Rectangle(x, y, w, h);}}。
Java坦克大战图片版V3.4(加入各种类型墙的图片)【严重模仿90坦克】作者:Magci 日期:2008-04-25 06:49 PM字体大小: 小中大3.4版更新内容:加入各种类型墙的图片:1.石墙:炮弹、坦克都不能穿透;1.砖墙:炮弹能打掉,坦克不能穿透;3.河流:炮弹能穿透,坦克不能穿透;4.草地:炮弹、坦克都能穿透。
TankClient.java:程序代码package .ahau.mgc.tankwar;import java.awt.*;import java.awt.event.*;import java.util.*;import java.util.List;/*** 此类用于创建游戏窗体* @author Magci**/public class TankClient extends Frame {public static final int WINDOW_Y = 100;/*** 窗体宽度*/public static final int WINDOW_WIDTH = 800; /*** 窗体高度*/public static final int WINDOW_HEIGHT = 600; /*** 坦克起始位置左上角X坐标*/public static final int Tank_X = 400;/*** 坦克起始位置左上角Y坐标*/public static final int Tank_Y = 540;/*** 窗体刷新率*/public static final int REFRESH_RATE = 50; /*** 墙起始点X坐标*/public static final int WALL_X = 4;/*** 墙起始点Y坐标*/public static int WALL_Y = 75;//窗体左上角X坐标private int windowX = 0;//窗体左上角Y坐标private int windowY = 0;//敌方坦克总数量private int tankAllNum;//敌方坦克同时出现的最大数量private int tankMaxNum;//当前敌方坦克数量private int tankNum = 0;//我方坦克总数量private int myTankNum;//用于双缓冲的图片Image offScreenImage = null;//我方坦克Tank myTank = null;//存放敌方坦克的容器List<Tank> enemyTanks = new ArrayList<Tank>();//存放炮弹的容器List<Missile> missiles = new ArrayList<Missile>();//存放爆炸的容器List<Explode> explodes = new ArrayList<Explode>();//存放爆炸的容器List<Wall> walls = new ArrayList<Wall>();//宝物Treasure trea = null;//用于生成随机数Random rand = new Random();public static void main(String[] args) {// 创建一个窗体new TankClient("TankClient", 20, 5, 3);}/*** 根据标题,敌我坦克数量创建一个窗体* @param title 窗体标题* @param tankAllNum 敌方坦克总数量* @param tankMaxNum 敌方坦克同时出现的最大数量* @param myTankNum 我方坦克总数量*/public TankClient(String title, int tankAllNum, int tankMaxNum, int myTankNum) { super(title);this.tankAllNum = tankAllNum;this.tankMaxNum = tankMaxNum;this.myTankNum = myTankNum;windowX = Integer.parseInt(PropertyMgr.getProperty("windowX"));windowY = Integer.parseInt(PropertyMgr.getProperty("windowY"));this.setBounds(windowX, windowY, WINDOW_WIDTH, WINDOW_HEIGHT); this.setResizable(false);this.setBackground(Color.BLACK);this.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {setVisible(false);System.exit(0);}});this.addKeyListener(new KeyMonitor());this.setVisible(true);myTank = new Tank(Tank_X, Tank_Y, 4, true, this);//加入敌方坦克for (int i = 0; i < tankMaxNum; i++) {Tank enemyTank = new Tank(22 + 180 * i, 40, 4, false, this);enemyTanks.add(enemyTank);this.tankNum ++;}//加入墙String sytle = null;for (int i = 0; i < 29; i++) {for (int j = 0; j < 44; j++) {if (i == 0) {if (j % 10 == 1 || j % 10 == 2) {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "stone", this); walls.add(wall);}}if (i > 0 && i < 10) {if (j != 4 && j != 5 && j != 20 && j != 21 && j != 39 && j != 40) {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "tile", this); walls.add(wall);}}if (i >= 10 && i < 12) {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "grass", this);walls.add(wall);}if (i >= 12 && i < 14) {if (j > 10 && j < 34) {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "river", this); walls.add(wall);} else {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "grass", this); walls.add(wall);}}if (i >= 14 && i < 16) {if (j == 0 || j == 1 || j == 42 || j == 43) {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "stone", this); walls.add(wall);}}if (i >= 16 && i < 18) {if (j % 8 < 4) {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "stone", this); walls.add(wall);}}if (i >= 18 && i < 25) {if (j % 10 < 8) {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "tile", this); walls.add(wall);}}if (i >= 25 && i < 29) {if (j < 8) {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "grass", this); walls.add(wall);}if (j > 35) {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "river", this); walls.add(wall);}if (i > 26 && (j == 16 || j == 17 || j == 28 || j == 29)) {Wall wall = new Wall(WALL_X + j * 18, WALL_Y + i * 18, "tile", this); walls.add(wall);}}}}// 启动重画线程PaintThread pt = new PaintThread();Thread t = new Thread(pt);t.start();}/*** 在窗体中画出游戏界面*/public void paint(Graphics g) {if (this == null)return;Color c = g.getColor();g.setColor(Color.RED);if (!myTank.isLive()) {if (-- this.myTankNum > 0) {myTank = new Tank(Tank_X, Tank_Y, 4, true, this); } else {g.drawString("GameOver!", 350, 280);g.drawString("按F2键重新开始..", 340, 300);return;}}if (tankAllNum == 0) {g.drawString(".:恭喜过关!:.", 350, 280);g.drawString("按F2键重新开始..", 340, 300);return;}g.setColor(c);this.reinforceTank();this.drawMissiles(g);this.drawMyTank(g);this.drawEnemyTanks(g);this.drawWalls(g);this.drawExplodes(g);this.drawTreasure(g);this.drawMessage(g);}/*** 重写update方法,先将窗体上的图形画在图片对象上,再一次性显示*/public void update(Graphics g) {if (offScreenImage == null) {offScreenImage = this.createImage(WINDOW_WIDTH, WINDOW_HEIGHT); }Graphics gImage = offScreenImage.getGraphics();Color c = gImage.getColor();gImage.setColor(Color.BLACK);gImage.fillRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);gImage.setColor(c);paint(gImage);g.drawImage(offScreenImage, 0, 0, null);}/*** 用线程重画,每隔一段时间重画窗体* @author Magci**/private class PaintThread implements Runnable {/*** 每隔REFRESH_RATE毫秒重画一次窗体*/public void run() {while (true) {repaint();try {Thread.sleep(REFRESH_RATE);} catch (InterruptedException e) {e.printStackTrace();}}}}/*** 监听键盘事件,按方向键控制坦克移动* @author Magci**/private class KeyMonitor extends KeyAdapter {/*** 处理按键被按下事件*/public void keyPressed(KeyEvent e) {myTank.keyPressed(e);}/*** 处理按键被松开事件*/public void keyReleased(KeyEvent e) {myTank.keyReleased(e);}}/*** 敌方坦克增援*/public void reinforceTank() {if (tankNum < tankMaxNum && tankAllNum > tankNum) {int i = rand.nextInt(10);Tank enemyTank = new Tank(50 + 150 * i, 40, 4, false, this);if (!enemyTank.collidesWithTank(myTank, true) && !enemyTank.collidesWithTanks (enemyTanks, true)) {enemyTanks.add(enemyTank);this.tankNum ++;}}}/*** 加入墙* @param g Graphics对象*/public void drawWalls(Graphics g) {for (int i = 0; i < walls.size(); i++) { Wall wall = walls.get(i);wall.draw(g);}}/*** 画我方坦克* @param g Graphics对象*/public void drawMyTank(Graphics g) { if (myTank != null) {myTank.draw(g);if (trea != null)myTank.eatTreasure(trea);}}/*** 画敌方坦克* @param g Graphics对象*/public void drawEnemyTanks(Graphics g) {for (int i = 0; i < enemyTanks.size(); i++) {Tank enemyTank = enemyTanks.get(i);enemyTank.draw(g);enemyTank.collidesWithTank(myTank, false);enemyTank.collidesWithTanks(enemyTanks, false); }}/*** 画炮弹* @param g Graphics对象*/public void drawMissiles(Graphics g) {for (int i = 0; i < missiles.size(); i++) {Missile m = missiles.get(i);if (m != null) {m.draw(g);m.hitTanks(enemyTanks);m.hitTank(myTank);m.hitMissiles(missiles);}}}/*** 加入爆炸* @param g Graphics对象*/public void drawExplodes(Graphics g) {for (int i=0; i < explodes.size(); i++) { Explode e = explodes.get(i);e.draw(g);}}/*** 出现宝物* @param g Graphics对象*/public void drawTreasure(Graphics g) {if (rand.nextInt(100) == 0)trea = null;if (rand.nextInt(300) == 0) {int x = rand.nextInt(785);int y = rand.nextInt(555);trea = new Treasure(x, y, this);}if (trea != null) {trea.collidesWithWalls(walls);trea.draw(g);}}/*** 打印信息* @param g Graphics对象*/public void drawMessage(Graphics g) {Color c = g.getColor();g.setColor(Color.YELLOW);g.drawString("EnemyTanks Count: " + enemyTanks.size(), 10, 50);g.drawString("All EnemyTanks Count: " + this.tankAllNum, 10, 70);g.drawString("MyTank Count: " + this.myTankNum, 10, 90);g.drawString("MyTank Life: " + myTank.getLife(), 10, 110);g.setColor(c);}/*** 返回敌方坦克总数量* @return 敌方坦克总数量*/public int getTankAllNum() {return tankAllNum;}/*** 设置敌方坦克总数量* @param tankAllNum 敌方坦克总数量*/public void setTankAllNum(int tankAllNum) {this.tankAllNum = tankAllNum;}/*** 返回当前敌方坦克数量* @return 返回当前敌方坦克数量*/public int getTankNum() {return tankNum;}/*** 设置当前敌方坦克数量* @param tankNum 当前敌方坦克数量*/public void setTankNum(int tankNum) { this.tankNum = tankNum;}}Tank.java:程序代码package .ahau.mgc.tankwar; import java.awt.*;import java.awt.event.*;import java.util.*;import java.util.List;/*** 此类用于创建一个坦克* @author Magci**/public class Tank {/*** 坦克水平垂直移动时X、Y轴上的速度*/public static final int SPEED = 4;/*** 坦克45度移动时X、Y轴上的速度*/public static final int XYSPEED = (int) (Math.sqrt(2) * SPEED / 2); /*** 坦克的宽度*/public static final int WIDTH = 30;/*** 坦克的高度*/public static final int HEIGHT = 30;/*** 炮筒长度*/public static final int PT_LENGTH = 20;/*** 45度炮筒的X、Y坐标偏移量*/public static final int PT_XY = (int) (Math.sqrt(2) * PT_LENGTH) / 2; /*** 坦克初始生命值*/public static final int LIFE = 100;// 坦克左上角位置private int x, y;// 标记方向键的状态:true表示被按下,false表示被松开private boolean bL = false, bU = false, bR = false, bD = false;/*** 坦克方向*/public Direction dir = Direction.STOP;/*** 坦克炮筒方向*/public Direction ptDir = Direction.U;TankClient tc = null;//标记敌我坦克,true表示我方坦克,false表示敌方坦克private boolean good;//标记坦克生命状态private boolean live = true;private Random rand = new Random();//地方坦克改变一次方向需要的步数private int step = rand.nextInt(10) + 3;//坦克的上一个位置private int lastX = -1, lastY = -1;//坦克的生命值private int life = LIFE;//坦克生命条LifeBar lb = new LifeBar();//方向数private int dirNum = 8;//判断是否初始化private boolean init = false;private static Toolkit tk = Toolkit.getDefaultToolkit();private static Image[] tankImgs;private static Map<String,Image> imgs = new HashMap<String,Image>();static {tankImgs = new Image[] {tk.getImage(Tank.class.getClassLoader().getResource("images/myTankL.gif")),tk.getImage(Tank.class.getClassLoader().getResource("images/myTankU.gif")),tk.getImage(Tank.class.getClassLoader().getResource("images/myTankR.gif")),tk.getImage(Tank.class.getClassLoader().getResource("images/myTankD.gif")),tk.getImage(Tank.class.getClassLoader().getResource("images/enemyTankL.gif")), tk.getImage(Tank.class.getClassLoader().getResource("images/enemyTankU.gif")), tk.getImage(Tank.class.getClassLoader().getResource("images/enemyTankR.gif")),tk.getImage(Tank.class.getClassLoader().getResource("images/enemyTankD.gif")) };imgs.put("myTankL", tankImgs[0]);imgs.put("myTankU", tankImgs[1]);imgs.put("myTankR", tankImgs[2]);imgs.put("myTankD", tankImgs[3]);imgs.put("enemyTankL", tankImgs[4]);imgs.put("enemyTankU", tankImgs[5]);imgs.put("enemyTankR", tankImgs[6]);imgs.put("enemyTankD", tankImgs[7]);}/*** 根据坦克位置和敌我状态创建一个坦克* @param x 坦克左上角X坐标* @param y 坦克左上角Y坐标* @param good 坦克的敌我状态*/public Tank(int x, int y, boolean good) {this.x = x;this.y = y;this.good = good;}/*** 根据坦克位置,敌我状态和当前游戏窗体创建一个坦克* @param x 坦克左上角X坐标* @param y 坦克左上角Y坐标* @param good 坦克的敌我状态* @param tc 当前游戏窗体*/public Tank(int x, int y, boolean good, TankClient tc) {this(x, y, good);this.tc = tc;}/*** 根据坦克位置,敌我状态和当前游戏窗体创建一个坦克* @param x 坦克左上角X坐标* @param y 坦克左上角Y坐标* @param dirNum 方向数* @param good 坦克的敌我状态* @param tc 当前游戏窗体*/public Tank(int x, int y, int dirNum, boolean good, TankClient tc) { this(x, y, good, tc);this.dirNum =dirNum;}/*** 在窗体上画出坦克* @param g Graphics对象*/public void draw(Graphics g) {if (!this.live) {if (!this.good)tc.enemyTanks.remove(this);tc.setTankNum(tc.getTankNum() - 1);tc.setTankAllNum(tc.getTankAllNum() - 1); return;}Color c = g.getColor();if (good)g.setColor(Color.RED);elseg.setColor(Color.BLUE);this.drawTank(g);if (good)lb.draw(g);g.setColor(c);//敌方坦克定位if (!good) {if (step == 0) {Direction[] dirs = Direction.values();int i = rand.nextInt(5);dir = dirs[i];if (rand.nextInt(20) == 0)dir = Direction.D;step = rand.nextInt(10) + 3;}step --;if (!this.hasMyMissile())fire();}move();}/*** 方向键被按下后标记被按下的键* @param e 键盘事件*/public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode();switch (keyCode) {case KeyEvent.VK_LEFT:bL = true;break;case KeyEvent.VK_UP:bU = true;break;case KeyEvent.VK_RIGHT:bR = true;break;case KeyEvent.VK_DOWN:bD = true;break;case KeyEvent.VK_CONTROL:if (!this.hasMyMissile())fire();break;case KeyEvent.VK_A:superFire();break;case KeyEvent.VK_F2:tc = new TankClient("TankClient", 50, 10, 3); break;}locateDirection();}/*** 方向键被松开后标记被松开的键* @param e 键盘事件*/public void keyReleased(KeyEvent e) {int keyCode = e.getKeyCode();switch (keyCode) {case KeyEvent.VK_LEFT:bL = false;break;case KeyEvent.VK_UP:bU = false;break;case KeyEvent.VK_RIGHT:bR = false;break;case KeyEvent.VK_DOWN:bD = false;break;}locateDirection();}/*** 根据按下的键定位方向*/public void locateDirection() {if (dirNum == 4 || dirNum ==8) { if (bL && !bU && !bR && !bD) dir = Direction.L;if (!bL && bU && !bR && !bD) dir = Direction.U;if (!bL && !bU && bR && !bD) dir = Direction.R;if (!bL && !bU && !bR && bD) dir = Direction.D;}if (dirNum == 8) {if (bL && bU && !bR && !bD)dir = Direction.LU;if (!bL && bU && bR && !bD)dir = Direction.RU;if (!bL && !bU && bR && bD)dir = Direction.RD;if (bL && !bU && !bR && bD)dir = Direction.LD;}if (!bL && !bU && !bR && !bD) dir = Direction.STOP;}/*** 根据方向移动坦克*/public void move() {lastX = x;lastY = y;switch (dir) {case L:x -= SPEED;break;case LU:x -= XYSPEED;y -= XYSPEED;break;case U:y -= SPEED;break;case RU:x += XYSPEED;y -= XYSPEED;break;case R:x += SPEED;break;case RD:x += XYSPEED;y += XYSPEED;break;case D:y += SPEED;break;case LD:x -= XYSPEED;y += XYSPEED;break;case STOP:break;}if (dir != Direction.STOP)ptDir = dir;//控制坦克不出界if (x < 0)x = 0;if (y < 30)y = 30;if (x > TankClient.WINDOW_WIDTH - this.WIDTH) x = TankClient.WINDOW_WIDTH - this.WIDTH; if (y > TankClient.WINDOW_HEIGHT - this.HEIGHT) y = TankClient.WINDOW_HEIGHT - this.HEIGHT; }/*** 根据坦克的位置和炮筒的方向发射炮弹*/public void fire() {int mW = 0;int mH = 0;if (!this.live)return;if (ptDir == Direction.U || ptDir == Direction.D) {mW = Missile.WIDTH / 2;mH = Missile.HEIGHT / 2;} else if (ptDir == Direction.L || ptDir == Direction.R) { mW = Missile.HEIGHT / 2;mH = Missile.WIDTH / 2;}int x = this.x + Tank.WIDTH / 2 - mW;int y = this.y + Tank.HEIGHT / 2 - mH;Missile m = new Missile(x, y, this.good, ptDir, this, tc); tc.missiles.add(m);}/*** 根据方向画坦克* @param g Graphics对象*/public void drawTank(Graphics g) {if (good) {switch (ptDir) {case L:g.drawImage(imgs.get("myTankL"), x, y, null);break;case LU:break;case U:g.drawImage(imgs.get("myTankU"), x, y, null);break;case RU:break;case R:g.drawImage(imgs.get("myTankR"), x, y, null);break;case RD:break;case D:g.drawImage(imgs.get("myTankD"), x, y, null);break;case LD:break;}} else {switch (ptDir) {case L:g.drawImage(imgs.get("enemyTankL"), x, y, null); break;case LU:break;case U:g.drawImage(imgs.get("enemyTankU"), x, y, null);break;case RU:break;case R:g.drawImage(imgs.get("enemyTankR"), x, y, null);break;case RD:break;case D:g.drawImage(imgs.get("enemyTankD"), x, y, null);break;case LD:break;}}}/*** 返回坦克的矩形碰撞区域* @return 坦克的矩形碰撞区域*/public Rectangle getRect() {Rectangle rect = new Rectangle(x, y, this.WIDTH, this.HEIGHT); return rect;}/*** 返回坦克的生命状态* @return 坦克的生命状态*/public boolean isLive() {return live;}/*** 设置坦克的生命状态* @param live 坦克的生命状态*/public void setLive(boolean live) { this.live = live;}/*** 返回坦克的敌我状态* @return 坦克的敌我状态*/public boolean isGood() {return good;}/*** 设置坦克的方向* @param dir 坦克的方向*/public void setDir(Direction dir) {this.dir = dir;}/*** 坦克回到上一个位置*/public void stay() {if (x != -1 && y != -1) {this.x = stX;this.y = stY;} else {tc.enemyTanks.remove(this);tc.setTankAllNum(tc.getTankAllNum() - 1);tc.setTankNum(tc.getTankNum() - 1);}}/*** 判断是否与其他坦克相撞* @param t 坦克* @param newTank 是否新坦克* @return 坦克是否与其他坦克相撞*/public boolean collidesWithTank(Tank t, boolean newTank) {if (this.live && t.isLive() && t != this && this.getRect().intersects(t.getRect())) { if (!newTank) {this.stay();t.stay();}return true;}return false;}/*** 依次判断其他所有坦克是否与该坦克相撞* @param tanks 存放坦克的容器* @param newTank 是否新坦克* @return 坦克是否与其他坦克相撞*/public boolean collidesWithTanks(List<Tank> tanks, boolean newTank) { for (int i = 0; i < tanks.size(); i++) {Tank t = tanks.get(i);this.collidesWithTank(t, newTank);}return false;}/*** 发射超级炮弹(四个方向同时开火)*/public void superFire() {if (!this.live)return;int x = 0, y = 0, mW = 0, mH = 0;Direction[] dirs = Direction.values();for (int i = 0; i < 5; i++) {if (ptDir == Direction.U || ptDir == Direction.D) {mW = Missile.WIDTH / 2;mH = Missile.HEIGHT / 2;} else if (ptDir == Direction.L || ptDir == Direction.R) { mW = Missile.HEIGHT / 2;mH = Missile.WIDTH / 2;}x = this.x + Tank.WIDTH / 2 - mW;y = this.y + Tank.HEIGHT / 2 - mH;if (dirs[i] != Direction.STOP) {Missile m = new Missile(x, y, this.good, dirs[i], this, tc); tc.missiles.add(m);}}}/*** 返回坦克的生命值* @return 坦克的生命值*/public int getLife() {return life;}/*** 设置坦克的生命值* @param life 坦克的生命值*/public void setLife(int life) {this.life = life;}/*** 创建生命条* @author Magci**/class LifeBar {/*** 在坦克上方画生命条* @param g Graphics对象*/public void draw(Graphics g) {Color c = g.getColor();g.setColor(Color.RED);g.drawRect(x, y - 10, WIDTH, 5);g.fillRect(x, y - 10, WIDTH * life / 100, 5);g.setColor(c);}}/*** 判断坦克是否碰到宝物* @param trea 宝物* @return 坦克是否碰到宝物*/public boolean eatTreasure(Treasure trea) {if (this.live && trea.isLive() && this.getRect().intersects(trea.getRect())) { trea.setLive(false);this.life = LIFE;return true;}return false;}/*** 返回坦克左上角X坐标* @return 坦克左上角X坐标*/public int getX() {return x;}/*** 设置坦克左上角X坐标* @param x*/public void setX(int x) {this.x = x;}/*** 返回坦克左上角Y坐标* @return 坦克左上角Y坐标*/public int getY() {return y;}/*** 设置坦克左上角Y坐标* @param y 坦克左上角Y坐标*/public void setY(int y) {this.y = y;}/*** 判断是否有该坦克发射的炮弹* @return 是否有该坦克发射的炮弹*/public boolean hasMyMissile() {for (int i = 0; i < tc.missiles.size(); i++) { Missile m = tc.missiles.get(i);if (m.getT() == this)return true;}return false;}}Missile.java:程序代码package .ahau.mgc.tankwar; import java.awt.*;import java.util.List;import java.util.*;/*** 此类用于创建炮弹* @author Magci**/public class Missile {/*** 炮弹宽度*/public static final int WIDTH = 30; /*** 炮弹长度*/public static final int HEIGHT = 30; /*** 炮弹水平垂直发射时X、Y轴上的速度 */public static final int SPEED = 15;/*** 炮弹45度发射时X、Y轴上的速度*/public static final int XYSPEED = (int) (Math.sqrt(2) * SPEED / 2);// 炮弹左上角位置private int x, y;Direction ptDir;TankClient tc = null;Tank t;//标记炮弹是否存在private boolean live = true;//标记炮弹的敌我状态private boolean good;//标记是否初始化private boolean init = false;private static Toolkit tk = Toolkit.getDefaultToolkit();private static Image[] missileImgs;private static Map<String, Image> imgs = new HashMap<String, Image>();static {missileImgs = new Image[] {tk.getImage(Missile.class.getClassLoader().getResource("images/missileL.gif")), tk.getImage(Missile.class.getClassLoader().getResource("images/missileU.gif")), tk.getImage(Missile.class.getClassLoader().getResource("images/missileR.gif")), tk.getImage(Missile.class.getClassLoader().getResource("images/missileD.gif")) };imgs.put("L",missileImgs[0]);imgs.put("U",missileImgs[1]);imgs.put("R",missileImgs[2]);imgs.put("D",missileImgs[3]);}/*** 根据坦克位置、炮筒方向、坦克敌我状态、发射炮弹的坦克、当前窗体创建炮弹* @param x 坦克中心X坐标* @param y 坦克中心Y坐标* @param good 坦克敌我状态* @param ptDir 炮筒方向* @param t 发射炮弹的坦克* @param tc 当前窗体*/public Missile(int x, int y, boolean good, Direction ptDir, Tank t, TankClient tc) { this.x = x;this.y = y;this.good = good;this.ptDir = ptDir;this.t = t;this.tc = tc;}/*** 在窗体上画出炮弹* @param g Graphics对象*/public void draw(Graphics g) {if (!this.live) {tc.missiles.remove(this);return;}if (!init) {for(int i = 0; i < missileImgs.length; i++)g.drawImage(missileImgs[i], -100, -100, null); init = true;}Color c = g.getColor();if (this.good)g.setColor(Color.RED);elseg.setColor(Color.BLACK);this.drawMissile(g);g.setColor(c);move();}/*** 根据炮筒方向发射炮弹*/public void move() {switch (ptDir) {case L:x -= SPEED;break;case LU:x -= XYSPEED; y -= XYSPEED; break;case U:y -= SPEED;break;case RU:x += XYSPEED; y -= XYSPEED; break;case R:x += SPEED; break;case RD:x += XYSPEED; y += XYSPEED; break;case D:y += SPEED; break;case LD:x -= XYSPEED; y += XYSPEED; break;}//判断炮弹是否出界if (x < 0 || x > TankClient.WINDOW_WIDTH || y < 0 || y > TankClient.WINDOW_HE IGHT) {live = false;}}/*** 返回炮弹的矩形碰撞区域* @return 炮弹的矩形碰撞区域*/public Rectangle getRect() {int w = 0, h = 0;if (ptDir == Direction.U || ptDir == Direction.D) {w = this.WIDTH;h = this.HEIGHT;} else if (ptDir == Direction.L || ptDir == Direction.R) {w = this.HEIGHT;h = this.WIDTH;}Rectangle rect = new Rectangle(x, y, w, h);return rect;}/*** 判断是否击中坦克* @param t 坦克* @return 是否击中坦克*/public boolean hitTank(Tank t) {if (this.getRect().intersects(t.getRect()) && t.isLive() && this.live && t.isGood() != thi s.good) {if (t.isGood()) {t.setLife(t.getLife() - 20);if (t.getLife() <= 0)t.setLive(false);} else {t.setLive(false);}this.live = false;Explode e = new Explode(x, y, tc);tc.explodes.add(e);return true;}return false;}/*** 依次判断所有的敌方坦克是否被该炮弹击中* @param enemyTanks 敌方坦克* @return 否击中敌方坦克*/public boolean hitTanks(List<Tank> enemyTanks) {for (int i = 0; i < enemyTanks.size(); i++) {Tank enemyTank = enemyTanks.get(i);if (hitTank(enemyTank))return true;}return false;}/*** 设置炮弹左上角的X坐标* @return 炮弹左上角的X坐标*/public int getX() {return x;}/*** 设置炮弹左上角的Y坐标* @return 炮弹左上角的Y坐标*/public int getY() {return y;}/*** 判断炮弹是否击中对方炮弹* @param m 炮弹* @return 炮弹是否击中对方炮弹*/public boolean hitMissile(Missile m) {if (this.live && m.isLive() && this.good != m.isGood() && this.getRect().intersects(m. getRect())) {this.live = false;m.setLive(false);return true;}return false;}/*** 依次判断对方所有的炮弹是否被该炮弹击中* @param missiles 存放炮弹的容器* @return 炮弹是否击中对方炮弹*/public boolean hitMissiles(List<Missile> missiles) { for (int i = 0; i < missiles.size(); i++) {Missile m = missiles.get(i);if (hitMissile(m))return true;}return false;}/*** 返回炮弹的敌我状态* @return 炮弹的敌我状态*/public boolean isGood() {return good;}/*** 返回炮弹的生命状态* @return 炮弹的生命状态*/public boolean isLive() {return live;}/*** 设置炮弹的生命状态* @param live 炮弹的生命状态*/public void setLive(boolean live) { this.live = live;}/*** 返回发射该炮弹的坦克* @return 发射该炮弹的坦克*/public Tank getT() {return t;}/*** 根据方向画炮弹* @param g Graphics对象*/public void drawMissile(Graphics g) {switch (ptDir) {case L:g.drawImage(imgs.get("L"), x, y, null); break;case LU:break;case U:g.drawImage(imgs.get("U"), x, y, null); break;case RU:break;case R:g.drawImage(imgs.get("R"), x, y, null); break;case RD:break;case D:g.drawImage(imgs.get("D"), x, y, null); break;case LD:break;}}}Explode.java:程序代码package .ahau.mgc.tankwar;import java.awt.*;/*** 此类用于创建爆炸* @author Magci**/public class Explode {private int x, y;private int step = 0;private boolean live = true;private int radius = 10;TankClient tc;private static Toolkit tk = Toolkit.getDefaultToolkit();private static Image[] imgs = {tk.getImage(Explode.class.getClassLoader().getResource("images/0.gif")), tk.getImage(Explode.class.getClassLoader().getResource("images/1.gif")), tk.getImage(Explode.class.getClassLoader().getResource("images/2.gif")), tk.getImage(Explode.class.getClassLoader().getResource("images/3.gif")), tk.getImage(Explode.class.getClassLoader().getResource("images/4.gif")), tk.getImage(Explode.class.getClassLoader().getResource("images/5.gif"))。
MyTankGame2.javapackage test;import javax.swing.*;import java.awt.*;import java.awt.event.*;//import java.io.*;import java.util.*;class MyTankGame2 extends JFrame implements ActionListener {MyPanel mp=null;//定义一个开始的面板MyStartPanel msp=null;//做出我需要的菜单JMenuBar jmb=null;//开始游戏JMenu jm1=null;JMenuItem jmi1=null;//退出系统JMenuItem jmi2=null;//存盘退出JMenuItem jmi3=null;JMenuItem jmi4=null;public static void main(String[] args){//System.out.println("Hello World!");MyTankGame2 mtg=new MyTankGame2();}//构造方法public MyTankGame2(){//创建菜单及菜单选项jmb=new JMenuBar();jm1=new JMenu("游戏(G)");//设置助记符jm1.setMnemonic('G');jmi1=new JMenuItem("开始新游戏(N)");jmi2=new JMenuItem("退出游戏(E)");jmi3=new JMenuItem("存盘退出游戏");jmi4=new JMenuItem("继续上局游戏");jmi4.addActionListener(this);jmi4.setActionCommand("continueGame");jmi3.addActionListener(this);jmi3.setActionCommand("saveExit");jmi2.setMnemonic('E');//对jmi1进行响应jmi1.addActionListener(this);jmi1.setActionCommand("newGame");jmi2.addActionListener(this);jmi2.setActionCommand("exit");jm1.add(jmi1);jm1.add(jmi2);jm1.add(jmi3);jm1.add(jmi4);jmb.add(jm1);msp=new MyStartPanel();Thread t=new Thread(msp);t.start();this.setJMenuBar(jmb);this.add(msp);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setSize(600,450);this.setVisible(true);}@Overridepublic void actionPerformed(ActionEvent e) {//对用户不同的点击进行不同的处理if(e.getActionCommand().equals("newGame")){mp=new MyPanel("newGame");Thread t=new Thread(mp);t.start();//先删除旧的面板this.remove(msp);this.add(mp);//注册监听this.addKeyListener(mp);//显示this.setVisible(true);}else if(e.getActionCommand().equals("exit")){//保存击毁敌人的数量Recorder.keepRecording();System.exit(0);}//对存盘退出做处理else if(e.getActionCommand().equals("saveExit")){//工作Recorder re=new Recorder();re.setEts(mp.ets);//保存击毁敌人的数量和敌人的坐标re.keepRecAndEnemyTank();//退出System.exit(0);}else if(e.getActionCommand().equals("continueGame")){ //mp=new MyPanel("con");//mp.flag=;Thread t=new Thread(mp);t.start();//先删除旧的面板this.remove(msp);this.add(mp);//注册监听this.addKeyListener(mp);//显示this.setVisible(true);}}}class MyStartPanel extends JPanel implements Runnable{ int times=0;public void paint(Graphics g){super.paint(g);g.fillRect(0, 0, 400, 300);//提示信息if(times%2==0){g.setColor(Color.yellow);//开关信息的字体Font myFont=new Font("华文新魏",Font.BOLD,30);g.setFont(myFont);g.drawString("stage:1", 150, 140);}}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){//休眠try {Thread.sleep(100);} catch (Exception e) {// TODO: handle exception}times++;//重画this.repaint();}}}//我的面板class MyPanel extends JPanel implements KeyListener,Runnable {//定义我的坦克Hero hero=null;//判断继续上局还是新游戏//定义敌人的坦克组Vector<EnemyTank> ets=new Vector<EnemyTank>();Vector<Node> nodes=new Vector<Node>();//定义炸弹集合Vector<Bomb> bombs=new Vector<Bomb>();int enSize=5;//定义三张图片Image image1=null;Image image2=null;Image image3=null;//构造方法public MyPanel(String flag){//恢复记录Recorder.getRecording();hero=new Hero(30,231);if(flag.equals("newGame")){//初始化敌人的坦克for(int i=0;i<enSize;i++){//创建一辆敌人的坦克对象EnemyTank et=new EnemyTank((i+1)*50,0);et.setColor(0);et.setDirect(2);//将MyPanel的敌人坦克向量交给该敌人坦克et.setEts(ets);//启动敌人的坦克Thread t=new Thread(et);t.start();//给敌人的坦克添加一颗子弹Shot s=new Shot(et.x+10, et.y+30, 2,1);et.ss.add(s);new Thread(s).start();ets.add(et);//加入}}else{nodes=new Recorder().getNodesAndEnNums();//初始化敌人的坦克for(int i=0;i<nodes.size();i++){Node node=nodes.get(i);//创建一辆敌人的坦克对象EnemyTank et=new EnemyTank(node.x,node.y);et.setColor(0);et.setDirect(node.direct);//将MyPanel的敌人坦克向量交给该敌人坦克et.setEts(ets);//启动敌人的坦克Thread t=new Thread(et);t.start();//给敌人的坦克添加一颗子弹Shot s=new Shot(et.x+10, et.y+30, 2,1);et.ss.add(s);new Thread(s).start();ets.add(et);//加入}}/*try {image1=ImageIO.read(new File("/bomb_1.gif"));image2=ImageIO.read(new File("/bomb_2.gif"));image3=ImageIO.read(new File("/bomb_3.gif"));} catch (Exception e) {e.printStackTrace();// TODO: handle exception}*///播放开战声音AePlayWave apw=new AePlayWave("F:\\myjava\\day9\\坦克大战\\TankGamae13\\src\\111.wav");apw.start();//初始化图片image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource( "/bomb_1.gif"));image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource( "/bomb_2.gif"));image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource( "/bomb_3.gif"));}//画出提示信息public void showInfo(Graphics g){//画出提示信息坦克(该坦克不参与战斗)this.drawTank(100, 320, g, 0, 0);g.setColor(Color.black);g.drawString(Recorder.getEnNum()+"", 128, 343);this.drawTank(165, 320, g, 0, 1);g.setColor(Color.black);g.drawString(Recorder.getMyLife()+"", 195, 343);//画出玩家的总成绩g.setColor(Color.black);Font f=new Font("宋体",Font.BOLD,20);g.setFont(f);g.drawString("您的总成绩", 410, 25);this.drawTank(420, 60, g, 0, 0);g.setColor(Color.black);g.drawString(Recorder.getAllEnNum()+"", 455, 80);}//重写paint函数public void paint(Graphics g){super.paint(g);g.fillRect(0,0,400,300);//画出提示信息this.showInfo(g);//画出自己的坦克if(hero.isLive){this.drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),1);}//从ss中取出每一颗子弹并绘制for(int i=0;i<hero.ss.size();i++){Shot myShot =hero.ss.get(i);//画出子弹if(myShot!=null&&myShot.isLive==true){g.draw3DRect(myShot.x, myShot.y, 1, 1, false);}if(myShot.isLive==false){//从ss中删除掉该子弹hero.ss.remove(myShot);}}//画出炸弹for(int i=0;i<bombs.size();i++){Bomb b=bombs.get(i);if(b.life>6){g.drawImage(image1, b.x, b.y, 30, 30,this);}else if(b.life>3){g.drawImage(image2, b.x, b.y, 30, 30,this);}else{g.drawImage(image3, b.x, b.y, 30, 30,this);}//让b的生命值减小b.lifeDown();if(b.life==0){//把炸弹从向量中去掉bombs.remove(b);}}//画出敌人的坦克for(int i=0;i<ets.size();i++){ EnemyTank et=ets.get(i);if(et.isLive){this.drawTank(et.getX(),et.getY(), g, et.getDirect(), 0);//顺便画出敌人的子弹for(int j=0;j<et.ss.size();j++){//取出子弹Shot enemyShot=et.ss.get(j);if(enemyShot.isLive){g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);}else{//如果死亡了,就从Vextor中删除掉et.ss.remove(enemyShot);}}}}}//判断我的子弹是否会击中敌人的坦克public void hitEnemyTank(){//判断是否会击中for(int i=0;i<hero.ss.size();i++){//取出子弹Shot myShot=hero.ss.get(i);//判断子弹是否有效if(myShot.isLive){//取出每一个敌人坦克与之匹配for(int j=0;j<ets.size();j++){//取出坦克EnemyTank et=ets.get(j);if(et.isLive){if(this.hitTank(myShot, et)){ //减少敌人数量Recorder.reduceEnNum();//增加我的记录Recorder.addEnEnum();}}}}}}//我是否被击中public void hitMe(){//取出每一个敌人的坦克for(int i=0;i<this.ets.size();i++){//取出坦克EnemyTank et=ets.get(i);//取出每颗子弹for(int j=0;j<et.ss.size();j++){//取出子弹Shot enemyShot=et.ss.get(j);if(hero.isLive){if(this.hitTank(enemyShot, hero)){//待写}}}}}//画出一个专门判断子弹是否击中敌人坦克的函数public boolean hitTank(Shot s ,Tank et){boolean b2=false;//判断该坦克的方向switch(et.direct){//敌人坦克的方向是向上或者向下case 0:case 2:if(s.x>et.x&&s.x<et.x+20&&s.y>et.y&&s.y<et.y+30){//击中//子弹死亡s.isLive=false;//敌人坦克死亡et.isLive=false;b2=true;//System.out.println("hytfyfrujyg");//创建一颗炸弹放入VectorBomb b=new Bomb(et.x, et.y);bombs.add(b);}break;case 1:case 3:if(s.x>et.x&&s.x<et.x+30&&s.y>et.y&&s.y<et.y+20){//击中//子弹死亡s.isLive=false;//敌人坦克死亡et.isLive=false;b2=true;Bomb b=new Bomb(et.x, et.y);bombs.add(b);}break;}return b2;}//画出坦克的函数(扩展)public void drawTank(int x,int y,Graphics g,int direction,int type) {//判断类型switch(type){case 0:g.setColor(Color.CYAN);break;case 1:g.setColor(Color.yellow);break;}//判断方向switch(direction){//向上走case 0://g.setColor(Color.CYAN);//画出我的坦克(到时再封装成一个函数)//1.画出左边的矩形g.fill3DRect(x,y,5,30,false);//2.画出右边边的矩形g.fill3DRect(x+15,y,5,30,false);//3画出中间的矩形g.fill3DRect(x+5,y+5,10,20,false);//4画圆形g.fillOval(x+5,y+10,10,10);//5.画出线g.drawLine(x+10,y+15,x+10,y);break;case 1://向右g.fill3DRect(x, y, 30,5, false);g.fill3DRect(x, y+15, 30,5 ,false);g.fill3DRect(x+5, y+5, 20, 10, false);g.fillOval(x+10, y+5, 10, 10);g.drawLine(x+15, y+10, x+30, y+10);break;case 2://向下g.fill3DRect(x,y,5,30,false);//2.画出右边边的矩形g.fill3DRect(x+15,y,5,30,false);//3画出中间的矩形g.fill3DRect(x+5,y+5,10,20,false);//4画圆形g.fillOval(x+5,y+10,10,10);//5.画出线g.drawLine(x+10,y+15,x+10,y+30);break;case 3://向左g.fill3DRect(x, y, 30,5, false);g.fill3DRect(x, y+15, 30,5 ,false);g.fill3DRect(x+5, y+5, 20, 10, false);g.fillOval(x+10, y+5, 10, 10);g.drawLine(x+15, y+10, x, y+10);break;}}@Overridepublic void keyTyped(KeyEvent e) {// TODO Auto-generated method stub}@Override//w上,s下,a左,右边public void keyPressed(KeyEvent e) {// TODO Auto-generated method stubif(e.getKeyCode()==KeyEvent.VK_W){//设置我的坦克的方向上this.hero.setDirect(0);if(this.hero.y>0){this.hero.moveUp();}}else if(e.getKeyCode()==KeyEvent.VK_D){//设置我的坦克的方向右边this.hero.setDirect(1);if(this.hero.x<370){this.hero.moveRight();}}else if(e.getKeyCode()==KeyEvent.VK_S){//设置我的坦克的方向 xia边this.hero.setDirect(2);if(this.hero.y<=271){this.hero.moveDown();}}else if(e.getKeyCode()==KeyEvent.VK_A){//设置我的坦克的方向左边this.hero.setDirect(3);if(this.hero.x>0){this.hero.moveLeft();}}if(e.getKeyCode()==KeyEvent.VK_K){//玩家按了一个k键,开火if(this.hero.ss.size()<=5){this.hero.shotEnemy();}}//必须用repaintPanelthis.repaint();}@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub }@Overridepublic void run() {// TODO Auto-generated method stub//每隔100毫秒去重画while(true){try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.hitEnemyTank();this.hitMe();//重绘this.repaint();}}}Members.javapackage test;import java.io.*;import java.util.Vector;import javax.sound.sampled.AudioFormat;import javax.sound.sampled.AudioInputStream;import javax.sound.sampled.AudioSystem;import javax.sound.sampled.DataLine;import javax.sound.sampled.SourceDataLine;class AePlayWave extends Thread {private String filename;public AePlayWave(String wavfile) {filename = wavfile;}public void run() {File soundFile = new File(filename);AudioInputStream audioInputStream = null;try {audioInputStream = AudioSystem.getAudioInputStream(soundFile);} catch (Exception e1) {e1.printStackTrace();return;}AudioFormat format = audioInputStream.getFormat();SourceDataLine auline = null; info = new (SourceDataLine.class, format);try {auline = (SourceDataLine) AudioSystem.getLine(info);auline.open(format);} catch (Exception e) {e.printStackTrace();return;}auline.start();int nBytesRead = 0;byte[] abData = new byte[512];try {while (nBytesRead != -1) {nBytesRead = audioInputStream.read(abData, 0, abData.length);if (nBytesRead >= 0)auline.write(abData, 0, nBytesRead);}} catch (IOException e) {e.printStackTrace();return;} finally {auline.drain();auline.close();}}}class Node//恢复点{int x,y,direct;public Node(int x,int y,int direct){this.x=x;this.y=y;this.direct=direct;}}//记录类,同时也可以保存一些设置class Recorder{//记录每关有多少敌人private static int enNum=5;//设置我有多少可用的人private static int myLife=3;//记录总共消灭了多少敌人private static int allEnNum=0;//从文件中恢复记录点static Vector<Node> nodes=new Vector<Node>();private static FileWriter fw=null;private static BufferedWriter bw=null;private static FileReader fr=null;private static BufferedReader br=null;private Vector <EnemyTank> ets=new Vector<EnemyTank>();public Vector<EnemyTank> getEts() {return ets;}public void setEts(Vector<EnemyTank> ets) {this.ets = ets;}//完成读取任务public Vector<Node> getNodesAndEnNums(){try {fr=new FileReader("F:\\myRecording.txt");br=new BufferedReader(fr);String n="";//先读取第一行n=br.readLine();allEnNum=Integer.parseInt(n);while((n=br.readLine())!=null){String []xyz=n.split(" ");Node node=new Node(Integer.parseInt(xyz[0]),Integer.parseInt(xyz[1]),Integer.parseInt(xyz[2]));nodes.add(node);}} catch (Exception e) {e.printStackTrace();// TODO: handle exception}finally{try {br.close();fr.close();} catch (Exception e2) {// TODO: handle exception}}return nodes;}//保存击毁敌人坦克的数量和敌人坦克的坐标,方向public void keepRecAndEnemyTank(){try {//创建fw=new FileWriter("F:\\myRecording.txt");bw=new BufferedWriter(fw);bw.write(allEnNum+"\r\n");//保存当前还活着的坐标和方向for(int i=0;i<ets.size();i++){//取出第一个坦克EnemyTank et=ets.get(i);if(et.isLive){String record=et.x+" "+et.y+" "+et.direct;//写入到文件bw.write(record+"\r\n");}}} catch (Exception e) {// TODO: handle exception}finally{//关闭流try {bw.close();fw.close();} catch (Exception e2) {// TODO: handle exception}}}//从文件中读取记录public static void getRecording(){try {fr=new FileReader("F:\\myRecording.txt");br=new BufferedReader(fr);String n=br.readLine();allEnNum=Integer.parseInt(n);} catch (Exception e) {e.printStackTrace();// TODO: handle exception}finally{try {br.close();fr.close();} catch (Exception e2) {// TODO: handle exception}}}//把玩家击毁敌人的坦克数量保存到文件中public static void keepRecording(){try {//创建fw=new FileWriter("F:\\myRecording.txt");bw=new BufferedWriter(fw);bw.write(allEnNum+"\r\n");} catch (Exception e) {// TODO: handle exception}finally{//关闭流try {bw.close();fw.close();} catch (Exception e2) {// TODO: handle exception}}}public static int getAllEnNum() {return allEnNum;}public static void setAllEnNum(int allEnNum) { Recorder.allEnNum = allEnNum;}public static int getEnNum() {return enNum;}public static void setEnNum(int enNum) {Recorder.enNum = enNum;}public static int getMyLife() {return myLife;}public static void setMyLife(int myLife) { Recorder.myLife = myLife;}//减少敌人数public static void reduceEnNum(){enNum--;}//消灭敌人public static void addEnEnum(){allEnNum++;}}//炸弹类class Bomb{int x,y;//炸弹的生命int life=9;boolean isLive=true;public Bomb(int x,int y){this.x=x;this.y=y;}//减少生命值public void lifeDown(){if(life>0){life--;}else{this.isLive=false;}}}//子弹类class Shot implements Runnable{int x,y;int direct;int speed=1;//是否还活着boolean isLive=true;public Shot(int x,int y,int direct,int speed) {this.x=x;this.y=y;this.direct=direct;this.speed=speed;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}switch(direct){case 0://向上y-=speed;break;case 1://向右x+=speed;break;case 2://下y+=speed;break;case 3:x-=speed;break;}//子弹何时死亡if(x<0||x>400||y<0||y>300){this.isLive=false;break;}//System.out.println(x+""+y);}}}//坦克类class Tank{int x=0;int y=0;//定义方向的值0上,右2,下3,左int direct=0;//坦克的速度int speed=1;int color=0;boolean isLive=true;public int getColor() {return color;}public void setColor(int color) {this.color = color;}public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}public int getDirect() {return direct;}public void setDirect(int direct) {this.direct = direct;}public Tank(int x,int y){this.x=x;this.y=y;}public int getX(){return x;}public int getY(){return y;}public void setX(int x){this.x=x;}public void setY(int y){this.y=y;}}//敌人的坦克 ,做成线程class EnemyTank extends Tank implements Runnable {//boolean isLive=true;int times=0;//定义一个向量,可以访问到MyPanel上所有敌人的坦克Vector<EnemyTank> ets=new Vector<EnemyTank>();//定义一个向量,可以存放敌人的子弹Vector <Shot> ss=new Vector<Shot>();//敌人添加子弹应当在刚刚创建坦克和敌人的坦克子弹死亡之后public EnemyTank(int x, int y){super(x, y);}//得到MyPanel的敌人坦克向量public void setEts(Vector<EnemyTank>vv){this.ets=vv;}//判断是否碰到了别人的敌人的坦克public boolean isTouchOtherEnemy(){boolean b=false;//..。