Java学习二(飞机大战项目)day07

Posted lj-6112

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习二(飞机大战项目)day07相关的知识,希望对你有一定的参考价值。

day07

功能实现的步骤:

1.先写行为:
    1)若是某个对象特有的行为,则将设计在派生类中
        若是所有对象共有的行为,则将设计在超类中
      1.1)所有派生类行为都一样,设计为普通方法
      1.2)所有派生类行为都不一样,设计为抽象方法,而后派生类重写

2.窗口调用:
    1)定时触发的,在run()中调用
    2)事件触发的,在监听器中调用
    3)画出来的,在paint()中调用

项目功能:
    
1.敌人入场 ---------- 定时发生
    1)创建敌人对象
    敌人对象 --------------- 是由窗口创建出来的
    ---创建敌人对象的行为 ----设计在窗口类World中设计nextOne()

    /** 成员方法:生成敌人(小敌机、大敌机、小蜜蜂)对象 */
    public FlyingObject nextOne() {
        Random rand = new Random();    //随机数对象
        int type = rand.nextInt(20);    //0~19之间的数
        if (type < 8) {                //0~7返回小敌机
            return new Airplane();
        } else if(type < 16){            //8~15返回小敌机
            return new BigAirplane();
        } else {                        //16~19返回小敌机
            return new Bee();
        }
    }

    2)将对象添加到enemies数组中
    敌人入场为定时发生的,在run()中调用enterAction()实现敌人入场,
  在enterAction()中,每400毫秒调用nextOne()方法获取敌人,enemies数组扩容,装在最后一个元素上。 /** 成员方法:敌人(小敌机、大敌机、小蜜蜂)入场 */ int enterIndex = 0; //敌人入场计数 public void enterAction() { //每10个毫秒走一次 enterIndex++; //每10毫秒增1 if(enterIndex%40 == 0) { //每400(10*40)毫秒走一次 FlyingObject obj = nextOne(); enemies = Arrays.copyOf(enemies,enemies.length+1);//数组扩容 //将敌人对象填充到enemies数组的最后一个元素上 enemies[enemies.length-1] = obj; } }

2.子弹入场 ---------- 定时发生
    1)创建子弹对象
    子弹对象 --------------- 是由英雄机发射出来的
    ---创建子弹对象的行为 ----设计在英雄机类Hero中
    /**    成员方法:英雄机发射子弹(创建子弹对象)    */
    public Bullet[] shoot() {
        int xStep = this.width/4;    //xStep:1/4英雄机的宽
        int yStep = 20;            //yStep:固定的20
        if (doubleFire > 0) {        //双
            Bullet[] bs = new Bullet[2];        //2发子弹
            //英雄机的x坐标加1/4英雄机的宽
        bs[0] = new Bullet(this.x + 1 * xStep,y-yStep);    
            //英雄机的x坐标加3/4英雄机的宽
        bs[1] = new Bullet(this.x + 3 * xStep, y-yStep);    
            doubleFire -= 2;    //发射一次双倍火力,火力值减2
            return bs;
        } else {                    //单
            Bullet[] bs = new Bullet[1];        //1发子弹
        //英雄机的x坐标加2/4英雄机的宽
        bs[0] = new Bullet(this.x + 2 * xStep, y-yStep);    
            return bs;
        }
    }
import java.awt.image.BufferedImage;

/**
 * 英雄机
 * @author soft01
 */
public class Hero extends FlyingObject{
    /** 静态变量:英雄机图片    */
    private static BufferedImage[] images;
    static {
        images = new BufferedImage[2];
        for (int i = 0; i < images.length; i++) {
            images[i] = loadImage("hero" + i + ".png");
        }
    }
    
    /**    成员变量:生命、火力值    */
    private int life;        //生命
    private int doubleFire;        //火力值
    
    /**    构造方法    */
    public Hero(){
        super(97,124,140,400);
        life = 3;
        doubleFire = 0;
    }
    
