【小白学习之路】Java实现简单的飞机大战小游戏

飞机大战小游戏

在这里插入图片描述
目录

  1. 项目介绍
  2. 框架搭建
  3. 代码实现
  4. 总结分析

前言:
前一段时间写了一个仿QQ的聊天室,主要涉及Java通信有关的知识,今天写的这个飞机大战主要是复习之前写过的,这次我会加入一些其他的元素和对界面进行一些完善。

这篇博客我会写的比较通透,主要是自己用来复习和巩固知识点的,所以大家如果感兴趣的话,可以参考我的这篇博客!特别是正在学习Java的同学哦!!!

项目介绍

实现飞机大战设计的知识点还是比较多的,所以特别推荐编程小白先上手这种简单的游戏,这样既可以巩固简单的Java基础知识,又可以实现自己编写的小作品,展现自己的能力,何乐而不为呢?下面我就简单地介绍一下实现飞机大战要了解和使用的相关知识吧ƪ(˘⌣˘)ʃ

  1. 继承机制
    一. 为什么要用继承?
    简单说:首先要实现飞机大战,根据Java面向对象编程的特性,我们就必须明白整个游戏有哪几个对象?不难知道有:自己的战机、敌机、子弹(敌机和我机子弹)和背景。观察这几个对象可以知道,它们都有一些共同的属性,如战机和敌机的血量、它们的坐标和移动的方法等等。
    由上所述,我们可以合理地采用接口或者抽象类来让子类继承,这样可以充分地复用代码,大大地减少了代码的冗余。让我们更快地完成飞机大战这个小游戏。
    二.如何使用继承?
    对于为什么要用继承上面我已经说明了,下面就详详细说一下接口和抽象类。我们都知道,但我们用extends去继承一个类的时候,子类就拥有了父类的属性和方法,自然就可以去调用。同时我们也可以覆写父类的方法(如果父类的方法比较不具体),这里就有一个名词:抽象类,该类本身就要声明为abstract,同时抽象的方法也要声明。如果我们就是想要一个十分抽象的类,该类中的方法全部是抽象的方法(只是定义了方法的名称,没有方法体的方法),目的是为了子类可以继承该类从而覆写其中的的所有方法,我们把这个类称为接口,我们用interface来定义接口,implement来实现接口。
    接口和抽象类的比较:
    从上面可知,按抽象的程度来比较,一般的类<抽象类<接口,下面简单说一下接口和抽象类用法的比较:
    大家可以参考这篇博客:java面向对象编程技术详解
  2. 监听事件
    我们都知道,在飞机大战游戏中我们要用鼠标点击开始游戏和停止游戏的按钮,而且我们要通过键盘操控飞机的移动和开火。这里就要用到鼠标点击监听器和键盘监听器,有童鞋可能也会用鼠标移动监听器来控制飞机的运动。不管怎么用,这些监听都是接口,我们用implement实现其中的方法就可以啦!!!
框架搭建

综合前面的分析我们就可以搭建一个简单的框架:

  1. Entity.java:接口,功能:定义子类共有的抽象的方法:移动、画图、设置和获得坐标。
  2. MyFeiji.java:自己的战机类,功能:实现接口中的方法,控制移动和检测是否是受到攻击。
  3. DiJi.java:敌机类,功能:实现接口中的方法,随机产生敌机并设置敌机相关的一些属性。
  4. MyFeiJiBullet.java:战机炮弹类,功能:实现接口中的方法,检测是否攻击到敌方。
  5. DiJiBullet.java:敌机炮弹类,功能:实现接口中的全部方法,同时要控制边界。
  6. BackGroundPhotosMusic.java:背景图片音乐类,功能:实现接口中的方法,画出移动的图片、一些界面的设置。
  7. MainUI.java:主界面类,功能:创建队列控制所有的对象的移动和画图,同时实现键盘监听器控制战机的移动和发射炮弹。
  8. RemoveThread.java:去除线程类,功能:创建线程来实现对越界子弹敌机的去除,控制飞机的碰撞。
    上面就是大致的飞机大战的一个框架,对于这种封装性比较强的代码,我们接下来的编写是比较容易的,让我们来实现它吧!
    在这里插入图片描述
代码实现
  1. Entity.java:接口
