雷霆战鸟(游戏源码)

雷霆战鸟(游戏源码)

  • 前言
  相信许多刚刚接触java的萌新们,在完成java初步学习之后,都跟我一样在最后的大作业或实训上犯了难。
  (在接触到一个非常宽泛的范围之后无从下手,不知道自己想搞什么,也不知道自己能搞什么)。
  如果你抛弃了制作系统的想法,想干一票大的,搞游戏开发。那你就来对地方了!
  这里有一个现成的游戏源码,既可以打开你的思路,又能让你知道制作游戏所必须掌握的技术,以及一些可以通用的小套路。
  我并不建议你直接Ctrl A,Ctrl C,Ctrl V.因为这样你不仅得不到任何收获,而且万一我火了呢?万一我的视频及代码被你的批改老师刚好瞅见了呢?是吧!
  (如果你实在忍不住,那也请你一定要理解代码,看懂注释,再参考我的改进建议多做一些优化改动)。
  • 改进建议

游戏界面

 

游戏背景(可以采用轮换式,及到达一定时间之后更换成令一个背景)

 

背景音效

 

联机优化(这个有难度,我特别介绍一下)

在这个游戏中虽然制作了联网,但是只停留在最简单的传输数据层面及全服排名这个功能,

如果你想要挑战自己,我建议你向双人模式或多人模式努力一下,及在不同的电脑上显示

同一个画面,同时玩家可以操控不同的小鸟进行比赛。这个联机的实现难度在你自己自学联网

之后可以察觉到,嘿嘿,主要是随机数的处理十分繁琐,当时其实已经找到了解决方法,但是

。。。。。。是吧,懂得都懂。就交由学有余力的你们来解决了,哈哈哈。

 

技能升级(技能这种东西自然是多多益善)

 

苹果的规律生成

 说是苹果,其实在游戏中它就是个草莓,友友们也不用过多纠结这个。相信大家都玩过跑酷类

游戏吧,里面的金币是不是大多都是规律出现的,及一列一列或是有特定图形的一团一团出现的。

我们是不是可以将苹果由随机数生成转变为由特定类生成的呢?好了,点到为止。

 

  • 游戏源码

(每个类在对应包中的位置)

 

 

 

 

 

 

 

 

 

 

 

(源码)

 备注:图片及音频资源可以根据自己的爱好自行寻找(下面列出了几个用到的图片),另外在CSDN上有介绍插音乐所需包的下载地址及jlayer-1.0.1-1.jar的下载地址。(注意图片大小,这个是可以自己调的,方式多种,在这就不加以累述了)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

package com.bird.app;

import com.bird.main.EasyGameFrame;
import com.bird.main.GameFrame;
import com.bird.main.Music;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import javax.swing.JFrame;


/**
 * @author
 * @create
 */
public class GameApp {

    public static void main(String[] args) {
        Music music = new Music();
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MyJFrame myjframe = new MyJFrame();
                    myjframe.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

class MyJFrame extends JFrame {
    Font f = new Font("隶书",Font.PLAIN,40);
    JButton jb1,jb2,jb3,jb4,jb5;
    public MyJFrame () {
        //创建一个JLayeredPane用于分层的。
        JLayeredPane layeredPane=new JLayeredPane();
        //获取图片
        ImageIcon image=new ImageIcon("img/1.jpeg");
        //JLabel用于存放背景图片,作为背景添加到JPanel上
        JLabel jl=new JLabel(image);
        //创建JPanel,并将JLabel添加
        JPanel jp=new JPanel();
        //设置JPanel大小为背景图片大小
        jp.setBounds(0,0,image.getIconWidth(),image.getIconHeight());
        jp.add(jl);


        JLabel jLabel_title = new JLabel("雷霆战鸟(无尽版)");
        jLabel_title.setBounds(650,0,400,100);
        jLabel_title.setFont(f);


        JPanel jPanel_label = new JPanel();
        jPanel_label.setLayout(null);
        jPanel_label.setBackground(Color.cyan);
        jPanel_label.setBounds(0,0,image.getIconWidth(),100);
        jPanel_label.add(jLabel_title);

        //创建测试按钮
        jb1=new JButton("游戏说明");
        jb1.setBounds(0,75,200,75);
        jb1.setFont(f);
        jb1.setForeground(Color.RED);
        jb1.setContentAreaFilled(false);
        jb1.setBorder(null);
        jb1.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                GameRule gameRule = new GameRule();
            }
        });


        jb2=new JButton("全服排名");
        jb2.setContentAreaFilled(false);
        jb2.setBorder(null);
        jb2.setBounds(0,150,200,75);
        jb2.setFont(f);
        jb2.setForeground(Color.RED);
        jb2.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                dispose();
                Internet internet = new Internet();
            }
        });


        jb3=new JButton("演示教程");
        jb3.setContentAreaFilled(false);
        jb3.setBorder(null);
        jb3.setBounds(0,225,200,75);
        jb3.setFont(f);
        jb3.setForeground(Color.RED);
        jb3.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                dispose();
                EasyGameFrame gameFrame = new EasyGameFrame();
                gameFrame.setVisible(true);
            }
        });


        jb4=new JButton("开始游戏");
        jb4.setContentAreaFilled(false);
        jb4.setBorder(null);
        jb4.setBounds(0,300,200,75);
        jb4.setFont(f);
        jb4.setForeground(Color.RED);
        jb4.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                dispose();
                GameFrame gameFrame = new GameFrame();
                gameFrame.setVisible(true);

            }
        });

        jb5=new JButton("退出游戏");
        jb5.setContentAreaFilled(false);
        jb5.setBorder(null);
        jb5.setBounds(0,375,200,75);
        jb5.setFont(f);
        jb5.setForeground(Color.RED);
        jb5.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });


        JPanel jPanel = new JPanel();
        jPanel.setLayout(null);
        jPanel.setBackground(Color.darkGray);
        jPanel.setBounds(0,100,200,image.getIconHeight());

        jPanel.add(jb1);
        jPanel.add(jb2);
        jPanel.add(jb3);
        jPanel.add(jb4);
        jPanel.add(jb5);

        //将jp放到JLayeredPane的最底层
        layeredPane.add(jp,JLayeredPane.DEFAULT_LAYER);
        //将jb放到jp高一层的地方
        layeredPane.add(jPanel_label,JLayeredPane.MODAL_LAYER);
        layeredPane.add(jPanel,JLayeredPane.MODAL_LAYER);

        //设置窗体
        this.setLayeredPane(layeredPane);
        this.setSize(image.getIconWidth(),image.getIconHeight());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);



    }
}

 

package com.bird.app;

import com.bird.main.EasyGameFrame;
import com.bird.main.GameFrame;
import com.bird.main.Music;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import javax.swing.JFrame;


/**
 * @author
 * @create
 */
public class GameApp {

    public static void main(String[] args) {
        Music music = new Music();
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MyJFrame myjframe = new MyJFrame();
                    myjframe.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

class MyJFrame extends JFrame {
    Font f = new Font("隶书",Font.PLAIN,40);
    JButton jb1,jb2,jb3,jb4,jb5;
    public MyJFrame () {
        //创建一个JLayeredPane用于分层的。
        JLayeredPane layeredPane=new JLayeredPane();
        //获取图片
        ImageIcon image=new ImageIcon("img/1.jpeg");
        //JLabel用于存放背景图片,作为背景添加到JPanel上
        JLabel jl=new JLabel(image);
        //创建JPanel,并将JLabel添加
        JPanel jp=new JPanel();
        //设置JPanel大小为背景图片大小
        jp.setBounds(0,0,image.getIconWidth(),image.getIconHeight());
        jp.add(jl);


        JLabel jLabel_title = new JLabel("雷霆战鸟(无尽版)");
        jLabel_title.setBounds(650,0,400,100);
        jLabel_title.setFont(f);


        JPanel jPanel_label = new JPanel();
        jPanel_label.setLayout(null);
        jPanel_label.setBackground(Color.cyan);
        jPanel_label.setBounds(0,0,image.getIconWidth(),100);
        jPanel_label.add(jLabel_title);

        //创建测试按钮
        jb1=new JButton("游戏说明");
        jb1.setBounds(0,75,200,75);
        jb1.setFont(f);
        jb1.setForeground(Color.RED);
        jb1.setContentAreaFilled(false);
        jb1.setBorder(null);
        jb1.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                GameRule gameRule = new GameRule();
            }
        });


        jb2=new JButton("全服排名");
        jb2.setContentAreaFilled(false);
        jb2.setBorder(null);
        jb2.setBounds(0,150,200,75);
        jb2.setFont(f);
        jb2.setForeground(Color.RED);
        jb2.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                dispose();
                Internet internet = new Internet();
            }
        });


        jb3=new JButton("演示教程");
        jb3.setContentAreaFilled(false);
        jb3.setBorder(null);
        jb3.setBounds(0,225,200,75);
        jb3.setFont(f);
        jb3.setForeground(Color.RED);
        jb3.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                dispose();
                EasyGameFrame gameFrame = new EasyGameFrame();
                gameFrame.setVisible(true);
            }
        });


        jb4=new JButton("开始游戏");
        jb4.setContentAreaFilled(false);
        jb4.setBorder(null);
        jb4.setBounds(0,300,200,75);
        jb4.setFont(f);
        jb4.setForeground(Color.RED);
        jb4.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                dispose();
                GameFrame gameFrame = new GameFrame();
                gameFrame.setVisible(true);

            }
        });

        jb5=new JButton("退出游戏");
        jb5.setContentAreaFilled(false);
        jb5.setBorder(null);
        jb5.setBounds(0,375,200,75);
        jb5.setFont(f);
        jb5.setForeground(Color.RED);
        jb5.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });


        JPanel jPanel = new JPanel();
        jPanel.setLayout(null);
        jPanel.setBackground(Color.darkGray);
        jPanel.setBounds(0,100,200,image.getIconHeight());

        jPanel.add(jb1);
        jPanel.add(jb2);
        jPanel.add(jb3);
        jPanel.add(jb4);
        jPanel.add(jb5);

        //将jp放到JLayeredPane的最底层
        layeredPane.add(jp,JLayeredPane.DEFAULT_LAYER);
        //将jb放到jp高一层的地方
        layeredPane.add(jPanel_label,JLayeredPane.MODAL_LAYER);
        layeredPane.add(jPanel,JLayeredPane.MODAL_LAYER);

        //设置窗体
        this.setLayeredPane(layeredPane);
        this.setSize(image.getIconWidth(),image.getIconHeight());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);



    }
}

 

package com.bird.app;

import com.bird.app.GameApp;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;

import static com.bird.util.Constant.FRAM_HEIGNT;
import static com.bird.util.Constant.FRAM_WIDTH;

