Java 实现飞机大战

飞机大战设计基本流程

1.窗口显示 JFrame

2.画板/面板 JPanel

public static void main(String[] args) {

        JFrame window = new JFrame("飞机大战");     //创建对象 并设定窗口的标题
        GamePanel g = new GamePanel();

        window.add(g);
        g.action();

        window.setSize(WIDTH, HEIGHT);                                      //设置窗口的长宽
        window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);     //设置窗口的关闭
        window.setLocationRelativeTo(null);                                 //窗口居中
        window.setVisible(true);                                            //显示窗口
    }
原生的 JPanel 中, 不能自定义绘画,只能画按钮, 输入框.. 等一些组件

功能加强 -> 自定义类继承 JPanel

3.图片读取

   1.硬盘中有图片文件
   
   2.将硬盘中的图片文件, 读取到JVM内存中, 成一个对象
     InputOutput -> IO

     类名.class -> 所有的类加载到方法区中,对应一个Class对象

通过重复使用一下语句,可以将图片读入内存中
	airplane = ImageIO.read(FlyGame.class.getResourceAsStream("res/airplane.png"));

4.程序的设计

  类的设计
    飞机大战:
        拥有相似的需求: 自己的飞机, 敌机, 小蜜蜂, 子弹
        
    子类 extends 父类
        自己的飞机: Hero
        敌机: Airplane
        小蜜蜂: Bee
        子弹: Bullet - 有参的构造方法
        大敌机: BigPlane
        
        以上类中相同的成员变量, 和相同的方法, 提取出来
        
    父类: FlyingObject
        int x, int y, 图片, int width, int height
        move() - 移动

5.补充父类中的构造方法

    FlyingObject(int x, int y, BufferedImage img, int life) {
        this.img = img;
        this.width = img.getWidth();
        this.height = img.getHeight();
        this.x = x;
        this.y = y;
        this.life = life;
    }

6.在主程序中创建各种对象进行测试测试

7.写入各个飞行物类的move方法

    @Override
    public void move() {
        setY(getY() + y_speed);
        setX(getX() + x_speed);
        if (getX() > FlyGame.WIDTH - FlyGame.bee.getWidth() - 10) {
            x_speed = -x_speed;
        } else if (getX() < 0) {
            x_speed = -x_speed;
        }
    }

8.主程序中: 添加定时器

a.生成新的飞行物(小蜜蜂, 敌机, 大敌机)
b.移动所有飞行物
d.发射子弹 - 属于英雄机的行为 - 写在Hero类中
e.移动所有子弹
c.判断飞行物和子弹越界
f.判断子弹和飞行物碰撞
g.英雄机移动 - move - 鼠标控制
h.英雄机和敌机碰撞
i.判断游戏是否结束
z.重画
public void action() {
        //TimerTask  需要重复的代码
        //long 定时器开始的时间
        //long 时间间隔
        time.schedule(new TimerTask() {
            @Override
            public void run() {
                if (state == RUNING) {
                    //创建敌机
                    createFlyingObject();
                    //创建敌机的移动
                    paintFlyMove();
                    //创建子弹
                    createBullet();
                    //创建子弹的移动
                    bulletMove();
                    //越界处理
                    outOfBoundsAction();
                    //碰撞
                    boonAction();
                }
                //重新绘制
                repaint();
            }
        }, 1000, 30);
    }

9.添加鼠标监听事件 - 监听器 - 接口

单击\移动\鼠标移出界面\鼠标移入界面
窗口/画板.addMouseListener  -> 单击\鼠标移入\鼠标移出
窗口/画板.addMouseMotionListener -> 鼠标移动
注意:
 接口功能太多, 选择性使用功能, 提供了一个适配器 - 抽象类
 MouseAdapter - 抽象类, 将所有接口方法空实现
