坦克大战JAVA程序(韩顺平老师)

坦克大战java程序

目前程序完成的功能:
1.打开游戏选择继续上一局游戏还是重新开始
2.页面打开后有一段背景音乐,增加体验感
3.页面显示击毁的敌方坦克数量
4.玩家坦克由wasd键控制方向,j键控制射击
敌方坦克被击中后,出现爆炸效果
5.敌人坦克随机移动射击
6.坦克移动过程中不会发生重叠现象
游戏页面展示

目前代码

坦克类(父类)

package ketanglianxi;
public class Tank {
private int x;//̹坦克x坐标
private int y;//̹坦克的y坐标
private int speed =1;
boolean isLive = true;
private int direct;//̹坦克移动方向
	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;
	}
	public int getDirect() {
		return direct;
	}
	public void setDirect(int direct) {
		this.direct = direct;
	}
	//坦克移动的方法
	public void moveUp() {
		y-=speed;
	}
	public void moveRight() {
		x+=speed;
	}public void moveDown() {
		y+=speed;
	}public void moveLeft() {
		x-=speed;
	}
	public int getSpeed() {
		return speed;
	}
	public void setSpeed(int speed) {
		this.speed = speed;
	}
}

玩家坦克类(子类)

import java.util.Vector;
public class Hero extends Tank{
	Shot shot = null;//设置子弹类
	//将子弹放入Vector集合中
	Vector<Shot>shots= new Vector<>();
public Hero(int x,int y) {
	super(x,y);
}
//射击敌方坦克
public void shotEnemyTank() {
	//玩家坦克设置为五枚子弹
	if(shots.size()==5) {
		return;
	}
	//根据坦克前进方向控制子弹方向
	switch(getDirect()){
	   case 0://UP
		   shot = new Shot(getX()+20,getY(),0);
		   break;
	   case 1://RIGHT
		   shot = new Shot(getX()+60,getY()+20,1);
		   break;
	   case 2://DOWN
		   shot = new Shot(getX()+20,getY()+60,2);
		   break;
	   case 3://LEFT
		   shot = new Shot(getX(),getY()+20,3);
		   break;
	}
	shots.add(shot);
	//开启进程
	new Thread(shot).start();
}
}

敌方坦克(子类)