public class GameRule extends Frame {
    public GameRule(){
        Font f = new Font("隶书",Font.PLAIN,30);
        ImageIcon icon1=new ImageIcon("img/1.jpeg" );
        //添加JLabel 放置图片
        JLabel label1=new JLabel(icon1);
        //设置label的位置、大小,label大小为图片的大小
        label1.setBounds(0,0,icon1.getIconWidth(),icon1.getIconHeight());

        JFrame jf = new JFrame("游戏说明");
        jf.getLayeredPane().add(label1, new Integer(Integer.MIN_VALUE));

        jf.setSize(icon1.getIconWidth(),icon1.getIconHeight());
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        JPanel panelTop=new JPanel();
        panelTop=(JPanel)jf.getContentPane();

        //panel和panelTop设置透明
        panelTop.setOpaque(false);
        panel.setOpaque(false);
        //添加panel,设置大小,可视
        jf.add(panel);
        jf.setSize(icon1.getIconWidth(),icon1.getIconHeight());
        jf.setVisible(true);
        String text = "                                          游戏说明\n"
                +"游戏规则:\n"
                +"玩家通过“↑”来控制小鸟飞行高度,小鸟死亡即游戏结束\n"
                +"玩家可以通过\nA键释放无敌技能\nD键释放清屏技能\n"
                +"内置数据:\n"
                +"小鸟的初始血量:100\n(小鸟上升速度是下降速度的1/2)\n怪物血量:100 \n子弹的攻击力:25"
                ;

        // 创建一个 30 行 30 列的文本区域
        final JTextArea textArea = new JTextArea(text,30,30);
        textArea.setBackground(new Color(120,120,120));
        //设置文本域透明
        textArea.setOpaque(false);
        textArea.setForeground(Color.white);

        // 设置自动换行
        textArea.setLineWrap(true);
        // 设置文本内容不可更改
        textArea.setEditable(false);
        ;
        textArea.setFont(f);
        // 添加到内容面板
        panel.add(textArea);

        jf.setContentPane(panel);
        jf.setVisible(true);
        JButton rejb = new JButton("返回菜单");
        jf.setLayout(null);
        rejb.setBounds(1300,500,200,75);
        rejb.setFont(f);
        rejb.setForeground(Color.RED);
        rejb.setContentAreaFilled(false);
        rejb.setBorder(null);
        jf.add(rejb);
        rejb.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                dispose();
                MyJFrame myJFrame = new MyJFrame();
                myJFrame.setVisible(true);

            }
        });
    }

    class run extends Thread{
        @Override
        public void run() {
            while (true) {
                repaint();
                try {
                    Thread.sleep(33);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

 

package com.bird.app;

import com.bird.app.GameApp;
import com.bird.network.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;

import static com.bird.util.Constant.FRAM_HEIGNT;
import static com.bird.util.Constant.FRAM_WIDTH;

public class Internet extends JFrame {
    Font f = new Font("隶书",Font.PLAIN,60);
    public Internet(){
        ImageIcon icon1=new ImageIcon("img/1.jpeg" );
        //添加JLabel 放置图片
        JLabel label1=new JLabel(icon1);
        //设置label的位置、大小,label大小为图片的大小
        label1.setBounds(0,0,icon1.getIconWidth(),icon1.getIconHeight());

        JFrame jf = new JFrame("全服排名");
        jf.getLayeredPane().add(label1,new Integer(Integer.MIN_VALUE));
        jf.setSize(icon1.getIconWidth(),icon1.getIconHeight());
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        JPanel panelTop=new JPanel();
        panelTop=(JPanel)jf.getContentPane();
        //panel和panelTop设置透明
        panelTop.setOpaque(false);
        panel.setOpaque(false);
        //添加panel,设置大小,可视
        jf.add(panel);
        jf.setSize(icon1.getIconWidth(),icon1.getIconHeight());
        jf.setVisible(true);
        jf.setContentPane(panel);
        jf.setVisible(true);
        jf.setLayout(null);


        JButton jb1 = new JButton("返回菜单");
        JButton jb2 = new JButton("客户端");
        JButton jb3 = new JButton("服务端");

        jb1.setBounds(1300,800,300,100);
        jb1.setFont(f);
        jb1.setForeground(Color.RED);
        jb1.setContentAreaFilled(false);
        jb1.setBorder(null);
        jf.add(jb1);
        jb1.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                dispose();
                MyJFrame myJFrame = new MyJFrame();
                myJFrame.setVisible(true);

            }
        });

        jb2.setBounds(500,200,300,100);
        jb2.setFont(f);
        jb2.setForeground(Color.RED);
        jb2.setContentAreaFilled(false);
        jb2.setBorder(null);
        jf.add(jb2);
        jb2.addActionListener(new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed(ActionEvent e) {
                dispose();
                Client client = new Client();
                client.start();

            }
        });

        jb3.setBounds(500,400,300,100);
        jb3.setFont(f);
        jb3.setForeground(Color.RED);
        jb3.setContentAreaFilled(false);
        jb3.setBorder(null);
        jf.add(jb3);
        jb3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new Thread(){
                    @Override
                    public void run(){
                        new ServerStart().main(null);
                    }
                }.start();

            }
        });



    }

    class run extends Thread{
        @Override
        public void run() {
            while (true) {
                repaint();
                try {
                    Thread.sleep(33);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

 

package com.bird.main;

import com.bird.util.Constant;
import com.bird.util.GameUtil;

import java.awt.*;
import java.awt.image.BufferedImage;

public class Apple {

    //矩形参数
    private Rectangle rect;

    //苹果生命
    private int life = 1;
    //苹果移动速度
    private int speed = 5;
    //苹果需要的图片
    private static BufferedImage[] imgs;
    //苹果的状态
    private boolean visible;

    static {
        final int COUNT = 1;
        //类加载的时候将图片初始化
        imgs = new BufferedImage[COUNT];
        for (int i = 0; i < COUNT; i++) {
            imgs[i] = GameUtil.loadBufferedImage(Constant.APPLE_IMG[i]);
        }
    }

    //位置
    private int x, y;
    //宽度和高度
    private int width, height;

    //获得苹果的宽度和高度
    public static final int APPLE_WIDTH = imgs[0].getWidth();
    public static final int APPLE_HEIGHT = imgs[0].getHeight();

    public Apple() {

        rect = new Rectangle();

    }

    public Apple(int x, int y, int height) {
        this.x = x;
        this.y = y;
        this.height = APPLE_HEIGHT;
        this.width = APPLE_WIDTH;
    }

    public void draw(Graphics g){
        if (x < -40 || life == 0) {
            visible = false;
        }
        x -= speed;
        g.drawImage(imgs[0],x,y,null );
        rect(g);

    }

    /**
     * 绘制苹果碰撞矩形
     *
     * @return
     */
    public void rect(Graphics g) {
        int x1 = this.x;
        int y1 = this.y;
        int w1 = imgs[0].getWidth();
        g.setColor(Color.blue);
        //         g.drawRect(x1, y1, w1, height);
        setRectangle(x1, y1, w1, height);
    }

    /**
     * 苹果的碰撞矩形参数
     *
     * @return
     */
    public void setRectangle(int x, int y, int width, int height) {
        rect.x = x;
        rect.y = y;
        rect.width = width;
        rect.height = height;
    }
    //对苹果的碰撞矩形相关参数进行设置。

    public boolean isInFrame() {
        return 600 - x > 150;
    }


    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 int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    public Rectangle getRect() {
        return rect;
    }

}

 

package com.bird.main;

import java.util.ArrayList;
import java.util.List;

public class ApplePool {
    //用于管理池中所有对象的容器
    private static List<Apple> pool = new ArrayList<>();
    //池中初始的对象个数
    public static final int initCount = 16;
    //对象池中最大个数
    public static final int maxCOunt = 20;

    static {
        //初始化池中的对象
        for (int i = 0; i < initCount; i++) {
            pool.add(new Apple());
        }
    }


    /**
     * 从池中获取一个对象
     */
    public static Apple getPool(){
        int size = pool.size();
        //如果池中有对象才可以拿
        if (size > 0) {
//            System.out.println("返回了"+pool.get(size-1)+pool.get(size-1).isVisible());
            //移除并返回对象
            return pool.remove(size-1);
        }else {
            //池中没有对象了 只能new
            return new Apple();
        }
    }


    /**
     * 将对象归还容器中
     */
    public static void setPool(Apple apple){
        if (pool.size() < maxCOunt) {
            pool.add(apple);
        }
    }

}

 

package com.bird.main;

import com.bird.util.Constant;
import com.bird.util.GameUtil;

import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * 障碍物类
 */
public class Barrier {


    //矩形参数
    private Rectangle rect;

    private boolean mob = true;

    //障碍物移动速度
    private int speed = 3;
    //障碍物需要的三个图片
    private static BufferedImage[] imgs;

    //障碍物的状态
    private boolean visible;


    static {
        final int COUNT = 3;
        //类加载的时候将三个图片初始化
        imgs = new BufferedImage[COUNT];
        for (int i = 0; i < COUNT; i++) {
            imgs[i] = GameUtil.loadBufferedImage(Constant.BARRIER_IMG_PATH[i]);
        }
    }

    //位置
    private int x, y;
    //宽度和高度
    private int width, height;
    //障碍物的类型
    private int type;
    public static final int TYPE_TOP_NORMAL = 0;
    public static final int TYPE_BOTTOM_NORMAL = 2;
    public static final int TYPE_HOVER_NORMAL = 4;
    public static final int TYPE_MOBILE = 6;

    //获得障碍物的宽度和高度
    public static final int BARRIER_WIDTH = imgs[0].getWidth();
    public static final int BARRIER_HEIGHT = imgs[0].getHeight();
    public static final int BARRIER_HEAD_WIDTH = imgs[1].getWidth();
    public static final int BARRIER_HEAD_HEIGHT = imgs[1].getHeight();

    public Barrier() {

        rect = new Rectangle();

    }

    public Barrier(int x, int y, int height, int type) {
        this.x = x;
        this.y = y;
        this.height = height;
        this.type = type;
        this.width = BARRIER_WIDTH;
    }

    //根据不同的类型绘制障碍物
    public void draw(Graphics g) {
        switch (type) {
            case TYPE_TOP_NORMAL:
                drawTopNormal(g);
                break;
            case TYPE_BOTTOM_NORMAL:
                drawNormalTop(g);
                break;
            case TYPE_HOVER_NORMAL:
                drawHoverNormal(g);
                break;
            case TYPE_MOBILE:
                drawMobile(g);
                break;
        }
    }

    //绘制从上向下的障碍物
    private void drawTopNormal(Graphics g) {
        //求出所需要的障碍物的块数
        int count = (height - BARRIER_HEAD_HEIGHT) / BARRIER_HEIGHT + 1;
        //for循坏绘制障碍物
        for (int i = 0; i < count; i++) {
            g.drawImage(imgs[0], x, y + i * BARRIER_HEIGHT, null);
        }

        //绘制头
        int y = height - BARRIER_HEAD_HEIGHT;
        g.drawImage(imgs[2], x - (BARRIER_HEAD_WIDTH - BARRIER_WIDTH) / 2, y, null);
        x -= speed;
        if (x < -50) {
            visible = false;
        }
        rect(g);

    }

    //绘制从下向上的障碍物
    private void drawNormalTop(Graphics g) {
        //求出所需要的障碍物的块数
        int count = height / BARRIER_HEIGHT + 1;
        //for循环绘制障碍物
        for (int i = 0; i < count; i++) {
            g.drawImage(imgs[0], x, Constant.FRAM_HEIGNT - i * BARRIER_HEIGHT, null);
        }
        //绘制头
        int y = Constant.FRAM_HEIGNT - height;
        g.drawImage(imgs[1], x - (BARRIER_HEAD_WIDTH - BARRIER_WIDTH) / 2, y, null);
        x -= speed;
        if (x < -50) {
            visible = false;
        }
        rect(g);
    }
    //绘制中间的障碍物
    private void drawHoverNormal(Graphics g) {
        //求出所需要的障碍物的块数
        int count = (height- BARRIER_HEAD_HEIGHT)/ BARRIER_HEIGHT;
        //绘制上头
        g.drawImage(imgs[1],x,y,null);
        //for循环绘制障碍物
        for (int i = 0; i < count; i++) {
            g.drawImage(imgs[0], x, y+ BARRIER_HEAD_HEIGHT +i* BARRIER_HEIGHT, null);
        }
        rect(g);

        //绘制下头
        int y11 = y+height- BARRIER_HEAD_HEIGHT;
        g.drawImage(imgs[2],x,y11,null);
        x -= speed;
        if (x < -50) {
            visible = false;
        }
    }

    //绘制移动的障碍物
    private void drawMobile(Graphics g) {
        //求出所需要的障碍物的块数
        int count = (height- BARRIER_HEAD_HEIGHT)/ BARRIER_HEIGHT;
        //绘制上头
        g.drawImage(imgs[1],x,y,null);
        //for循环绘制障碍物
        for (int i = 0; i < count; i++) {
            g.drawImage(imgs[0], x, y+ BARRIER_HEAD_HEIGHT +i* BARRIER_HEIGHT, null);
        }
        rect(g);

        //绘制下头
        int y11 = y+height- BARRIER_HEAD_HEIGHT;
        g.drawImage(imgs[2],x,y11,null);
        x -= speed;
        if (x < -50) {
            visible = false;
        }

        if (mob) {
            y+=5;
            if (y >= 250) {
                mob=false;
            }
        }else if (!mob){
            y-=5;
            if (y <= 100) {
                mob=true;
            }
        }
    }

    /**
     * 绘制障碍物碰撞矩形
     *
     * @return
     */
    public void rect(Graphics g) {
        int x1 = this.x;
        int y1 = this.y;
        int w1 = imgs[0].getWidth();
        setRectangle(x1, y1, w1, height);
    }

    /**
     * 障碍物的碰撞矩形参数
     *
     * @return
     */
    public void setRectangle(int x, int y, int width, int height) {
        rect.x = x;
        rect.y = y;
        rect.width = width;
        rect.height = height;
    }


    //判断什么时候绘制下一组障碍物
    public boolean isInFrame() {
        return 400 - x > 150;

    }

    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 int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    public Rectangle getRect() {
        return rect;
    }
}

 

package com.bird.main;


import java.util.ArrayList;
import java.util.List;

/**
 * 为了避免反复的创建和销毁对象,使用对象池来提前创建好一些对象。
 * 使用的时候从池中获得,使用完毕后,归还
 */
public class BarrierPool {
    //用于管理池中所有对象的容器
    private static List<Barrier> pool = new ArrayList<>();
    //池中初始的对象个数
    public static final int initCount = 16;
    //对象池中最大个数
    public static final int maxCOunt = 20;

    static {
        //初始化池中的对象
        for (int i = 0; i < initCount; i++) {
            pool.add(new Barrier());
        }
    }


    /**
     * 从池中获取一个对象
     */
    public static Barrier getPool(){
        int size = pool.size();
        //如果池中有对象才可以拿
        if (size > 0) {
            //移除并返回对象
            return pool.remove(size-1);
        }else {
            //池中没有对象了 只能new
            return new Barrier();
        }
    }


    /**
     * 将对象归还容器中
     */
    public static void setPool(Barrier barrier){
        if (pool.size() < maxCOunt) {
            pool.add(barrier);
        }
    }


}

 

package com.bird.main;


import static com.bird.util.Constant.*;
import com.bird.util.GameUtil;
import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * 小鸟类
 */
public class Bird {

    //小鸟矩形对象
    private Rectangle rect;

    private Skill skill1 = new Skill(7,1);

    private Skill skill2 = new Skill(5,1);

    //小鸟的生命
    public int life = 100;

    //存放小鸟图片
    private BufferedImage[] images;

    public static final int BIRD_IMG_COUNT = 3;
    //鸟的状态
    private int state;
    public static final int STATE_NORMAL = 0;//平着飞
    public static final int STATE_UP = 1;//向上飞
    public static final int STATE_DOWN = 2;//向下飞

    //小鸟的位置
    private int x=200,y=200;


    //小鸟移动方向 上下
    private boolean up=false,down=false;

    //小鸟移动速度
    private int speed=1;


    //构造方法中对资源初始化
    public Bird() {
        images = new BufferedImage[BIRD_IMG_COUNT];
        for (int i = 0; i < BIRD_IMG_COUNT; i++) {
            images[i] = GameUtil.loadBufferedImage(BIRD_IMG[i]);
        }

        int w = images[0].getWidth();
        int h = images[0].getHeight();
        rect = new Rectangle(w,h);
    }



    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
        if(this.speed >= 8){
            this.speed = 8;
        }
    }

    //绘制小鸟
    public void draw(Graphics g) {
        setSpeed(getSpeed()+1 );  //小鸟下降加速度
        flyLogic();
        skill1.isAvailable();
        skill2.isAvailable();
        g.drawImage(images[state], x, y, null);

        //绘制小鸟的矩形

        GameUtil.drawLife(x,y,getLife(),g);
        rect.x=this.x;
        rect.y=this.y;
    }

    //技能1释放
    public void skill1_Begin(){
        skill1.begin();
    }

    //技能2释放
    public void skill2_Begin(GameMonsterLayer gameMonsterLayer, GameBarrierLayer gameBarrierLayer){
        if(!skill2.isBegin()){
            skill2.begin();
            gameBarrierLayer.restart();
            gameMonsterLayer.restart();
        }

    }
    public void skill2_Begin(GameBarrierLayer gameBarrierLayer) {
        if(!skill2.isBegin()){
            skill2.begin();
            gameBarrierLayer.restart();
        }
    }

    //控制小鸟移动方向
    public void flyLogic(){
        if (up && !down){
            setSpeed(0);
            y-=4;
            if (y<20){
                y=20;
            }
        }
        if (down && !up){
            y+=getSpeed();
            if (y>575){
                y=575;
            }
        }
        if(!down&&!up) {
            if (y>575){
                y=575;
            }
            if (y<20){
                y=20;
            }
        }
    }



    public void fly(int fly){
        switch (fly){
            case 1:
                state=1;
                up=true;
                down = false;
                break;
            case 3:
                state = 3;
                up = false;
                down = false;
            case 5:
                state=2;
                up=false;
                down = true;
                break;
        }
    }

    public Rectangle getRect() {
        return rect;
    }

    /**
     * 重新绘制小鸟的位置
     */
    public void  restartDraw(){
        skill1.skillOver();
        life=100;
        x=200;
        y=200;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }

    public Skill getSkill1() {
        return skill1;
    }

    public void setSkill1(Skill skill1) {
        this.skill1 = skill1;
    }

    public Skill getSkill2() {
        return skill2;
    }

    public void setSkill2(Skill skill2) {
        this.skill2 = skill2;
    }

}

 

package com.bird.main;

import com.bird.util.Constant;
import com.bird.util.GameUtil;

import java.awt.*;
import java.awt.image.BufferedImage;

public class Bullet {
    private int life = 1;
    //矩形参数
    private Rectangle rect;

    //子弹移动速度
    private int speed = 40 ;
    //子弹需要的图片
    private static BufferedImage[] imgs;
    //子弹的状态
    private boolean visible;

    static {
        final int COUNT = 1;
        //类加载的时候将图片初始化
        imgs = new BufferedImage[COUNT];
        for (int i = 0; i < COUNT; i++) {
            imgs[i] = GameUtil.loadBufferedImage(Constant.BULLET_IMG[i]);
        }
    }

    //位置
    private int x, y;
    //宽度和高度
    private int width, height;

    //获得子弹的宽度和高度
    public static final int BULLET_WIDTH = imgs[0].getWidth();
    public static final int BULLET_HEIGHT = imgs[0].getHeight();

    public Bullet() {

        rect = new Rectangle();

    }

    public Bullet(int x, int y, int height) {
        this.x = x;
        this.y = y;
        this.height = BULLET_HEIGHT;
        this.width = BULLET_WIDTH;
    }

    public void draw(Graphics g){
        x = speed + x;
        g.drawImage(imgs[0],x,y,null );
        if (!isInFrame()) {
            visible = false;
        }
        rect(g);
    }

    /**
     * 绘制子弹碰撞矩形
     *
     * @return
     */

    public void rect(Graphics g) {
        int x1 = this.x;
        int y1 = this.y;
        int w1 = imgs[0].getWidth();
        g.setColor(Color.blue);
        //g.drawRect(x1, y1, w1, height);
        setRectangle(x1, y1, w1, height);
    }

    /**
     * 子弹的碰撞矩形参数
     *
     * @return
     */
    public void setRectangle(int x, int y, int width, int height) {
        rect.x = x;
        rect.y = y;
        rect.width = width;
        rect.height = height;
    }

    public boolean isInFrame() {
        return x < 650;
    }


    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 int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    public Rectangle getRect() {
        return rect;
    }

    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }
}

 

package com.bird.main;

import java.util.ArrayList;
import java.util.List;

public class BulletPool {
    //用于管理池中所有对象的容器
    private static List<Bullet> pool = new ArrayList<>();
    //池中初始的对象个数
    public static final int initCount = 1;
    //对象池中最大个数
    public static final int maxCount = 1;

    static {
        //初始化池中的对象
        for (int i = 0; i < initCount; i++) {
            pool.add(new Bullet());
        }
    }


    /**
     * 从池中获取一个对象
     */
    public static Bullet getPool(){
        int size = pool.size();
        //如果池中有对象才可以拿
        if (size > 0) {
            //移除并返回对象
            return pool.remove(size-1);
        }else {
            //池中没有对象了 只能new
            return new Bullet();
        }
    }


    /**
     * 将对象归还容器中
     */
    public static void setPool(Bullet bullet){
        if (pool.size() < maxCount) {
            pool.add(bullet);
        }
    }

}

 

package com.bird.main;

import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * 云彩类
 */
public class Cloud {
    //云彩图片
    private BufferedImage img;
    //云彩速度
    private  int speed;
    //云彩的位置
    private  int x,y;

    public Cloud(){}

    public Cloud(BufferedImage img, int speed, int x, int y) {
        this.img = img;
        this.speed = speed;
        this.x = x;
        this.y = y;
    }

    public void draw(Graphics g){
        x-=speed;
        g.drawImage(img,x,y,null);
    }
    /**
     * 用于判断云彩是否飞出屏幕以外
     */
    public boolean isOutFrame(){
        if (x < -100) {
            return true;
        }
        return false;
    }

}

 

package com.bird.main;

import com.bird.util.Constant;
import com.bird.util.GameUtil;

import javax.swing.*;
import java.awt.*;
import java.io.*;

public class DisplayMessage {
    private GameTime gameTime;
    private ImageIcon[] imageIcons;

    private int txt;

    //用于储存游戏数据
    File file = new File("file\\game.txt");

    public DisplayMessage(){
        gameTime = new GameTime();
        gameTime.begin();
        imageIcons = new ImageIcon[2];
        for(int i = 0; i< 2; i++){
            imageIcons[i] = new ImageIcon(Constant.SKILL_IMAGE[i]);
        }
    }

    public void restart(){
        gameTime.begin();
    }


    public void draw(Graphics g,Bird bird){
        displayScore(g);
        displaySkillIcon(g,bird);
//        g.drawImage(imageIcon.getImage(),100,100,null);
    }

    public void displaySkillIcon(Graphics g,Bird bird){
        if(!bird.getSkill1().isAvailable()) {
            if(bird.getSkill1().isSkillRunning()){
                GameUtil.drawSkillIcon(imageIcons[0].getImage(), 50, 520, 50, 50, bird.getSkill1().runningTime(),bird.getSkill1().getSkillTime(), bird.getSkill1().getCoolingTime(), g,GameUtil.SKILL_STATE_RUNNING,"A");
                GameUtil.drawSkill2(g);
            } else {
                GameUtil.drawSkillIcon(imageIcons[0].getImage(), 50, 520, 50, 50, bird.getSkill1().runningTime(),bird.getSkill1().getSkillTime(), bird.getSkill1().getCoolingTime(), g,GameUtil.SKILL_STATE_COOLING,"A");
            }
        } else {
            GameUtil.drawSkillIcon(imageIcons[0].getImage(), 50, 520, 50, 50, bird.getSkill1().runningTime(),bird.getSkill1().getSkillTime(), bird.getSkill1().getCoolingTime(), g,GameUtil.SKILL_STATE_NORMAL,"A");
        }

        if(!bird.getSkill2().isAvailable()) {
            if(bird.getSkill2().isSkillRunning()){
                GameUtil.drawSkill1(g);
                GameUtil.drawSkillIcon(imageIcons[1].getImage(), 120, 520, 50, 50, bird.getSkill2().runningTime(),bird.getSkill2().getSkillTime(), bird.getSkill2().getCoolingTime(), g,GameUtil.SKILL_STATE_RUNNING,"D");
            } else {
                GameUtil.drawSkillIcon(imageIcons[1].getImage(), 120, 520, 50, 50, bird.getSkill2().runningTime(),bird.getSkill2().getSkillTime(), bird.getSkill2().getCoolingTime(), g,GameUtil.SKILL_STATE_COOLING,"D");
            }
        } else {
            GameUtil.drawSkillIcon(imageIcons[1].getImage(), 120, 520, 50, 50, bird.getSkill2().runningTime(),bird.getSkill2().getSkillTime(), bird.getSkill2().getCoolingTime(), g,GameUtil.SKILL_STATE_NORMAL,"D");
        }

    }

    //成绩显示
    public void displayScore(Graphics g){
        long differ = gameTime.differ();
        g.setColor(Color.white);
        g.setFont(new Font("微软雅黑", 1, 20));
        g.drawString("坚持了:" + differ + "秒", 30, 50);

        //显示最高成绩
        txt = getTxt();
        if (differ <= txt){
            g.drawString("最高成绩:" + txt , 200, 50);
        }else {
            setTxt(String.valueOf(differ));
            g.drawString("最高成绩:" + getTxt() , 200, 50);
        }
    }

    /**
     * 从文件获取数据
     * @return
     */
    public int getTxt()   {
        BufferedReader in = null;
        try {
            in = new BufferedReader(new FileReader(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        int read = 0;
        try {
            read = Integer.parseInt(in.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return read;
    }

    /**
     * 写入数据到文件
     * @param str
     */
    public void setTxt(String str)   {
        FileWriter out = null;
        try {
            out = new FileWriter(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            out.write(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public GameTime getGameTime() {
        return gameTime;
    }
}

 

package com.bird.main;

import com.bird.util.GameUtil;

import static com.bird.util.Constant.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

/**
 * 游戏的主窗口类,所有的关于游戏中绘制的内容都在此类中完成。
 */
public class EasyGameFrame extends Frame {

    //实例化gamebackGround类
    private GameBackGround gameBackGround;

    //实例化Bird类
    private Bird bird;

    //实例化monster类
    private Monster monster;

    //实例化
    private GameBarrierLayer gameBarrierLayer;
    private GameAppleLayer gameAppleLayer;
    private GameBulletLayer gameBulletLayer;


    //实例化GameFrontGround类
    private GameFrontGround gameFrontGround;
    //实例化DisplayMessage类
    private DisplayMessage displayMessage;


    //存放图片的图片
    private BufferedImage buffimg = new BufferedImage(FRAM_WIDTH,FRAM_HEIGNT,BufferedImage.TYPE_4BYTE_ABGR);


    //构造方法中初始化一些参数
    public EasyGameFrame(){
        //窗口是否可见
        setVisible(true);
        //窗口的大小
        setSize(FRAM_WIDTH,FRAM_HEIGNT);
        //窗口的标题
        setTitle(FRAM_TITLE);
        //窗口的初始化位置
        setLocation(FRAM_X,FRAM_Y);
        //窗口的大小不可改变
        setResizable(false);


        //窗口的关闭事件
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);//结束程序
            }
        });


        //初始化游戏对象
        initGame();

        new run().start();

        //添加按键监听
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                add(e);
                minu(e);
                birdSkill(e);
            }

            @Override
            public void keyReleased(KeyEvent e) {
                mine(e);
            }

        });

        //添加按键监听
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_S){
                    gameBulletLayer.logic(buffimg.getGraphics(),bird);
                }
            }
        });



    }

    //对游戏中的对象初始化
    public void initGame(){
        gameBackGround = new GameBackGround();
        bird = new Bird();
        monster = new Monster();
        gameFrontGround = new GameFrontGround();
        gameBarrierLayer = new GameBarrierLayer();
        gameAppleLayer = new GameAppleLayer();
        gameBulletLayer = new GameBulletLayer();
        displayMessage = new DisplayMessage();
    }



    class run extends Thread{
        @Override
        public void run() {
            while (true) {
                repaint();
                try {
                    Thread.sleep(40);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 所有的我们需要绘制的内容都在此方法中进行调用绘制
     */
    @Override
    public void update(Graphics g) {
        if(bird.life>=0){//
            //得到图片的画笔
            Graphics graphics = buffimg.getGraphics();

            gameBackGround.draw(graphics);
            bird.draw(graphics);
            monster.easyDraw(graphics);
            gameFrontGround.draw(graphics);
            gameBarrierLayer.draw(graphics,bird);
            gameAppleLayer.draw(graphics,bird);
            gameBulletLayer.draw(graphics,gameBarrierLayer);
            displayMessage.draw(graphics,bird);
            //一次性的将图片绘制到屏幕中
            g.drawImage(buffimg,0,0,null);
        }else {
            String over = "游戏结束";
            g.setColor(Color.red);
            g.setFont(new Font("微软雅黑",1,60));
            g.drawString(over,180,250);

            String reset = "Space Reset Game";
            g.drawString(reset,25,350);
        }
    }

    //小鸟技能释放判断
    public void birdSkill(KeyEvent e){
        if(e.getKeyCode() == KeyEvent.VK_A){
            bird.skill1_Begin();
        }
        if(e.getKeyCode() == KeyEvent.VK_D){
            bird.skill2_Begin(gameBarrierLayer);

        }
    }


    //按键
    public void add(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_UP:
                bird.fly(1);
                break;
            case KeyEvent.VK_SPACE:
                if (bird.life <= 0) {
                    restart();
                }
                break;
        }
    }



    //抬键
    public void mine(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_UP:
            case KeyEvent.VK_DOWN:
                bird.fly(3);
                break;
        }
    }
    //按键
    public void minu(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_UP:
                bird.fly(1);
                break;
            case KeyEvent.VK_DOWN:
                bird.fly(5);
                break;
        }
    }
    /**
     * 重置游戏
     */
    public void restart(){
        gameBarrierLayer.restart();
        gameAppleLayer.restart();
        gameBulletLayer.restart();
        bird.restartDraw();
        displayMessage.restart();
    }



}

 

package com.bird.main;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class GameAppleLayer {

    private GameTime gameTime;
    private Random random = new Random();
    private List<Apple> apples;
    private List<Bullet> bullets;//

    public GameAppleLayer() {
        bullets = new ArrayList<>();//
        apples = new ArrayList<>();
        gameTime = new GameTime();
    }


    //绘制苹果
    public void draw(Graphics g, Bird bird) {
        for (int i = 0; i < apples.size(); i++) {
            Apple apple = apples.get(i);
            collideBird(apple,bird);
            if (apple.isVisible()) {
                apple.draw(g);
            } else {
                Apple remove = apples.remove(i);
                ApplePool.setPool(remove);
                i--;
            }
        }

        logic(g);
    }

    public void logic(Graphics g){
        if (apples.size() == 0) {
            insert(600, 0, 30);
        } else {
            //判断最后一个障碍物是否完全进入屏幕内
            Apple last = apples.get(apples.size() - 1);
            if (last.isInFrame()) {
                ran();
                if (number < 50){
                    insert(600,50,30);
                }else if (number>450){
                    insert(600,300,30);
                }else {
                    insert(600, 150,  30);
                }

            }
        }
    }
    private int number;
    public void ran() {
        number = random.nextInt(600);
    }

    /**
     * 用于从池中获取对象,并吧参数封装成apple 存入apples数组中
     */
    public void insert(int x, int y, int num) {
        Apple top = ApplePool.getPool();
        top.setX(x);
        top.setY(y);
        top.setHeight(num);
        top.setVisible(true);
        apples.add(top);

    }

    /**
     * 判断苹果和小鸟发生碰撞
     */
    public boolean collideBird(Apple apple,Bird bird) {
        if(apple.getRect().intersects(bird.getRect())){
            if(apple.isVisible()){
                bird.setLife(bird.getLife() + 2);
                System.out.println(bird.life);
                if(bird.getLife() > 100) bird.setLife(100);
                apple.setVisible(false);
                apple.getRect().setRect(0,0,1,1);
            }

            return true;
        }
        return false;
    }


    /**
     * 用于清空苹果的池子
     */
    public void restart(){
        apples.clear();
    }




}

 

package com.bird.main;

import static com.bird.util.Constant.*;

import com.bird.util.Constant;
import com.bird.util.GameUtil;

import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * 游戏背景类
 */
public class GameBackGround {
    //背景需要的资源图片
    private BufferedImage bkimg;

    //构造器初始化资源
    public GameBackGround(){
        bkimg = GameUtil.loadBufferedImage(Constant.BK_IMG_OATH);
    }

    //绘制图片
    public void draw(Graphics g){

        //填充背景色
        g.setColor(BK_COLOR);
        g.fillRect(0,0,FRAM_WIDTH,FRAM_HEIGNT);
        g.setColor(Color.black);


        //得到图片的高度和宽度
        int height = bkimg.getHeight();
        int weight = bkimg.getWidth();
        //循环的次数
        int count = Constant.FRAM_WIDTH/weight+1;
        for (int i = 0; i < count; i++) {
            g.drawImage(bkimg,weight*i,Constant.FRAM_HEIGNT-height,null);
        }
    }
}

 

package com.bird.main;


import java.awt.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


/**
 * 游戏中障碍物层
 */
public class GameBarrierLayer {


    private Random random = new Random();

    private List<Barrier> barriers;

    public GameBarrierLayer() {
        barriers = new ArrayList<>();
    }

    //绘制障碍物
    public void draw(Graphics g, Bird bird) {
        for (int i = 0; i < barriers.size(); i++) {
            Barrier barrier = barriers.get(i);

            if (barrier.isVisible()) {
                barrier.draw(g);
            } else {
                Barrier remove = barriers.remove(i);
                BarrierPool.setPool(remove);
                i--;
            }
        }
        collideBird(bird);
        logic(g);
    }

    public void logic(Graphics g) {
        if (barriers.size() == 0) {
            ran();
            insert(600, 0, numberTop, 0);
            insert(600, 600 - numberDown, numberDown, 2);
        } else {
            //判断最后一个障碍物是否完全进入屏幕内
            Barrier last = barriers.get(barriers.size() - 1);
            if (last.isInFrame()) {
                ran();
                if (number < 50){
                    insert(600,32,440,4);
                }else if (number>450){
                    insert(600,125,200,6);
                }else {
                    insert(600, 0, numberTop, 0);
                    insert(600, 600 - numberDown, numberDown, 2);
                }

            }
        }
    }





    /**
     * 用于从池中获取对象,并吧参数封装成barrier 存入barriers数组中
     */
    public void insert(int x, int y, int num, int type) {
        Barrier top = BarrierPool.getPool();
        top.setX(x);
        top.setY(y);
        top.setHeight(num);
        top.setType(type);
        top.setVisible(true);
        barriers.add(top);
    }


    //上方障碍物高度
    private int numberTop;
    //下方障碍物高度
    private int numberDown;
    private int number;

    //产生两个100-500之间的随机高度
    public void ran() {
        numberTop = random.nextInt(400) + 100;
        numberDown = random.nextInt(400) + 100;
        number = random.nextInt(500);
        //如果管道重合,则重新随机
        if (numberTop + numberDown > 450) {
            ran();
        }
    }

    /**
     * 判断障碍物和小鸟发生碰撞
     */
    public boolean collideBird(Bird bird) {
        for (int i = 0; i < barriers.size(); i++) {
            Barrier barrier = barriers.get(i);
            //判断矩形是否相交
            if (barrier.getRect().intersects(bird.getRect())) {
                bird.life-= 100;
                //小鸟技能1释放不扣血
                if(bird.getSkill1().isSkillRunning()){
                    bird.life= bird.life + 100;
                }
            }
        }
        return false;
    }


    /**
     * 用于清空障碍物的池子
     */
    public void restart(){
        barriers.clear();
    }

    public List<Barrier> getBarriers() {
        return barriers;
    }
}

 

package com.bird.main;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;


public class GameBulletLayer {
    private GameTime gameTime;
    private List<Bullet> bullets;
    private int count = 0;

    public GameBulletLayer() {
        bullets = new ArrayList<>();
        gameTime = new GameTime();
    }

    public void draw(Graphics graphics, GameBarrierLayer barrierLayer) {
        for(int j = 0; j < barrierLayer.getBarriers().size(); j++){
            for (int i = 0; i < bullets.size(); i++) {
                Bullet bullet = bullets.get(i);
                collideBarrier(barrierLayer.getBarriers().get(j));//碰撞障碍物判断
                if (bullet.isVisible() && bullet.getLife() > 0 ) {//子弹撞击判断
                } else {
                    Bullet remove = bullets.remove(i);
                    remove.setLife(1);
                    BulletPool.setPool(remove);
                    i--;
                }
            }
        }
    }

    //绘制子弹
    public void draw(Graphics g, GameMonsterLayer gameMonsterLayer,GameBarrierLayer barrierLayer) {
        for(int j = 0; j < barrierLayer.getBarriers().size(); j++){
            for (int i = 0; i < bullets.size(); i++) {
                Bullet bullet = bullets.get(i);
                collideBarrier(barrierLayer.getBarriers().get(j));//碰撞障碍物判断
                if (bullet.isVisible() && bullet.getLife() > 0 ) {//子弹撞击判断
                } else {
                    Bullet remove = bullets.remove(i);
                    remove.setLife(1);
                    BulletPool.setPool(remove);
                    i--;
                }
            }
        }
        for(int j = 0; j < gameMonsterLayer.getMonsters().size(); j++){
            for (int i = 0; i < bullets.size(); i++) {
                Bullet bullet = bullets.get(i);
                collideMonster(gameMonsterLayer.getMonsters().get(j));//碰撞怪物判断
                if (bullet.isVisible() && bullet.getLife() > 0 ) {//子弹撞击判断
                    bullet.draw(g);
                } else {
                    Bullet remove = bullets.remove(i);
                    remove.setLife(1);
                    BulletPool.setPool(remove);
                    i--;
                }
            }
        }
//        if(count % 10 == 0){
//            count = 0;
//            logic(g,bird);
//        }

    }

    public void logic(Graphics g,Bird bird){
        if(bullets.size() == 0){
            insert(bird.getX()+20,bird.getY()+10,5);
        }
//        System.out.println("=======");

    }

    /**
     * 用于从池中获取对象,并吧参数封装成bullet 存入bullets数组中
     */
    public void insert(int x, int y, int num) {
        Bullet top = BulletPool.getPool();
        top.setX(x);
        top.setY(y);
        top.setHeight(num);
        top.setVisible(true);
        bullets.add(top);
    }

    /**
     * 判断子弹和怪兽发生碰撞
     */
    public boolean collideMonster(Monster monster) {
        for (int i = 0; i < bullets.size(); i++) {
            Bullet bullet = bullets.get(i);
            //判断矩形是否相交
            if (bullet.getRect().intersects(monster.getRect())) {
                monster.setLife(monster.getLife() - 22);
                bullet.setLife(0);
                GameFrame.music.setMonsterAttacked(true);
                return true;
            }
        }
        return false;
    }

    /**
     * 判断子弹和障碍物发生碰撞
     */
    public boolean collideBarrier(Barrier barrier) {
        for (int i = 0; i < bullets.size(); i++) {
            Bullet bullet = bullets.get(i);
            //判断矩形是否相交
            if(bullet.getRect().intersects(barrier.getRect())){
                bullet.setLife(0);
                return true;
            }
        }
        return false;
    }

    /**
     * 用于清空子弹的池子
     */
    public void restart(){
        bullets.clear();
    }


}

 

package com.bird.main;

import com.bird.util.GameUtil;

import static com.bird.util.Constant.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

/**
 * 游戏的主窗口类,所有的关于游戏中绘制的内容都在此类中完成。
 */
public class GameFrame extends Frame {

    //实例化gamebackGround类
    private GameBackGround gameBackGround;

    //实例化Bird类
    private Bird bird;
    //实例化monster类
    private Monster monster;

    //实例化
    private GameBarrierLayer gameBarrierLayer;
    private GameAppleLayer gameAppleLayer;
    private GameBulletLayer gameBulletLayer;
    private GameMonsterLayer gameMonsterLayer;

    //实例化GameFrontGround类
    private GameFrontGround gameFrontGround;
    //实例化DisplayMessage类
    private DisplayMessage displayMessage;

    public static Music music = new Music();

    //存放图片的图片
    private BufferedImage buffimg = new BufferedImage(FRAM_WIDTH,FRAM_HEIGNT,BufferedImage.TYPE_4BYTE_ABGR);


    //构造方法中初始化一些参数
    public GameFrame(){
        //窗口是否可见
        setVisible(true);
        //窗口的大小
        setSize(FRAM_WIDTH,FRAM_HEIGNT);
        //窗口的标题
        setTitle(FRAM_TITLE);
        //窗口的初始化位置
        setLocation(FRAM_X,FRAM_Y);
        //窗口的大小不可改变
        setResizable(false);
        music.start();

        //窗口的关闭事件
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);//结束程序
            }
        });


        //初始化游戏对象
        initGame();

        new run().start();

        //添加按键监听
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                add(e);
                minu(e);
                birdSkill(e);
            }

            @Override
            public void keyReleased(KeyEvent e) {
                mine(e);
            }

        });

        //添加按键监听
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_S){
                    gameBulletLayer.logic(buffimg.getGraphics(),bird);
                    music.setBird(true);
                }
            }
        });



    }

    //对游戏中的对象初始化
    public void initGame(){
        gameBackGround = new GameBackGround();
        bird = new Bird();
        monster = new Monster();
        gameFrontGround = new GameFrontGround();
        gameBarrierLayer = new GameBarrierLayer();
        gameAppleLayer = new GameAppleLayer();
        gameBulletLayer = new GameBulletLayer();
        gameMonsterLayer = new GameMonsterLayer();
        displayMessage = new DisplayMessage();
    }



    class run extends Thread{
        @Override
        public void run() {
            int millis = 33;
            while (true) {
               if(displayMessage.getGameTime().differ() == 10){
                   millis = 30;
               }
                else if(displayMessage.getGameTime().differ() == 15){
                    millis = 27;
                }
                else if(displayMessage.getGameTime().differ() == 20){
                    millis = 24;
                }
                else if(displayMessage.getGameTime().differ() == 25){
                    millis = 21;
                }
               else if(displayMessage.getGameTime().differ() == 35){
                   millis = 18;
               }
               else if(displayMessage.getGameTime().differ() == 50){
                   millis = 15;
               }
               else if(displayMessage.getGameTime().differ() == 75){
                   millis = 13;
               }
               else if(displayMessage.getGameTime().differ() == 100){
                   millis = 10;
               }

                repaint();

                try {
                    Thread.sleep(millis);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 所有的我们需要绘制的内容都在此方法中进行调用绘制
     */
    @Override
    public void update(Graphics g) {
        if(bird.life>=0){//
            //得到图片的画笔
            Graphics graphics = buffimg.getGraphics();

            gameBackGround.draw(graphics);
            bird.draw(graphics);
            gameFrontGround.draw(graphics);
            gameBarrierLayer.draw(graphics,bird);
            gameAppleLayer.draw(graphics,bird);
            gameBulletLayer.draw(graphics,gameMonsterLayer,gameBarrierLayer);
            gameMonsterLayer.draw(graphics,bird);
            displayMessage.draw(graphics,bird);
            //一次性的将图片绘制到屏幕中
            g.drawImage(buffimg,0,0,null);
        }else {
            String over = "游戏结束";
            g.setColor(Color.red);
            g.setFont(new Font("微软雅黑",1,60));
            g.drawString(over,180,250);

            String reset = "Space Reset Game";
            g.drawString(reset,25,350);
        }
    }

    //小鸟技能释放判断
    public void birdSkill(KeyEvent e){
        if(e.getKeyCode() == KeyEvent.VK_A){
            bird.skill1_Begin();
        }
        if(e.getKeyCode() == KeyEvent.VK_D){
            bird.skill2_Begin(gameMonsterLayer,gameBarrierLayer);

        }
    }


    //按键
    public void add(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_UP:
                bird.fly(1);
                break;
            case KeyEvent.VK_SPACE:
                if (bird.life <= 0) {
                    restart();
                }
                break;
        }
    }



    //抬键
    public void mine(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_UP:
            case KeyEvent.VK_DOWN:
                bird.fly(3);
                break;
        }
    }
//按键
    public void minu(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_UP:
                bird.fly(1);
                break;
            case KeyEvent.VK_DOWN:
                bird.fly(5);
                break;
        }
    }
    /**
     * 重置游戏
     */
    public void restart(){

        gameBarrierLayer.restart();
        gameAppleLayer.restart();
        gameBulletLayer.restart();
        gameMonsterLayer.restart();
        bird.restartDraw();
        displayMessage.restart();
    }



}

 

