飞机大战小游戏

实现过程

  1. 新建FlyObject类
  2. 创建飞行物(小蜜蜂、小飞机、大飞机、英雄机、子弹)子类
  3. 实现生成飞行物
  4. 实现飞行物的移动
  5. 实现碰撞消失以及爆炸效果
  6. 增加奖励以及分数机制
    添加了飞机爆炸效果,并且设有多重难度以及奖励,玩法更丰富
    以下是相应代码
    FlyObject类: 所有飞行物的父类
import java.awt.image.BufferedImage;

/**
 * 飞行物类:x,y,图片、宽、高、速度 子类:英雄机、小敌机、小蜜蜂、子弹、大敌机
 */
public abstract class FlyObject {
    protected int x;
    protected int y;
    protected BufferedImage image;
    protected int speed;
    protected int width;
    protected int height;
    protected int flood;

    public FlyObject() {

    }

    public abstract void move();

    public boolean crashBullet(Bullet a) {
        int x = a.getX();
        int y = a.getY();
        return this.x < x && x < this.x + width && this.y < y && y < this.y + height;
    }

    public BulletEnemy shootHero() {
        return null;
    }

    public int getFlood() {
        return flood;
    }

    public void setFlood(int flood) {
        this.flood = flood;
    }

    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 BufferedImage getImage() {
        return image;
    }

    public void setImage(BufferedImage image) {
        this.image = image;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

}

Hero类: 英雄机

import java.awt.image.BufferedImage;

/**
 * 英雄机类:继承FlyObject 子弹、生命、分数
 */
public class Hero extends FlyObject {
    private int life;//英雄机生命
    private Bullet bullet;
    private int awardType;//判断奖励类型,攻击子弹类型
    private boolean check;//判断是否收到撞击,是否显示爆炸效果
    private int count;//显示爆炸效果的计数
    private int shootSpeed;//发射子弹速度

    public Hero() {
        x = 150;
        y = 450;
        // hero0.png图片和Hero类在同一个包下
        image = ShootGame.hero0Img;
        width = image.getWidth();
        height = image.getHeight();
        speed = 1;
        life = 3;
        awardType = 0;
        count = 0;
        check = false;
        shootSpeed = 30;
    }

    // 英雄机移动
    BufferedImage[] images = {ShootGame.hero0Img, ShootGame.hero1Img};
    BufferedImage[] images2 = {ShootGame.hero_ember0Img, ShootGame.hero_ember1Img, ShootGame.hero_ember2Img, ShootGame.hero_ember3Img};

	//英雄机动画效果
    @Override
    public void move() {
        //切换image
        if (check) {
            if (count < 4) {
                image = images2[count];
                count++;
            } else {
                count = 0;
                check = false;
            }
        } else {
            image = images[speed++ % 2];
        }
    }

    //敌机撞击
    public boolean crashFlyings(FlyObject flying) {
        int x = flying.getX();
        int y = flying.getY();
        int flyingWidth = flying.getWidth();
        int flyingHeight = flying.getHeight();
        return (this.x < x + flyingWidth && x < this.x + width && this.y + height / 3 < y + flyingHeight && y < this.y + height);
    }

    //撞击子弹
    public boolean crashBulletEnemy(BulletEnemy a) {
        int x = a.getX();
        int y = a.getY();
        return this.x < x && x < this.x + width && this.y + height / 3 < y && y < this.y + height;
    }