import java.util.List;
import java.util.Vector;
public class EnemyTank extends Tank implements Runnable{
	boolean isLive =true;
	Vector <Shot> shots = new Vector<>();
//敌人坦克类,使用Vector保存多个shot
//增加成员,EnemyTank可以得到敌人坦克的Vector
	Vector<EnemyTank>enemyTanks = new Vector<>();
	//1.enemyTanks在MyPanel类中
   public EnemyTank(int x, int y) {
		super(x, y);
		// TODO Auto-generated constructor stub
		
	}
   //这里提供一个方法,可以将MyPanel的成员Vector <Shot> shots = new Vector<>();
   //设置到EnemyTank的成员enemyTanks
public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
	this.enemyTanks = enemyTanks;
}
//编写方法,判断当前的这个敌人坦克,是否和enemyTanks中的其他坦克发生重叠
public boolean isTouchEnemyTank() {
	//判断当前敌人坦克(this)方向
	switch(this.getDirect()) {
	case 0://当前坦克向上
		//让当前敌人坦克和其他所有的敌人坦克比较
		for(int i =0;i<enemyTanks.size();i++) {
			//从Vector中取出一个敌人坦克
			EnemyTank enemyTank = enemyTanks.get(i);
			if(enemyTank!=this) {
				//如果敌人坦克是上/下,x的范围[enemyTank.getX(),enemyTank.getX()+40]
				//y的范围[enemyTank.getY(),enemyTank.getX()+60]
				if(enemyTank.getDirect()==0||enemyTank.getDirect()==2) {
					//2.当前坦克左上角坐标[this.getX(),this.getY()]
					//3.当前坦克右上角坐标[this.getX()+40,this.getY()]
					if(this.getX()>=enemyTank.getX()
							&&this.getX()<=enemyTank.getX()+40
							&&this.getY()>=enemyTank.getY()
							&&this.getY()<=enemyTank.getY()+60)
						return true;
					if(this.getX()+40>=enemyTank.getX()
							&&this.getX()+40<=enemyTank.getX()+40
							&&this.getY()>=enemyTank.getY()
							&&this.getY()<=enemyTank.getY()+60)
						return true;
				}
				//如果敌人坦克是左或右
				//敌人坦克x的范围[enemyTank.getX(),enemyTank.getX()+60]
				//       y的范围[enemyTank.getY(),enemyTank.getY()+40]
				if(enemyTank.getDirect()==1||enemyTank.getDirect()==3) {
					if(this.getX()>=enemyTank.getX()
							&&this.getX()<=enemyTank.getX()+60
							&&this.getY()>=enemyTank.getY()
							&&this.getY()<=enemyTank.getY()+40)
						return true;
					if(this.getX()+40>=enemyTank.getX()
							&&this.getX()+40<=enemyTank.getX()+60
							&&this.getY()>=enemyTank.getY()
							&&this.getY()<=enemyTank.getY()+40)
						return true;
				}
			}
		}
		break;
	case 1://当前坦克向右
		for(int i =0;i<enemyTanks.size();i++) {
			//从Vector中取出一个敌人坦克
			EnemyTank enemyTank = enemyTanks.get(i);
			if(enemyTank!=this) {
				//如果敌人坦克是左/右,x的范围[enemyTank.getX(),enemyTank.getX()+60]
				//y的范围[enemyTank.getY(),enemyTank.getX()+40]
				if(enemyTank.getDirect()==0||enemyTank.getDirect()==2) {
					//2.当前坦克右上角坐标[this.getX()+60,this.getY()]
					//3.当前坦克右下角坐标[this.getX()+60,this.getY()+40]
					if(this.getX()+60>=enemyTank.getX()
							&&this.getX()+60<=enemyTank.getX()+40
							&&this.getY()>=enemyTank.getY()
							&&this.getY()<=enemyTank.getY()+60)
						return true;
					//当前坦克右下角的坐标[this.getX()+60,this.getY()+40]
					if(this.getX()+60>=enemyTank.getX()
							&&this.getX()+60<=enemyTank.getX()+40
							&&this.getY()+40>=enemyTank.getY()
							&&this.getY()+40<=enemyTank.getY()+60)
						return true;
				}
				//如果敌人坦克是左或右
				//敌人坦克x的范围[enemyTank.getX(),enemyTank.getX()+60]
				//       y的范围[enemyTank.getY(),enemyTank.getY()+40]
				if(enemyTank.getDirect()==1||enemyTank.getDirect()==3) {
					//1.当前坦克右上角坐标[this.getX()+60,this.getY()]
					if(this.getX()+60>=enemyTank.getX()
							&&this.getX()+60<=enemyTank.getX()+60
							&&this.getY()>=enemyTank.getY()
							&&this.getY()<=enemyTank.getY()+40)
						return true;
					//2.当前坦克右下角坐标[this.getX()+60,this.getY()+40]
					if(this.getX()+60>=enemyTank.getX()
							&&this.getX()+60<=enemyTank.getX()+60
							&&this.getY()+40>=enemyTank.getY()
							&&this.getY()+40<=enemyTank.getY()+40)
						return true;
				}
			}
		}
		break;
	case 2://当前坦克向下
		for(int i =0;i<enemyTanks.size();i++) {
			//从Vector中取出一个敌人坦克
			EnemyTank enemyTank = enemyTanks.get(i);
			if(enemyTank!=this) {
				//如果敌人坦克是上/下,x的范围[enemyTank.getX(),enemyTank.getX()+60]
				//y的范围[enemyTank.getY(),enemyTank.getX()+40]
				if(enemyTank.getDirect()==0||enemyTank.getDirect()==2) {
					//2.当前坦克左下角坐标[this.getX(),this.getY()+60]
					//3.当前坦克右下角坐标[this.getX()+40,this.getY()+60]
					if(this.getX()>=enemyTank.getX()
							&&this.getX()<=enemyTank.getX()+40
							&&this.getY()+60>=enemyTank.getY()
							&&this.getY()+60<=enemyTank.getY()+60)
						return true;
					//当前坦克右下角的坐标[this.getX()+40,this.getY()+60]
					if(this.getX()+40>=enemyTank.getX()
							&&this.getX()+40<=enemyTank.getX()+40
							&&this.getY()+60>=enemyTank.getY()
							&&this.getY()+60<=enemyTank.getY()+60)
						return true;
				}
				//如果敌人坦克是左/右
				//敌人坦克x的范围[enemyTank.getX(),enemyTank.getX()+60]
				//       y的范围[enemyTank.getY(),enemyTank.getY()+40]
				if(enemyTank.getDirect()==1||enemyTank.getDirect()==3) {
					//1.当前坦克左下角坐标[this.getX(),this.getY()+60]
					if(this.getX()>=enemyTank.getX()
							&&this.getX()<=enemyTank.getX()+60
							&&this.getY()+60>=enemyTank.getY()
							&&this.getY()+60<=enemyTank.getY()+40)
						return true;
					//2.当前坦克右下角坐标[this.getX()+40,this.getY()+60]
					if(this.getX()+40>=enemyTank.getX()
							&&this.getX()+40<=enemyTank.getX()+60
							&&this.getY()+60>=enemyTank.getY()
							&&this.getY()+60<=enemyTank.getY()+40)
						return true;
				}
			}
		}
		break;
	case 3://当前坦克向左
		for(int i =0;i<enemyTanks.size();i++) {
			//从Vector中取出一个敌人坦克
			EnemyTank enemyTank = enemyTanks.get(i);
			if(enemyTank!=this) {
				//如果敌人坦克是上/下,x的范围[enemyTank.getX(),enemyTank.getX()+60]
				//y的范围[enemyTank.getY(),enemyTank.getX()+40]
				if(enemyTank.getDirect()==0||enemyTank.getDirect()==2) {
					//2.当前坦克左上角坐标[this.getX(),this.getY()]
					//3.当前坦克左下角坐标[this.getX()+60,this.getY()+40]
					if(this.getX()>=enemyTank.getX()
							&&this.getX()<=enemyTank.getX()+40
							&&this.getY()>=enemyTank.getY()
							&&this.getY()<=enemyTank.getY()+60)
						return true;
					//当前坦克左下角的坐标[this.getX(),this.getY()+40]
					if(this.getX()>=enemyTank.getX()
							&&this.getX()<=enemyTank.getX()+40
							&&this.getY()+40>=enemyTank.getY()
							&&this.getY()+40<=enemyTank.getY()+60)
						return true;
				}
				//如果敌人坦克是左或右
				//敌人坦克x的范围[enemyTank.getX(),enemyTank.getX()+60]
				//       y的范围[enemyTank.getY(),enemyTank.getY()+40]
				if(enemyTank.getDirect()==1||enemyTank.getDirect()==3) {
					//1.当前坦克左上角坐标[this.getX(),this.getY()]
					if(this.getX()>=enemyTank.getX()
							&&this.getX()<=enemyTank.getX()+60
							&&this.getY()>=enemyTank.getY()
							&&this.getY()<=enemyTank.getY()+40)
						return true;
					//2.当前坦克左下角坐标[this.getX(),this.getY()+40]
					if(this.getX()>=enemyTank.getX()
							&&this.getX()<=enemyTank.getX()+60
							&&this.getY()+40>=enemyTank.getY()
							&&this.getY()+40<=enemyTank.getY()+40)
						return true;
				}
			}
		}
		break;
	}
	return false;
}