package com.bird.main;

import com.bird.util.Constant;
import com.bird.util.GameUtil;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 游戏的前景类
 */
public class GameFrontGround {

    //云彩的个数
    private static final int CLOUND_COUNT = 2;
    //存放云彩的容器
    private List<Cloud> clouds;
    //云彩的飞行速度
    private static final int CLOUNG_SPEED = 8;
    //使用到图片资源
    private BufferedImage[] img;
    //用于产生随机数
    private Random random;

    // 构造器初始化数据
    public GameFrontGround() {
        clouds = new ArrayList<>();

        img = new BufferedImage[CLOUND_COUNT];

        //容器中添加云彩的图片
        for (int i = 0; i < CLOUND_COUNT; i++) {
            img[i] = GameUtil.loadBufferedImage("img/cloud" + i + ".png");
        }
        random = new Random();

    }

    //绘制云彩
    public void draw(Graphics g) {
        logic();
        for (int i = 0; i < clouds.size(); i++) {
            clouds.get(i).draw(g);
        }
    }


    /**
     * 用于云彩的个数控制
     */
    private void logic() {
        if ((int) (500 * Math.random()) < 5) {
            Cloud cloud = new Cloud(img[random.nextInt(CLOUND_COUNT)], CLOUNG_SPEED, 600, random.nextInt(150));
            clouds.add(cloud);
        }
        for (int i = 0; i < clouds.size(); i++) {
            Cloud cloud = clouds.get(i);
            if (cloud.isOutFrame()){
                clouds.remove(i);
                i--;
            }
        }

    }
}

 