    //发射子弹
    public Bullet[] shoot() {
        int type = 0;
        if (awardType >= 70) {
            type = 7;
        } else if (awardType >= 40) {
            type = 6;
        } else if (awardType >= 20) {
            type = 5;
        } else if (awardType >= 10) {
            type = 4;
        } else if (awardType >= 5) {
            type = 3;
        } else if (awardType >= 1) {
            type = 2;
        } else if (awardType >= 0) {
            type = 1;
        }
        Bullet[] bu;

        if (type == 1) {
            bu = new Bullet[1];
            shootSpeed = 20;
            bu[0] = new Bullet(x + width / 2 - ShootGame.bulletImg.getWidth() / 2, y);
        } else if (type == 2) {
            bu = new Bullet[2];
            shootSpeed = 20;
            bu[0] = new Bullet(x + width / 4, y);
            bu[1] = new Bullet(x + width * 3 / 4, y);
        } else if (type == 3) {
            bu = new Bullet[2];
            shootSpeed = 15;
            bu[0] = new Bullet(x + width / 4, y);
            bu[1] = new Bullet(x + width * 3 / 4, y);
        } else if (type == 4) {
            bu = new Bullet[3];
            shootSpeed = 15;
            bu[0] = new Bullet(x + width / 4, y);
            bu[1] = new Bullet(x + width / 2, y);
            bu[2] = new Bullet(x + width * 3 / 4, y);
        } else if (type == 5) {
            bu = new Bullet[4];
            shootSpeed = 10;
            bu[0] = new Bullet(x, y);
            bu[1] = new Bullet(x + width / 4, y);
            bu[2] = new Bullet(x + width * 3 / 4, y);
            bu[3] = new Bullet(x + width, y);
        } else if (type == 6) {
            bu = new Bullet[6];
            shootSpeed = 5;
            bu[0] = new Bullet(x, y);
            bu[1] = new Bullet(x + width * 2 / 10, y);
            bu[2] = new Bullet(x + width * 4 / 10, y);
            bu[3] = new Bullet(x + width * 6 / 10, y);
            bu[4] = new Bullet(x + width * 8 / 10, y);
            bu[5] = new Bullet(x + width, y);
        } else if (type == 7) {
            bu = new Bullet[8];
            shootSpeed = 5;
            bu[0] = new Bullet(x - width * 2 / 10, y);
            bu[1] = new Bullet(x, y);
            bu[2] = new Bullet(x + width * 2 / 10, y);
            bu[3] = new Bullet(x + width * 4 / 10, y);
            bu[4] = new Bullet(x + width * 6 / 10, y);
            bu[5] = new Bullet(x + width * 8 / 10, y);
            bu[6] = new Bullet(x + width, y);
            bu[7] = new Bullet(x + width * 12 / 10, y);
        } else {
            bu = new Bullet[1];
            shootSpeed = 15;
            bu[0] = new Bullet(x + width / 2 - ShootGame.bulletImg.getWidth() / 2, y);
        }
        return bu;
    }

    public int getShootSpeed() {
        return shootSpeed;
    }

    public void setShootSpeed(int shootSpeed) {
        this.shootSpeed = shootSpeed;
    }

    public boolean isCheck() {
        return check;
    }

    public void setCheck(boolean check) {
        this.check = check;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getAwardType() {
        return awardType;
    }

    public void setAwardType(int awardType) {
        this.awardType = awardType;
    }

    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }
}

Bee类: 小蜜蜂(加奖励)

/**
 * 小蜜蜂类:继承FlyObject
 * 奖励、血量
 */
public class Bee extends FlyObject implements Award{
    private boolean flag = true;
    private int award;

    public Bee() {
        image = ShootGame.beeImg;
        width = image.getWidth();
        height = image.getHeight();
        x = (int) (Math.random() * (400 - width));
        y = -height;
        speed = 3;
        flood = 2;
        award = (int) (Math.random() * 2);//奖励类型:0/1
    }

    @Override
    public int getAward() {
        return award;
    }

    @Override
    public void move() {
        setY(getY() + getSpeed());
        if (getX() < 0) {
            flag = true;
        } else if (getX() > 400 - width) {
            flag = false;
        }
        if (flag) {
            setX(getX() + getSpeed() * 2);
        } else {
            setX(getX() - getSpeed() * 2);
        }
    }

    public int getFlood() {
        return flood;
    }

    public void setFlood(int flood) {
        this.flood = flood;
    }

}

Airplane类: 小飞机(加分数)

/**
 * 敌机类:继承FlyObject 血量、分数
 */
public class Airplane extends FlyObject implements Enemy {
    private int score;

    public Airplane() {
        image = ShootGame.airplaneImg;
        width = image.getWidth();
        height = image.getHeight();
        speed = 4;
        x = (int) (Math.random() * (400 - width));
        y = -height;
        flood = 2;
        score = 10;
    }

    @Override
    public int getScore() {
        return score;
    }

    @Override
    public void move() {
        setY(getY() + getSpeed());
    }

    public int getFlood() {
        return flood;
    }