/**
* 接口
* @author 梦想少年
* 定义子类共有的抽象的方法:移动、画图、设置和获得坐标
*/
public interface Entity {
//移动方法
public void move();
//画图的方法
public void draw(Graphics g);
//设置和得到X和Y坐标的方法
public void setX(int startX);
public void setY(int startY);
public int getX();
public int getY();
}
  1. MyFeiji.java:自己的战机类
/**
 * 自己的战机类
 * @author 梦想少年
 * 实现接口中的方法,控制移动和检测是否是受到攻击
 */
public class MyFeiJi implements Entity {
     //控制飞机上下左右移动
  boolean up=false;
  boolean down=false;
  boolean left=false;
  boolean right=false;
  private int x,y;
  //得分和血量
  private int scores;
  private int hp;
    //我机图片
  private Image image_myfeiji;
  public MyFeiJi(){
    image_myfeiji=new ImageIcon("D:\\常用\\图片\\"
                  + "Camera Roll\\image\\战机.png").getImage();
 } 
  //移动界限 
 public void move() {
  if(x<=40){
  x=40; 
  }
  if(x>=1790){
  x=1790;
  }
  if(y<=100){
  y=100;
  }
  if(y>=910){
  y=910; 
  }
 //移动速度 
    if(up){
  y-=3;
 }
    if(down){
  y+=3;
 }
    if(left){
  x-=4;
 }
    if(right){
  x+=3;
 }
}
 public void draw(Graphics g) {
  g.setFont(new Font("黑体",Font.BOLD, 35));
  g.setColor(Color.RED);
  g.drawString("我的血量:"+hp,30,90);
  g.setFont(new Font("黑体",Font.BOLD, 35));
  g.setColor(Color.RED);
  g.drawString("我的得分:"+scores,30,140);
  g.drawImage(image_myfeiji, x, y, null); 
 }
 //判断是否输赢
 public boolean isDefeat(){
  if(hp<=0){
  return true;
  }else{
  return false;
  }
 }
//设置和获得坐标的方法
 public void setX(int startX) {
  this.x=startX;
 }
 public void setY(int startY) {
  this.y=startY;
 }
 public int getX() {
  return x;
 }
 public int getY() {
  return y;
 }
  //检测我的飞机是否被敌机子弹击中
 public boolean isShootByDiJiBullet(DiJiBullet dijibullet){
   int x1=this.x;//我的飞机x坐标
   int y1=this.y;//我的飞机y坐标
   int width1=this.image_myfeiji.getWidth(null);//我机的宽度
   int height1=this.image_myfeiji.getHeight(null);//我机的高度
   int x11=x1+width1/2;
   int y11=y1+height1/2;//确定中心位置
   //敌机的横纵坐标和高度
   int x2=dijibullet.getX();
   int y2=dijibullet.getY();
   int width2=dijibullet.getDiJiBulletWidth();
   int height2=dijibullet.getDiJiBulletHeight();
   int x22=x2+width2/2;
   int y22=y2+height2/2;
   //计算距离
   int distanceX=Math.abs(x22-x11);
   int distanceY=Math.abs(y22-y11);
   //是否碰撞
   if(distanceX<=30&&distanceY<=25){
       return true; 
   }else{
    return false;
   }
  }
   //检测我的飞机是否被敌机碰撞
 public boolean isShootByDiJi(Diji diji){
   int x1=this.x;//我的飞机x坐标
   int y1=this.y;//我的飞机y坐标
   int width1=this.image_myfeiji.getWidth(null);//我机的宽度
   int height1=this.image_myfeiji.getHeight(null);//我机的高度
   int x11=x1+width1/2;
   int y11=y1+height1/2;//确定中心位置
   //敌机的横纵坐标和高度
   int x2=diji.getX();
   int y2=diji.getY();
   int width2=diji.getDiJiWidth();
   int height2=diji.getDiJiHeight();
   int x22=x2+width2/2;
   int y22=y2+height2/2;
   //计算距离
   int distanceX=Math.abs(x22-x11);
   int distanceY=Math.abs(y22-y11);
   //是否碰撞
   if(distanceX<=100&&distanceY<=100){
       return true; 
   }else{
    return false;
   }
  }
  //掉血方法
 public void subBlood(){
  this.hp--;
 }
 public void subDoubleBlood(){
  this.hp-=5;
 }
//加分方法
 public void addScores(){
  scores+=5;
 }
 public void addDoubleScores(){
  scores+=10;
 }
//设置血量
 public void setHP(int hp){
  this.hp=hp;
 }
 public int getHP(){
  return hp;
 }
}
  1. DiJi.java:敌机类