//创建一个鼠标的适配器
        MouseAdapter Mouse = new MouseAdapter() {
            //重写鼠标点击
            @Override
            public void mouseClicked(MouseEvent e) {
                //判断状态
                if (state == START) {
                    state = RUNING;
                } else if (state == GAMEOVER) {     //若游戏结束
                    state = START;
                    //重新生成英雄机、飞行物、子弹
                    hero = new Hero();
                    flyings = new ArrayList<>();
                    flyBullet = new ArrayList<>();
                }
            }

            //重写鼠标移入窗口  实现继续游戏
            @Override
            public void mouseEntered(MouseEvent e) {
                if (state == PAUSE) {
                    state = RUNING;
                }
            }

            //重写鼠标移出窗口  实现暂停
            @Override
            public void mouseExited(MouseEvent e) {
                if (state == RUNING) {
                    state = PAUSE;
                }
            }

            //重写鼠标的移动   并实现使用鼠标控制英雄机
            @Override
            public void mouseMoved(MouseEvent e) {
                if (state == RUNING) {
                    hero.setX(e.getX() - FlyGame.hero0.getWidth() / 2);
                    hero.setY(e.getY() - FlyGame.hero0.getHeight() / 2);
                    bullet.setX(hero.getX());
                    bullet.setY(hero.getY());
                }
            }
        };

10.游戏状态的设置

   a.初始状态 start
   b.运行状态 running
   c.暂停状态 pause
   d.游戏结束 gameover
   start -> 鼠标单击 -> running
   running -> 移出 -> pause-> hero.getLife()==0 -> gameover
   pause -> 鼠标移入 -> running
   gameover -> 鼠标单击 -> start
//判断窗口当前状态,并输出相应的图片
        switch (state) {
            case START:
                g.drawImage(FlyGame.start, 0, 0, this);
                break;
            case GAMEOVER:
                g.drawImage(FlyGame.gameover, 0, 0, this);
                break;
            case PAUSE:
                g.drawImage(FlyGame.pause, 0, 0, this);
                break;
        }

11.奖励类型: [火力加成], 生命值加成

// 发射子弹并生成新的子弹
    public Bullet[] shoot() {
        Bullet[] bullets;
        if (doubleFire == 0) {
            bullets = new Bullet[1];
            bullets[0] = new Bullet(this.getX() + this.getWidth() / 2, this.getY());
        } else {
            bullets = new Bullet[2];
            bullets[0] = new Bullet(this.getX() + this.getWidth() / 4, this.getY());
            bullets[1] = new Bullet(this.getX() + this.getWidth() / 4 * 3, this.getY());
            doubleFire--;
        }
        return bullets;
    }

12.碰撞

子弹和飞行物的碰撞: 要么加分, 要么奖励
飞行物和英雄机的碰撞: 减英雄机生命值
private void boonAction() {
        for (int i = 0; i < flyBullet.size(); i++) {
            FlyingObject bul = flyBullet.get(i);
            for (int j = 0; j < flyings.size(); j++) {
                FlyingObject fly = flyings.get(j);
                //敌机和子弹的碰撞
                if (bul.getX() > fly.getX() && bul.getX() < fly.getX() + fly.getWidth()
                        && bul.getY() > fly.getY() && bul.getY() < fly.getY() + fly.getWidth()) {
                    flyBullet.remove(i);
                    fly.flyLife();
                    if (fly.getLife() == 0) {
                        flyings.remove(j);
                        //利用接口实现分数的累加
                        if (fly instanceof Enemy) {
                            Enemy enemy = (Enemy) fly;
                            hero.addScore(enemy.getScore());
                        }
                        //利用接口实现奖励机制
                        if (fly instanceof Award) {
                            Award award = (Award) fly;
                            if (award.getAwardType() == Award.ADD_LIFE)
                                hero.addLife();
                            else {
                                hero.addDoubleFire();
                            }
                        }
                    }
                    i--;
                    j--;
                    break;
                }
                //敌机和英雄机的碰撞
                if (hero.getX() + FlyGame.hero0.getWidth() / 2 > fly.getX()
                        && hero.getX() + FlyGame.hero0.getWidth() / 2 < fly.getX() + fly.getWidth()
                        && hero.getY() < fly.getY() && hero.getY() + FlyGame.hero0.getHeight() > fly.getY()) {
                    flyings.remove(j);
                    j--;
                    hero.setLife(hero.getLife() - 1);
                    if (hero.getLife() == 0) {
                        state = GAMEOVER;
                        break;
                    }
                }
            }
        }
    }

实现代码:Github链接:

https://github.com/923677975/flygame.git
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值