    public void setFlood(int flood) {
        this.flood = flood;
    }

}

Bigplane类: 大飞机(加分数和加奖励)

/**
 * 大敌机类:继承FlyObject 奖励、血量、分数
 */
public class Bigplane extends FlyObject implements Enemy, Award{
    private int score;
    private int award;

    public Bigplane() {
        image = ShootGame.bigplaneImg;
        width = image.getWidth();
        height = image.getHeight();
        speed = 1;
        x = (int) (Math.random() * (400 - width));
        y = -height;
        flood = 6;
        score = 20;
        award = 1;
    }

    @Override
    public int getScore() {
        return score;
    }

    @Override
    public BulletEnemy shootHero() {
        BulletEnemy bu = new BulletEnemy(x + width / 2 - ShootGame.bulletImg.getWidth() / 2, y + height);
        return bu;
    }

    @Override
    public void move() {
        setY(getY() + getSpeed());
    }

    public int getFlood() {
        return flood;
    }

    public void setFlood(int flood) {
        this.flood = flood;
    }

    public int getAward() {
        return award;
    }

}

Bullet类 英雄机发射的子弹

/**
 * 子弹类:继承FlyObject 类型
 */
public class Bullet extends FlyObject {
    private int bulletType;

    public Bullet(int x, int y) {
        // x、y是根据英雄机的位置动态传入的值
        image = ShootGame.bulletImg;
        width = image.getWidth();
        height = image.getHeight();
        speed = 3;
        this.x = x;
        this.y = y;
    }

    @Override
    public void move() {
        setY(getY() - getSpeed() * 3);
    }

    public int getBulletType() {
        return bulletType;
    }

    public void setBulletType(int bulletType) {
        this.bulletType = bulletType;
    }

}

Ember类: 爆炸效果的父类

public class Ember {
    protected FlyObject fly;
    protected int count;

    public Ember(FlyObject fly) {
        this.fly = fly;
    }

    public Ember() {

    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public void changeImg(){

    }
}

EmberAirplane类: 小飞机爆炸

import java.awt.image.BufferedImage;

public class EmberAirplane extends Ember {
    public EmberAirplane(FlyObject fly) {
        super(fly);
        count = 0;
    }
    BufferedImage[] images = {ShootGame.airplane_ember0Img, ShootGame.airplane_ember1Img, ShootGame.airplane_ember2Img, ShootGame.airplane_ember3Img};
    @Override
    public void changeImg() {
        this.fly.setImage(images[count]);
    }
}

EmberBee类: 小蜜蜂爆炸

import java.awt.image.BufferedImage;

public class EmberBee extends Ember {
    public EmberBee(FlyObject fly) {
        super(fly);
        count = 0;
    }
    BufferedImage[] images = {ShootGame.bee_ember0Img, ShootGame.bee_ember1Img, ShootGame.bee_ember2Img, ShootGame.bee_ember3Img};
    @Override
    public void changeImg() {
        this.fly.setImage(images[count]);
    }
}

EmberBigplane类: 大飞机爆炸

import java.awt.image.BufferedImage;

public class EmberBigplane extends Ember{
    public EmberBigplane(FlyObject fly) {
        super(fly);
        count = 0;
    }
    BufferedImage[] images = {ShootGame.bigplane_ember0Img, ShootGame.bigplane_ember1Img, ShootGame.bigplane_ember2Img, ShootGame.bigplane_ember3Img};
    @Override
    public void changeImg() {
        this.fly.setImage(images[count]);
    }
}

BulletEnemy类: 难度4以上,大飞机发射的子弹

public class BulletEnemy extends FlyObject{

    public BulletEnemy(int x, int y) {
        // x、y是根据英雄机的位置动态传入的值
        image = ShootGame.bulletImg;
        width = image.getWidth();
        height = image.getHeight();
        speed = 3;
        this.x = x;
        this.y = y;
    }

