java飞机大战--点到点分解

项目简介:

1、游戏开始可以产生:敌机/小蜜蜂/自己的飞机,随机(概率)出现
2、跟鼠标相关的:开始/结束游戏界面、移动自己的飞机、鼠标移除窗口,游戏暂停、鼠标进入窗口,游戏继续、子弹射中敌人/小蜜蜂:分数加成(或者生命值加1)
3、子弹打中小蜜蜂: 奖励加成 -> 生命+1或者双倍火力
4、子弹打中敌机: 分数+2
5、实现背景滚动卷轴
6、飞行物越界问题

项目的思维导图:

在这里插入图片描述

遇见问题:

边界问题:在父类构造抽象方法 isout(),分别在airplane、hero、bee类中通过控制x和y轴的位置,如果跃出边界,则在flyobject和bullet里面删除相应的物体。
背景的滚动卷轴问题:在shootgame里面通过创造y轴back _y来实现x轴不变,y轴随着绘画的调用不断重复,达到滚动的效果。
素材更换问题:在photo包里面,将其删除,并将相应的素材粘贴进来,将素材文件命名为与原来图片一样名字(注意命名空格问题),相同文件格式。这样避免了修改源代码问题。
代码没错但运行报错问题:①、这个可以再创建一个类局部调试,如果报错,那就是代码原本问题。②、可能程序零时缓存有问题,需要删除缓存out后,再进行运行。③、可以再窗口实现的paint方法里面,看看实现的先后顺序问题。④、看看方法有没有调用,如果没有调用,需要在相应的地方调用。
不同机器报错问题:①、需要更改一些文件的绝对路径为运行机器的绝对路径。

运行页面:

开始界面: 在这里插入图片描述
暂停界面:在这里插入图片描述

死亡界面: 在这里插入图片描述
运行界面:在这里插入图片描述

类的实现

ShootGame类:

package com.qicco.shoot;

import com.qicco.photo.Photo;
import sun.audio.AudioStream;

import javax.imageio.ImageIO;
import javax.sound.sampled.*;
import javax.swing.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.*;
import java.util.List;
import java.util.Timer;
/* 图片加载,描绘窗口之类工作都在该类中完成
1.继承JPanel类
点菜:
JPanel类(盘子)
* JFrame类是用来窗口描绘(桌子)
* */
public class ShootGame extends JPanel {

    /*2.规定窗体宽高 ,定义成static,我们需要在其他地方使用、但我不想变-->大写*/
    public static final int WIDHT = 650;//窗体宽度
    public static final int HEIGHT = 950;//窗体高度
    //标记游戏失败结束,ture为游戏结束
    public boolean GAMEOVER;
    //标记游戏胜利结束,ture为游戏结束
    public boolean VECTORY;

    /*3. 变量声明(容器)*/
    public static BufferedImage background;//背景图片
    public static BufferedImage airplane;//敌机图片
    public static BufferedImage bee;//蜜蜂图片
    public static BufferedImage bullet;//子弹图片
    public static BufferedImage hero0;//英雄机0图片
    public static BufferedImage hero1;//英雄机1图片
    public static BufferedImage pause;//暂停

    public static BufferedImage start;//开始
    public static BufferedImage gameover;//结束

    /*6.厨师炒菜,准备上菜(将图片准备好,并且加载到当前Shootgame类中,然后准备画面)-----------*/

    /*7.将蜜蜂敌机装到一个容器里面,使用集合存储蜜蜂和敌机----------------------------------*/
    private List<flyObject> flyings = new ArrayList<>();//仅仅在当前页面使用
    /*8.准备容器中,并将子弹放入其中---------------------------------------------------*/
    private List<Bullet> bullets = new ArrayList<>();
    /*9.准备英雄机的容器-------------------------------------------------------------*/
    private Hero hero = new Hero();//因为here类中已经存在一个List集合存放我们英雄机了
    /*16.定时器,时间间隔*/
    private Timer timer;//
    private int time = 15;//时间间隔:15毫秒
    /*26.定义总分*/
    private int score = 0;//每调用一次,就加一分

    /*================================================*/
    //背景竖坐标,用于背景图片滚动
    int back_y = -background.getHeight(null) + background.getHeight(null);
    /*================================================*/