/**
 * 敌机类
 * @author 梦想少年
 * 实现接口中的方法,随机产生敌机并设置敌机相关的一些属性
 */
public class Diji implements Entity{//敌机
 private int x,y;
 //控制敌机可以追踪战机
 private int automaticMove;
 //判断敌机是否爆炸
 private boolean isDied;
 //爆炸音乐
 File musicFile;
 //敌机图片
 private Image dijiImage;
 //爆炸图片
 private Image diedImage;
 //产生子弹的数量
 private int dijiBulletCount;
 //初始化
 public Diji(){
  musicFile=new File("C:\\Users\\梦想少年\\Music\\"
                  + "AudioConvert\\大爆炸.wav");
  dijiImage=new ImageIcon("D:\\常用\\图片\\"
                  + "Camera Roll\\image\\diji.png").getImage();
  diedImage=new ImageIcon("D:\\常用\\图片\\"
                  + "Camera Roll\\image\\1\\7.png").getImage();
  Random random=new Random();
  x=random.nextInt(100)+1900;
  y=random.nextInt(800)+80; 
 }
//移动方法 
 public void move() {
  if(automaticMove==1){
   y--;
  }
  if(automaticMove==2){
   y++;
  }
  x-=2;
 }
 //画出敌机
 public void draw(Graphics g) {
  g.drawImage(dijiImage,x,y,128,128,null);
  if(isDied){
  g.drawImage(diedImage, x, y, null); 
  }  
 } 
 //判断是否越界
 public boolean isOutBounds(){
  if(x<0){
  return true; 
  }else{
  return false; 
  }
 }
//设置飞机炮炸的方法
 public void Blast(){
  isDied=true;
 }
 //打开敌机炮炸音乐
 @SuppressWarnings("deprecation")
 public void startMusic(){
  URL url;
   try {
    url = musicFile.toURL();
    AudioClip aud;
    aud=Applet.newAudioClip(url);
    aud.play();
  try {
   Thread.sleep(1000);
  } catch (InterruptedException e) {
    //TODO Auto-generated catch block
   e.printStackTrace();
  }
  aud.stop();
  } catch (MalformedURLException e) {
   //e.printStackTrace();
  }
 }
 //获得和设置坐标
 public void setX(int startX) {
  this.x=startX;
 }
 public void setY(int startY) {
  this.y=startY;
 }
 public int getX() {
  return x;
 }
 public int getY() {
  return y;
 }
 //发射子弹计数器和获得产生子弹的数量
    public void addBulletCount(){
     dijiBulletCount++;
  }
 public int getBulletCount(){
  return dijiBulletCount;
  }
  //获得敌机子弹的高度和宽度
 public int getDiJiHeight(){
  return dijiImage.getHeight(null);
  }
 public int getDiJiWidth(){
  return dijiImage.getWidth(null);
  }
} 
  1. MyFeiJiBullet.java:战机炮弹类
