当前位置:首页 » 《资源分享》 » 正文

用java编写飞机大战

7 人参与  2024年10月13日 08:01  分类 : 《资源分享》  评论

点击全文阅读


游戏界面使用JFrame和JPanel构建。背景图通过BG类绘制。英雄机和敌机在界面上显示并移动。子弹从英雄机发射并在屏幕上移动。游戏有四种状态:READY、RUNNING、PAUSE、GAMEOVER。状态通过鼠标点击进行切换:点击开始游戏(从READY变为RUNNING)。点击重新开始游戏(从GAMEOVER变为READY)。鼠标移出窗口时游戏暂停(从RUNNING变为PAUSE)。鼠标移入窗口时游戏继续(从PAUSE变为RUNNING)。开局默认玩家生命值为3,分数为0。每隔一定时间随机生成敌机(小飞机、大飞机、小飞碟)。敌机在屏幕上移动,并与英雄机进行碰撞检测。英雄机可以发射子弹。子弹在屏幕上移动,并与敌机进行碰撞检测。英雄机与敌机发生碰撞时,英雄机会损失一条生命值。子弹与敌机发生碰撞时,敌机会被摧毁,玩家的分增加。当子弹与奖励机发生碰撞时,奖励机会被摧毁,玩家随机获得两张奖励(生命值加1、双倍子弹)。在屏幕左上角显示当前的生命值和得分。生命值减少到0时,游戏进入结束状态。再次点击,重新开始游戏。

1.图片素材(百度网盘分享)

链接:https://pan.baidu.com/s/10QiTcddI_Zxw5jbn8fmOpA?pwd=huan 
提取码:huan

2.主页面world.java

