【面向对象项目】基于【JAVA】实战的飞机大战(二)

🚀个人主页:j欢迎访问Ali.S的主页

📆 最近更新:2022年7月12日

⛽ Java框架学习系列:Mybatis框架

⛳ Java基础学习系列:面向对象飞机大战

🏆 通信仿真学习系列:【硬件】【通信】【MATLAB】

🍄 个人简介:通信工程本硕🌈、Java程序员🚴。目前只会CURD😂

💌 点赞 👍 收藏 💗留言 💬 都是我最大的动力💯

在这里插入图片描述


一、前情回顾

前面已经完成了主页面的编写和敌机的移动,在框架中能够显示出敌机的移动和英雄机、子弹的位置,以及分数和血量的显示。今天在前面的基础上继续完成英雄机、敌机、子弹的操作,前面操作请看上一篇看我如何一步一步做飞机大战(一)在这里插入图片描述

二、主要实现

1.子弹入场

创建子弹对象,完成子弹入场的方法。由于随机生成子弹,并且是一直在游戏结束之前产生,所以这里使用了集合的来声子弹大本营,也可以使用数组来完成,只是数组的长度需要考虑,涉及到数组的扩容和缩容,相对来说数组操作起来稍微麻烦一点,过程是大同小异的。count是用来控制敌机入场的速度的,防止出现密集恐惧页面,不然敌机说我压力太大了。当然还可以设置同时出现多排子弹,通过int dir=0,1,2来设置三排子弹,具体每排子弹怎么移动就是控制在每个方向的速度不同。

 int count=0;
    protected void FireEnter() {
        count++;
        if (count>5){
            //创建子弹对象
            Fire fire=new Fire(hero);
            //将子弹加入到大本营中
            fs.add(fire);
            count=0;
        }
    }

2.子弹的移动

完成子弹的入场后,就要考虑子弹的移动方式了,具体是怎么动的,可以根据自己的想法来设置,可以是沿直线,也可以是曲线,或者其他的方式,主要是通过不同方向的速度变化来完成想要的效果,要是想要散弹效果,可以设置在x和y方向上speed来实现,这里是写的沿直线运动。注意子弹是向上移动,恰好跟敌机相反。


    protected void FireMove() {
            //连续产生子弹
            for (int i=0;i<fs.size();i++){
                fs.get(i).y-=10;
            }
    }

3.判断子弹击中敌机

当把子弹做好后,子弹库中的子弹发射了,就开始做击中效果判断,看是否击中敌机,因为每一颗子弹都有可能击中敌机,所以要遍历所有敌机。这里判断击中效果是通过边界条件来做的,当击中时,敌机就消失。

  private boolean FireShoot(Fire fire) {
        //遍历所有敌机
        for (int i=0;i<eps.size();i++){
            //判断是否击中该敌机
            if ((fire.y-eps.get(i).h<=eps.get(i).y)&&
                    (((eps.get(i).x-fire.x<=fire.w)&&(eps.get(i).x-fire.x>0))||
                    ((fire.x-eps.get(i).x<=eps.get(i).w)&&(fire.x-eps.get(i).x>0)))){
              //敌机消失
                eps.remove(eps.get(i));
               return true;
            }
        }
        return false;
    }

4.子弹击中敌机

因为所有子弹都可能击中任意一架敌机,所以遍历所有子弹,如果判断成功,就执行子弹消失,分数增加的操作。

 protected void FireHit() {
        //遍历所有子弹
        for (int i=0;i<fs.size();i++){
            //判断子弹是否击中敌机
            if (FireShoot(fs.get(i))){
                //子弹消失
               fs.remove(fs.get(i));
               //分数增加
                score+=10;
            }
        }
    }

5.判断英雄机与敌机碰撞

通过上面的子弹与敌机的碰撞操作,这里英雄机与敌机的操作是类似的,通过遍历敌机来做判断,碰撞成功,就让敌机消失。

 private boolean HeroHitOut(Hero hero) {
        //遍历所有敌机
        for (int i=0;i< eps.size();i++){
            if ((hero.y-eps.get(i).h<=eps.get(i).y)&&
                    (((eps.get(i).x-hero.x<=hero.w)&&(eps.get(i).x-hero.x>0))||
                            ((hero.x-eps.get(i).x<=eps.get(i).w)&&(hero.x-eps.get(i).x>0)))){
                eps.remove(eps.get(i));
                return true;
            }
        }
        return false;
    }