@Override
public void run() {
	// TODO Auto-generated method stub
	while(true) {
		
		if(isLive&&shots.size()<5) {
			Shot s = null;
			
			switch(getDirect()) {
			 case 0:
				 s= new Shot(getX()+20,getY(),0);
				 break;
			 case 1:
				 s=new Shot(getX()+60,getY()+20,1);
				 break;
			 case 2:
				 s=new Shot(getX()+20,getY()+60,2);
				 break;
			 case 3:
				 s= new Shot(getX(),getY()+20,3);
				 break;
			}
			shots.add(s);
			//开启进程
			new Thread(s).start();
		}
		
		//控制方向
		switch(getDirect()) {
		 case 0:
			for(int i =0;i<30;i++) {
			if(getY()>0&&!isTouchEnemyTank()) {
				moveUp();
			}
			
			 try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			break;
		  case 1:for(int i =0;i<30;i++) {
				 
			  if(getX()+60<1000&&!isTouchEnemyTank())
				  {
				  moveRight();
				  }
		     
				 try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
		  }
				
		  break;
		  case 2:for(int i =0;i<30;i++) {
			  if(getY()+60<750&&!isTouchEnemyTank()) {
				 moveDown();
			  }
				 try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
		  }
		  break;
		  case 3:for(int i =0;i<30;i++) {
			  if(getX()>0&&!isTouchEnemyTank()) {
				 moveLeft();
			  }
		
				 try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
		  }
		  break;
		}
	
		//由随机数生成函数控制坦克方向
		setDirect((int)(Math.random()*4));
		if(!isLive) {
			break;
		}
	}
}

}