package com.bird.main;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


/**
 * 游戏中障碍物层
 */
public class GameMonsterLayer{

    private Random random = new Random();

    private List<Monster> monsters;

    public GameMonsterLayer() {
        monsters = new ArrayList<>();
    }

    //绘制障碍物
    public void draw(Graphics g, Bird bird) {
        for (int i = 0; i < monsters.size(); i++) {
            Monster monster = monsters.get(i);

            if (monster.isVisible()&& !monster.isDeath() && monster.getLife() >= 0) {
                monster.draw(g);
            }
            else if(monster.isVisible() && !monster.isDeath() && monster.getLife() < 0) {
                monster.getGt().begin();
                GameFrame.music.setMonsterDeath(true);
                monster.setDeath(true);
            }
            else if(monster.isVisible()&& monster.isDeath()) {
                monster.drawMonsterDeath(g);
            }
            else {
                Monster remove = monsters.remove(i);
                remove.setLife(100);
                MonsterPool.setPool(remove);
                i--;
            }
            monster.MonsterDeath();
        }
        collideBird(bird);
        logic(g);
    }

    public void logic(Graphics g) {
        if (monsters.size() == 0) {
            ran();
            insert(600, numberTop,number);

        } else {

            //判断最后一个障碍物是否完全进入屏幕内
            Monster last = monsters.get(monsters.size() - 1);
            if (last.isInFrame()) {
                ran();
                insert(600,numberTop,number);

            }
        }
    }