    /**    成员方法:英雄机移动        */
    public void step() {}
    
    /**    成员方法:英雄机随鼠标移动    */
    void moveTo(int x,int y) {    }
    
    /**    成员方法:获取图片    */
    int index = 0;
    @Override
    public BufferedImage getImage() {
        if(isLife()) {
            return images[index++%2];        //(index++%2)余数为0或1
        }
        return null;
    }
    
    /**    成员方法:英雄机发射子弹(创建子弹对象)    */
    public Bullet[] shoot() {
        int xStep = this.width/4;    //xStep:1/4英雄机的宽
        int yStep = 20;            //yStep:固定的20
        if (doubleFire > 0) {        //
            Bullet[] bs = new Bullet[2];        //2发子弹
            //英雄机的x坐标加1/4英雄机的宽
        bs[0] = new Bullet(this.x + 1 * xStep,y-yStep);    
            //英雄机的x坐标加3/4英雄机的宽
        bs[1] = new Bullet(this.x + 3 * xStep, y-yStep);    
            doubleFire -= 2;    //发射一次双倍火力,火力值减2
            return bs;
        } else {                    //
            Bullet[] bs = new Bullet[1];        //1发子弹
        //英雄机的x坐标加2/4英雄机的宽
        bs[0] = new Bullet(this.x + 2 * xStep, y-yStep);    
            return bs;
        }
    }
}

 2)将对象添加到bullets数组中
    子弹入场为定时发生的,在run()中调用shootAction()实现敌人入场,
  在shootAction()中,每300毫秒调用shoot()方法获取子弹,bullets数组扩容,数组追加。 /** 成员方法:子弹入场,英雄机发射子弹 */ int shootIndex = 0; //子弹入场计数 public void shootAction() { //每10个毫秒走一次 shootIndex++; //每10毫秒增1 if(shootIndex%30 == 0) { //每300(10*30)毫秒走一次 //获取英雄机发射出来的子弹对象 Bullet[] bs = hero.shoot(); //扩容(bs有几个元素就扩大几个) bullets = Arrays.copyOf(bullets,bullets.length+bs.length); //数组的追加 System.arraycopy(bs, 0, bullets,bullets.length - bs.length, bs.length); } } 3.飞行物移动 ---------- 定时发生 1)移动是所有对象所共有的行为,并且每个对象移动的行为都是不一样的,
  所以在超类FlyingObject中设计了抽象方法step(), /** 抽象方法:飞行物移动 */ public abstract void step(); 派生类重写step()方法 /** 成员方法:英雄机移动 */ public void step() {} /** 成员方法:小敌机移动 */ /** 成员方法:大敌机移动 */ public void step() { y += speed; //y+(向下) }
import java.awt.image.BufferedImage;

/**
 * 小敌机
 * @author soft01
 */
public class Airplane  extends FlyingObject{
    /** 静态变量:小敌机图片*/
    private static BufferedImage[] images;
    static {
        images = new BufferedImage[5];
        for (int i = 0; i < images.length; i++) {
            images[i] = loadImage("airplane" + i + ".png");
        }
    }
    
    /**    成员变量:移动速度    */
    private int speed;        //移动速度
    
    /**    构造方法    */
    public Airplane() {
        super(49,36);
        speed = 2;
    }
    
    /**    成员方法:小敌机移动        */
    public void step() {
        y += speed;    //y+(向下)
    }
    
    /**    成员方法:获取图片    */
    int index = 1;    //轮换图片的起始位置
    @Override
    public BufferedImage getImage() {    //每10个毫秒轮换一次
        if(isLife()) {                    //若活着的
            return images[0];            //返回第一张图
        } else if(isDead()) {        //若死了的
            BufferedImage img = images[index++];    //从第2张图片到最后一张图片轮换
            if (index == images.length) {    //如果是最后一张图片时
                state = REMOVE;                //状态改为删除
            }    
            return img;                        //返回对应下标的图片
        }
        return null;                        //死了的和删除的,都返回null
    }
}
/**
 * 大敌机
 * @author soft01
 */
public class BigAirplane extends FlyingObject{
    /** 静态变量:大敌机图片*/
    private static BufferedImage[] images;
    static {
        images = new BufferedImage[2];
        for (int i = 0; i < images.length; i++) {
            images[i] = loadImage("bigplane" + i + ".png");
        }
    }
    
    /**    成员变量:移动速度    */
    private int speed;        //移动速度
    
    /**    构造方法    */
    public BigAirplane() {
        super(69,99);
        speed = 2;
    }
    
    /**    成员方法:大敌机移动        */
    @Override
    public void step() {
        y += speed;        //y+(向下)
    }
    
    /**    成员方法:获取图片    */
    int index = 1;    //轮换图片的起始位置
    @Override
    public BufferedImage getImage() {    //每10个毫秒轮换一次
        if(isLife()) {                    //若活着的
            return images[0];            //返回第一张图
        } else if(isDead()) {        //若死了的
            BufferedImage img = images[index++];    //从第2张图片到最后一张图片轮换
            if (index == images.length) {    //如果是最后一张图片时
                state = REMOVE;                //状态改为删除
            }    
            return img;                        //返回对应下标的图片
        }
        return null;                        //死了的和删除的,都返回null
    }
}

 

    /**    成员方法:子弹移动    */
    @Override
    public void step() {
        y -= speed;    //y-(向上)
    }
import java.awt.image.BufferedImage;

/**
 * 子弹
 * @author soft01
 */
public class Bullet extends FlyingObject{
    /** 静态变量:子弹图片*/
    private static BufferedImage image;
    static {
        image = loadImage("bullet.png");
    }
    
    /**    成员变量:移动速度    */
    private int speed;            //移动速度
    
    /**    构造方法    */
    public Bullet(int x,int y) {
        super(8,14,x,y);
        speed = 3;
    }
    
    /**    成员方法:子弹移动    */
    @Override
    public void step() {
        y -= speed;    //y-(向上)
    }
    
    /**    成员方法:获取图片    */
    @Override
    public BufferedImage getImage() {
        if(isLife()) {                    //若活着的
            return image;                    //返回image
        } else if(isDead()) {        //若死了的
            state= REMOVE;                //状态改为删除
        }
        return null;                        //死了的和删除的,都返回null
    }
}

    /**    成员方法:小蜜蜂移动        */
    @Override
    public void step() {
        x += xSpeed;
        y += ySpeed;
        if(x <= 0 || x >= World.WIDTH-this.width) {        
            xSpeed *= -1;
        }
    }
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 小蜜蜂
 * @author soft01
 */
public class Bee  extends FlyingObject{
    /** 静态变量:小蜜蜂图片*/
    private static BufferedImage[] images;
    static {
        images = new BufferedImage[2];
        for (int i = 0; i < images.length; i++) {
            images[i] = loadImage("bee" + i + ".png");
        }
    }
    
    /**    成员变量:移动速度    */
    private int xSpeed;            //x坐标移动速度
    private int ySpeed;            //y坐标移动速度
    private int awardType;        //奖励类型
    
    /**    构造方法    */
    public Bee() {
        super(60,50);
        xSpeed = 1;
        ySpeed = 2;
        Random rand = new Random();
        awardType = rand.nextInt(2);        //0~1之间的随机数
    }
    /**    成员方法:小蜜蜂移动        */
    @Override
    public void step() {
        x += xSpeed;
        y += ySpeed;
        if(x <= 0 || x >= World.WIDTH-this.width) {        
            xSpeed *= -1;
        }
    }
    
    /**    成员方法:获取图片    */
    int index = 1;    //轮换图片的起始位置
    @Override
    public BufferedImage getImage() {    //每10个毫秒轮换一次
        if(isLife()) {                    //若活着的
            return images[0];            //返回第一张图
        } else if(isDead()) {        //若死了的
            BufferedImage img = images[index++];    //从第2张图片到最后一张图片轮换
            if (index == images.length) {    //如果是最后一张图片时
                state = REMOVE;                //状态改为删除
            }    
            return img;                        //返回对应下标的图片
        }
        return null;                        //死了的和删除的,都返回null
    }
}

    /**    成员方法:天空移动    */
    public void step() {    
        y +=speed;  //y+(向下)
        y1+=speed; //y1+(向下)
        if(y>=World.HEIGHT){ //若y>=窗口的高
            y = -World.HEIGHT; //则修改y的值为负的窗口的高
        }
        if(y1>=World.HEIGHT){ //若y1>=窗口的高
            y1 = -World.HEIGHT; //则修改y1的值为负的窗口的高
        }    
    }

import java.awt.Graphics;
import java.awt.image.BufferedImage;


/**
 * 天空
 * @author soft01
 */
public class Sky extends FlyingObject{
    /** 静态变量:天空图片 */
    private static BufferedImage image;
    static {
        image = loadImage("background.png");
    }
    
    /**    成员变量:移动速度    */
    private int y1;            //第二张图片的y坐标
    private int speed;        //移动速度
    
    /**    构造方法    */
    public Sky(){
        super(World.WIDTH,World.HEIGHT,0,0);
        y1 = -height;
        speed = 1;
    }
    
    /**    成员方法:天空移动    */
    public void step() {    
        y +=speed;  //y+(向下)
        y1+=speed; //y1+(向下)
        if(y>=World.HEIGHT){ //若y>=窗口的高
            y = -World.HEIGHT; //则修改y的值为负的窗口的高
        }
        if(y1>=World.HEIGHT){ //若y1>=窗口的高
            y1 = -World.HEIGHT; //则修改y1的值为负的窗口的高
        }    
    }
    
    /**    成员方法:获取图片    */
    
    public BufferedImage getImage() {
        return image;
    }
    
    /** 成员方法:画对象的 g:画笔 */
    
    public void paintObject(Graphics g) {
        g.drawImage(getImage(),x,y,null);
        g.drawImage(getImage(),x,y1,null);
    }
    
}

    2)飞行物移动为定时发生的,在run()中调用stepAction()实现飞行物移动,
  在stepAction()中,天空动,遍历敌人而后敌人动,遍历子弹而后子弹动 /** 成员方法:飞行物入场 */ public void stepAction() { sky.step(); //天空移动 for (int i = 0; i < enemies.length; i++) { enemies[i].step(); //飞行物移动 } for (int i = 0; i < bullets.length; i++) { bullets[i].step(); //子弹移动 } } /** 启动程序的执行 */ public void action() { Timer timer = new Timer(); //创建定时器对象 int interval = 10; //定时间隔(以毫秒为单位) timer.schedule(new TimerTask() { @Override public void run() {//定时干的事(每10个毫秒走一次) enterAction(); //敌人入场,子弹入场,飞行物移动 shootAction(); //子弹入场,英雄机发射子弹 stepAction(); //飞行物入场 repaint(); //重画(重新调用paint()方法) } },interval,interval); //定时计划 }

import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Random;
import java.util.Arrays;

/**
 * 整个世界
 * @author soft01
 */
public class World extends JPanel{
    /** 常量:窗口宽、窗口高 */
    public static final int WIDTH = 400;
    public static final int HEIGHT = 700;

    /**    成员变量:天空、英雄机、飞行物敌人数组、子弹数组    */
    private Sky sky = new Sky();                            
    private Hero hero = new Hero();                        
    private FlyingObject[] enemies = {};
    private Bullet[] bullets = {};        
    
    /**    启动程序的执行    */
    public void action() {
        Timer timer = new Timer();               //创建定时器对象
        int interval = 10;                       //定时间隔(以毫秒为单位)
        timer.schedule(new TimerTask() {                        
            @Override
            public void run() {                  //定时干的事(每10个毫秒走一次)
                enterAction();                   //敌人入场,子弹入场,飞行物移动
                shootAction();                   //子弹入场,英雄机发射子弹
                stepAction();                    //飞行物入场
                repaint();                       //重画(重新调用paint()方法)
            }
        },interval,interval);                     //定时计划
    }
    
    
    /** 成员方法:生成敌人(小敌机、大敌机、小蜜蜂)对象 */
    public FlyingObject nextOne() {
        Random rand = new Random();    //随机数对象
        int type = rand.nextInt(20);    //0~19之间的数
        if (type < 8) {                            //0~7返回小敌机
            return new Airplane();
        } else if(type < 16){                //8~15返回小敌机
            return new BigAirplane();
        } else {                                        //16~19返回小敌机
            return new Bee();
        }
    }
    
    /** 成员方法:敌人(小敌机、大敌机、小蜜蜂)入场 */
    int enterIndex = 0;                            //敌人入场计数
    public void enterAction() {            //每10个毫秒走一次
        enterIndex++;                                    //每10毫秒增1
        if(enterIndex%40 == 0) {            //每400(10*40)毫秒走一次
            FlyingObject obj = nextOne();
            enemies = Arrays.copyOf(enemies, enemies.length+1);    //数组扩容
            enemies[enemies.length-1] = obj;                //将敌人对象填充到enemies数组的最后一个元素上
        }
    }
    
    /** 成员方法:子弹入场,英雄机发射子弹 */
    int shootIndex = 0;                            //子弹入场计数
    public void shootAction() {            //每10个毫秒走一次
        shootIndex++;                                    //每10毫秒增1
        if(shootIndex%30 == 0) {            //每300(10*30)毫秒走一次
            Bullet[] bs = hero.shoot();    //获取英雄机发射出来的子弹对象
            bullets = Arrays.copyOf(bullets, bullets.length+bs.length);    //扩容(bs有几个元素就扩大几个)
            System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length);     //数组的追加
        }
    }
    
    /** 成员方法:飞行物入场 */
    public void stepAction() {
        sky.step();                    //天空移动
        for (int i = 0; i < enemies.length; i++) {
            enemies[i].step();    //飞行物移动
        }
        for (int i = 0; i < bullets.length; i++) {
            bullets[i].step();    //子弹移动
        }
    }
    
    /** 成员方法:paint()方法 */
    @Override
    public void paint(Graphics g) {
        sky.paintObject(g);                                                //画天空
        hero.paintObject(g);                                            //画英雄机
        for (int i = 0; i < enemies.length; i++) {    //遍历所有敌人
            enemies[i].paintObject(g);                                //画敌对飞行物
        }
        for (int i = 0; i < bullets.length; i++) {    //遍历子弹
            bullets[i].paintObject(g);                                //画子弹
        }
    }
    
    /** main主方法 */
    public static void main(String[] args) {
        JFrame frame = new JFrame();                                                    //创建窗口
        World world = new World();                                                        //创建面板
        frame.add(world);                                                                        //将面板添加到窗口
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    //设置关闭窗口即停止运行程序
        frame.setSize(WIDTH,HEIGHT);                                                    //设置窗口大小
        frame.setLocationRelativeTo(null);                                     //设置窗口居中显示
        frame.setVisible(true);                                                         //1)设置窗口可见        2)尽快调用paint()方法
        
        world.action();                                                                            //启动程序
    }

}

 

 








以上是关于Java学习二(飞机大战项目)day07的主要内容,如果未能解决你的问题,请参考以下文章

Java学习二(飞机大战项目)day09

项目实战---飞机大战---初学者学习使用详解

项目实战---飞机大战---初学者学习使用详解

Python——飞机大战(day10)

Java实现飞机大战小游戏|Java入门结课作业

雷电飞机大战游戏|基于Java开发实现雷电飞机大战游戏