码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2018-03-29 00:03:29      阅读:327      评论:0      收藏:0      [点我收藏+]

标签:height   boolean   throw   operation   visible   paint   get   panel   sem   

day09

1.子弹与敌人的碰撞
    1)在超类中FlyingObject设计hit()实现敌人与子弹/英雄机得碰撞

    /** 成员方法:检测敌人与子弹/英雄机的碰撞
     *  this:敌人    other:子弹 */
    public boolean hit(FlyingObject other) {
        int x1 = this.x - other.width;
        int x2 = this.x + this.width;        
        int y1 = this.y - other.height;    
        int y2 = this.y + this.height;    
        int x = other.x;                                
        int y = other.y;                                
        return x>=x1 && x<=x2 && y>=y1 && y<=y2;    
    }

    在超类中FlyingObject设计goDead()实现飞行物去死的

    /** 成员方法:飞行物去死 */
    public void goDead() {
        state = DEAD;    //将当前状态修改为DEAD
    }
import java.util.Random;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.awt.Graphics;
/**
 * 飞行物--超类
 * @author soft01
 */
public abstract class FlyingObject {
    /** 常量: 三种状态(活着的、死了的、删除的)    */
    public static final int LIFE = 0;
    public static final int DEAD = 1;
    public static final int REMOVE = 2;
    
    /** 成员变量:当前状态(默认为活着的) */
    protected int state = LIFE;    
    
    /** 成员变量:宽、高、x轴、y轴 */
    protected int width;        
    protected int height;    
    protected int x;                
    protected int y;                
    
    /** 构造方法:专门给英雄机、天空、子弹用 */
    public FlyingObject(int width,int height,int x,int y) {
        this.width = width;
        this.height = height;
        this.x = x;
        this.y = y;
    }
    
    /** 构造方法:专门给小敌机、大敌机、小蜜蜂用 */
    public FlyingObject(int width,int height) {
        this.width = width;
        this.height = height;
        Random rand = new Random();
        x = rand.nextInt(World.WIDTH-width);
        y = -height;    
    }

    /**    抽象方法:飞行物移动        */
    public abstract void step();
    
    /**    抽象方法:获取图片        */
    public abstract BufferedImage getImage();
    
    /** 抽象方法:检查飞行物是否越界 */
    public abstract boolean outOfBounds();
    
    /** 静态方法:读取图片 */
    public static BufferedImage loadImage(String fileName) {
        try {
            BufferedImage img = ImageIO.read(FlyingObject.class.getResource(fileName));    //同包中读图片
            return img;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    /** 成员方法:判断状态(活着的、死了的、删除的) */
    public boolean isLife() {
        return state == LIFE;
    }
    public boolean isDead() {
        return state == DEAD;
    }
    public boolean isRemove() {
        return state == REMOVE;
    }

    /** 成员方法:画对象的 g:画笔 */
    public void paintObject(Graphics g) {
        g.drawImage(getImage(),x,y,null);
    }
    
    /** 成员方法:检测敌人与子弹/英雄机的碰撞
     *  this:敌人    other:子弹 */
    public boolean hit(FlyingObject other) {
        int x1 = this.x - other.width;        //敌人的x - 子弹/英雄机的宽
        int x2 = this.x + this.width;        //敌人的x + 敌人的宽
        int y1 = this.y - other.height;    //敌人的y - 子弹/英雄机的高
        int y2 = this.y + this.height;        //敌人的y + 敌人的高
        int x = other.x;                                //子弹/英雄机的x
        int y = other.y;                                //子弹/英雄机的y    
        return x>=x1 && x<=x2 && y>=y1 && y<=y2;    //x在x1和x2之间,y在y1和y2之间
    }
    
    /** 成员方法:飞行物去死 */
    public void goDead() {
        state = DEAD;        //将当前状态修改为DEAD
    }
}

 


    在Hero类中设计addLife()增命、addDoubleFire()增火力

    /**    成员方法:命数增加    */
    public void addLife() {
        life++;    //命数增1
    }
    
    /**    成员方法:火力值增加        */
    public void addDoubleFire() {
        doubleFire += 40;        //火力值增40
    }
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 addLife() {
        life++;    //命数增1
    }
    
    /**    成员方法:获取命数    */
    public int getLife() {
        return life;    //返回命
    }
    
    /**    成员方法:火力值增加        */
    public void addDoubleFire() {
        doubleFire += 40;        //火力值增40
    }
    
    /**    成员方法:英雄机移动        */
    public void step() {}
    
    /**    成员方法:英雄机随鼠标移动x,y    */
    public void moveTo(int x,int y) {    
        this.x = x - this.width/2;        //英雄机的x=鼠标的x-1/2英雄机的宽
        this.y = y - this.height/2;    //英雄机的y=鼠标的y-1/2英雄机的高
    }
    
    /**    成员方法:获取图片    */
    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;
        }
    }
    
    /**    成员方法:英雄机永不越界    */
    @Override
    public boolean outOfBounds() {
        return false;
    }
}

  2)子弹与敌人的碰撞为定时发生的,所以在run()中调用BulletBangAction()方法
在BulletBangAction()中:
遍历所有子弹,获取每一个子弹,遍历所有敌人,获取每个敌人
判断是否撞上了,若撞上了:
    1)子弹去死,敌人去死
    2)小敌机和大敌机 ----------得分
       小蜜蜂 ----------------英雄机得命或双倍火力