    /**
     * 用于从池中获取对象,并吧参数封装成barrier 存入barriers数组中
     */
    public void insert(int x, int y,int type) {
        Monster top = MonsterPool.getPool();
        top.setX(x);
        top.setY(y);
        top.setType(type);
        top.setDeath(false);
        top.setVisible(true);
        monsters.add(top);
    }


    //上方障碍物高度
    private int numberTop;
    //下方障碍物高度
    private int numberDown;
    private int number;

    //产生两个100-500之间的随机高度
    public void ran() {
        numberTop = random.nextInt(500);
        numberDown = random.nextInt(500);
        number = random.nextInt(4);
        //如果管道重合,则重新随机
        if (numberTop + numberDown > 450) {
            ran();
        }
    }

    /**
     * 判断障碍物和小鸟发生碰撞
     */
    public boolean collideBird(Bird bird) {
        for (int i = 0; i < monsters.size(); i++) {
            Monster monster = monsters.get(i);
            //判断矩形是否相交
            if (!bird.getSkill1().isSkillRunning()&&monster.getRect().intersects(bird.getRect())) {
                bird.life -=1;
            }
        }
        return false;
    }

    /**
     * 用于清空障碍物的池子
     */
    public void restart(){
        monsters.clear();
    }

    public List<Monster> getMonsters() {
        return monsters;
    }
}

 