    @Override
    public void move() {
        setY(getY() + getSpeed() * 3);
    }
}

Award接口:

public interface Award {
    int getAward();
}

Enemy接口:

public interface Enemy {
    int getScore();
}

ShootGame类以及主程序:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * 界面类:窗口类JFrame-对象 面板/画板类JPanel - 不能直接new JPanel();
 */
public class ShootGame extends JPanel {
    //画板宽度和高度
    public static final int WIDTH = 400;//游戏界面的宽
    public static final int HEIGHT = 654;//游戏界面的高
    public static final int START = 0;//开始
    public static final int RUNNING = 1;//运行
    public static final int PAUSE = 2;//暂停
    public static final int GAMEOVER = 3;//游戏结束
    private int state;//游戏状态
    private int score = 0;//游戏分数
    private int difficultType = 1;//游戏难度
    private int difficultShootSpeed = 60;//大飞机射击速度
    private int difficult = 50;//飞行物生成速度
    private int countAirplane = 0;//计数击杀小飞机数量
    private int countBigplane = 0;//计数击杀大飞机数量
    private int countBee = 0;//计数击杀小蜜蜂数量
    private Hero hero;//英雄机
    private FlyObject[] flyings = {};// 用于存放敌机+小蜜蜂
    private Bullet[] bullets = {};// 用于存放英雄机子弹
    private BulletEnemy[] bullets2 = {};// 用于存放大敌机子弹
    private Ember[] embers = {};//用于存放灰烬
    // 定义所有的图片资源
    public static BufferedImage hero0Img;
    public static BufferedImage hero1Img;
    public static BufferedImage hero_ember0Img;
    public static BufferedImage hero_ember1Img;
    public static BufferedImage hero_ember2Img;
    public static BufferedImage hero_ember3Img;
    public static BufferedImage beeImg;
    public static BufferedImage bee_ember0Img;
    public static BufferedImage bee_ember1Img;
    public static BufferedImage bee_ember2Img;
    public static BufferedImage bee_ember3Img;
    public static BufferedImage bulletImg;
    public static BufferedImage airplaneImg;
    public static BufferedImage airplane_ember0Img;
    public static BufferedImage airplane_ember1Img;
    public static BufferedImage airplane_ember2Img;
    public static BufferedImage airplane_ember3Img;
    public static BufferedImage bigplaneImg;
    public static BufferedImage bigplane_ember0Img;
    public static BufferedImage bigplane_ember1Img;
    public static BufferedImage bigplane_ember2Img;
    public static BufferedImage bigplane_ember3Img;
    public static BufferedImage background;
    public static BufferedImage startImg;
    public static BufferedImage pauseImg;
    public static BufferedImage gameoverImg;
    public static BufferedImage luFuImg;

