Java day09——飞机大战part1

2022-08-02,,,,

目录

  • 窗口参数
  • 画板参数
  • 飞机大战
    • 设计思路
    • 类的实现
      • 飞行物类
      • 英雄机类
      • 蜜蜂类
      • 子弹类
      • 大敌机类
      • 主类

窗口参数

窗口显示 JFrame

public static void main(String[] args) {
	    // 空参构造方法 -> 创建一个原始的很小的窗口
        JFrame window = new JFrame();
        window.setTitle("飞机大战");
        // 有参构造方法 -> 参数:窗口标题
//        JFrame window = new JFrame("飞机大战");
        // 设置窗口大小
        window.setSize(400, 650);
        // 设置窗口的默认关闭选项 0~3
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置窗口居中
        window.setLocationRelativeTo(null);
        // 设置置顶
        window.setAlwaysOnTop(true);
        // 设置窗口没有外边框
        window.setUndecorated(true);
        // 显示窗口
        window.setVisible(true);
}

画板参数

画板/面板 JPanel
原生的 JPanel 中, 不能自定义绘画
只能画 按钮, 输入框… 等一些组件
功能加强 -> 自定义类继承 JPanel

// 1.自定义类, 来继承JPanel
class MyPanel extends JPanel {
 // 2.重写自定义绘画方法
 @Override
 public void paint(Graphics g) {
     //清除绘画内容
     super.paint(g);
     // 以下是绘画的自定义增强
     // 设置 g -> 画笔 的字体属性
     Font font = new Font("Microsoft YaHei", Font.BOLD, 20);
     g.setFont(font);
     // 设置 画笔 颜色
     /*Color c = new Color(255, 0, 0);
     g.setColor(c);*/
     // 英文可译的颜色, 在Color中直接定义好了静态常量
     g.setColor(Color.BLACK);

     g.drawString("HelloWorld", 20, 50);
     paintAirplane(g);
 }
 // 将绘画方法拆解 - 便于维护
 private void paintAirplane(Graphics g) {
     BufferedImage img = null;
     try {
         img = ImageIO.read(
                 MyPanel.class.getResourceAsStream
                         ("background.png"));
         // 继续读取其他图片
     } catch (IOException e) {
         e.printStackTrace();
     }
     // 按照图片原来大小显示
     g.drawImage(img, 100, 200, this);
     // 按照规定宽高来显示图片, 缩放
     g.drawImage(img, 100, 200, 50, 50, this);
 }

在主方法中将画板对象添加到窗口对象

public class JPanelDemo {
    public static void main(String[] args) {
        JFrame window = new JFrame();
        // 3.创建子类对象
        MyPanel p = new MyPanel();
        // 4.将画板对象添加到窗口对象中
        window.add(p);
        window.setSize(400, 600);
        window.setVisible(true);
    }
}

飞机大战

游戏可以产生小的敌机\大的敌机\小蜜蜂 -> 随机,概率
游戏打开, 鼠标单击, 游戏开始, 自动发射子弹, 英雄机跟随鼠标移动
鼠标移动到窗口外面, 游戏暂停, 鼠标移动回来, 游戏继续
子弹打击到敌机和小蜜蜂, 生命值0, 消失
敌机 撞击到英雄机, 英雄机生命值-1, 直到0时, 游戏结束
小敌机: 分数+
大敌机: 分数+ 奖励(生命值加成, 火力加成)
小蜜蜂: 奖励(生命值加成, 火力加成)

设计思路

  1. 提取对象:自己的飞机, 敌机, 小蜜蜂, 子弹
  2. 设计类
  • 子类 extends 父类

    自己的飞机: Hero——发射的子弹, int life, int 分数
    敌机: Airplane
    小蜜蜂: Bee
    子弹: Bullet - 有参的构造方法
    大敌机: BigPlane—— int 血量
    以上类中相同的成员变量, 和相同的方法, 提取出来

  • 父类: FlyingObject
    int x, int y, 图片image, int width, int height
    move() - 移动

类的实现

飞行物类

/*
    飞行物类, 所有飞行物的父类
 */
public abstract class FlyingObject {
	//		写法2
	//    protected int x;
	//    protected int y;
	//    protected BufferedImage img;
    private int x;
    private int y;
    private BufferedImage img;
    private int width;
    private int height;
	//有参构造方法,为了给子类使用,提高利用率
    protected FlyingObject(int x, int y, BufferedImage img) {
        this.img = img;
        this.width = img.getWidth();
        this.height = img.getHeight();
        this.x = x;
        this.y = y;
    }
    // 移动的方法——抽象方法
    public abstract void move();
	//成员变量都为private类型,用get/set方法获取和赋值
    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 getImg() {
        return img;
    }
    public void setImg(BufferedImage img) {
        this.img = img;
    }
    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;
    }
}