6.英雄机与敌机碰撞

当英雄机与敌机发生了碰撞,敌机消失后,英雄机血量减少,分数增加,类似子弹与敌机碰撞成功后的操作。

 protected void HeroHit() {
        //判断是否撞击
        if (HeroHitOut(hero)){
            //英雄机命数减少
            hero.hp--;
            //分数增加
            score+=5;
        }
    }

7.判断英雄机死亡

判断英雄机是否死亡,是为了后续做重新开始游戏做准备,如果英雄机血量为0了,就需要重新开始游戏,设置了游戏状态gameover为true。

  private boolean isHeroOver() {
        if (hero.hp==0){
            gameover=true;
            return true;
        }
        return false;
    }

8.重新开始游戏

当英雄机的血量下降到0时,就需要重新绘制游戏页面,这里需要将页面上的所有对象都清空,通过鼠标点击事件来完成游戏重新开始。

    public void ReStartPaint(Graphics g){
        if (gameover){
            g.setColor(Color.red);
            g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,30));
            g.drawString("GAMEOVER",175,300);
            g.setColor(Color.yellow);
            g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,30));
            g.drawString("您本次的游戏得分为:"+score,115,330);
            restart=App.getImg("图片路径");
            g.drawImage(restart,125,380,null);
        }
    }

9.鼠标点击事件监听

这里创建了鼠标监听器,用于监听鼠标的点击事件,当鼠标点击游戏结束页面的重新开始图标时,就将所有对象清空,重新开始新的游戏。

   //创建鼠标监听对象
        MouseAdapter adapter=new MouseAdapter() {
            @Override//点击事件
            public void mouseClicked(MouseEvent e){
                if (gameover){
                    hero=new Hero();
                    gameover=false;
                    score=0;
                    bg=App.getImg("图片路径");
                    eps=new ArrayList<>();
                    fs=new ArrayList<>();
                    repaint();
                }
            }
        //将鼠标对象加入到监听事件中
        addMouseListener(adapter);
        addMouseMotionListener(adapter);
    }

10.键盘移动事件监听

鼠标监听事件完成了,这里多做了一步键盘监听事件,通过键盘上的不同按键,来完成英雄机的不同操作,注意这里跟鼠标监听事件添加监听的区别 gameFrame.addKeyListener(keyAdapter);需要加到框架中。

     //创建键盘监听对象
        KeyAdapter keyAdapter=new KeyAdapter() {
            //键盘监听事件
            @Override
            public void keyPressed(KeyEvent e) {
                //判断按的不同的键来调用不同的移动方法
                if (e.getKeyCode()==KeyEvent.VK_D){
                    hero.MoveRight();
                }else if (e.getKeyCode()==KeyEvent.VK_A){
                    hero.MoveLeft();
                }else if (e.getKeyCode()==KeyEvent.VK_S){
                    hero.MoveDown();
                }else if(e.getKeyCode()==KeyEvent.VK_W){
                    hero.MoveUp();
                }
                repaint();
            }
        };
        //将键盘对象加入到窗体监听事件中
        gameFrame.addKeyListener(keyAdapter);


11.主线程启动

前面所有准备工作都完成了,最后就要实现主线程操作了,调用前面的方法,逐步实现游戏效果。判断游戏没有结束就执行循环操作。

     //主要逻辑实现
    public void action(){
        //创建线程,控制对象移动
       new Thread(() -> {
           while(true){
               //游戏是否结束
               if (!isHeroOver()) {
                   //敌机入场方法调用
                   EpEnter();
                   //敌机移动
                   EpMove();
                   //子弹入场方法调用
                   FireEnter();
                   //子弹移动
                   FireMove();
                   //子弹击中敌机判断
                   FireHit();
                   //英雄机撞击敌机
                   HeroHit();
               }
               try {
                   Thread.sleep(50);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               //重新绘制页面
               repaint();

           }
       }).start();
    }

在这里插入图片描述

三、总结

在这里插入图片描述
做到这里就完成了飞机大战的基本有操作,简单版的飞机大战就实现了,后面计划继续完善更多的其它功能,后续操作请看下一篇。需要源码请移步:源码

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ali.s

你的鼓励将是我前进的最好动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值