    static {// 加载图片资源
//		String path = Hero.class.getResource("hero0.png").getFile();
        try {// read静态方法
            background = ImageIO.read(Hero.class.getResource("background.png"));
            hero0Img = ImageIO.read(Hero.class.getResource("hero0.png"));
            hero1Img = ImageIO.read(Hero.class.getResource("hero1.png"));
            hero_ember0Img = ImageIO.read(Hero.class.getResource("hero_ember0.png"));
            hero_ember1Img = ImageIO.read(Hero.class.getResource("hero_ember1.png"));
            hero_ember2Img = ImageIO.read(Hero.class.getResource("hero_ember2.png"));
            hero_ember3Img = ImageIO.read(Hero.class.getResource("hero_ember3.png"));
            beeImg = ImageIO.read(Hero.class.getResource("bee.png"));
            bee_ember0Img = ImageIO.read(Hero.class.getResource("bee_ember0.png"));
            bee_ember1Img = ImageIO.read(Hero.class.getResource("bee_ember1.png"));
            bee_ember2Img = ImageIO.read(Hero.class.getResource("bee_ember2.png"));
            bee_ember3Img = ImageIO.read(Hero.class.getResource("bee_ember3.png"));
            bulletImg = ImageIO.read(Hero.class.getResource("bullet.png"));
            airplaneImg = ImageIO.read(Hero.class.getResource("airplane.png"));
            airplane_ember0Img = ImageIO.read(Hero.class.getResource("airplane_ember0.png"));
            airplane_ember1Img = ImageIO.read(Hero.class.getResource("airplane_ember1.png"));
            airplane_ember2Img = ImageIO.read(Hero.class.getResource("airplane_ember2.png"));
            airplane_ember3Img = ImageIO.read(Hero.class.getResource("airplane_ember3.png"));
            bigplaneImg = ImageIO.read(Hero.class.getResource("bigplane.png"));
            bigplane_ember0Img = ImageIO.read(Hero.class.getResource("bigplane_ember0.png"));
            bigplane_ember1Img = ImageIO.read(Hero.class.getResource("bigplane_ember1.png"));
            bigplane_ember2Img = ImageIO.read(Hero.class.getResource("bigplane_ember2.png"));
            bigplane_ember3Img = ImageIO.read(Hero.class.getResource("bigplane_ember3.png"));
            startImg = ImageIO.read(Hero.class.getResource("start.png"));
            pauseImg = ImageIO.read(Hero.class.getResource("pause.png"));
            gameoverImg = ImageIO.read(Hero.class.getResource("gameover.png"));
            luFuImg = ImageIO.read(Hero.class.getResource("lufu.jpg"));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public ShootGame() {// 测试
        // 创建英雄机
        hero = new Hero();
    }

    // 绘画的方法 - JPanel父类给的 - 重写
    // setVisiable(true)-自动调用paint
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        // 自定义绘画方法
        // 图片对象:image x坐标 y坐标 null
        g.drawImage(background, 0, 0, null);//画背景
        paintAll(g);
        g.drawImage(hero.getImage(), hero.getX(), hero.getY(), null);//画英雄机
        paintFlyObject(g);//画敌机+小蜜蜂
        paintBullets(g);//画子弹
        paintBulletEnemy(g);//画敌机子弹
        paintEmbers(g);//画爆炸效果
        paintState(g);//画状态
        // 字符串 x坐标 y坐标
        g.setColor(new Color(255, 255, 0));//设置颜色
        Font font = new Font("宋体", Font.BOLD, 15);//字体、风格:三个常量IFont.PLAIN,Font.BOLD,Font.ITALIC、字号
        setFont(font);
        g.drawString("SCORE:" + score, 10, 15);//画分数
        g.drawString("LIFE:" + hero.getLife(), 10, 30);//画生命
        paintDifficult(g);//画难度
        g.drawString("小飞机:" + countAirplane, 10, 580);//画击杀小飞机数量
        g.drawString("大敌机:" + countBigplane, 10, 595);//画击杀大敌机数量
        g.drawString("小蜜蜂:" + countBee, 10, 610);//画击杀小蜜蜂数量
        g.drawString("awardType:" + hero.getAwardType(), 250, 610);//奖励数量

    }

    // 画飞行物:画敌机+小蜜蜂flyings
    private void paintFlyObject(Graphics g) {
        for (int i = 0; i < flyings.length; i++) {
            g.drawImage(flyings[i].getImage(), flyings[i].getX(), flyings[i].getY(), null);
        }

    }

    // 画子弹
    private void paintBullets(Graphics g) {
        for (int i = 0; i < bullets.length; i++) {
            g.drawImage(bullets[i].getImage(), bullets[i].getX(), bullets[i].getY(), null);
        }

    }

    //画地方子弹
    private void paintBulletEnemy(Graphics g) {
        for (int i = 0; i < bullets2.length; i++) {
            g.drawImage(bullets2[i].getImage(), bullets2[i].getX(), bullets2[i].getY(), null);
        }

    }

    //画状态
    private void paintState(Graphics g) {
        switch (state) {
            case START:
                g.drawImage(startImg, 0, 0, null);
                break;
            case PAUSE:
                g.drawImage(pauseImg, 0, 0, null);
                break;
            case GAMEOVER:
                g.drawImage(gameoverImg, 0, 0, null);
                break;
        }
    }
    //画难度

    public void paintDifficult(Graphics g) {
        switch (difficultType) {
            case 1:
                g.drawString("难度:1", 10, 45);
                break;
            case 2:
                g.drawString("难度:2", 10, 45);
                break;
            case 3:
                g.drawString("难度:3", 10, 45);
                break;
            case 4:
                g.drawString("难度:4", 10, 45);
                break;
            case 5:
                g.drawString("难度:5", 10, 45);
                break;
            case 6:
                g.drawString("难度:6", 10, 45);
                break;
        }
    }

    //画爆炸效果
    public void paintEmbers(Graphics g) {
        for (int i = 0; i < embers.length; i++) {
            g.drawImage(embers[i].fly.getImage(), embers[i].fly.getX(), embers[i].fly.getY(), null);
        }
    }

    //画清屏效果
    public void paintAll(Graphics g) {
        if (countClick >= 3) {
            g.drawImage(luFuImg, -500, 0, null);
        }
    }

    /**
     * 开始游戏:定时器-持续性、周期性
     * 生成敌机、小蜜蜂 -> 飞行物
     * 生成子弹 -> 英雄机
     * 移动 -> 飞行物
     * 判断游戏是否结束
     * 判断飞行物和子弹有没有撞击
     * 判断英雄机和飞行物有没有撞击
     * 判断子弹有没有出界
     * 判断飞行物有没有出界
     */
    // 定时器
    Timer timer = new Timer();
    //清屏效果
    private int countClick = 0;
    private long time1 = 0;
    private long time2 = 0;

    // 开始游戏
    public void action() {
        //匿名内部类方式实现监听
        MouseAdapter ma = new MouseAdapter() {
            //鼠标单击时调用
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                switch (state) {
                    case START:
                        state = RUNNING;
                        break;
                    case GAMEOVER:
                        //全部清空归0
                        hero = new Hero();
                        flyings = new FlyObject[0];
                        bullets = new Bullet[0];
                        bullets2 = new BulletEnemy[0];
                        state = START;
                        score = 0;
                        countAirplane = 0;
                        countBee = 0;
                        countBigplane = 0;
                        difficultShootSpeed = 60;
                        difficultType = 1;
                        break;
                    case RUNNING://清屏效果(生命-1)
                        if (countClick < 3) {
                            time1 = System.currentTimeMillis();
                            countClick++;
                        } else {
                            time2 = System.currentTimeMillis();
                            countClick = 0;
                        }
                        if (Math.abs(time2 - time1) <= 500) {
//                            flyings = new FlyObject[0];
//                            bullets2 = new BulletEnemy[0];
//                            System.out.println("清屏");
                            hero.setLife(hero.getLife() - 1);//作弊器:快速点击三下鼠标,攻击最大化
                            hero.setAwardType(80);
                            time1 = 0;
                            time2 = 0;
                        }
                }
            }

            //鼠标进入时调用
            @Override
            public void mouseEntered(MouseEvent e) {
                super.mouseEntered(e);
                if (state == PAUSE) {
                    state = RUNNING;
                }
            }

            //鼠标移出时调用
            @Override
            public void mouseExited(MouseEvent e) {
                super.mouseExited(e);
                if (state != GAMEOVER && state != START) {
                    state = PAUSE;
                }
            }

            //鼠标移动时调用
            @Override
            public void mouseMoved(MouseEvent e) {
                super.mouseMoved(e);
                if (state == RUNNING) {
                    hero.setX(e.getX() - hero.getWidth() / 2);
                    hero.setY(e.getY() - hero.getHeight() / 2);
                    repaint();
                }
            }
        };
        //添加鼠标事件
        this.addMouseListener(ma);
        this.addMouseMotionListener(ma);
        // 过1s后开始执行,每0.1s执行一次
        timer.schedule(new TimerTask() {
            // 周期性任务
            @Override
            public void run() {
                if (state == RUNNING) {
                    //生成飞行物
                    enterFlyObject();
                    //生成子弹
                    shootAction();
                    //移动
                    goFlyings();
                    //子弹与飞行物撞击
                    crashBulletAndFlyings();
                    //英雄机与飞行物撞击
                    crashHeroFlyings();
                    //英雄机和大飞机子弹撞击
                    crashBulletEnemy();
                    //清理出界
                    outOfBoundsAction();
                    //爆炸效果
                    goEmber();
                    //检查游戏是否结束
                    checkGame();
                }
                //界面刷新
                repaint();
            }

        }, 100, 20);
    }