子弹类

public class Shot implements Runnable{
	int x;
	int y;
	int direct=0;
	int speed = 3;
	boolean isLive =true;//子弹还存在
	Shot(int x,int y,int direct){
		this.x=x;
		this.y=y;
		this.direct=direct;
	}
	
	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;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true) {
			try {
				Thread.sleep(50);//休眠50ms
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.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<=1000&&y>=0&&y<=750&&isLive)) {
				isLive = false;
				break;
			}
		}
	}

}

Recorder类

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Vector;
/*该类记录我方击毁敌方坦克数
 * 2.当游戏结束,将数据写入到文件(IO)
 * 3.当退出游戏时,记录敌人坦克坐标和方向
 * 4.将每个敌人信息,恢复成Node对象->Vector
 * 
 */
//用于记录相关信息,和文件交互
public class Recorder {
	//定义变量,记录我方击毁敌人坦克数
	private static int allEnemyTankNum = 0;
	//定义IO对象,准备写数据到文件中
	private static FileWriter fw = null;
	private static BufferedReader br = null;
	private static BufferedWriter bw =null;
	//把记录文件保存到src下
	private static String recordFile = "src\\myRecord.txt";
	

	public static String getRecordFile() {
		return recordFile;
	}
	
	//定义Vector,指向MyPanel对象的敌人坦克Vector
	private static Vector<EnemyTank>enemyTanks = null;
	//定义一个Node的Vector,用于保存敌人的信息node
	private static Vector<Node>nodes= new Vector<>();
	