package com.bird.main;

/**
 * 游戏计时器
 */
public class GameTime {

//开始
    private long beginTime;
    //结束
    private long endTime;
    //时间差
    private long differ;

    public GameTime(){
        beginTime = 0;
        endTime = 0;
    }

    public void  begin(){
        beginTime = System.currentTimeMillis();
    }
    public long differ(){
        endTime = System.currentTimeMillis();
        return differ=(endTime-beginTime)/1000;

    }

}

 

package com.bird.main;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.geom.Rectangle2D;

public class Life {//生命类
    private int x;
    private int y;
    private int width=40;

    private int height=10;

    private int life;

    public Life() {
        super();
// TODO Auto-generated constructor stub
    }

    public Life(int x, int y,int life) {

        super();

        this.life=life;

    }

    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 void draw(Graphics g){

        Graphics2D g2=(Graphics2D) g;

//画外圈

        Rectangle2D r2=new Rectangle2D.Double(x, y-height, width, height);

        g2.setColor(Color.YELLOW);

        g2.draw(r2);

//根据血量比例画血条

        Rectangle2D r=new Rectangle2D.Double(x+1, y-height+1, width*((double)life/100)-1, height-1);

        g2.setColor(Color.RED);

        g2.fill(r);

    }

}

 

package com.bird.main;

import com.bird.util.Constant;
import com.bird.util.GameUtil;


import javax.swing.*;
import java.awt.*;


/**
 * 障碍物类
 */
public class Monster {
    private int life = 100;
    //矩形参数
    private Rectangle rect;

    //death = false;假死状态,将会执行death()方法,变成真死,同时将执行死亡特效演示;
    private boolean death;

    private GameTime gt;

    private boolean mob = true;

    //怪物移动速度,应该比矩形快
    private final int speed = 5;
    //怪物物需要的三个图片

    private static final ImageIcon img1;
    private static final ImageIcon img2;
    private static final ImageIcon img3;
    private static final ImageIcon img4;
    //怪物死亡动画
    private static final ImageIcon imgd;
    //怪物的状态
    private boolean visible;


    static {
        //类加载的时候将三个图片初始化
        img1 = new ImageIcon(Constant.MONSTER_IMG_PATH[1]);//骷髅兵
        img2 = new ImageIcon(Constant.MONSTER_IMG_PATH[2]);//幽灵怪
        img3 = new ImageIcon(Constant.MONSTER_IMG_PATH[3]);//黑色飞龙
        img4 = new ImageIcon(Constant.MONSTER_IMG_PATH[5]);//说明
        imgd = new ImageIcon(Constant.MONSTER_DEATH_GIF_PATH);//死亡特效
    }

    //位置
    private int x, y;
    //宽度和高度
    private int width, height;
    //怪物的类型
    private int type;
    public static final int TYPE_TOP_NORMAL = 0;//顶部
    public static final int TYPE_BOTTOM_NORMAL = 1;//底部
    public static final int TYPE_HOVER_NORMAL = 2;//悬浮
    public static final int TYPE_MOBILE = 3;//移动

    //获得怪物的宽度和高度
    public static final int MONSTER1_WIDTH = img1.getIconWidth();//骷髅宽度
    public static final int MONSTER1_HEIGHT = img1.getIconHeight();//骷髅高度
    public static final int MONSTER2_WIDTH = img2.getIconWidth();//幽灵宽度
    public static final int MONSTER2_HEIGHT = img2.getIconHeight();//幽灵高度
    public static final int MONSTER3_WIDTH = img3.getIconWidth();//小飞龙宽度
    public static final int MONSTER3_HEIGHT = img3.getIconHeight();//小飞龙高度

    public Monster() {
        rect = new Rectangle();
        gt = new GameTime();
    }

    public Monster(int x, int y, int type) {
        this.x = x;
        this.y = y;
        this.type = type;
    }

    //根据不同的类型绘制障碍物
    public void draw(Graphics g) {
        switch (type) {
            case TYPE_TOP_NORMAL -> drawTopNormal(g);
            case TYPE_BOTTOM_NORMAL -> drawBottomNormal(g);
            case TYPE_HOVER_NORMAL -> drawHoverNormal(g);
            case TYPE_MOBILE -> drawMobile(g);
        }
    }
    //教程模式里画出一个怪物
    public void easyDraw(Graphics g) {
        g.drawImage(img3.getImage(), 500, 300 , null);
        g.drawImage(img4.getImage(), 80, 280 , null);
    }

    //绘制上面的怪物--幽灵
    private void drawTopNormal(Graphics g) {
        //for循坏绘制障碍物
        g.drawImage(img2.getImage(), x, y , null);
        x -= speed;
        if (x < 50) {
            visible = false;
        }
        rectGhost(g);
    }

    //绘制下面的怪物--骷髅
    private void drawBottomNormal(Graphics g) {
        //for循环绘制障碍物
        setY(500);
        g.drawImage(img1.getImage(), x, y , null);

        //绘制头
        x -= speed;
        if (x < -50) {
            visible = false;
        }
        rectSolder(g);
    }
    //绘制悬浮的怪物--幽灵
    private void drawHoverNormal(Graphics g) {
        g.drawImage(img2.getImage(), x, y , null);
        x -= speed;
        if (x < 50) {
            visible = false;
        }
        rectGhost(g);
    }


    //绘制移动的怪物--飞龙
    private void drawMobile(Graphics g) {
        //for循环绘制障碍物
        g.drawImage(img3.getImage(), x, y, null);
        rectDragon(g);
        x -= speed;
        if (x < -50 ) {
            visible = false;
        }

        if (mob) {
            y+=5;
            if (y >= 250) {
                mob=false;
            }
        }else if (!mob){
            y-=5;
            if (y <= 100) {
                mob=true;
            }
        }
    }

    /**
     * 绘制怪物碰撞矩形
     *
     * @return
     */
    public void rectGhost(Graphics g) {//幽灵怪
        int x1 = this.x;
        int y1 = this.y;

        GameUtil.drawLife(x,y,life,g);
        setRectangle(x1, y1, MONSTER2_WIDTH, MONSTER2_HEIGHT);
    }
    public void rectDragon(Graphics g) {//小飞龙
        int x1 = this.x;
        int y1 = this.y;

        GameUtil.drawLife(x,y,life,g);
        setRectangle(x1, y1, MONSTER3_WIDTH, MONSTER3_HEIGHT);
    }
    public void rectSolder(Graphics g) {//骷髅兵
        int x1 = this.x;
        y = 500;

        GameUtil.drawLife(x,y,life,g);
        setRectangle(x1, y, 100, 100);
    }

    /**
     * 障碍物的碰撞矩形参数
     *
     * @return
     */
    public void setRectangle(int x, int y, int width, int height) {
        rect.x = x;
        rect.y = y;
        rect.width = width;
        rect.height = height;
    }

    /**
     * 怪物的的死亡特效
     *
     * 火龙的死亡特效
     */

    public void drawMonsterDeath(Graphics g) {
        g.drawImage(imgd.getImage(), x,y+15,null);
        setRectangle(0, 0, 0, 0);
    }
    public void MonsterDeath() {
        if(gt.differ() == 1) {
            setVisible(false);
        }
    }