    private int countFlyings = 0;//定时

    // 生成敌机、小蜜蜂 -> flyings
    private void enterFlyObject() {
        countFlyings++;
        if (score > 5000) {
            difficultShootSpeed = 10;//大飞机射击速度
            difficultType = 6;//游戏难度
            difficult = 5;//飞行物生成速度
        } else if (score > 3000) {
            difficultShootSpeed = 30;//大飞机射击速度
            difficultType = 5;//游戏难度
            difficult = 20;//飞行物生成速度
        } else if (score > 1500) {
            difficultShootSpeed = 60;
            difficultType = 4;
            difficult = 30;
        } else if (score > 500) {
            difficultShootSpeed = 60;
            difficultType = 3;
            difficult = 30;
        } else if (score > 200) {
            difficultShootSpeed = 60;
            difficultType = 2;
            difficult = 50;
        } else {
            difficultShootSpeed = 60;
            difficultType = 1;
            difficult = 60;
        }
        if (countFlyings % difficult == 0) {
            int random = (int) (Math.random() * 15);
            FlyObject newFly;
            if (random == 0) {
                newFly = new Bee();
            } else if (random > 0 && random < 5) {
                newFly = new Bigplane();
            } else {
                newFly = new Airplane();
            }
            flyings = Arrays.copyOf(flyings, flyings.length + 1);
            flyings[flyings.length - 1] = newFly;
        }
    }