/**
 * 飞机子弹类
 * @author 梦想少年
 * 实现接口中的方法,检测是否攻击到敌方
 */
 public class MyFeiJiBullet implements Entity {
 //子弹类型
 private int bulletType;
 //坐标
 private int x,y;
 //子弹图片
 Image image;
 //初始化图片
 public MyFeiJiBullet(){
  image=new ImageIcon("D:\\常用\\图片\\"
            + "Camera Roll\\image\\bullet2.png").getImage();
 }
  //移动
 public void move() {
     x+=7;
 }
 //画图
 public void draw(Graphics g) {
  if(bulletType==1){
        g.drawImage(image, x, y, 100, 100, null); 
  }
 }
 //检测是否越界
 public boolean isOutBounds(){
  if(x>1920){
  return true; 
  }else{
  return false; 
  }
 }
  //设置子弹类型的方法
 public void setBulletType(int bulletType){
  this.bulletType=bulletType;
 }
  //设置和获得坐标的方法
 public void setX(int startX) {
  this.x=startX;
 }
 public void setY(int startY) {
  this.y=startY;
 }
 public int getX() {
  return x;
 }
 public int getY() {
  return y;
 }
  //检测我的飞机是否被敌机子弹击中
 public boolean isShootDiJiBullet(DiJiBullet dijibullet){
   int x1=this.x;//我的子弹x坐标
   int y1=this.y;//我的子弹y坐标
   int width1=this.image.getWidth(null);//我的子弹宽度
   int height1=this.image.getHeight(null);//我的子弹高度
   int x11=x1+width1/2;
   int y11=y1+height1/2;//确定中心位置
   //敌机的横纵坐标和高度
   int x2=dijibullet.getX();
   int y2=dijibullet.getY();
   int width2=dijibullet.getDiJiBulletWidth();
   int height2=dijibullet.getDiJiBulletHeight();
   int x22=x2+width2/2;
   int y22=y2+height2/2;
   //计算距离
   int distanceX=Math.abs(x22-x11);
   int distanceY=Math.abs(y22-y11);
   //是否碰撞
   if(distanceX<=200&&distanceY<=100){
       return true; 
   }else{
    return false;
   }
  }
   //检测我的飞机是否被敌机碰撞
 public boolean isShootDiJi(Diji diji){
   int x1=this.x;//我的子弹x坐标
   int y1=this.y;//我的子弹y坐标
   int width1=this.image.getWidth(null);//我的子弹宽度
   int height1=this.image.getHeight(null);//我的子弹高度
   int x11=x1+width1/2;
   int y11=y1+height1/2;//确定中心位置
   //敌机的横纵坐标和高度
   int x2=diji.getX();
   int y2=diji.getY();
   int width2=diji.getDiJiWidth();
   int height2=diji.getDiJiHeight();
   int x22=x2+width2/2;
   int y22=y2+height2/2;
   //计算距离
   int distanceX=Math.abs(x22-x11);
   int distanceY=Math.abs(y22-y11);
   //是否碰撞
   if(distanceX<=100&&distanceY<=100){
       return true; 
   }else{
    return false;
   }
  }
}
  1. DiJiBullet.java:敌机炮弹类
/**
 * 敌机子弹类
 * @author 梦想少年
 * 实现接口中的全部方法,同时要控制边界
 */
public class DiJiBullet implements Entity {
 private int x,y;
 private Image image;
 //初始化
 public DiJiBullet(){
  image=new ImageIcon("D:\\常用\\图片\\"
                 + "Camera Roll\\image\\1\\5.PNG").getImage();
 }
//移动的方法 
 public void move() {
 x-=3; 
 }
 //画图的方法
 public void draw(Graphics g) {
 g.drawImage(image, x, y, null); 
 }
//检测是否越界
 public boolean isOutBounds(){
  if(x<0){
  return true; 
  }else{
  return false; 
  }
 }
 //设置和获得坐标的方法
 public void setX(int startX) {
  this.x=startX;
 }
 public void setY(int startY) {
  this.y=startY;
 }
 public int getX() {
  return x;
 }
 public int getY() {
  return y;
 }
 //获得敌机子弹的高度和宽度
 public int getDiJiBulletHeight(){
  return image.getHeight(null);
 }
 public int getDiJiBulletWidth(){
  return image.getWidth(null);
 }
}
  1. BackGroundPhotosMusic.java:背景图片类