    public GameTime getGt() {
        return gt;
    }

    //判断什么时候绘制下一组怪物
    public boolean isInFrame() {
        return 300 - x > 150;
    }

    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 void setType(int type) {
        this.type = type;
    }

    public boolean isDeath() {
        return death;
    }

    public void setDeath(boolean death) {
        this.death = death;
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    public Rectangle getRect() {
        return rect;
    }

    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }

}

 

package com.bird.main;

import java.util.ArrayList;
import java.util.List;

/**
 * 为了避免反复的创建和销毁对象,使用对象池来提前创建好一些对象。
 * 使用的时候从池中获得,使用完毕后,归还
 */
public class MonsterPool {
    //用于管理池中所有对象的容器
    private static List<Monster> pool = new ArrayList<>();
    //池中初始的对象个数
    public static final int initCount = 16;
    //对象池中最大个数
    public static final int maxCOunt = 50;

    static {
        //初始化池中的对象
        for (int i = 0; i < initCount; i++) {
            pool.add(new Monster());
        }
    }


    /**
     * 从池中获取一个对象
     */
    public static Monster getPool(){
        int size = pool.size();
        //如果池中有对象才可以拿
        if (size > 0) {
            //移除并返回对象
            return pool.remove(size-1);
        }else {
            //池中没有对象了 只能new
            return new Monster();
        }
    }


    /**
     * 将对象归还容器中
     */
    public static void setPool(Monster monster){
        if (pool.size() < maxCOunt) {
            pool.add(monster);
        }
    }


}

 

package com.bird.main;

import com.bird.util.Constant;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;
import java.io.*;

public class Music extends Thread{
    private File file_bk_music = new File(Constant.BK_MUSIC);
    private File file_bird = new File(Constant.MUSIC_BIRD);
    private File file_monster_death = new File(Constant.MUSIC_MONSTER_DEATH);
    private File file_monster_attacked = new File(Constant.MUSIC_MONSTER_ATTACKED);
    private Player player;
    private boolean bird;
    private boolean monsterDeath;
    private boolean monsterAttacked;

    public Music() {
        bird = false;
        monsterAttacked = false;
        monsterDeath = false;
    }

    public void playBackGroundMusic(){
        try {
            player = new Player(new FileInputStream(file_bk_music));
            player.play();
        } catch (JavaLayerException e) {
            System.out.println("背景音乐播放失败");
        } catch (FileNotFoundException e) {
            System.out.println("背景音乐读取失败");
        }
        player.close();
    }

    public void bird() {
        try {
            player = new Player(new FileInputStream(file_bird));
            player.play();
        } catch (JavaLayerException e) {
            System.out.println("鸟叫播放失败");
        } catch (FileNotFoundException e) {
            System.out.println("鸟叫读取失败");
        }
        player.close();

    }

    public void monsterDeath(){
        try {
            player = new Player(new FileInputStream(file_monster_death));
            player.play();
        } catch (JavaLayerException e) {
            System.out.println("怪物死亡播放失败");
        } catch (FileNotFoundException e) {
            System.out.println("怪物死亡读取失败");
        }
        player.close();
    }

    public void monsterAttack(){
        try {
            player = new Player(new FileInputStream(file_monster_attacked));
            player.play();
        } catch (JavaLayerException e) {
            System.out.println("怪物受攻击播放失败");
        } catch (FileNotFoundException e) {
            System.out.println("怪物受攻击读取失败");
        }
        player.close();
    }

    @Override
    public void run() {
        while(true){
            if(bird){
                new Thread(){
                    @Override
                    public void run(){
                        try {
                            player = new Player(new FileInputStream(file_bird));
                            player.play();
                        } catch (JavaLayerException e) {
                            System.out.println("鸟叫播放失败");
                        } catch (FileNotFoundException e) {
                            System.out.println("鸟叫读取失败");
                        }
                        player.close();
                    }
                }.start();
                bird = false;
            }
            if(monsterDeath){
                new Thread(){
                    @Override
                    public void run(){
                        try {
                            player = new Player(new FileInputStream(file_monster_death));
                            player.play();
                        } catch (JavaLayerException e) {
                            System.out.println("怪物死亡播放失败");
                        } catch (FileNotFoundException e) {
                            System.out.println("怪物死亡读取失败");
                        }
                        player.close();
                    }
                }.start();
                monsterDeath = false;
            }
            if(monsterAttacked){
                new Thread(){
                    @Override
                    public void run(){
                        try {
                            player = new Player(new FileInputStream(file_monster_attacked));
                            player.play();
                        } catch (JavaLayerException e) {
                            System.out.println("怪物受攻击播放失败");
                        } catch (FileNotFoundException e) {
                            System.out.println("怪物受攻击读取失败");
                        }
                    }
                }.start();

                monsterAttacked = false;
            }
            System.out.println(bird);
        }

    }

    public boolean isMonsterDeath() {
        return monsterDeath;
    }

    public void setMonsterDeath(boolean monsterDeath) {
        this.monsterDeath = monsterDeath;
    }

    public boolean isMonsterAttacked() {
        return monsterAttacked;
    }

    public void setMonsterAttacked(boolean monsterAttacked) {
        this.monsterAttacked = monsterAttacked;
    }

    public boolean isBird() {
        return bird;
    }

    public void setBird(boolean bird) {
        this.bird = bird;
    }
}

 

package com.bird.main;

public class Skill {
    private GameTime gameTime;
    //冷却时间
    private int coolingTime;
    private boolean isBegin;
    private int skillTime;
    private boolean skillRunning;


    public Skill(int coolingTime,int skillTime){
        gameTime = new GameTime();
        isBegin = false;
        this.coolingTime = coolingTime;
        this.skillRunning = false;
        this.skillTime = skillTime;
    }

    /**
     * 返回技能是否可用,用于刷新状态
     */
    public boolean isAvailable(){
        long time;
        if(isBegin){//如果开始
            time = gameTime.differ();
            if (time > coolingTime){
                isBegin = false;
                System.out.println("冷却结束");
                return true;
            }
            if(time > skillTime){
                skillRunning = false;
            } else {
                System.out.println("释放中");
            }
            return false;
        }
        return true;
    }

    /**
     * 技能开始
     */
    public void begin(){
        if(!isBegin){
            gameTime.begin();
            isBegin = true;
            skillRunning = true;
            System.out.println("技能释放");
        }

    }

    public int runningTime(){
        return (int)gameTime.differ();
    }

    public int getCoolingTime() {
        return coolingTime;
    }

    public void setCoolingTime(int coolingTime) {
        this.coolingTime = coolingTime;
    }

    public boolean isBegin() {
        return isBegin;
    }

    public void setBegin(boolean begin) {
        isBegin = begin;
    }

    public int getSkillTime() {
        return skillTime;
    }

    public void setSkillTime(int skillTime) {
        this.skillTime = skillTime;
    }

    public boolean isSkillRunning() {
        return skillRunning;
    }

    public void setSkillRunning(boolean skillRunning) {
        this.skillRunning = skillRunning;
    }

    public void skillOver(){
        isBegin = false;
        skillRunning = false;
    }
}

 

package com.bird.network;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
import java.util.Vector;

public class Client extends JFrame{
    private JButton jButton;
    private JPanel jPanel;
    private JTextField jTextField_name;
    private JTextField jTextField_ip;
    private JLabel jLabel_name;
    private JLabel jLabel_ip;
    private JDialog jDialog;
    private JLabel jLabel_Err;
    private Socket socket;
    private Scanner scanner;
    private PrintStream printStream;
    private Vector<String> vector;

    public Client(){
        jButton = new JButton("确认");
        jPanel = new JPanel();
        jTextField_ip = new JTextField();
        jTextField_name = new JTextField();
        jLabel_ip = new JLabel("服务器ip");
        jLabel_name = new JLabel("用户姓名");
        jDialog = new JDialog();
        jLabel_Err = new JLabel();
        vector = new Vector<>();
    }
    public void start(){
        setLocation(600,200);
        setSize(600,600);
        setVisible(true);
        setResizable(false);

        //布局设置
        jPanel.setLocation(0,0);
        jPanel.setSize(600,600);
        jPanel.setLayout(null);

        jLabel_ip.setLocation(150,200);
        jLabel_ip.setSize(100,25);

        jLabel_name.setLocation(150,250);
        jLabel_name.setSize(100,25);

        jTextField_ip.setLocation(250,200);
        jTextField_ip.setSize(100,25);

        jTextField_name.setLocation(250,250);
        jTextField_name.setSize(100,25);

        jButton.setLocation(250,300);
        jButton.setSize(100,25);

        jLabel_Err.setLocation(70,75);
        jLabel_Err.setSize(250,25);
        jLabel_Err.setHorizontalAlignment(JLabel.CENTER);
        jDialog.setLocation(700,400);
        jDialog.setSize(400,200);
        jDialog.setLayout(null);
        jDialog.add(jLabel_Err);

        jPanel.add(jButton);
        jPanel.add(jLabel_ip);
        jPanel.add(jLabel_name);
        jPanel.add(jTextField_ip);
        jPanel.add(jTextField_name);

        add(jPanel);
        //事件监听
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if( jTextField_name.getText().length() == 0 ){
                    jLabel_Err.setText("姓名未输入");
                    jDialog.setVisible(true);
                    return;
                }

                try {
                    socket = new Socket(jTextField_ip.getText(),6666);
                } catch (IOException ex) {
                    jLabel_Err.setText("服务器未找到");
                    jDialog.setVisible(true);
                    return;
                }
                try {
                    display();
                } catch (IOException ex) {
                    jLabel_Err.setText("显示异常");
                    jDialog.setVisible(true);
                    return;
                }

            }
        });
    }

    public void display() throws IOException {
        scanner = new Scanner(socket.getInputStream());
        printStream = new PrintStream(socket.getOutputStream());
        printStream.println(jTextField_name.getText());
        printStream.println(getTxt());
        vector.clear();
        while(scanner.hasNext()){
            vector.add(scanner.nextLine());
        }
        new RankImage(vector);

    }

    public int getTxt()   {
        BufferedReader in = null;
        try {
            in = new BufferedReader(new FileReader("file\\game.txt"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        int read = 0;
        try {
            read = Integer.parseInt(in.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return read;
    }
}

 

package com.bird.network;

public class ClientStart {
    public static void main(String[] args) {
        new Client().start();
    }
}

 

package com.bird.network;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Vector;

public class RankImage extends JFrame {
    private Vector<String> vector = new Vector<>();
    private ImageIcon imageIcon = new ImageIcon("img\\ranking.png");
    private Font font = new Font("宋体",Font.BOLD,40);

    public RankImage(Vector vector){
        this.vector = vector;
        setLocation(600,100);
        setSize(600,900);
        setVisible(true);
        //窗口的关闭事件
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);//结束程序
            }
        });
    }


    @Override
    public void paint(Graphics g){
        g.drawImage(imageIcon.getImage(),0,20,null);
        g.setFont(font);
        int count;
        if(vector.size() < 10){
            count = vector.size();
        } else {
            count = 10;
        }
        for(int i = 0; i < count; i++){
            g.drawString(vector.get(i),100,180 + i * 60 );
        }
    }
}

 

package com.bird.network;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;