    /*背景音乐*/
    // 设置背景音乐
    public static void setMusicGame() throws IOException {
        FileInputStream stream = null;
        try {

            stream = new FileInputStream("D:\\ideafile\\TrainingCourse\\plangame\\src\\com\\qicco\\photo\\background.png");
            AudioStream audioStream = new AudioStream(stream);
            sun.audio.AudioPlayer.player.start(audioStream);
        } catch (Exception e) {
            System.out.println(e);

            System.err.println("错误!");
        }finally {
            stream.close();
        }
    }


    /*10初始化该类 加载图片
     * 使用构造方法 获取敌机,蜜蜂,英雄机,子弹图片,装到准备好的容器中
     * 10.1将蜜蜂装到容器里(flyings)
     * */
    public ShootGame() {
        flyings.add(new Bee());//将蜜蜂存到flyings中
        flyings.add(new airPlane());//将敌机存到flyings中
        //bullets.add(new Bullet(200, 300));//子弹存放到bullets里,需要传参
    }

    /*11.开始画画 画背景图 用一个方法Paint(),该方法是由JFrame提供的
     * graphics:相当于画笔
     * *-------------------------------------------------------------------------------*/
    @Override
    public void paint(Graphics g) {
        g.drawImage(background, 0, 0, null);
        /*drawImage需要传入四个参数
          第一个参数代表需要画的图片
          第二个和第三个参数代表从哪里开始(起始位置)
          第四个参数代表通知哪些对象* */
        /*======================================*/

        //使背景无限滚动
        g.drawImage(background, 0, back_y++, null);
        g.drawImage(background, 0, back_y - background.getHeight(null), null);
        if (back_y == background.getHeight(null)) {
            back_y = 0;
        }

        paintHero(g);
        paintFlyingObject(g);//需要前往Bee和airplane类中将y轴改成100看见效果
        painBullet(g);
        /*==========================================================================*/
        /*g.setFont(new Font("宋体", Font.BOLD, 20));
        g.drawString("得分:",20, 60);//画文字*/
        /*====================================================================*/
        //g.drawString(Integer.toString(score), 80, 60);//画文字
        //g.drawString("生命:", 20, 90);//画文字
        // /*====================================================================*/
        //g.drawString(Integer.toString(hero.getlife()), 80, 90);
        g.drawImage(hero.image, hero.x, hero.y, null);
        /*调用画分数方法*/
        paintScore(g);
        paintStatus(g);


    }


    /*12.画英雄机----------------------------------------------------------------*/
    public void paintHero(Graphics g) {
        /*可以自己设置*/
        g.drawImage(hero.getImage(), hero.getX(), hero.getY(), 10, 20, null);
    }

    /*13.画蜜蜂和敌机 都存到了flyings中,所以需要遍历处理------------------------------------*/
    public void paintFlyingObject(Graphics g) {
        for (flyObject f : flyings) {
            flyObject fly = f;//将遍历结果存放到fly中,方便画画
            g.drawImage(fly.getImage(), fly.getX(), fly.getY(),100,80,null);//开始画敌机和蜜峰

        }
    }

    /*14.画敌机放在bullets里面了----------------------------------------------------------*/
    public void painBullet(Graphics g) {
        for (Bullet b : bullets) {
            Bullet bul = b;//将遍历结果存放到bul中,方便画画
            g.drawImage(bul.getImage(), bul.getX(), bul.getY(), 20,20,null);
        }
    }

