黑马_blog2_坦克大战游戏代码

来源:互联网 发布:小学生编程比赛 编辑:程序博客网 时间:2024/05/21 16:59

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

坦克大战游戏思路及代码:

/** * 1.画出坦克 * 2.坦克能移动 * 3.画出3个敌人的坦克 * 4.我的坦克能够发射一个子弹,并且碰到边缘的时候停止,子弹可以连发(最多5颗子弹) * 5.我方坦克集中敌人的坦克时,敌人的坦克就消失,做出爆炸效果最好 * 6.让敌人的坦克可以自由随机的上下左右移动  * 7.控制敌人坦克在一定范围内移动 * 8.让敌人的坦克也能发射子弹 * 9.当敌人的坦克击中我的坦克时,我的坦克就爆炸 * 10.可以分关 * 11.可以玩游戏的时候暂停和继续 *    将坦克和子弹的速度设为0,并且坦克的方向不变化 * 12.可以记录玩家的成绩 *    先保存共击毁多少坦克 *    可以记录敌人坦克坐标并可以恢复 * 13.java对声音的处理 */import java.awt.*;import javax.imageio.ImageIO;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;import javax.swing.*;import java.awt.event.*;import java.io.*;import java.util.*;@SuppressWarnings("serial")public class MyTankGame extends JFrame implements ActionListener{private MyPanel mp;private FirstPanel fp;private MenuBar mb;private Menu m;private MenuItem mi1,mi2,mi3,mi4;public MyTankGame(){//界面fp=new FirstPanel();new Thread(fp).start();this.add(fp);//菜单mb=new MenuBar();m=new Menu("菜单");mi1=new MenuItem("开始游戏");mi2=new MenuItem("退出游戏");mi3=new MenuItem("存盘退出");mi4=new MenuItem("续上一局");mi1.addActionListener(this);mi1.setActionCommand("开始游戏");mi2.addActionListener(this);mi2.setActionCommand("退出游戏");mi3.addActionListener(this);mi3.setActionCommand("存盘退出");mi4.addActionListener(this);mi4.setActionCommand("续上一局");m.add(mi1);m.add(mi2);m.add(mi3);m.add(mi4);mb.add(m);this.setMenuBar(mb);//this.setSize(600,500);this.setLocation(300,300);this.setVisible(true);}public static void main(String[] args) {// TODO Auto-generated method stubnew MyTankGame();}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif(e.getActionCommand().equals("开始游戏")){mp=new MyPanel("newgame");new Thread(mp).start();this.addKeyListener(mp);this.setSize(600,500);//先移除原来的,再增加现在的this.remove(fp);this.add(mp);//设置可见为truethis.setVisible(true);}else if(e.getActionCommand().equals("退出游戏")){//保存之前的存储记录,再退出Recorder.keepRecording();System.exit(0);}else if(e.getActionCommand().equals("存盘退出")){Recorder rd=new Recorder();rd.setEts(mp.ets);rd.keepEnemyRecording();System.exit(0);}else if(e.getActionCommand().equals("续上一局")){mp=new MyPanel("lastgame");new Thread(mp).start();this.addKeyListener(mp);this.setSize(600,500);//先移除原来的,再增加现在的this.remove(fp);this.add(mp);//设置可见为truethis.setVisible(true);}}}//播放声音的类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;DataLine.Info info = new DataLine.Info(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;int y;int direct;public Node(int x,int y,int direct){this.x=x;this.y=y;this.direct=direct;}}//记录类class Recorder{  private static int enNum=20;private static int myNum=3;private static int allTankNum=0;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>();private Vector<Node> nodes=new Vector<Node>();public Vector<EnemyTank> getEts() {return ets;}public void setEts(Vector<EnemyTank> ets) {this.ets = ets;}public static int getEnNum() {return enNum;}public static void setEnNum(int enNum) {Recorder.enNum = enNum;}public static int getMyNum() {return myNum;}public static void setMyNum(int myNum) {Recorder.myNum = myNum;}public static int getAllTankNum() {return allTankNum;}public static void setAllTankNum(int allTankNum) {Recorder.allTankNum = allTankNum;}public static void reduceEnNum(){enNum--;}public static void reduceMyNum(){myNum--;}public static void addAllTankNum(){allTankNum++;}//将坦克的坐标和方向写入硬盘中public  void keepEnemyRecording(){try{fw=new FileWriter("Recorder.txt");bw=new BufferedWriter(fw);bw.write(allTankNum+"\r\n");for(int i=0;i<ets.size();i++){EnemyTank et=ets.get(i);String n=et.getX()+" "+et.getY()+" "+et.getDirect()+"\r\n";bw.write(n);}}catch(IOException e){e.printStackTrace();}finally{try{if(bw!=null)bw.close();}catch(IOException e){e.printStackTrace();}}}//将坦克的位置和方向读入到内存中public Vector<Node> getEnemyRecording(){try{fr=new FileReader("Recorder.txt");br=new BufferedReader(fr);allTankNum=Integer.parseInt(br.readLine());String 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(IOException e){e.printStackTrace();}finally{try{if(br!=null)br.close();}catch(IOException e){e.printStackTrace();}}return nodes;}//从硬盘中将坦克数量读入到内存中public static void getRecording(){try{File f=new File("Recorder.txt");if(!f.exists()){allTankNum=0;}else{fr=new FileReader(f);    br=new BufferedReader(fr);allTankNum=Integer.parseInt(br.readLine());}}catch(IOException e){e.printStackTrace();}finally{try{if(br!=null){br.close();    }}catch(IOException e){e.printStackTrace();}}}//将击毁的坦克数量存到硬盘中public static void keepRecording(){try{fw=new FileWriter("recorder.txt");bw=new BufferedWriter(fw);bw.write(allTankNum+"\r\n");}catch(IOException e){e.printStackTrace();}finally{try{if(bw!=null){bw.close();}}catch(IOException e){e.printStackTrace();}}}}//炸弹类class Bomb{int x;int y;int life=6;boolean isAlive=true;public Bomb(int x,int y){this.x=x;this.y=y;}public void lifeDown(){if(life>0){life--;}else{this.isAlive=false;}}}//子弹类class Shot implements Runnable{int x;int y;int direct;int speed=5;boolean isAlive=true;public Shot(int x,int y,int direct){this.x=x;this.y=y;this.direct=direct;}public void run(){while(true){try{Thread.sleep(50);}catch(Exception e){e.printStackTrace();}switch(this.direct){case 0:y-=speed;break;case 1:x+=speed;break;case 2:y+=speed;break;case 3:x-=speed;break;}if(this.x<0||this.x>400||this.y<0||this.y>300){this.isAlive=false;break;}}}}//坦克类class Tank{int x;int y;int direct=0;int speed=1;Color color;boolean isAlive=true;public Color getColor() {return color;}public void setColor(Color color) {this.color = color;}public int getDirect() {return direct;}public void setDirect(int direct) {this.direct = direct;}public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}public Tank(int x,int y){this.x=x;this.y=y;}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;}}//我的坦克class Hero extends Tank{Vector<Shot> ss=new Vector<Shot>();Shot s;public Hero(int x,int y){super(x,y);}public void moveUp(){this.direct=0;this.y-=this.speed;}public void moveRight(){this.direct=1;this.x+=this.speed;}public void moveDown(){this.direct=2;this.y+=this.speed;}public void moveLeft(){this.direct=3;this.x-=this.speed;}public void shotEnemy(){  switch(this.direct)  {  case 0:  s=new Shot(this.x,this.y-15,0);  break;  case 1:  s=new Shot(this.x+15,this.y,1);  break;  case 2:  s=new Shot(this.x,this.y+15,2);  break;  case 3:  s=new Shot(this.x-15,this.y,3);  break;    }  ss.add(s);  new Thread(s).start();}}//敌人的坦克class EnemyTank extends Tank implements Runnable{Vector<Shot> ss=new Vector<Shot>();Shot s=null;int time=1;Vector<EnemyTank> ets=new Vector<EnemyTank>();public EnemyTank(int x,int y){super(x,y);}public void setEts(Vector<EnemyTank> ets){this.ets=ets;}//判断敌人的坦克是否重叠public boolean isTouched(){boolean b=false;switch(this.direct){case 0:for(int i=0;i<ets.size();i++){EnemyTank et=ets.get(i);if(et!=this){if(et.direct==0||et.direct==2){if(this.x-10<=et.x+10&&this.x-10>=et.x-10&&this.y-15<=et.y+15&&this.y-15>=et.y-15){return true;}if(this.x+10<=et.x+10&&this.x+10>=et.x-10&&this.y-15<=et.y+15&&this.y-15>=et.y-15){return true;}}if(et.direct==1||et.direct==3){if(this.x-10<=et.x+15&&this.x-10>=et.x-15&&this.y-15<=et.y+10&&this.y-15>=et.y-10){return true;}if(this.x+10<=et.x+15&&this.x+10>=et.x-15&&this.y-15<=et.y+15&&this.y-10>=et.y-10){return true;}}}}break;case 1:for(int i=0;i<ets.size();i++){EnemyTank et=ets.get(i);if(et!=this){if(et.direct==0||et.direct==2){if(this.x+15<=et.x+10&&this.x+15>=et.x-10&&this.y-10<=et.y+15&&this.y-10>=et.y-15){return true;}if(this.x+15<=et.x+10&&this.x+15>=et.x-10&&this.y+10<=et.y+15&&this.y+10>=et.y-15){return true;}}if(et.direct==1||et.direct==3){if(this.x+15<=et.x+15&&this.x+15>=et.x-15&&this.y-10<=et.y+10&&this.y-10>=et.y-10){return true;}if(this.x+15<=et.x+15&&this.x+15>=et.x-15&&this.y+10<=et.y+10&&this.y+10>=et.y-10){return true;}}}}break;case 2:for(int i=0;i<ets.size();i++){EnemyTank et=ets.get(i);if(et!=this){if(et.direct==0||et.direct==2){if(this.x-10<=et.x+10&&this.x-10>=et.x-10&&this.y+15<=et.y+15&&this.y+15>=et.y-15){return true;}if(this.x+10<=et.x+10&&this.x+10>=et.x-10&&this.y+15<=et.y+15&&this.y+15>=et.y-15){return true;}}if(et.direct==1||et.direct==3){if(this.x-10<=et.x+15&&this.x-10>=et.x-15&&this.y+15<=et.y+10&&this.y+15>=et.y-10){return true;}if(this.x+10<=et.x+15&&this.x+10>=et.x-15&&this.y+15<=et.y+10&&this.y+15>=et.y-10){return true;}}}}break;case 3:for(int i=0;i<ets.size();i++){EnemyTank et=ets.get(i);if(et!=this){if(et.direct==0||et.direct==2){if(this.x-15<=et.x+10&&this.x-15>=et.x-10&&this.y-10<=et.y+15&&this.y-10>=et.y-15){return true;}if(this.x-15<=et.x+10&&this.x-15>=et.x-10&&this.y+10<=et.y+15&&this.y+10>=et.y-15){return true;}}if(et.direct==1||et.direct==3){if(this.x-15<=et.x+15&&this.x-15>=et.x-15&&this.y-10<=et.y+10&&this.y-10>=et.y-10){return true;}if(this.x-15<=et.x+15&&this.x-15>=et.x-15&&this.y+10<=et.y+10&&this.y+10>=et.y-10){return true;}}}}break;}return b;}//敌人的坦克是一个线程public void run(){while(true){switch(this.direct){case 0:for(int i=0;i<30;i++){if(y>16&&!this.isTouched())y-=speed;try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}break;case 1:for(int i=0;i<30;i++){if(x<384&&!this.isTouched())x+=speed;try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}break;case 2:for(int i=0;i<30;i++){if(y<286&&!this.isTouched())y+=speed;try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}break;case 3:for(int i=0;i<30;i++){if(x>16&&!this.isTouched())x-=speed;try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}break;}//随机生成敌人的坦克的方向this.direct=(int)(Math.random()*4);if(this.isAlive==false){break;}time++;if(time%2==0){if(this.isAlive==true){if(ss.size()<5){switch(this.direct){case 0:s=new Shot(this.x,this.y-15,0);break;case 1:s=new Shot(this.x+15,this.y,1);break;case 2:s=new Shot(this.x,this.y+15,2);break;case 3:s=new Shot(this.x-15,this.y,3);break;}this.ss.add(s);new Thread(s).start();}}}}}}//第一个面板,文字闪烁的效果,做成线程@SuppressWarnings("serial")class FirstPanel extends JPanel  implements Runnable{int time=0;public void paint(Graphics g){super.paint(g);g.fillRect(0, 0, 400, 300);if(time%2==0){g.setFont(new Font("华文舒体",Font.PLAIN,20));g.setColor(Color.cyan);g.drawString("Stage 1", 150, 150);}}public void run(){while(true){try {Thread.sleep(400);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}time++;this.repaint();}}}//我的面板@SuppressWarnings("serial")class MyPanel extends JPanel implements KeyListener,Runnable{Hero hero;Vector<EnemyTank> ets;Vector<Bomb> bombs=new Vector<Bomb>();Vector<Node> nodes=new Vector<Node>();Image image1=null;Image image2=null;Image image3=null;public MyPanel(String flag){Recorder.getRecording();hero=new Hero(80,200);ets=new Vector<EnemyTank>();int etsize=4;//根据构造函数传入的字符串判断是开始游戏,还是续上一局if(flag.equals("newgame")){for(int i=0;i<etsize;i++){EnemyTank et=new EnemyTank(50*i+50,50);et.setColor(Color.yellow);et.setDirect(2);new Thread(et).start();ets.add(et);}}else{nodes=new Recorder().getEnemyRecording();for(int i=0;i<nodes.size();i++){EnemyTank et=new EnemyTank(nodes.get(i).x,nodes.get(i).y);et.setColor(Color.yellow);et.setDirect(nodes.get(i).direct);new Thread(et).start();ets.add(et);}}//播放声音AePlayWave aw=new AePlayWave("111.wav");aw.start();//炸弹爆炸效果,三个图片的切换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 (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//显示玩家的成绩public void showResult(Graphics g){this.drawTank(50, 370, g, 0, 1);g.setColor(Color.BLACK);g.drawString(Recorder.getEnNum()+"", 70, 375);this.drawTank(130, 370, g, 0, 0);g.setColor(Color.BLACK);g.drawString(Recorder.getMyNum()+"", 150, 375);g.setFont(new Font("宋体",Font.BOLD,20));g.drawString("您的总成绩", 420, 60);this.drawTank(450, 100, g, 0, 1);g.setColor(Color.BLACK);g.setFont(new Font("宋体",Font.PLAIN,13));g.drawString(Recorder.getAllTankNum()+"", 470, 105);}public void paint(Graphics g){super.paint(g);g.fillRect(0, 0, 400, 300);this.showResult(g);//画出我的坦克 if(hero.isAlive){drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),0);}//画出子弹if(hero.isAlive){    for(int i=0;i<hero.ss.size();i++){if(hero.ss.get(i)!=null&&hero.ss.get(i).isAlive==true){g.fillRect(hero.ss.get(i).x, hero.ss.get(i).y, 2, 2);}if(hero.ss.get(i).isAlive==false){hero.ss.remove(hero.ss.get(i));}}}//画出敌人的坦克for(int i=0;i<ets.size();i++){EnemyTank et=ets.get(i);if(et.isAlive){this.drawTank(et.getX(), et.getY(), g, et.getDirect(), 1);//令敌人的坦克知道所有的坦克的信息et.setEts(ets);//画出子弹for(int j=0;j<et.ss.size();j++){Shot s=et.ss.get(j);if(s.isAlive){g.fillRect(s.x, s.y, 2, 2);}else{et.ss.remove(s);}}}}//画出炸弹for(int i=0;i<bombs.size();i++){Bomb b=bombs.get(i);if(b.life>4) {g.drawImage(image1, b.x-13, b.y-13, 30, 30, this);}else if(b.life>2){g.drawImage(image2, b.x-13, b.y-13, 30, 30, this);}else {g.drawImage(image3, b.x-13, b.y-13, 30, 30, this);}b.lifeDown();if(b.isAlive==false) {bombs.remove(b);}}}//判断我的子弹是否击中敌人的坦克public void hitEnemyTank(){for(int i=0;i<this.hero.ss.size();i++){if(this.hero.ss.get(i).isAlive){for(int j=0;j<ets.size();j++){if(ets.get(j).isAlive){if(this.hitTank(hero.ss.get(i), ets.get(j))){Recorder.reduceEnNum();Recorder.addAllTankNum();}}else{ets.remove(j);}}}}}//判断敌人的子弹是否击中我的坦克public void hitMe(){for(int i=0;i<ets.size();i++){EnemyTank et=ets.get(i);for(int j=0;j<et.ss.size();j++){Shot s=et.ss.get(j);if(hero.isAlive){if(this.hitTank(s, hero)){Recorder.reduceMyNum();}}}}}//判断子弹是否击中坦克public boolean hitTank(Shot s,Tank t){boolean b=false; switch(t.direct) { case 0: case 2: if(s.x>t.x-10&&s.x<t.x+10&&s.y>t.y-15&&s.y<t.y+15) { s.isAlive=false; t.isAlive=false; b=true;  bombs.add(new Bomb(t.x,t.y)); } break; case 1: case 3: if(s.y>t.y-10&&s.y<t.y+10&&s.x>t.x-15&&s.x<t.x+15) { s.isAlive=false; t.isAlive=false; b=true; bombs.add(new Bomb(t.x,t.y)); } break; } return b;}//画出坦克public void drawTank(int x,int y,Graphics g,int direct,int type){switch(type){case 0:g.setColor(Color.cyan);break;case 1:g.setColor(Color.pink);break;}switch(direct){case 0:g.fill3DRect(x-10, y-15, 5, 30, false);g.fill3DRect(x+5, y-15, 5, 30, false);g.fill3DRect(x-5, y-10, 10, 20, false);g.fillOval(x-6, y-5, 10, 10);g.drawLine(x, y, x, y-15);break;case 1:g.fill3DRect(x-15, y-10,30 , 5, false);g.fill3DRect(x-15, y+5, 30, 5, false);g.fill3DRect(x-10, y-5, 20, 10, false);g.fillOval(x-5, y-6, 10, 10);g.drawLine(x, y, x+15, y);break;case 2:g.fill3DRect(x-10, y-15, 5, 30, false);g.fill3DRect(x+5, y-15, 5, 30, false);g.fill3DRect(x-5, y-10, 10, 20, false);g.fillOval(x-6, y-5, 10, 10);g.drawLine(x, y, x, y+15);break;case 3:g.fill3DRect(x-15, y-10,30 , 5, false);g.fill3DRect(x-15, y+5, 30, 5, false);g.fill3DRect(x-10, y-5, 20, 10, false);g.fillOval(x-5, y-6, 10, 10);g.drawLine(x, y, x-15, y);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_UP){hero.moveUp();}else if(e.getKeyCode()==KeyEvent.VK_DOWN){hero.moveDown();}else if(e.getKeyCode()==KeyEvent.VK_LEFT){hero.moveLeft();}else if(e.getKeyCode()==KeyEvent.VK_RIGHT){hero.moveRight();}if(e.getKeyCode()==KeyEvent.VK_SPACE){if(this.hero.ss.size()<=4)this.hero.shotEnemy();}this.repaint();}@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub}//MyPanel是一个线程@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){try{Thread.sleep(50);}catch(Exception e){e.printStackTrace();}//判断我的子弹是否击中敌人的坦克this.hitEnemyTank();//判断敌人的子弹是否击中我的坦克this.hitMe();//刷新this.repaint();}}}

运行结果截图:


0 0
原创粉丝点击