	public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
		Recorder.enemyTanks = enemyTanks;
	}
	//增加一个方法,用于读取recordFile,恢复相关信息
	//该方法在继续上局时调用即可
	public static Vector<Node> getNodesAndEnemyTankRec(){
		try {
			br = new BufferedReader(new FileReader(recordFile));
		
			allEnemyTankNum=Integer.parseInt(br.readLine());
			//循环读取文件,生成nodes集合
			String line="";
			while((line=br.readLine())!=null) {
				String[] xyd=line.split(" ");
			Node node=	new Node(Integer.parseInt(xyd[0]),Integer.parseInt(xyd[1]),
						Integer.parseInt(xyd[2]));
			nodes.add(node);//放入到Vector
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(br!=null) {
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
		return nodes;
	}
	
	//增加一个方法,当游戏退出时,我们将allEnemyTankNum保存到recordFile
	//对此方法进行升级,保存敌人坦克的坐标和方向
	public static void keepRecord() {
		try {
			
			 bw = new BufferedWriter((new FileWriter(recordFile)));
			 bw.write(String.valueOf(allEnemyTankNum)+"\r\n");
			
			 //遍历敌人坦克的Vector,然后根据情况保存即可
			 //定义一个属性,然后通过setXxx得到敌人坦克的Vector
			 for(int i =0;i<enemyTanks.size();i++) {
				 //取出敌人坦克
				 EnemyTank enemyTank = enemyTanks.get(i);
				 if(enemyTank.isLive) {
					//保存该坦克信息
					 String record = enemyTank.getX()+" "+enemyTank.getY()+" "+enemyTank.getDirect();
					 //写入到文件
					 bw.write(record+"\r\n");
					 
				 }
			 }
			 bw.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(bw!=null) {
				try {
					bw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	public static int getAllEnemyTankNum() {
		return allEnemyTankNum;
	}
	public static void setAllEnemyTankNum(int allEnemyTankNum) {
		Recorder.allEnemyTankNum = allEnemyTankNum;
	}
	//当我方坦克击毁一个敌人坦克,就应当allEnemyTankNum++
	public static void addAllEnemyTankNum() {
		Recorder.allEnemyTankNum++;
	}
	
}

Node类

/*一个Node对象,
 * 表示一个坦克信息 
 */
public class Node {
private int x;
private int y;
private int direct;
public Node(int x,int y,int direct) {
	this.x=x;
	this.y=y;
	this.direct =direct;
}
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 getDirect() {
	return direct;
}
public void setDirect(int direct) {
	this.direct = direct;
}
}

Bomb炸弹类

public class Bomb {
int x,y;//炸弹坐标
int life = 9;//生命值设为9
boolean isLive = true;//生命值设为true
public Bomb(int x, int y) {
	this.x = x;
	this.y = y;
}
	public void lifeDown() {
		if(life>0) {
			life--;
		} else {
			isLive = false;
		}
	}
}

播放声音类

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

//播放声音的类
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();
      }

  }  
}

页面类

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Vector;
import javax.swing.JPanel;


public class MyPanel extends JPanel implements KeyListener ,Runnable {
	//定义玩家坦克
	Hero hero = null;
	//定义敌人坦克,放入到Vector
	Vector<EnemyTank>enemyTanks = new Vector<>();
	//定义一个存放Node对象的Vector,用于恢复敌人坦克的坐标和方法
	Vector<Node>nodes = new Vector<>();
	//定义一个Vector,用于存放炸弹
	Vector<Bomb> bombs = new Vector<>();
	int enemyTankSize = 3;
	//定义三张炸弹图片,用于存放炸弹
	Image image1 =null;	
	Image image2 =null;
	Image image3 =null;
	public MyPanel(String key) {//key决定开启新游戏还是继续上次游戏
		//先将判断记录文件是否存在
		//如果存在,就正常执行,如果文件不存在,提示只能开启新游戏
		File file =new File(Recorder.getRecordFile());
		if(file.exists()&&"2".equals(key)) {
		nodes=Recorder.getNodesAndEnemyTankRec();
		}else {
			System.out.println("只能开启新游戏");
			key="1";
		}
			
		//将MyPanel对象的enemyTanks设置给Recorder的enemyTanks
		Recorder.setEnemyTanks(enemyTanks);
		hero= new Hero(500,100);//
		hero.setSpeed(1);
		switch(key) {
		case "1"://初始化敌人坦克
			for(int i =0;i<enemyTankSize;i++) {
				EnemyTank enemyTank = new  EnemyTank(100*(i+1),0);
				//将enemyTanks设置给enemyTank
				enemyTank.setEnemyTanks(enemyTanks);
				enemyTank.setDirect(2);
				
				new Thread(enemyTank).start();

				Shot shot=new Shot(enemyTank.getX()+20,enemyTank.getY()+60,enemyTank.getDirect());
				//加入
				enemyTank.shots.add(shot);
				enemyTanks.add(enemyTank);
				//启动shot对象
				new Thread(shot).start();
			}
			break;
		case "2"://继续上局游戏
			
			//初始化敌人坦克
			for(int i =0;i<nodes.size();i++) {
				Node node = nodes.get(i);
				EnemyTank enemyTank = new  EnemyTank(node.getX(),node.getY());
				//将enemyTanks设置给enemyTank
				enemyTank.setEnemyTanks(enemyTanks);
				enemyTank.setDirect(node.getDirect());
				
				new Thread(enemyTank).start();
				Shot shot=new Shot(enemyTank.getX()+20,enemyTank.getY()+60,enemyTank.getDirect());
				enemyTank.shots.add(shot);
				enemyTanks.add(enemyTank);
				new Thread(shot).start();
			}
			break;
		default:
			System.out.println("输入错误");
		}
		//这里,播放指定的音乐
		new AePlayWave("src\\bgm.wav").start();
		//初始化图片对象
		image1=Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/bomb1.jpg"));
		image2=Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/bomb1.jpg"));
		image3=Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/bomb1.jpg"));

		
	}
	//编写方法,显示我方击毁敌方坦克信息
	public void showInfo(Graphics g) {
		//画出玩家的总成绩
		g.setColor(Color.BLACK);
		Font font =new Font("宋体",Font.BOLD,25);
		g.setFont(font);
		g.drawString("您累计击毁敌方坦克",1020,30);
		drawTank(1020,60,g,0,1);//画出一个敌方坦克
		g.setColor(Color.BLACK);//这里需要重新设置成黑色
		g.drawString(Recorder.getAllEnemyTankNum()+"", 1080,100);
		
	}
	
	public void paint(Graphics g) {
		super.paint(g);
		g.fillRect(0,0,1000,750);//填充矩形,默认黑色
		showInfo(g);
		if(hero!=null&&hero.isLive) {
		//画出坦克
		drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),0);
		}

		for(int i = 0;i<hero.shots.size();i++) {
			Shot shot = hero.shots.get(i);
				if(shot!=null&&shot.isLive!=false) {
					 g.setColor(Color.cyan);	
				g.draw3DRect(shot.x, hero.shot.y, 2, 2,false);
				} else {
					hero.shots.remove(i);
					
				}
		}
	
		for(int i =0;i<bombs.size();i++) {
				
					Bomb bomb = bombs.get(i);

					if(bomb.life>6) {
						g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);
						
					} else if(bomb.life>3) {
						g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
						
					}  else {
						g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
					}

					bomb.lifeDown();
			if(bomb.life==0) {
						bombs.remove(bomb);
						
					}
				}
				
		
		for(int i = 0;i<enemyTanks.size();i++) {
		
			EnemyTank enemyTank = enemyTanks.get(i);
			if(enemyTank.isLive) {		drawTank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirect(),1);
		
			for(int j=0;j<enemyTank.shots.size();j++) {
			
				Shot shot = enemyTank.shots.get(j);
			
				if(shot.isLive) {
					g.setColor(Color.yellow);
					g.draw3DRect(shot.x, shot.y, 2, 2,false);
				} 
				else {
					enemyTank.shots.remove(shot);
				}
			}
			
		} 
		}
		
	}
	
	
	
	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.yellow);
			break;
		}

		switch(direct) {
		case 0:g.fill3DRect(x, y,10,60,false );
			   g.fill3DRect(x+30, y, 10, 60, false);
			   g.fill3DRect(x+10, y+10, 20, 40, false);
			   g.fillOval(x+10, y+20, 20, 20);
			   g.drawLine(x+20,y+30,x + 20,y);
		       break;
		case 1:
			g.fill3DRect(x, y,60,10,false );
			 g.fill3DRect(x, y+30, 60, 10, false);
			 g.fill3DRect(x+10, y+10, 40, 20, false);
			 g.fillOval(x+20, y+10, 20, 20);
			 g.drawLine(x+30,y+20,x + 60,y+20);
			 break;
		case 2:
			g.fill3DRect(x, y,10,60,false );
			   g.fill3DRect(x+30, y, 10, 60, false);
			   g.fill3DRect(x+10, y+10, 20, 40, false);
			   g.fillOval(x+10, y+20, 20, 20);
			   g.drawLine(x+20,y+30,x + 20,y+60);
		       break;
		case 3:
			g.fill3DRect(x, y,60,10,false );
			g.fill3DRect(x, y+30,60,10,false );
			g.fill3DRect(x+10,y+10,40,20,false);
			 g.fillOval(x+20, y+10, 20, 20);
			 g.drawLine(x+30,y+20,x ,y+20);
			 break;
		default:
			System.out.println("暂无安排");
		}
	}
	
	public void hitEnemyTank() {
		for(int j =0;j<hero.shots.size();j++) {
			Shot shot = hero.shots.get(j);
			for(int i =0;i<enemyTanks.size();i++) {
			EnemyTank enemyTank=enemyTanks.get(i);
				hitTank(shot,enemyTank);
			}
		}
	}
	public  void hitTank(Shot s,Tank tank) {
		
		switch(tank.getDirect()) {
		case 0://̹坦克向上
		case 2://̹坦克向下
			if(s.x>tank.getX()&&s.x<tank.getX()+40
					&&s.y>tank.getY()&&s.y<tank.getY()+60) {
				s.isLive=false;
				tank.isLive=false;
				//坦克被击中后就拿掉
				enemyTanks.remove(tank);
				//当我方击毁一个敌人坦克时,就对数据allEnemyTankNum++
				//因为此处坦克可以是hero坦克,也可以是enemyTank,
				if(tank instanceof EnemyTank) {
					Recorder.addAllEnemyTankNum();
				}
				//创建Bomb对象,加入到bombs集合
				Bomb bomb = new Bomb(tank.getX(),tank.getY());
				bombs.add(bomb);
			}
		case 1://向右
		case 3://向左
			if(s.x>tank.getX()&&s.x<tank.getX()+60
					&&s.y>tank.getY()&&s.y<tank.getY()+40) {
				s.isLive=false;
				tank.isLive=false;
				enemyTanks.remove(tank);
				if(tank instanceof EnemyTank) {
					Recorder.addAllEnemyTankNum();
				}
				Bomb bomb = new Bomb(tank.getX(),tank.getY());
				bombs.add(bomb);
			}
		}
	}
	//判断是否打到玩家坦克
	public void hitHero() {
		//遍历敌人家坦克
		for(int i = 0;i<enemyTanks.size();i++) {
			
			EnemyTank enemyTank= enemyTanks.get(i);
			//遍历敌人坦克的每个子弹
			for(int j = 0;j<enemyTank.shots.size();j++) {
				
             Shot shot=	enemyTank.shots.get(j);
             //
             if(hero.isLive&&shot.isLive) {
            	 hitTank(shot,hero);
             }
			}
		}
	}
	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		if(e.getKeyCode()==KeyEvent.VK_W) {
			hero.setDirect(0);
			
			if(hero.getY()>0) {
			hero.moveUp();
			}
		} else if(e.getKeyCode()==KeyEvent.VK_D) {
			hero.setDirect(1);
			if(hero.getX()+60<1000) {
			hero.moveRight();
			}
		} else if(e.getKeyCode()==KeyEvent.VK_S) {
			hero.setDirect(2);
			if(hero.getY()+60<750) {
			hero.moveDown();
			}
		} else if(e.getKeyCode()==KeyEvent.VK_A) {
			hero.setDirect(3);
			if(hero.getX()>0) {
			hero.moveLeft();
			}
		}
		
			hero.shotEnemyTank();
		}
		repaint();
	}
	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void run() {
		while(true) {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(hero.shot!=null&&hero.shot.isLive) {
		for(int i = 0;i<enemyTanks.size();i++){//遍历敌人的坦克
			
				EnemyTank enemyTank = enemyTanks.get(i);
				hitEnemyTank();
			}
		}
		//判断是否射击到玩家坦克
		hitHero();
	
		this.repaint();
		}
	}
	
}