    //发射子弹
    private void shootAction() {
        if (countFlyings % hero.getShootSpeed() == 0) {
            Bullet[] newBullet = hero.shoot();
            bullets = Arrays.copyOf(bullets, bullets.length + newBullet.length);
            System.arraycopy(newBullet, 0, bullets, bullets.length - newBullet.length, newBullet.length);
        }
        if (difficultType >= 4) {
            if (countFlyings % difficultShootSpeed == 0) {
                for (int i = 0; i < flyings.length; i++) {
                    if (flyings[i] instanceof Bigplane) {
                        BulletEnemy newBullet = flyings[i].shootHero();
                        bullets2 = Arrays.copyOf(bullets2, bullets2.length + 1);
                        bullets2[bullets2.length - 1] = newBullet;
                    }
                }
            }
        }
    }

    //飞行物移动
    private void goFlyings() {
        for (int i = 0; i < flyings.length; i++) {
            flyings[i].move();
        }
        for (int i = 0; i < bullets.length; i++) {
            bullets[i].move();
        }
        for (int i = 0; i < bullets2.length; i++) {
            bullets2[i].move();
        }
        hero.move();
    }

    //清理过界
    private void outOfBoundsAction() {
        //判断飞行物
        for (int i = 0; i < flyings.length; i++) {
            if (flyings[i].getY() > HEIGHT) {
                hero.setAwardType(hero.getAwardType() / 2);//有飞机飞过界奖励减半
                FlyObject temp = flyings[i];
                flyings[i] = flyings[flyings.length - 1];
                flyings[flyings.length - 1] = temp;
                flyings = Arrays.copyOf(flyings, flyings.length - 1);
            }
        }
        //判断子弹
        for (int i = 0; i < bullets.length; i++) {
            if (bullets[i].getY() < -bullets[i].height) {
                Bullet temp = bullets[i];
                bullets[i] = bullets[bullets.length - 1];
                bullets[bullets.length - 1] = temp;
                bullets = Arrays.copyOf(bullets, bullets.length - 1);
            }
        }
        for (int i = 0; i < bullets2.length; i++) {
            if (bullets2[i].getY() > HEIGHT) {
                bullets2[i] = bullets2[bullets2.length - 1];
                bullets2 = Arrays.copyOf(bullets2, bullets2.length - 1);
            }
        }
    }