/**
 * 背景图片音乐类
 * @author 梦想少年
 * 实现接口中的方法,画出移动的图片、一些界面的设置
 */
 public class BackGroundPhotosMusic implements Entity{//添加背景
  private int x,y;
  private Image image;
  //背景音乐(一定要wav格式的音乐才有效)
  private AudioClip audio;
  //播放关闭音乐字符串和状态
  private boolean isMusic;
  private String musicString;
  //游戏状态
  private boolean isGame;
  private String gameString;
    //初始化背景图片
  public BackGroundPhotosMusic(){
  image=new ImageIcon("D:\\常用\\图片\\"
    + "Camera Roll\\image\\bg11.jpg").getImage();
  File  musicFile=new File("C:\\Users\\梦想少年\\Music\\"
    + "AudioConvert\\薛之谦 - 天后 (Live).wav");
  try {
   audio=Applet.newAudioClip(musicFile.toURI().toURL());
  } catch (MalformedURLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
  //移动背景
 public void move() {
      x--;
 }
 //画出背景
 public void draw(Graphics g) {
    if((x+image.getWidth(null)<=0)){
      x=0;
 }
    g.drawImage(image, x, y, 1920, 1080, null);
   g.drawImage(image, x+image.getWidth(null), y, 1920, 1080, null);  
   //相关设置
     g.setFont(new Font("黑体",Font.BOLD,30));
  g.setColor(Color.BLUE);
  g.drawString("游戏设置",30,180);
  //音乐启停
  g.setFont(new Font("黑体",Font.BOLD,20));
  g.setColor(Color.RED);
  g.drawString(musicString,35,220);
  g.setColor(Color.WHITE);
  g.drawRect(35,200,85,25);
  //暂停游戏
  g.setFont(new Font("黑体",Font.BOLD,20));
  g.setColor(Color.RED);
  g.drawString(gameString,35,250);
  g.setColor(Color.WHITE);
  g.drawRect(35,230,85,25);
  //退出游戏
  g.setFont(new Font("黑体",Font.BOLD,20));
  g.setColor(Color.RED);
  g.drawString("退出游戏",35,280);
  g.setColor(Color.WHITE);
  g.drawRect(35,260,85,25);
 }
  public void setX(int startX){}
 public void setY(int startY){}
 public int getX() {
  return 0;
 }
 public int getY() {
  return 0;
 }
 //播放音乐
 public void startMusic(){
  if(!isMusic){
  audio.loop();
  musicString="暂停音乐";
  isMusic=true;
  }else{
  audio.stop();
  musicString="打开音乐";
  isMusic=false;
  }
 }
  //游戏停止
 public void StartGame(){
  if(!isGame){
  gameString="暂停游戏";
  isGame=true;
  }else{
  gameString="开始游戏";
  isGame=false;
  }
 }
 //返回游戏状态
 public boolean gameState(){
  return isGame;
 }
}
  1. MainUI.java:主界面类
/**
 * 主界面类
 * @author 梦想少年
 * 创建队列控制所有的对象的移动和画图,同时实现键盘监听器控制战机的移动和发射炮弹
 * 其他功能(1.开始界面2.游戏界面3.背景音乐和爆炸音乐)
 */
 public class MainUI implements KeyListener,MouseListener{
 //创建主队列
 ArrayList<Entity> wholelist=new ArrayList<>();
 
 public static void main(String[] args){  
  MainUI ui=new MainUI();
  ui.showUI();
 }
  //创建飞机对象
 MyFeiJi myfeiji=new MyFeiJi();
 //创建背景对象
 BackGroundPhotosMusic background=new BackGroundPhotosMusic();
 //主界面
    public void showUI(){
  JFrame jframe=new JFrame("雷霆战机");
  jframe.setSize(1920, 1080);
  jframe.setLayout(new FlowLayout());
  jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  jframe.setLocationRelativeTo(null);      
  jframe.addKeyListener(this);
  jframe.addMouseListener(this);
  jframe.setVisible(true);
    //将背景对象加入主队列
  background.startMusic();
  background.StartGame();
     wholelist.add(background);
     //将玩家飞机加入队列,注意顺序,避免画图覆盖
     myfeiji.setX(300);
     myfeiji.setY(500);
     myfeiji.setHP(100);
     wholelist.add(myfeiji); 
       //开启清除线程
  RemoveThread remove=new RemoveThread(wholelist);
  remove.start(); 
  //定时产生敌机&&&及它的子弹
  Timer timer=new Timer();
  timer.schedule(new TimerTask() {
     public void run(){
  //敌机   
    Diji diji1=new Diji();
    wholelist.add(diji1);
      //敌机子弹  
  for(int i=0;i<=30;i++){ 
   DiJiBullet dijizidan1=new DiJiBullet();
   //设置初始坐标
   dijizidan1.setX(diji1.getX()-20);
   dijizidan1.setY(diji1.getY()+45);
   //子弹计数加1
   diji1.addBulletCount();
    wholelist.add(dijizidan1);
         //控制子弹的数量
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     e.printStackTrace();
     }
    if(diji1.getBulletCount()==5){
     break;
     }
    }
   }
  },1,1);
    //双缓冲改善画面
  Graphics g=jframe.getGraphics();
        BufferedImage bufferedimage=new BufferedImage(jframe.getWidth(),
                 jframe.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
  Graphics bufferG=bufferedimage.getGraphics();
  //不断遍历主队列并不断调用主方法,画出所有图像
  while(true){
   for(int i=0;i<wholelist.size();i++){
    Entity whole=wholelist.get(i);
    whole.draw(bufferG);
    if(!myfeiji.isDefeat()&&background.gameState()){
     whole.move();
    }else if(myfeiji.getHP()<=0){
    //游戏输赢
    int result=JOptionPane.showConfirmDialog(jframe,""
               + "是否退出游戏?");
    if(result==0){
     System.exit(0);
     }
    }
   }
      //画出缓存图片
   g.drawImage(bufferedimage,0,0,null);
   try {
    Thread.sleep(5);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   
  }  
 }
      public void keyPressed(KeyEvent e){ 
      //获得键盘事件
      int code=e.getKeyCode();
      
      if(code==KeyEvent.VK_F){
       //子弹1
       MyFeiJiBullet myfeijibullet1=new MyFeiJiBullet();
       //设置坐标
       myfeijibullet1.setX(myfeiji.getX()+100);
       myfeijibullet1.setY(myfeiji.getY()-10);
       //设置子弹类型
       myfeijibullet1.setBulletType(1);
       //加入队列
       wholelist.add(myfeijibullet1);
       
       //子弹2
       MyFeiJiBullet myfeijibullet2=new MyFeiJiBullet();
       //设置坐标
       myfeijibullet2.setX(myfeiji.getX()+100);
       myfeijibullet2.setY(myfeiji.getY()+55);
       //设置子弹类型
       myfeijibullet2.setBulletType(1);
       //加入队列
       wholelist.add(myfeijibullet2);
      }
            //上下左右控制飞机移动
      if(code==KeyEvent.VK_UP){
       myfeiji.up=true;
      }
      if(code==KeyEvent.VK_DOWN){
       myfeiji.down=true;
      }
      if(code==KeyEvent.VK_LEFT){
       myfeiji.left=true;
      }
      if(code==KeyEvent.VK_RIGHT){
       myfeiji.right=true;
      }
     }
     public void keyTyped(KeyEvent e){}
     public void keyReleased(KeyEvent e){
      int code=e.getKeyCode();
      if(code==KeyEvent.VK_UP){
       myfeiji.up=false;
      }
      if(code==KeyEvent.VK_DOWN){
       myfeiji.down=false;
      }
      if(code==KeyEvent.VK_LEFT){
       myfeiji.left=false;
      }
      if(code==KeyEvent.VK_RIGHT){
       myfeiji.right=false;
      }
     }
     //游戏菜单相关设置
  public void mouseClicked(MouseEvent e){}
  public void mousePressed(MouseEvent e){
   //获得点击的X和Y坐标
   int x=e.getX();
   int y=e.getY();
  //音乐开停
  if(x>=35&&x<=85&&y>=200&&y<=225){
   background.startMusic(); 
  //界面开停
  }else if(x>=35&&x<=85&&y>=230&&y<=255){
   background.StartGame();
  }else if(x>=35&&x<=85&&y>=260&&y<=285){
  System.exit(0); 
  }
  }
  public void mouseReleased(MouseEvent e){}
  public void mouseEntered(MouseEvent e){}
  public void mouseExited(MouseEvent e){} 
}
  1. RemoveThread.java:去除线程类
/**
* 去除线程类
* @author 梦想少年
* 创建线程来实现对越界子弹敌机的去除,控制飞机的碰撞
*/
public class RemoveThread extends Thread{
//各个对象的队列
ArrayList<Entity> list;
//攻击后我机的加分判断
private boolean isShootDiJiBullet;
private boolean isShootDiJi;
//初始化
public RemoveThread(ArrayList<Entity> list) {
 this.list=list;
}
 public void run(){
 while(true){
 //休息一下
  try {
   Thread.sleep(2);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  //清除所有的越界敌机、飞机子弹、敌机子弹
 for(int i=0;i<list.size();i++){   
   Entity entity=list.get(i);
    //清除敌机
   if(entity instanceof Diji){
  Diji diji=(Diji)entity;
    if(diji.isOutBounds()){
    list.remove(diji);
           }
//清除我机子弹
    }else if(entity instanceof MyFeiJiBullet){
     MyFeiJiBullet myfeijibullet=(MyFeiJiBullet)entity;
     if(myfeijibullet.isOutBounds()){
      list.remove(myfeijibullet);
     }
//清除敌机子弹
    }else if(entity instanceof DiJiBullet){
     DiJiBullet dijibullet=(DiJiBullet)entity;
     if(dijibullet.isOutBounds()){
      list.remove(dijibullet);
     }
    }
    //------------------------------------------------------  
   }
//清除和处理碰撞
  for(int i=0;i<list.size();i++){
   Entity entity1=list.get(i);
   for(int j=0;j<list.size();j++){
    Entity entity2=list.get(j);
   if(entity1 instanceof MyFeiJi){
    MyFeiJi myfeiji=(MyFeiJi)entity1;
         //设置一个加分的开关
        if(isShootDiJi){
         myfeiji.addDoubleScores();
         isShootDiJi=false;
        }else if(isShootDiJiBullet){
         myfeiji.addScores();
         isShootDiJiBullet=false;
        }
             //-------------------------------
    if(entity2 instanceof DiJiBullet){
    DiJiBullet dijibullet=(DiJiBullet)entity2;
    if(myfeiji.isShootByDiJiBullet(dijibullet)){
    list.remove(dijibullet);//清除敌机子弹
    myfeiji.subBlood();//我机掉血     
    }
    }//以上是敌机子弹范围
else  if(entity2 instanceof Diji){
 Diji diji=(Diji)entity2;
 if(myfeiji.isShootByDiJi(diji)){
  diji.Blast();//敌机爆炸
  diji.startMusic();//播放爆炸音乐  
  list.remove(diji);//去除敌机
  myfeiji.subDoubleBlood();//我机掉多倍的血量
 }
  }//以上是敌机范围     
      }//我的飞机范围
else  if(entity1 instanceof MyFeiJiBullet){
 MyFeiJiBullet myfeijibullet=(MyFeiJiBullet)entity1;
 if(entity2 instanceof DiJiBullet){
  DiJiBullet dijibullet=(DiJiBullet)entity2;
  if(myfeijibullet.isShootDiJiBullet(dijibullet)&&
                       i<list.size()&&j<list.size()){
   list.remove(myfeijibullet);//去除飞机子弹
   list.remove(dijibullet);//去除敌机子弹
   isShootDiJiBullet=true;//打开加分开关
  }
 }else if(entity2 instanceof Diji){
  Diji diji=(Diji)entity2;
  if(myfeijibullet.isShootDiJi(diji)&&
                   i<list.size()&&j<list.size()){
      list.remove(myfeijibullet);//去除我机子弹
      diji.Blast();//打开爆炸图片
      diji.startMusic();//打开爆炸音乐
      list.remove(diji);//去除敌机
      isShootDiJi=true;//打开加分开关
  }
 }
}//我的飞机子弹范围
   }
//------------------------- 
  }
//------------------------------------------------------
 } 
}
}
总结分析

先来看看效果吧!!!!
在这里插入图片描述
整体效果还是不错的,代码的可拓展性还是比较好的,大家如果想要添加一些别的功能:大boss、奖赏、添加技能等等。但是在编写的时候我遇到了一些问题:
1.清除线程存在错位和碰撞检测不及时的问题
2.不能很好地解决敌机爆炸和爆炸背景音乐播放的延时问题

大家如果有问题我们可以相互讨论啊ヾ(≧▽≦*)o,最后记得留下一个赞哦!!!

  • 8
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
基于Java飞机大战游戏主要需要我方飞机和敌方飞机,还有子弹,特殊nPC,开始背景,结束背景,以及背景音乐。我方飞机可以随意移动,敌方飞机无规律出现。游戏玩家通过鼠标移动控制飞机移动,我方飞机在游戏开始时就一直能发射子弹,当我方子弹碰到敌方飞机时,敌方飞机消失。当玩家飞机碰到敌方子弹时,生命值减一,直到玩家飞机生命值为一时,游戏结束。基本模块包括:游戏状态控制功能模块、游戏难度的调整模块、游戏界面绘画功能模块、玩家游戏控制功能模块等。本系统结构如下: (1)游戏状态控制功能模块:游戏的状态控制包括运行及结束游戏,首先进入游戏的开始页面,在游戏进行时,玩家必须躲避或者击落敌方飞机,玩家飞机的生命值降低为0的时候游 戏就会结束,弹出游戏结束界面 (2)游戏难度的调整模块:玩家玩的时间越长游戏的难度越高,敌方飞机的数量越多、敌方飞机出现的频率越高,玩家保证飞机的存活的难度越高,操作难度相应也高。 (3)游戏界面绘画功能模块:左上角会显示玩家飞机当前生命值,游戏时间,当前分数,其他地方用来输出玩家对我方飞机的控制与敌方飞机的动作显示 (4)玩家游戏控制功能模块: 玩家可以通过控制鼠标或者键盘来控制方飞机(Hero airplane)的移动。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值