package plane.gzeu;import javax.swing.*;import java.awt.*;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.util.Arrays;import java.util.Timer;import java.util.TimerTask;public class World extends JPanel {    //ImageIcon类:保存图片的路径----->读取图片//    ImageIcon icon = new ImageIcon("images\\background.png");//    BG bg = new BG(0,0,420,700,2);//    Airplane airplane = new Airplane(100,200,300,620,2);//    Bee bee = new Bee(200,100,200,700,2);    BG bg = new BG();    EnemyPlane [] planes;    Hero hero;    int index; //用来控制敌机的数量    Bullet[] bullets;  //创建子弹的数组    int life; //英雄机的生命值    int score; //分数    //定义游戏的四种状态:准备,运行,暂停,结束(常量)    public static final int READY = 0;    public static final int RUNNING = 1;    public static final int PAUSE = 2;    public static final int GAMEOVER = 3;    //游戏的初始状态    int state = READY;    //    Airplane [] airPlanes = new Airplane[10];//    Bigairplane [] bigAirPlanes = new Bigairplane[10];//    Bee [] bee = new Bee[10];//    Bom [] bom = new Bom[4];//    Bullet [] bullets = new Bullet[3];//    Hero [] hero =new Hero[2];    //初始化方法    public void init(){        bg = new BG();        hero = new Hero();        planes = new EnemyPlane[0]; //默认一个敌机都没有        bullets = new Bullet[0];  //默认一个子弹都没有        index = 0; //默认从0开始        life = 3; //默认3条命        score = 0; //分数为0    }    public World() {        init();//        for(int i=0;i<planes.length;i++){//            if(i%2==0){//                planes[i]=new Airplane();//            }//            else if(i%5==0 && i%2!=0){//                planes[i] = new Bee();//            }//            else {//                planes[i] = new Bigairplane();//            }//        }//        for(int i =0;i<airPlanes.length;i++){//            airPlanes[i] = new Airplane();//            bigAirPlanes[i]=new BigAirPlane();//            bee[i]=new Bee();//            bom[i]=new Bom();//            bullets[i]=new Bullet();//            hero[i]=new Hero();    }    //生成敌机的方法    public void createPlane(){        if(index%16==0){            int n = (int)(Math.random()*10);            EnemyPlane plane;            switch (n){                case 9 :                    plane = new Bee(); //10%生成小飞碟                    break;                case 8 :                case 7 :                    plane = new Bigairplane(); //20%生成大飞机                    break;                default:                    plane = new Airplane(); //70%生成小飞机            }            //将敌机存入数组中之前,要先对数组进行扩容处理            planes = Arrays.copyOf(planes,planes.length+1);            //将生存的敌机放入数组的最后一个位置            planes[planes.length-1] = plane;        }    }//        for(int i =0;i<bigAirPlanes.length;i++){//            bigAirPlanes[i]=new Bigairplane();//       }//    }    //绘制图片printing    @Override    public void paint(Graphics g) { //paint挂载到当前类,当前类实例化(创建对象)时自动调用//      super.paint(g);//      icon.paintIcon(this,g,0,y1++); //绘制背景,默认第一个绘制//        bg.icon.paintIcon(this,g,(int)bg.x,(int)bg.y);//      bg.move();//        airplane.icon.paintIcon(this,g,(int)airplane.x,(int)airplane.y);//        bee.icon.paintIcon(this,g,(int)bee.x,(int)bee.y);        bg.painting(g);        hero.painting(g);        for(int i=0;i<planes.length;i++){            planes[i].painting(g);        }        for(int i=0;i<bullets.length;i++){            bullets[i].painting(g);        }        g.setColor(new Color(255,255,255));        //设置字体        g.setFont(new Font("微软雅黑",Font.BOLD,20));        g.drawString("生命值"+life,20,20);        g.drawString("分数"+score,20,40);        if(state==READY){            Images.start.paintIcon(this,g,0,0);        }        if(state==PAUSE){            Images.pause.paintIcon(this,g,0,0);        }        if(state==GAMEOVER){            Images.gameover.paintIcon(this,g,0,0);        }//            for(int i =0;i<airPlanes.length;i++){//                airPlanes[i].painting(g);//            bigAirPlanes[i].painting(g);//            bee[i].painting(g);//            bom[i].painting(g);//            bullets[i].painting(g);//            hero[i].painting(g);//            }//            for(int i =0;i<bigAirPlanes.length;i++){//                bigAirPlanes[i].painting(g);//            }        repaint();//刷新窗口    }    public static void main(String[] args) {        //1.显示画框(外层):JFrame        JFrame jf = new JFrame();        //2.显示面板:Jpanel        World jp =new World();        //3.将面板放入画框中:        jf.add(jp);        //对窗口进行设置        jf.setTitle("我的窗口");//设置标题        jf.setSize(436,700); //设置窗口大小        jf.setLocationRelativeTo(null); //居中显示        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置关闭窗口后自动结束程序        //4.显示窗口        jf.setVisible(true);        jp.action();    }    //唤醒定时器的方法    public void action(){        java.util.Timer timer = new Timer();        MyTesk mt = new MyTesk();        timer.schedule(mt,1000,1000/50);        this.addMouseListener(new MouseAdapter() {            //监听鼠标点击            @Override            public void mouseClicked(MouseEvent e) {                if(state==READY){                    state=RUNNING;                }                if(state==GAMEOVER){                    state=READY;                    init();                }            }            //鼠标移除            @Override            public void mouseExited(MouseEvent e) {//                System.out.println("鼠标移出");                if(state==RUNNING){                    state=PAUSE;                }            }            //鼠标移入            @Override            public void mouseEntered(MouseEvent e) {                if(state==PAUSE){                    state=RUNNING;                }            }        });        //匿名内部类        MouseAdapter mouseAdapter = new MouseAdapter() {            @Override            public void mouseMoved(MouseEvent e) {                if(state==RUNNING){                    int x = e.getX();                    int y = e.getY();                    hero.move(x,y);                }            }        };        //安装监听器        this.addMouseMotionListener(mouseAdapter);    }    public void createBullet(){        if(!hero.isLiving()){ //英雄机死亡不发射子弹            return;        }        if(index%17==0){            Bullet[] bullets1 = hero.double_fire();            //俩个数组的合并           Bullet[] arr = Arrays.copyOf(bullets,bullets.length+bullets1.length);            System.arraycopy(bullets1,0,arr,bullets.length,bullets1.length);            bullets = arr;//            Bullet bullet =hero.fire();  //英雄机调用fire方法生成子弹//            //将子弹放入数组中//            bullets = Arrays.copyOf(bullets,bullets.length+1); //子弹扩容//            bullets[bullets.length-1] = bullet;        }    }    //加分的方法    public void addScore(FlyingObjesct plane){        if(plane.isDead()){            if(plane instanceof Enemy){                Enemy enemy = (Enemy) plane; //需要做一个强制转化                score += enemy.getScore();            }            if(plane instanceof Aword){                Aword aword = (Aword) plane;                int  type =aword.getAword();                if(type == Aword.DOUBLE_FIRE){                    hero.getdouble_fire();                }                if(type == Aword.LIFE){                    life++;                }            }        }    }    //检测敌机与英雄机的碰撞    public void hero_hit(){        if(hero.isLiving()){            for(int i=0;i<planes.length;i++){                if(!planes[i].isLiving()){                    continue;                }                if(hero.bong(planes[i])){                    hero.goDead();                    planes[i].goDead();                    break;                }            }        }        else if(hero.isWait()){ //僵尸状态            if(life>1){                //重新开始                hero = new Hero();                //清屏                for(int i=0;i<planes.length;i++){                    planes[i].goDead();                }                life--;            }            else{                life--;                state=GAMEOVER;            }        }    }    //检测每个敌机与子弹的碰撞情况    public void hit(){        for(int i=0;i<bullets.length;i++){            Bullet bullet = bullets[i]; //拿出每一颗子弹            if(!bullet.isLiving()){                continue;            }            for(int j=0;j<planes.length;j++){                FlyingObjesct p = planes[j];                if(!p.isLiving()){                    continue;                }                if(p.bong(bullet)){  //被击中                    p.attack();                    bullet.goDead();                    addScore(p);                }            }        }    }    //清理爆炸的飞机    public void clean(){        //清除飞机        EnemyPlane[] living = new EnemyPlane[planes.length];        int index = 0;        for(int i=0;i<planes.length;i++){  //遍历敌机数组            if(planes[i].isWait() || planes[i].outOfBound()){  //如果是等待状态的效果就跳过                continue;            }            living[index++] = planes[i];  //将不是等待状态的敌机存在living里面        }        planes = Arrays.copyOf(living,index);        //清除子弹        Bullet[] livingBullet = new Bullet[bullets.length];        index = 0;        for(int i=0;i<bullets.length;i++){            if(bullets[i].isDead() || bullets[i].outOfBound()){    //如果是已经爆炸的子弹就跳过                continue;            }            livingBullet[index++] = bullets[i];        }        bullets = Arrays.copyOf(livingBullet,index);    }    class MyTesk extends TimerTask {        @Override        public void run() {            index++;            if(state == RUNNING){                createPlane(); //调用生成敌机的方法                createBullet(); //调用生成子弹的方法                hit();//调用子弹击打的效果                clean(); //调用清理敌机方法                hero_hit();                bg.move();                for(int i =0;i<planes.length;i++){                    planes[i].move();                }                for(int i =0;i<bullets.length;i++){                    bullets[i].move();                }            }        }    }}

3.小飞机类Airplane.java

package plane.gzeu;import javax.swing.*;//飞机类public class Airplane extends EnemyPlane implements Enemy{ // 实现接口时,要实现接口中的方法    public Airplane(){        this.images = Images.airplane;        w = images[0].getIconWidth();        h = images[0].getIconHeight();        x=(int)(Math.random()*(420-images[0].getIconWidth()));        y=-2*images[0].getIconHeight();        this.step=(Math.random()*2.5+0.7);        this.icon=new ImageIcon("images\\airplane1.png");//        this.icon = Images.airplane[0];    }    public Airplane(double x, double y, double w, double h,double speed) {//        super(x, y, w, h);        this.step=speed;        this.icon=Images.airplane[0];    }    @Override    public int getScore() {        return 10;    }}

4.大飞机类Bigairplane

package plane.gzeu;//大飞机类public class Bigairplane extends EnemyPlane implements Enemy{    public Bigairplane(double x, double y, double w, double h,double step) {//        super(x, y, w, h);        this.step=step;        this.icon = Images.bigairplane[0];    }    public Bigairplane(){        this.images = Images.bigairplane; //初始化数组        w = images[0].getIconWidth();        h = images[0].getIconHeight();        x=(int)(Math.random()*(420-images[0].getIconWidth()));        y=-2*images[0].getIconHeight();        this.step=(Math.random()*3.5+0.7);//        this.icon = Images.bigairplane[0];        life = 4;    }    @Override    public int getScore() {        return 50;    }}

5.英雄机类Hero.java

package plane.gzeu;import javax.swing.*;import static plane.gzeu.Images.bullet;public class Hero  extends EnemyPlane{    public Hero(){        this.images = Images.hero;        x=431/2-images[0].getIconWidth()/2;        y=510;        w=images[0].getIconWidth();        h=images[0].getIconHeight();//        this.speed=0.2;        this.icon = Images.hero[0];    }    public Hero(double x, double y, double w, double h,double step) {//        super(x, y, w, h);        this.step=step;//        this.icon = new ImageIcon("images\\hero1.png"); //设置了Images类直接调用类名就可以引用图片        this.icon = Images.hero[0];    }    @Override    public void move() {}    //接收鼠标的坐标    public void move(int x,int y) {        this.x= x-images[0].getIconWidth()/2;        this.y = y-images[0].getIconHeight()/2;    }    /*     * 子弹的位置(在英雄机上) b.x = h.x-images[0].getIconWidth()/2; b.y=h.y     * 子弹的移动:向上:b.y-=b.step;     * 子弹是无限的:数序扩容     * 射击方法:当英雄机调用一次射击方法时,就发射一个子弹     * */    //射击的方法    public Bullet fire(){        double x = this.x+w/2-4; //获取英雄机的x坐标        Bullet bullet = new Bullet(x,y);//将处理过后的坐标传给子弹        return bullet; //将子弹返回    }    //获取双倍子弹的方法    int doubleTime = 0; // 双倍子弹的时间,20次    public void getdouble_fire(){        doubleTime = 20;    }    //双倍子弹方法    public Bullet[] double_fire(){        if(doubleTime>0){            double x = this.x+w/2-7;            double x1 = this.x+w/2-2; //获取英雄机的x坐标            Bullet bullet1 = new Bullet(x,y);            Bullet bullet2 = new Bullet(x1,y);//将处理过后的坐标传给子弹            Bullet [] bullets = new Bullet[]{bullet1,bullet2};//            return new Bullet[]{bullet1,bullet2};            return bullets;        }        else {            double x = this.x+w/2-4; //获取英雄机的x坐标            Bullet bullet1 = new Bullet(x,y);            return new Bullet[]{bullet1};        }//    }    //测试//    public static void main(String[] args) {//        Hero hero = new Hero();//        hero.move(200,300);//        Bullet bullet = hero.fire();//        System.out.println(bullet.x+"  "+bullet.y);//    }}

6.敌机类Bee.java

package plane.gzeu;import javax.swing.*;public class Bee extends EnemyPlane implements Aword {    double speed1;    public Bee(){        this.images = Images.bee;        w = images[0].getIconWidth();        h = images[0].getIconHeight();        x=(int)(Math.random()*(420-images[0].getIconWidth()));        y=-2*images[0].getIconHeight();        this.step=(Math.random()*4.5+2.5);        this.speed1=(Math.random()*3.5+0.5);//        this.icon=new ImageIcon("images\\bee0.png");        this.icon=Images.bee[0];        life = 6;    }    public Bee(double x, double y, double w, double h,double step) {//        super(x, y, w, h);        this.step=step;        this.icon = Images.bee[0];    }    @Override    public void move() {        y+=speed1;        x+=step;        if(x>431-images[0].getIconWidth()){            step = -step;        }        if(x<=0){            step = -step;        }    }    @Override    public int getAword() {        return Math.random()>0.5?DOUBLE_FIRE:LIFE;    }}

7.背景类BG.java

package plane.gzeu;import javax.swing.*;import java.awt.*;//背景类(子类)//继承FlyingObjesct类,得到FlyingObjesct类的方法及属性public class BG extends FlyingObjesct {    double y0;    public BG(){        x = 0;        y = 0;        icon = Images.bg;        w = icon.getIconWidth();        h = icon.getIconHeight();        y0 = -h;        step = 2;    }    public BG(double x, double y, double w, double h,double step) {        super(x, y, w, h); //重载:调用父类的构造方法,实现方法复用        this.step = step;        this.icon = Images.bg; //背景是固定的    }    public void painting(Graphics g){        icon.paintIcon(null,g,(int)x,(int)y);        icon.paintIcon(null,g,(int)x,(int)y0);    }    @Override    public void move() {        y+=step;        y0+=step;        if(y>=h){            y=-h;        }        if(y0>=h){            y0=-h;        }    }}

8.爆炸类Bom.java

package plane.gzeu;import javax.swing.*;public class Bom extends EnemyPlane{    public Bom(){        x=(int)(Math.random()*370);        y=(int)(Math.random()*370);        this.step = 0.2;        this.icon = Images.bom[0];    }    public Bom(double x, double y, double w, double h, double speed) {//要重写父类的构造方法。新增一个速度//        super(x, y, w, h);//重载:调用父类的构造方法,实现方法复用        this.step=speed;        this.icon=Images.bom[0];    }}

9.子弹类Bullet.java

package plane.gzeu;import javax.swing.*;//继承FlyingObjesct类,得到FlyingObjesct类的方法及属性public class Bullet extends EnemyPlane {    public Bullet(double x,double y){        this.icon = Images.bullet;        w = icon.getIconWidth();        h = icon.getIconHeight();        this.x = x;        this.y = y;        step = 2;    }    public Bullet(){        x=(int)(Math.random()*370);        y=(int)(Math.random()*370);        this.step = 0.2;        this.icon = Images.bullet;    }    public Bullet(double x, double y, double w, double h, double step) {//        super(x, y, w, h); //重载:调用父类的构造方法,实现方法复用        this.step = step;        this.icon = Images.bullet; //背景是固定的    }    @Override    public void move() {        y-=step;    }}

10.三种敌机总类EnemyPlane.java

package plane.gzeu;public abstract class EnemyPlane extends FlyingObjesct {    @Override    public void move() {        y+=step;    }}

11.飞行物的总类(父类)FlyingObjesct.java

package plane.gzeu;import javax.swing.*;import java.awt.*;//飞行物的总类(父类)public abstract class FlyingObjesct {    public static final int LIVING = 1; //活着    public static final int DEAD = 0; //死亡    public static final int WAIT = -1;  //等待死亡(播放爆炸动画)    //飞机默认是活着的    public int state = LIVING;    //飞机的生命值    public int life = 2;    public double x,y,step,w,h;//step速度    public ImageIcon icon; //图片//    Images images;    public ImageIcon[] images; //数组    public int index = 0;    public ImageIcon [] boms = Images.bom; //存放爆炸效果的图片    //赋初值:构造方法    //快速生成构建方法:快捷键Alt+Insert    public FlyingObjesct(double x, double y, double w, double h) {        this.x = x;        this.y = y;        this.w = w;        this.h = h;    }    //当飞机击打一次,生命值减一,当生命值为0时,进入死亡状态    public boolean attack(){        if(life>0){           life--;           if(life==0){               state = DEAD;           }           return true;        }        return false;    }//让敌机快速去死    public boolean goDead(){        if(state==LIVING){            life = 0;            state = DEAD;            return true;        }else{            return false;        }    }    //判断飞机的三种状态    public boolean isLiving(){        return state==LIVING;  //判断是否活着    }    public boolean isDead(){        return state==DEAD;  //判断是否死了    }    public boolean isWait(){        return state==WAIT;  //判断是否等待死亡    }    /*实现动画效果     * 1.用数组存储动画效果图片     * 2.初始化数组     * 3.定义一个计数器,作为切换图片的控制条件     * 4.写一个方法,实现切换图片的操作     * */    int i;    public void nextImage(){        switch (state){            case LIVING:                if(images == null) {                    return;                }                icon = images[index++/300%images.length]; //0-[数组的长度-1]                break;            case DEAD:                if(boms==null){                    return;                }                if(i++/300==boms.length){                    state = WAIT;                    return;                }                icon = boms[i++/300];        }    }    public FlyingObjesct(){}//无参构造    //移动    public abstract void move();    //绘制图形 方法    public void painting(Graphics g){        nextImage();        icon.paintIcon(null,g,(int)x,(int)y);    }    //检测敌机是否碰到子弹:判断条件中心距c=H/2+h/2    public boolean bong(FlyingObjesct bullet){        FlyingObjesct p =this;        double a = Math.min(p.w,p.h)/2;        double b = Math.min(bullet.w,bullet.h)/2;        double x1=p.x+p.w/2;        double y1=p.y+p.h/2;        double x2=bullet.x+bullet.w/2;        double y2=bullet.y+bullet.h/2;        double c = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));        return c<=a+b;    }    //清除越界的敌机和子弹条件: y<-h-100 || y>700+100    public boolean outOfBound(){        if(y<-h-100){            return true;        }else if(y>700+100){            return true;        }        return false;    }}

12.图片类Images.java

package plane.gzeu;import javax.swing.*;public class Images {    public static ImageIcon bg;    public static ImageIcon bullet;    public static ImageIcon start;    public static ImageIcon pause;    public static ImageIcon gameover;    public static ImageIcon[] hero;    public static ImageIcon[] bigairplane;    public static ImageIcon[] bee;    public static ImageIcon[] airplane;    public static ImageIcon[] bom;    static {        airplane = new ImageIcon[2];        airplane[0] = new ImageIcon("images/airplane0.png");        airplane[1] = new ImageIcon("images/airplane1.png");        bigairplane = new ImageIcon[2];        bigairplane[0] = new ImageIcon("images/bigairplane0.png");        bigairplane[1] = new ImageIcon("images/bigairplane1.png");        bee = new ImageIcon[2];        bee[0] = new ImageIcon("images\\bee0.png");        bee[1] = new ImageIcon("images\\bee1.png");        bom = new ImageIcon[4];        bom[0] = new ImageIcon("images/bom1.png");        bom[1] = new ImageIcon("images/bom2.png");        bom[2] = new ImageIcon("images/bom3.png");        bom[3] = new ImageIcon("images/bom4.png");        bg = new ImageIcon("images\\background.png");        bullet = new ImageIcon("images\\bullet.png");        start = new ImageIcon("images\\start.png");        pause = new ImageIcon("images\\pause.png");        gameover = new ImageIcon("images\\gameover.png");        hero = new ImageIcon[2];        hero[0] = new ImageIcon("images\\hero0.png");        hero[1] = new ImageIcon("images\\hero1.png");    }    //测试图片是否传过来了    public static void main(String[] args) {        System.out.println(start.getImageLoadStatus()); //如果输出8那图片传过来了,输出其他数字有问题        System.out.println(bg.getImageLoadStatus());        System.out.println(bom[0].getImageLoadStatus());        System.out.println(bee[1].getImageLoadStatus());        System.out.println(airplane[1].getImageLoadStatus());    }}

13.获得奖励的接口Aword.java

package plane.gzeu;//获得奖励的接口public interface Aword {    int DOUBLE_FIRE = 1; //第一种奖励,双倍火力    int LIFE = 2; //加生命值   int getAword(); //获得奖励的方法}

14.获得分数的接口Enemy.java

package plane.gzeu;//获得分数的接口public interface Enemy { //加分//    int a = 5;//都是静态常量//    public abstract void add(); //都是抽象方法    public int getScore(); //获得分数的方法}

运行界面:

开始界面

存活界面:

暂停界面

结束界面


点击全文阅读


本文链接:http://zhangshiyu.com/post/171212.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1