    /*4.加载图片(放入容器)
     * 使用静态代码块:读取
     * */
    static {
        //方法一:先通过file,将地址放进来,然后再传给backgrund
        //File file = new File("com/qicco/photo/background.png");

        try {
          /*  background = ImageIO.read(new File("com/qicco/photo/background.png"));
        不能直接传字符串,"com/qicco/photo/background.png"
        这里会出现IOException,但是静态代码块不能通过throw抛出异常,只能try catch处理

        方法二:使用反射机制 (通过类找到路径)
        */
            background = ImageIO.read(Photo.class.getResource("background.png"));
            airplane = ImageIO.read(Photo.class.getResource("airplane.png"));
            bee = ImageIO.read(Photo.class.getResource("bee.png"));
            bullet = ImageIO.read(Photo.class.getResource("bullet.png"));
            hero0 = ImageIO.read(Photo.class.getResource("hero0.png"));
            hero1 = ImageIO.read(Photo.class.getResource("hero1.png"));
            pause = ImageIO.read(Photo.class.getResource("pause.png"));
            start = ImageIO.read(Photo.class.getResource("start.png"));
            gameover = ImageIO.read(Photo.class.getResource("gameover.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*5程序入口方法,画出画板(窗口)------------------------------------------------------------*/
    public static void main(String[] args) throws InterruptedException {
        JFrame jFrame = new JFrame("飞机大战");//title:类似于桌号(窗口名称)
        ShootGame shootGame = new ShootGame();//为了告诉计算机,我要在当前类中画窗口
//    如果要在画板中绘画,进行创作,添加图片,描绘之类的,需要先将面板加载到窗口

        jFrame.add(shootGame);
        //jFrame.setSize(WIDTH, HEIGHT);
        jFrame.setBounds(100, 100, WIDHT, HEIGHT);
        //设置窗体永远在最上面显示
        jFrame.setAlwaysOnTop(true);
        //在窗口中可以关闭该窗口,不需要返回idea
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //调用paint方法,调用这个方法之后,就相当于在画板上去添加东西,准备画面了
        jFrame.setVisible(true);
        //一般出现在中间
        jFrame.setLocationRelativeTo(null);
        //上菜
         try {
                    setMusicGame();
                } catch (IOException e) {
                    System.err.println("音乐播放异常!");
                    e.printStackTrace();
                }
         //shootGame.loop();
        shootGame.action();
        //jFrame.setResizable(false);

    }


    /*15 将子类中所有飞行物体方法加载到该类中,使之移动*/
    public void stepAction() {

        /*15.1 让蜜蜂和敌机走一步*/
        for (flyObject fo : flyings) {
            flyObject f = fo;//接受遍历的结果
            f.step();
            //fo中有蜜蜂,有敌机,f.step方法会到每个子类中找到step方法
        }
        /*15.2 让子弹走一步,子弹存放集合里面------------------------------------------------*/
        for (Bullet bls : bullets) {
            Bullet b = bls;
            b.step();
        }
        /*15.3英雄机走一步---------------------------------------------------------------*/
        hero.step();
    }

    //使用循环使之一直动
    //方式 1:使用循环
    /* public void action() throws InterruptedException {
        while (true){
            stepAction();
            repaint();//重绘
            Thread.sleep(50);//线程,给它50毫秒
        }
    }*/
    //方式 2:使用定时器 动作
    public void action() {
        /*24.添加鼠标监听事件  需要用到mouseAdapter类*/
        MouseAdapter l = new MouseAdapter() {

            @Override
            public void mouseMoved(MouseEvent e) {
                if (status == RUNNING) {
                    int x = e.getX();//获得x轴坐标
                    int y = e.getY();//获得y
                    hero.moveT0(x, y);
                }
            }

            /*鼠标进入监听*/
            @Override
            public void mouseEntered(MouseEvent e) {//监测鼠标进入事件
                if (status == PAUSE) {
                    status = RUNNING;
                }
            }

            /*画板移出鼠标--鼠标移出监听 */
            @Override
            public void mouseExited(MouseEvent e) {
                if (status != GAME_OVER) {
                    status = PAUSE;
                }
            }

            /*鼠标点击事件   当前状态是:start -- >running
             *                当前是  gameover--->start*/
            @Override
            public void mouseClicked(MouseEvent e) {
                switch (status) {
                    case START:
                        status = RUNNING;
                        break;
                    case GAME_OVER:
                        /*删档  分数 生命值 飞行物 英雄机 子弹 */
                        score = 0;
                        flyings = new ArrayList<flyObject>();
                        hero = new Hero();
                        bullets = new ArrayList<Bullet>();
                        status = START;

                        break;
                }
            }
        };
        this.addMouseListener(l);
        /*============================================================================*/
        this.addMouseMotionListener(l);


        timer = new Timer();//util下的包
            /* schedule 需要传入三个参数
            第一个:代表想要定时器做什么
            第二个:执行时间
            第三个:时间间隔
*/
        timer.schedule(new TimerTask() {
            @Override
            /*----------------------------------*/
            public void run() {
                if (status == RUNNING) {
                    stepAction();//调用飞行物体

                    entryAction();//20.调用飞行物进入
                    shootAction();//22.调用射击方法
                    isoutplane();
                    isoutbee();
                    isoutbullet();
                    /*调用检测子弹碰撞*/
                    bangAction();
                    /*写一个控制死亡的方法*/
//                    isGameOver();
                    checkGameOverAction();

                }
                repaint();//重绘方法
            }
        }, time, time);
    }

    /*敌机蜜蜂只出现一次,子弹只有一发
     * 18.随机生成飞行物(敌机和蜜蜂)方法*/
    public flyObject nextOne() {
        Random random = new Random();
        int type = random.nextInt(20);
        if (type == 0) {
            return new Bee();
        } else {
            return new airPlane();
        }
    }

    /*19.设置飞行物进场方式*/
    int flyEnterIndex = 0;

    public void entryAction() {
        flyEnterIndex++;
        if (flyEnterIndex % 40 == 0) {//为了让我们飞行物进来,设置一个进入时间
            flyObject obj = nextOne();//
            flyings.add(obj);//需要传入flyobject类型的值
        }
        /*20.想要多发子弹
         * 子弹反射分两类:单倍火力,发射点在英雄机1/2处
         *             双倍火力,发射点在英雄级4/1+3/4处
         * */
    }

    /*21.射击方法*/
    int shootIndex = 0;

    public void shootAction() {
        shootIndex++;
        if (shootIndex % 30 == 0) {
            List<Bullet> bs = hero.shoot();
            /*遍历将集合里面的子弹取出来*/
            for (Bullet b : bs) {
                bullets.add(b);

            }
        }

    }


    /*23当前项目敌机,蜜蜂,子弹都可以的,英雄机移动t,鼠标事件,去hero类中写一个计算坐标的方法*/

    /*25 射击到飞行物使之消失
     * 分析:
     * 两张图片发生碰撞,需要一个碰撞范围 x轴坐标范围:x+飞行物宽度(width)
     * y轴坐标范围:y+飞行物高度(height)
     * 去flyobject中判断是否打中飞行物*/


    /*27.判断碰撞方法。检查子弹和飞行物体之间的碰撞 ,当前只是一颗子弹与飞行物进行比较*/
    public void bang(Bullet bullet) {
        int index = -1;//定义索引
        /*第一步:将集合里的飞行物取出来,再在那这颗子弹去比较*/
        for (flyObject f : flyings) {//for(数据类型,flyings)
            flyObject obj = f;
            index++;
            if (obj.shootBy(bullet)) {
                /*如果为真,则判断碰撞上了,让飞行物消失*/

                flyObject one = flyings.remove(index);//删除当前飞行物
                /*需要判断飞行物的类型,来选择效果*/
                if (one instanceof airPlane) {//敌机
                    //加分
                    airPlane ap = (airPlane) one;//强制转换 将flyobject 类型的one 转换成airplane类型
                    //这样才能调用方法getScore()
                    score = score + ap.getScore();//将两分
                }
                if (one instanceof Bee) {//蜜蜂
                    /*判断当前是什么奖励类型*/
                    Bee be = (Bee) one;//强制转换 将flyobject 类型的one 转换成bee类型
                    int type = be.getType();
                    switch (type) {
                        case 0:
                            hero.addDoubleFire();
                            break;
//                               双倍火力
                        case 1:
                            hero.addlife();
//                              加生命值
                            break;
                    }

                }


                break;
            }
            ;//结果判断

        }
    }

    /*28.所有子弹都去检查*/
    public void bangAction() {
        for (Bullet bt : bullets) {
            Bullet b = bt;
            bang(b);

        }
    }
    /*============?*/
//30 画分数和生命值
    public  void paintScore(Graphics g){
   /* Fond类作用:设置字体的一个类
     * 第一个参数,相当于当前类的名字
     * 第二个:设置字体
     * 第三个:设置字体大小*/
        Font font = new Font("分数",Font.BOLD,500);
        g.setColor(new Color(0xEF122C));
        g.drawString("分数:"+score,50,20);
        Font font1 = new Font("生命",Font.BOLD,500);
        g.setColor(new Color(0xEF122C));
        g.drawString("生命:"+hero.getlife(),50,60);
        g.setFont(font);
        g.setFont(font1);
        /*在画版上写字
        * 第一个:名称
        * 第二个*/
    }

    /*32.检测游戏结束方法
     * 1.英雄机是否发生碰撞和飞行物---
     * 飞行物消失---判断--
     * 减命+双倍活力消失
     * */
    public boolean isGameOver() {
        int index = -1;//
        for (flyObject f : flyings) {
            flyObject fl = f;
            index++;
            if (hero.hit(f)) {
                if (index != -1) {
                    flyings.remove(index);
                }
                hero.reduceLife();
                hero.setDoublefileZero();
                break;//避免死循环
            }
        }
        return hero.getlife() <= 0;//判断是否结束游戏
    }

    /*33.设置游戏开始 ,暂停和结束*/
    private int status;//设置游戏状态
    public static final int START = 0;
    public static final int RUNNING = 1;//游戏中
    public static final int PAUSE = 2;//游戏暂停
    public static final int GAME_OVER = 3;//游戏结束

    // 判断游戏结束
    public void checkGameOverAction() {
        if (isGameOver()) {
            status = GAME_OVER;
        }
    }

    /*35.画开始 暂停 结束页面*/
    public void paintStatus(Graphics g) {
        switch (status) {
            case START:
                g.drawImage(start, 170, 290, 300,300,null);
                break;
            case PAUSE:
                g.drawImage(pause, 150, 150,400,400,null);
                break;
            case GAME_OVER:
                g.drawImage(gameover, 60, 350, null);
                break;
        }
    }

    /*



     */
    /*================================================================================*/
//处理敌机出界方法
    public void isoutplane() {
        List<flyObject> removePlanes = new ArrayList<>();


        for (int j = 0; j < flyings.size(); j++) {
            flyObject F = flyings.get(j);
            if (F.isOut()) {
                removePlanes.add(F);
                break;
            }

        }

        flyings.removeAll(removePlanes);
    }

    //处理蜜蜂出界方法
    public void isoutbee() {
        List<flyObject> removeBees = new ArrayList<>();
        for (int j = 0; j < flyings.size(); j++) {
            flyObject bee = flyings.get(j);
            if (bee.isOut()) {
                removeBees.add(bee);
                break;
            }

        }

        flyings.removeAll(removeBees);
    }

    //处理子弹出界方法
    public void isoutbullet() {
        List<Bullet> removeBullets = new ArrayList<>();
        for (int j = 0; j < bullets.size(); j++) {
            Bullet bullet = bullets.get(j);
            if (bullet.isOut()) {
                removeBullets.add(bullet);
                break;
            }

        }

        bullets.removeAll(removeBullets);
    }

}

Hero类:

package com.qicco.shoot;


import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Random;

public class Hero extends flyObject {
    //暂时不设置英雄机的速度,它是一张图片,不是自己飞。随着鼠标而动的
    private List<BufferedImage> images = new ArrayList<>();//这个用来存放英雄集合的
    private int doublefile = 0;//双倍火力
    private int life = 3;//生命值
//   10 减少生命值
    public void reduceLife(){
        life--;
    }
    /*11.设置双倍火力清零*/
    public void setDoublefileZero(){
        this.doublefile = 0;
    }
    public int getlife(){
        return life;//调用方法时,给你返回生命数
    }
    /*7.设置双倍火力*/
    public void addDoubleFire(){
        doublefile = doublefile + 40;
    }
    /*8.增加生命力*/
    public void addlife(){//调用方法一次就加一条命
        life++;
    }

    /*重写飞行物体移动方法 需要无法确定英雄机移动轨迹,需要加入鼠标事件,先不写移动方法,改成英雄机喷气方法 */
    /*设置发射火力*/
    @Override
    public void step() {
        if (images.size()>0){//判断集合是否为空
            //1.使用ramdon随机类,让我们随机获得一张图片
            Random random = new Random();
            image = images.get(random.nextInt(2));
        }

    }
    /*==========================================================================*/
//判断是否出界
    public  boolean isOut(){
        return false;
    }
    /*==========================================================================*/

    //   2.构造方法初始化,加载图片
    public Hero(){
        this.image = ShootGame.hero0;//获取图片
        this.width = image.getWidth();
        this.height = image.getHeight();
//        3.获取X轴坐标/给一个暂时值
        x = 150;
        y = 400;
//       4. 图片加载
        images.add(ShootGame.hero0);
        images.add(ShootGame.hero1);
    }
    /*5.获得子弹方法*/
    public List<Bullet> shoot(){
        int xStep = width/4;// 1/4的图片
        int yStep = 20;//飞机与子弹的间距
        if (doublefile > 0){
            //5.1双培火力 弄好子弹
          Bullet bullet1= new Bullet(x + xStep,y - yStep);//第一发子弹 x轴 :图片1/4处 y轴 :图片 上面一点点
           Bullet bullet2 =  new Bullet(x + 3 * xStep,y - yStep);//第二发子弹,图片 3/4处
           //5.2装子弹的包
            List<Bullet> bullets = new ArrayList<>();
            //5.3装子弹
            bullets.add(bullet1);//装第一发
            bullets.add(bullet2);//装第二发
            doublefile = doublefile -2;//设置双倍火力发射次数
            //5.4发送
            return bullets;

        }else {
            //单倍活力
          Bullet bullet1 =  new Bullet(x+ 2*xStep,y - yStep);
//          因为在ShootGame中是使用集合bullets容器,专门存储子弹,
            /*5.2准备容器*/
            List<Bullet> bullets = new ArrayList<>();
            /*5.3子弹放进包里*/
            bullets.add(bullet1);
            /*5.4发送*/
            return bullets;
        }


    }

    /*6.计算英雄机坐标方法 本来会加上鼠标监听事件,由于坐标不是我们想要的,我们鼠标控制图片中心移动*/
    public void moveT0(int x,int y){//鼠标监听事件中的x轴坐标和y轴坐标
        this.x =x - width/2;//当前的X是英雄机的,我们需要鼠标的
        /*this.x谁调用,指向谁的x*/
        this.y = y- height/2;
      }
      /*12
      *x1:飞行物x - 1/2 hero的weith
      * x2:飞行物 + 1/2 hero的weith
      *y1:飞行物 - 1/2 hero的height
      *y2 : 飞行物 + 1/2 hero的height
      * 中心点x:herox+1/2hero width
      * 中心点y:hero.y +1/2 hero height
      * */
public boolean hit(flyObject flyObject){
    int x1 = flyObject.x -  this.width/2;
    int x2 = flyObject.x +  this.width/2;
    int y1 = flyObject.y -  this.height/2;
    int y2 = flyObject.y +  this.height/2;
    int centerx = this.x + this.width/2;
    int centery = this.y + this.height/2;
    boolean b = x1 < centerx && centerx <x2;
    boolean c = y1 < centery && centery <y2;
    return b&&c;
}


      }

Bullet类:

package com.qicco.shoot;

import java.util.Random;

public class Bullet extends flyObject{
    //1.定义特有属性:速度
    private int speed = 3;//比敌机稍快一点


    /*重写飞行移动方法 step方法*/
@Override
    public void step() {
    y -= speed;//由下往上发射的
    }
    /*=====================================================================*/
    @Override
    public boolean isOut() {
        if(y==0)
        {
            return true;

        }
        else {
            return false;
        }
    }
    /*=====================================================================*/


    //    2.使用构造方法,让类初始化就加载图片
    public Bullet(int x,int y){
//        2.获取图片
        this.image = ShootGame.bullet;
        this.width = image.getWidth();
        this.height = image.getHeight();
//    3.定义y,x轴坐标,需要随鼠标的移动来发射子弹,需要随时传入。
        this.x = x;
        this.y = y;

    }


}

flyObjet类:

package com.qicco.shoot;

import java.awt.image.BufferedImage;
//父类
public abstract class flyObject {
    protected int x;
    protected int y;
    protected BufferedImage image;//图片
    protected int width;//图片宽度
    protected int height;//图片高度

    /*3.检查子弹是否击中飞行物  传入子弹,去和页面中all飞行物比较*/

public boolean shootBy(Bullet bullet){
    /*在范围内,则表示碰撞
     * 分析:
     * 两张图片发生碰撞,需要一个碰撞范围 x轴坐标范围:x+飞行物宽度(width)
     * y轴坐标范围:y+飞行物高度(height)*/
    int x = bullet.getX();//得到子弹x的坐标
    int y= bullet.getY();//得到子弹y的坐标
//       boolean b = this.x < x&&x <this.x+width ;  //this.x敌机x轴
//      boolean c = this.y <y&&y<this.y + height;//y轴范围
         // b&&c;?

       boolean b = (this.x < x&&x <this.x+width)&&(this.y <y&&y<this.y + height);
       return b;//ture表明击中
    /*射击到蜜蜂时,要么增加命,要么双倍火力*/
}


    /*2.飞行物移动的方法(定义一个方法,让图片动起来)------------------------------*/
    public abstract void step();//抽象类,使子类必须重写飞行物体的移动方法

/*-----------------------------------------------------------------------------------------*/
    //添加越界方法
    public abstract boolean isOut();



  /*---------------------------------------------------------------------------------------*/
    /*添加get set toString 有参构造和无参构造 alt+insret
 constructor:构造方法
    getter:get方法
    setter:set方法
    toString:toString 方法
*/
    //无参构造
    public flyObject() {
    }

//按住shift选中最后----或按ctrl一个一个选
    //有参构造

    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 getWidth() {
        return width;
    }

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

    public int getHeight() {
        return height;
    }

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

    @Override
    public String toString() {
        return "flyObject{" +
                "x=" + x +
                ", y=" + y +
                ", image=" + image +
                ", width=" + width +
                ", height=" + height +
                '}';
    }
}

airPlane类:

package com.qicco.shoot;

import java.util.Random;

//敌机类
public class airPlane extends flyObject {
    //1.定义特有属性
    private int speed = 2;//定义速度
    /*重写飞行移动方法 step方法*/
    @Override
    public void step() {
        y +=speed;
    }
/*========================================================================*/
        @Override
        public boolean isOut() {
            if(y>ShootGame.HEIGHT-100||x>ShootGame.WIDHT-100)
            {
                return true;

            }
            else {
                return false;
            }
        }
/*========================================================================*/
    /*2.使用构造方法----显示图片
     * */
    public  airPlane(){
        this.image=ShootGame.airplane;//this。image父类继承而来,获取一张敌机图片
        this.width = image.getWidth();
        this.height = image.getHeight();
//        3.定义y轴,坐标怎么定义,因为图片从看不到的地方由上至下加载。所以起始坐标从负值开始
        y = -height;
//        4.定义x轴,敌机随机出现
//             4.1 使用random
        Random random = new Random();
        x = random.nextInt(ShootGame.WIDHT - width);//敌机存在宽度,400-敌机
    }
    /*3.设置加分的方法:   ,每次击中敌机,就加1分*/
    public  int getScore(){
        return 2;
    }
    /*射击到蜜蜂,不知道奖励,去bee里面弄*/
}

Bee类:

package com.qicco.shoot;

import java.util.Random;

//蜜蜂类
public class Bee extends flyObject {
    //1.设置速度.蜜蜂存在会弹的过程,在页面上会来回跑动
    private int xspeed = 1;
    private int yspeed = 3;

    /*5.设置奖励类型*/
    private int awardType;
    /*7.设置奖励类型,产生(new Bee())一只蜜蜂决定好奖励类型*/
    public  int getType(){
        return awardType;
    }




/*重写飞行移动方法*/
    @Override
    public void step() {
        //由于蜜蜂有一个回弹过程,所以存在两个速度,分别在x和y轴上
        x += xspeed;
        y += yspeed;//易出现x轴停止,但y轴未停止
        if ( x> ShootGame.WIDHT-width){
            xspeed = -1;
        }
        if (x<0){
            xspeed = 1;//说明蜜蜂已经到达最左边了
        }
    }
    /*==============================================================================*/
    @Override
    public boolean isOut() {
        if(y>ShootGame.HEIGHT||x>ShootGame.WIDHT)
        {
            return true;

        }
        else {
            return false;
        }

    }
    /*==============================================================================*/

    //    2.使用构造方法,让图片在初始化类的时候,可以调用
    public Bee(){
        this.image = ShootGame.bee;//获取蜜蜂图片
        this.width = image.getWidth();
        this.height = image.getHeight();
//    3.定义y轴坐标,从负轴开始
        y = -height;
//    4.定义X轴坐标,图片本身也有宽度,随机出现
        Random random = new Random();
        x = random.nextInt(ShootGame.WIDHT - width);//大框 - 小框
        /*6.一出生就定义好了,*/
        awardType = random.nextInt(2);

    }

}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值