Java day09-11——飞机大战

窗口参数

窗口显示 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);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
package cn.feike.shoot; import java.awt.Graphics; import java.awt.image.BufferedImage; public abstract class FlyingObject { protected double x;//物体的x坐标 protected double y;//物体的y坐标 protected double width;//物体的宽 protected double heigth;//物体的高 protected BufferedImage image;//当前正在显示的图片 protected int index = 0;//图片数组下标序号,子类中使用 protected double step;//飞行物每次(1/24秒)移动的距离 protected int life;//命 protected int state;//飞行物的状态 public static final int ACTIVE=0;//活着状态 public static final int DEAD=1;//死亡状态 public static final int REMOVE=2;//回收状态 //默认构造器 public FlyingObject() { life = 1; state = ACTIVE; } //有参构造器 public FlyingObject(double width,double heigth){ this();//调用无参数的构造器,必须写在第一行. this.x = (int)(Math.random()*(480-width)); this.y = -heigth; this.width = width; this.heigth = heigth; step = Math.random()*3+0.8;//初始化step为[0.8,3.8)之间的数 } //重写toString方法 public String toString() { return x+","+y+","+width+","+heigth+","+image; } //重写paint,方便子类对象的使用 public void paint(Graphics g) { g.drawImage(image, (int)x, (int)y, null);//绘制图片 } //飞行物移动的move方法 /** * 重构了move,方法实现播放销毁动画功能 */ public void move(){ if(state == ACTIVE){ y += step; return ; } if(state == DEAD){ //从子类对象中获取下一张照片 BufferedImage img = nextImage(); if(img == null){ state = REMOVE;//没有照片则回收 }else{ image = img;//否则把子类的图片传给image } //越界则销毁 if(y>=825){ state = REMOVE; } } } /** * 子类中必须有的方法,返回下一个要播放的照片引用, * 如果返回null表示没有可播放的照片了. */ protected abstract BufferedImage nextImage(); /** * 飞行物被打了一下 */ public void hit(){ if(life>0){ life--; } if(life==0){ state = DEAD; } } /** * 碰撞检测的方法 * 检测物体的位置是否在碰撞的范围内. * (子弹是否在飞行物的碰撞范围内) */ public boolean duang(FlyingObject obj){ //this(x,y,w,h) //obj(x,y,w,h) double x1 = this.x - obj.width; double x2 = this.x + this.width; double y1 = this.y - obj.width; double y2 = this.y + this.heigth; return x1<obj.x&&obj;.x<x2&&y1;<obj.y&&obj;.y<y2; } /** 重构FlyingObject,添加了状态检查方法 */ /** 检查飞行物死了吗 */ public boolean isDead(){ return state == DEAD; } /** 检查飞行物是否活动的 */ public boolean isActive(){ return state == ACTIVE; } /** 检查飞行是否可以被删除*/ public boolean canRemove(){ return state == REMOVE; } /** 飞行物添加"去死"方法*/ public void goDead(){ if(isActive()){ state = DEAD; } } }
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值