英雄机类

/*
    英雄机类 继承自 飞行物类
 */
public class Hero extends FlyingObject {
    private int life;
    private int score;
    // 自己发射的子弹, 一个或者两个
    private Bullet[] bullets;
    // 如果不想用数组
	// private ArrayList<Bullet> bullets;

//	写法2
//	public Hero(){
//        img=HeroTest.hero0;
//        x=300;
//        y=300;
//
//    }

    public Hero() {
    	//创建子类对象, 会先默认调用父类的无参构造器,因父类写了有参构造器替换了无参构造器,所以要手动调用父类的其他构造器
        super(300, 300, Main.hero0);
        life = 3;
    }
    //重写父类抽象方法
    @Override
    public void move() {
        // 切换图片
    }

    public int getLife() {
        return life;
    }
    public void setLife(int life) {
        this.life = life;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    public Bullet[] getBullets() {
        return bullets;
    }
    public void setBullets(Bullet[] bullets) {
        this.bullets = bullets;
    }
}

蜜蜂类

/*
小蜜蜂类
 */
public class Bee extends FlyingObject {
    public Bee() {
        super((int) (Math.random() * 400),
                - Main.bee.getHeight(),
                Main.bee);
    }

    @Override
    public void move() {
        // 先x变大, y变大,
        // x到最大值, x减小, y变大,
    }
}

子弹类

public class Bullet extends FlyingObject {
    public Bullet(int x, int y) {
        // 子弹的 x 和 y 不是随机的, 也不是固定的
        // 根据英雄机坐标决定
        super(x, y, Main.bullet);
    }
    @Override
    public void move() {
        // y坐标减小
    }
}

大敌机类

public class BigPlane extends FlyingObject {
    private int blood;
    public BigPlane() {
        super((int) (Math.random() * 400),
                - Main.bigplane.getHeight(),
                Main.bigplane);
        blood = 5;
    }

    @Override
    public void move() {
        // y坐标变大
    }

    public int getBlood() {
        return blood;
    }
    public void setBlood(int blood) {
        this.blood = blood;
    }
}

主类

public class Main extends JPanel {
	//图片的静态成员变量,可以通过类名.变量调用
    public static BufferedImage hero0;
    public static BufferedImage hero1;
    public static BufferedImage bee;
    public static BufferedImage bullet;
    public static BufferedImage airplane;
    public static BufferedImage bigplane;
    //静态代码块,在主方法之前,工作量大,程序最开始就一次性读取完
    static {
        try {
            hero0 = ImageIO.read(Main.class.getResourceAsStream("pic/hero0.png"));
            hero1 = ImageIO.read(Main.class.getResourceAsStream("pic/hero1.png"));
            bee = ImageIO.read(Main.class.getResourceAsStream("pic/bee.png"));
            bullet = ImageIO.read(Main.class.getResourceAsStream("pic/bullet.png"));
            airplane = ImageIO.read(Main.class.getResourceAsStream("pic/airplane.png"));
            bigplane = ImageIO.read(Main.class.getResourceAsStream("pic/bigplane.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void paint(Graphics g) {
        // 清除绘画内容
        super.paint(g);
        // 测试----
        // 画一个英雄机
        Hero hero = new Hero();
        g.drawImage(hero.getImg(), hero.getX(), hero.getY(), this);
        // 画一个小蜜蜂
        Bee bee = new Bee();
        System.out.println(bee.getX());
        // 画一个敌机
        // 画一个大敌机
        // 画一个子弹
        // 测试移动方法
        bee.move();
        System.out.println(bee.getX());
    }

    public static void main(String[] args) {
        JFrame window = new JFrame();
        window.setSize(400, 650);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 调用父类的无参构造器, 调用Main的无参构造器
        JPanel main = new Main();
        window.add(main);
        // 尽快调用paint方法
        window.setVisible(true);
    }
}

本文地址:https://blog.csdn.net/qq_40905010/article/details/107390288

《Java day09——飞机大战part1.doc》

下载本文的Word格式文档,以方便收藏与打印。