public class Server extends JFrame {
    private JPanel jPanel;
    private JLabel jLabel;
    private Vector<String[]> ranks;
    private JList jList;
    private JDialog jDialog;
    private JButton jButton;
    private JButton jButton_refresh;

    private Vector vector;


    private FileInputStream fileInputStream;
//    private FileOutputStream fileOutputStream;
    private PrintStream printStream;
    private PrintStream printStream_1;
    private Scanner scanner;
    private ServerSocket serverSocket;
    private Socket socket;
    private String name;
    private String score;

    public Server() throws FileNotFoundException {
        jPanel = new JPanel();
        jLabel = new JLabel();
        ranks = new Vector<>();
        jList = new JList();
        jList = new JList();
        jButton = new JButton();
        jButton_refresh = new JButton("刷新");
        vector = new Vector<>();

        scanner = new Scanner(new FileInputStream("file\\gameRanking.txt"));
    }

    public void start() throws IOException {
        setLocation(600,200);
        setSize(600,600);
        setVisible(true);
        setResizable(false);

        //组件设置
        jPanel.setLocation(0,0);
        jPanel.setSize(600,600);

        jList.setLocation(200,100);
        jList.setSize(200,400);

        jButton_refresh .setLocation(250,20);
        jButton_refresh.setSize(100,25);

        jPanel.add(jButton_refresh);
        jPanel.add(jList,BorderLayout.CENTER);
        jPanel.setLayout(new BorderLayout());
        add(jPanel);



        //从文件写入
        while(scanner.hasNext()){
            ranks.add(new String[]{scanner.next(), scanner.next()});
;        }

        ranks.sort(new Comparator<String[]>() {
            @Override
            public int compare(String[] o1, String[] o2) {
                if(Integer.parseInt(o1[1]) > Integer.parseInt(o2[1])){
                    return -1;
                } else if(Integer.parseInt(o1[1]) > Integer.parseInt(o2[1])){
                    return 0;
                } else
                    return 1;
            }
        });
        vector.clear();
        for(int i = 0; i< ranks.size(); i++){
            vector.add(String.format("用户名:%-10s     成绩:%s",ranks.get(i)[0],ranks.get(i)[1]));
        }

        jList.setListData(vector);


        jButton_refresh.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
//                try {
//                    scanner = new Scanner(new FileInputStream("file\\gameRanking.txt"));
//                } catch (FileNotFoundException ex) {
//                    throw new RuntimeException(ex);
//                }
//                ranks.clear();
//                //从文件写入
//                while(scanner.hasNext()){
//                    ranks.add(new String[]{scanner.next(), scanner.next()});
//                }
//
//                //排名
//                sort();

                jList.setListData(vector);
            }
        });

// = new PrintStream(new FileOutputStream("file\\gameRanking.txt"));
        //事件监听
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                try {
                    printStream_1 = new PrintStream("file\\gameRanking.txt");
                } catch (FileNotFoundException ex) {
                    System.out.println("最后写入文件异常");
                }
                for(int i = 0; i < ranks.size(); i++){
                    printStream_1.println(ranks.get(i)[0] +"  "+ ranks.get(i)[1]);
                }
                System.exit(0);
            }
        });

        serverSocket = new ServerSocket(6666);
        while(true){
            socket = serverSocket.accept();
            Scanner scanner1 = new Scanner(socket.getInputStream());
            printStream = new PrintStream(socket.getOutputStream());
            name = scanner1.next();
            score = scanner1.next();
            int j = 0;
            for(j = 0; j < ranks.size(); j++){
                if (ranks.get(j)[0].equals(name)) {
                    if(Integer.parseInt(score) > Integer.parseInt(ranks.get(j)[1])){
                        ranks.add(new String[]{name,score});
                        break;
                    }
                }
            }
            if(j == ranks.size()  ){
                ranks.add(new String[]{name,score});
            }
            sort();
            for(int i = 0; i < vector.size(); i++){
                printStream.println(vector.get(i));
            }
            printStream.close();
            scanner1.close();
        }
    }

    /**
     * 此方法用于将保存用户和分数的Vector ranks按分数排序后转化为一个包括用户名和分数的字符串
     */
    public void sort(){
        //排名排序设置
        ranks.sort(new Comparator<String[]>() {
            @Override
            public int compare(String[] o1, String[] o2) {
                if(Integer.parseInt(o1[1]) > Integer.parseInt(o2[1])){
                    return -1;
                } else if(Integer.parseInt(o1[1]) > Integer.parseInt(o2[1])){
                    return 0;
                } else
                    return 1;
            }
        });

        vector.clear();
        for(int i = 0; i< ranks.size(); i++){
            vector.add(String.format("用户名:%-5s成绩:%s",ranks.get(i)[0],ranks.get(i)[1]));
        }
    }
}

 

package com.bird.network;

import java.io.IOException;

public class ServerStart {
    public static void main(String[] args) {
        try {
            new Server().start();
        } catch (IOException e) {
            System.out.println("文件读取异常");
        }
    }
}

 

package com.bird.util;

import java.awt.*;
import java.util.List;

/**
 * @author
 * @create
 */
public class Constant {
    //窗口的大小
    public static final int FRAM_WIDTH= 600;
    public static final int FRAM_HEIGNT= 600;

    //窗口标题
    public static final String FRAM_TITLE= "飞翔的小鸟无尽版";

    //窗口的初始化位置
    public static final int FRAM_X= 200;
    public static final int FRAM_Y= 200;

    //背景图片
    public static final String BK_IMG_OATH = "img/bird_bk.png";

    //背景色
    public static final Color BK_COLOR = new Color(0x4BC4CF);

    //技能图标设置
    public static final String[] SKILL_IMAGE = {
            "img/skill1.png","img/skill2.png"
    };

    //小鸟图片资源
    public static final String[] BIRD_IMG={
            "img/bird_normal.png","img/bird_up.png","img/bird_down.png"
    };

    //苹果图片资源
    public static final String[] APPLE_IMG={
            "img/apple.png"
    };

    //子弹图片资源
    public static final String[] BULLET_IMG={
            "img/bullet.png"
    };

    //障碍物图片资源
    public static final String[] BARRIER_IMG_PATH ={
            "img/barrier.png","img/barrier_up.png","img/barrier_down.png"};

    //怪物图片资源
    public static final String[] MONSTER_IMG_PATH ={
            "img/monster.gif","img/monster1.gif","img/monster2.gif","img/monster3.gif","img/boss.gif","img/monster8.png"
    };
    //技能特效图片资源
    public static final String[] SKILL_IMG_PATH ={
            "img/skill0.gif","img/skill1.gif","img/skill2.gif"
    };
    public static final String MONSTER_DEATH_GIF_PATH = "img/fire.gif";
    //背景音乐路径
    public static final String BK_MUSIC  = "music/HoliznaCC0 - Puppy Love.mp3";
    //小鸟攻击音效
    public static final String MUSIC_BIRD = "sound/小鸟攻击.mp3";
    //怪物被攻击音效
    public static final String MUSIC_MONSTER_DEATH = "sound/怪物死亡.mp3";
    //怪物攻击音效
    public static final String MUSIC_MONSTER_ATTACKED = "sound/怪物死亡.mp3";

}

 

package com.bird.util;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * 游戏工具类
 */
public class GameUtil {
    private static Color colorCooling = new Color(0,0,0,200);
    private static Color colorSkill = new Color(223,227,167,200);
    private static Color color1 = new Color(242,120,75,255);
    private static Font font = new Font( "楷体",Font.BOLD,30);

    public static int SKILL_STATE_NORMAL = 1;
    public static int SKILL_STATE_RUNNING = 2;
    public static int SKILL_STATE_COOLING = 3;

    /**
     * 通过传入的数据绘制技能图标,
     *Image:图标 x,y:横纵坐标 width,height宽和高 time:技能释放了多久 skillTime:技能释放时长  AllTime:技能CD时间
     */
    public static void drawSkillIcon(Image image,int x, int y,int width, int height, int time,int skillTime,int AllTime ,Graphics graphics,int statement,String str){
        Graphics2D g2 = (Graphics2D)graphics;
        g2.setStroke(new BasicStroke(5));
        g2.setFont(font);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        if (statement == SKILL_STATE_NORMAL){
            graphics.drawImage(image,x,y,null);
            g2.setColor(Color.white);
            g2.drawOval(x,y,width,height);
            g2.setColor(Color.BLACK);
            g2.drawString(str,x+width/2-8,y+height/2+10);

        } else if(statement == SKILL_STATE_RUNNING){
            graphics.drawImage(image,x,y,null);
            g2.setColor(colorSkill);
            double percentage = 1.0-1.0*time / skillTime;
            g2.fillArc(x,y,width,height,0,(int)(360*percentage));
            g2.setColor(Color.WHITE);
            graphics.drawString(String.valueOf(skillTime - time),x+width/2-8,y+height/2+10);
            g2.setColor(Color.white);
            g2.drawOval(x,y,width,height);
            g2.setColor(color1);
            g2.drawArc(x,y,width,height,0,(int)(360*percentage));
        } else if(statement == SKILL_STATE_COOLING) {
            graphics.drawImage(image,x,y,null);
            graphics.setColor(colorCooling);
            double percentage = 1.0-1.0*(time-skillTime) / (AllTime-skillTime);
            graphics.fillArc(x,y,width,height,0,(int)(360*percentage));
            g2.setColor(Color.WHITE);
            graphics.drawString(String.valueOf(AllTime - time),x+width/2-8,y+height/2+10);
            g2.setColor(Color.white);
            g2.drawOval(x,y,width,height);
        };
    }

    /**
     * 通过传入的数据绘制技能特效,
     *Image:图标 x,y:横纵坐标 width,height宽和高 time:技能释放了多久 skillTime:技能释放时长  AllTime:技能CD时间
     */
    public static void drawSkill1(Graphics graphics){
        ImageIcon ic = new ImageIcon(Constant.SKILL_IMG_PATH[0]);
        graphics.drawImage(ic.getImage(),250,10,null);
        graphics.drawImage(ic.getImage(),250,260,null);
        graphics.drawImage(ic.getImage(),250,510,null);
        graphics.drawImage(ic.getImage(),450,10,null);
        graphics.drawImage(ic.getImage(),450,260,null);
        graphics.drawImage(ic.getImage(),450,510,null);
    }

    public static void drawSkill2(Graphics graphics){
        ImageIcon ic = new ImageIcon(Constant.SKILL_IMG_PATH[1]);
        graphics.drawImage(ic.getImage(),-50,10,null);

    }

    /**
     *该方法传入一个图片路径 读取图片
     */
    public static BufferedImage loadBufferedImage(String imgPath){
        try {
            return ImageIO.read(new FileInputStream(imgPath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 该方法绘制指定位置的血条
     */
    public static void drawLife(int x, int y, int life, Graphics graphics){
        Graphics2D g2=(Graphics2D) graphics;
        //初始化血条长和宽
        int width = 40, height = 10;

//画外圈

        Rectangle2D r2=new Rectangle2D.Double(x, y-height, width, height);

        g2.setColor(Color.YELLOW);

        g2.draw(r2);

//根据血量比例画血条

        Rectangle2D r=new Rectangle2D.Double(x+1, y-height+1, width*((double)life/100)-1, height-1);

        g2.setColor(Color.RED);

        g2.fill(r);
    }

}

 

posted @ 2022-07-17 20:11  青埃  阅读(91)  评论(1)    收藏  举报