/** 成员方法:子弹与敌人的碰撞 */
int score = 0;
public void bulletBangAction() {    //每10个毫秒走一次
    //遍历子弹数组        
    for (int i = 0; i < bullets.length; i++) {    
        Bullet b = bullets[i];//得到每一个子弹
        //遍历敌人数组
        for (int j = 0; j < enemies.length; j++) {    
            FlyingObject f = enemies[j];    //得到每一个敌人
            //如果活着的子弹和活着的敌人撞上了
            if(b.isLife() && f.isLife() && f.hit(b)) {        
                b.goDead();            //子弹去死
                f.goDead();            //敌人去死            
                if (f instanceof Enemy) {//若被撞对象是敌人
                    Enemy e = (Enemy)f;//强转为得分接口        
                    score += e.getScore();//玩家得分
                }
                if (f instanceof Award) {//若被撞对象是奖励
                  Award a = (Award)f;//    强转为奖励接口
                  int type = a.getType();//获取奖励类型                      //基于不同的类型来得到不同的奖励
                  switch (type) {
                  //若奖励为火力值                
                  case Award.DOUBLE_FIRE:
                    hero.addDoubleFire();    //则增加火力值        
                    break;
                    case Award.LIFE:        //若奖励为命        
                    hero.addLife();        //则增加命        
                    break;                                              }
                }
            }
        }
    }
}


2.画分和画命
    1)在Hero类中设计getLife()获取命

    /**    成员方法:获取命数    */
    public int getLife() {
        return life;    //返回命
    }

    2)在paint()方法中,画分和画命

    g.drawString("SCORE:" + score,10,25);
    g.drawString("LIFE:" + hero.getLife(), 10, 45);

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;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;;

/**
 * 整个世界
 * @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();                                                    //飞行物入场
                outOfBoundsAction();                                    //删除越界
                bulletBangAction();                                        //子弹与敌人的碰撞
                repaint();                                                     //重画(重新调用paint()方法)
            }
        },interval,interval);                                            //定时计划
        
        /** 鼠标侦听器 */
        MouseAdapter l = new MouseAdapter() {
            /** 重写mouseMoved()鼠标移动 */
            public void mouseMoved(MouseEvent e) {
                int x = e.getX();        //获取鼠标的x坐标
                int y = e.getY();        //获取鼠标的y坐标
                hero.moveTo(x, y);    //英雄机随着鼠标移动
            }
        };
        this.addMouseListener(l);                //处理鼠标操作事件
        this.addMouseMotionListener(l);    //处理鼠标滑动事件
    }
    
    
    /** 成员方法:生成敌人(小敌机、大敌机、小蜜蜂)对象 */
    public FlyingObject nextOne() {
        Random rand = new Random();    //随机数对象
        int type = rand.nextInt(20);    //0~19之间的数
        if (type < 11) {                            //0~7返回小敌机
            return new Airplane();
        } else if(type < 17){                //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%20 == 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();    //子弹移动
        }
    }
    
    /** 成员方法:删除越界 */
    public void outOfBoundsAction() {    //每10个毫秒走一次
        int index = 0;        //1)不越界敌人下标    2)不越界敌人个数
        FlyingObject[] enemyLives = new FlyingObject[enemies.length];     //不越界敌人数组
        for (int i = 0; i < enemies.length; i++) {    //获取敌人数组
            FlyingObject f = enemies[i];        //获取每一个敌人
            if(!f.outOfBounds()) {    //不越界
                enemyLives[index] = f;    //将不越界敌人放到不越界数组中
                index++;        //1)不越界敌人数组下标增一        2)不越界敌人个数增1
            }
        }
        enemies = Arrays.copyOf(enemyLives, index);    //将不越界数组中的元素复制到敌人数组之中,数组的长度为index
        
        index = 0;
        Bullet[] bulletLives = new Bullet[bullets.length];
        for (int i = 0; i < bullets.length; i++) {
            Bullet b = bullets[i];
            if(!b.outOfBounds()) {
                bulletLives[index] = b;
                index++;
            }
        }
        bullets = Arrays.copyOf(bulletLives, index);
    }
    
    /** 成员方法:子弹与敌人的碰撞 */
    int score = 0;
    public void bulletBangAction() {                                        //每10个毫秒走一次
        for (int i = 0; i < bullets.length; i++) {                //遍历子弹数组
            Bullet b = bullets[i];                                                //得到每一个子弹
            for (int j = 0; j < enemies.length; j++) {            //遍历敌人数组
                FlyingObject f = enemies[j];                                    //得到每一个敌人
                if(b.isLife() && f.isLife() && f.hit(b)) {        //如果活着的子弹和活着的敌人撞上了
                    b.goDead();                                                            //子弹去死
                    f.goDead();                                                            //敌人去死                
                    if (f instanceof Enemy) {                                    //若被撞对象是敌人
                        Enemy e = (Enemy)f;                                            //强转为得分接口
                        score += e.getScore();                                    //玩家得分
                    }
                    if (f instanceof Award) {                                    //    若被撞对象是奖励
                        Award a = (Award)f;                                            //    强转为奖励接口
                        int type = a.getType();                                    //获取奖励类型
                        switch (type) {                                                    //基于不同的类型来得到不同的奖励
                        case Award.DOUBLE_FIRE:                                    //若奖励为火力值
                            hero.addDoubleFire();                                    //则增加火力值
                            break;
                        case Award.LIFE:                                                //若奖励为命
                            hero.addLife();                                                //则增加命
                            break;                                                                
                        }
                    }
                }
            }
        }
    }
    
    
    /** 成员方法: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);                                //画子弹
        }
        g.drawString("SCORE:" + score,10,25);
        g.drawString("LIFE:" + hero.getLife(), 10, 45);
    }
    
    /** 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学习二(飞机大战项目)day09

标签:height   boolean   throw   operation   visible   paint   get   panel   sem   

原文地址:https://www.cnblogs.com/lj-6112/p/8666539.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!