    //子弹与飞行物撞击
    private void crashBulletAndFlyings() {
        int flag = -1;//飞行物下标
        for (int i = 0; i < bullets.length; i++) {// i -> 子弹下标
            flag = crashBulletFlyings(bullets[i]);
            if (flag != -1) {
                flyings[flag].setFlood(flyings[flag].getFlood() - 1);
                if (flyings[flag].getFlood() == 0) {
                    //生成灰烬
                    Ember newEmber;
                    if (flyings[flag] instanceof Airplane) {
                        newEmber = new EmberAirplane(flyings[flag]);
                    } else if (flyings[flag] instanceof Bigplane) {
                        newEmber = new EmberBigplane(flyings[flag]);
                    } else {
                        newEmber = new EmberBee(flyings[flag]);
                    }
                    embers = Arrays.copyOf(embers, embers.length + 1);
                    embers[embers.length - 1] = newEmber;

                    if (flyings[flag] instanceof Airplane) {
                        Airplane a = (Airplane) flyings[flag];
                        countAirplane++;//判断击杀计数
                        score += a.getScore();//计分
                    } else if (flyings[flag] instanceof Bigplane) {
                        Bigplane a = (Bigplane) flyings[flag];
                        countBigplane++;//判断击杀计数
                        score += a.getScore();//计分
                        if (a.getAward() == 0) {//判断获得奖励
                            hero.setLife(hero.getLife() + 1);//加生命
                        } else {
                            hero.setAwardType(hero.getAwardType() + 1);//加攻击等级
                        }
                    } else {
                        Bee a = (Bee) flyings[flag];
                        countBee++;//判断击杀计数
                        if (a.getAward() == 0) {//判断获得奖励
                            hero.setLife(hero.getLife() + 1);//加生命
                        } else {
                            hero.setAwardType(hero.getAwardType() + 1);//加攻击等级
                        }
                    }
                    FlyObject temp = flyings[flag];//清除撞击物
                    flyings[flag] = flyings[flyings.length - 1];
                    flyings[flyings.length - 1] = temp;
                    flyings = Arrays.copyOf(flyings, flyings.length - 1);
                }

                Bullet temp2 = bullets[i];//清除撞击物
                bullets[i] = bullets[bullets.length - 1];
                bullets[bullets.length - 1] = temp2;
                bullets = Arrays.copyOf(bullets, bullets.length - 1);
            }
        }
    }

    private int crashBulletFlyings(Bullet bullet) {
        int flag = -1;//飞行物下标
        for (int i = 0; i < flyings.length; i++) {
            if (flyings[i].crashBullet(bullet)) {
                flag = i;//记录撞击飞行物
                break;
            }
        }
        return flag;
    }

    //英雄机与飞行物撞击
    private void crashHeroFlyings() {
        int flag = -1;//飞行物下标
        for (int i = 0; i < flyings.length; i++) {
            if (hero.crashFlyings(flyings[i])) {
                flag = i;//记录撞击飞行物
                break;
            }
        }
        if (flag != -1) {
            hero.setCheck(true);//显示爆炸效果
            hero.setLife(hero.getLife() - 1);//生命-1
            hero.setAwardType(hero.getAwardType() / 2);//清除奖励
            FlyObject temp = flyings[flag];//清除撞击物
            flyings[flag] = flyings[flyings.length - 1];
            flyings[flyings.length - 1] = temp;
            flyings = Arrays.copyOf(flyings, flyings.length - 1);
        }
    }

    //英雄机和子弹撞击
    private void crashBulletEnemy() {
        int flag = -1;//飞行物下标
        for (int i = 0; i < bullets2.length; i++) {
            if (hero.crashBulletEnemy(bullets2[i])) {
                flag = i;//记录撞击飞行物
                break;
            }
        }
        if (flag != -1) {
            hero.setCheck(true);//显示爆炸效果
            hero.setLife(hero.getLife() - 1);//生命-1
            hero.setAwardType(hero.getAwardType() / 2);//清除奖励
            bullets2[flag] = bullets2[bullets2.length - 1];//清除子弹
            bullets2 = Arrays.copyOf(bullets2, bullets2.length - 1);
        }
    }

    //爆炸效果
    public void goEmber() {
        for (int i = 0; i < embers.length; i++) {
            if (embers[i].getCount() >= 4) {
                embers[i] = embers[embers.length - 1];
                embers = Arrays.copyOf(embers, embers.length - 1);
            } else {
                embers[i].changeImg();
                embers[i].setCount(embers[i].getCount() + 1);
            }
        }
    }

    //判断游戏是否结束
    public void checkGame() {
        if (hero.getLife() <= 0) {
            state = GAMEOVER;
        }
    }

    // 创建窗口,初始化画板
    public void showMe() {
        JFrame window = new JFrame("飞机大战");
        // 设置窗口大小
        window.setSize(WIDTH, HEIGHT);
        // 设置窗口的关闭选项
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置初始位置 - 居中
        window.setLocationRelativeTo(null);// 居中
        // 将画板添加到窗口上
        window.add(this);
        window.setVisible(true);// 显示窗口,最后一步
    }

    public static void main(String[] args) {
        ShootGame s = new ShootGame();
        s.showMe();
        s.action();

    }
}