主程序

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;

import javax.swing.JFrame;

public class TankGame01 extends JFrame{
//继承JFrame
	MyPanel mp = null;
	static Scanner sc=new Scanner(System.in);
	public static void main(String[] args) {
		
		TankGame01 tankGame = new TankGame01();
	}
	public TankGame01() {
		System.out.println("请输入选择1:新游戏 2:继续上局");
		String key = sc.next();
		mp=new MyPanel(key);
		//把mp加入thread
		Thread thread = new Thread(mp);
		thread.start();//开启进程
		this.add(mp);//把mp加入
		this.setSize(1300,950);
		this.addKeyListener(mp);//面板加上监视器
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		//在JFrame中增加相应关闭窗口的处理
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				Recorder.keepRecord();
				System.exit(0);
			}
		});
	}
}

我的改进思路:
(一)增加障碍物(铁墙:子弹打不穿;木墙:被子弹打数次后会消失)丰富游戏观感
(二)增加关卡,不同关卡的地图难度、敌方坦克数量及玩家生命值都有改变
(三)增加玩家坦克的生命值,如被击中三次才会失败,退出游戏
(四)丰富页面,选择关卡及选择是否开始新游戏时以弹出对话框的形式,增加用户体验感。

  • 17
    点赞
  • 118
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值