• java游戏制作-飞翔的鸟游戏


    一.准备工作
    首先创建一个新的Java项目命名为“飞翔的鸟”,并在src中创建一个包命名为“com.qiku.bird",在这个包内分别创建4个类命名为“Bird”、“BirdGame”、“Column”、“Ground”,并向需要的图片素材导入到包内。

    二.代码呈现
    package com.qiku.bird;
     
    import javax.imageio.ImageIO;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
     
    /*
     * 小鸟类
     * */
    public class Bird {
        int x;// 坐标
        int y;
        int width; // 宽高
        int height;
        BufferedImage image; // 图片
        BufferedImage[] images; // 小鸟所有图片
     
        public Bird() {
            // 初始化数组 保存八张图片
            images = new BufferedImage[8];
            // 使用循环结构 将小鸟所有图片 存入数组
            for (int i = 0; i < images.length; i++) {
                try {
                    images[i] = ImageIO.read(Bird.class.getResourceAsStream(i + ".png"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            image = BirdGame.bird_image;
            width = image.getWidth();
            height = image.getHeight();
            x = 120;
            y = 240;
        }
     
        // 小鸟飞翔的方法
        int index = 0;
     
        public void fly() {
            image = images[index % images.length];
            index++;
        }
     
        // h = v * t + g * t * t / 2
        int g = 6; //重力加速度
        double t = 0.15; // 下落时间
        double v = 0; // 初速度
        double h = 0; // 下落距离
     
        //小鸟下落一次
        public void down() {
            h = v * t + g * t * t / 2; // 具体下落的距离
            v = v + g * t; // 末速度 = 当前速度 + 重力加速度 * 时间
            y += (int) h;
        }
     
        // 小鸟向上飞
        public void up() {
            // 给一个 负方向的初速度
            v = -30;
        }
        /*
         * 小鸟撞地面
         * */
        public boolean hitGround(Ground ground) {
            boolean isHit = this.y + this.height >= ground.y;
            return isHit;
        }
     
        // 小鸟撞天花板
        public boolean hitCeiling() {
            boolean isHit = this.y <= 0;
            return isHit;
        }
     
        // 小鸟撞柱子
        public boolean hitColumn(Column c) {
            boolean b1 = this.x + this.width >= c.x;
            boolean b2 = this.x <= c.x + c.width;
            boolean b3 = this.y <= c.y + c.height / 2 - c.gap / 2;
            boolean b4 = this.y + this.height >= c.y + c.height / 2 + c.gap / 2;
            // 满足b1 b2表示水平方向 相撞 b1 b2 b3 同时满足 撞上柱子 b1 b2 b4 同时满足撞下柱子
            return b1 && b2 && (b3 || b4);
     
        }
     
    }

    package com.qiku.bird;
    import javax.imageio.ImageIO;
    import javax.swing.*;
     
    import java.awt.*;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
     
    /**
     * 游戏启动类
     * 使用extends 关键字 继承JPanel 画板类 ==> 于是BirdGame 就具备了画板类的功能
     */
    public class BirdGame extends JPanel {
        //    定义游戏状态
        public static final int START = 0;  // 开始
        public static final int RUNNING = 1;  // 运行
        public static final int GAME_OVER = 2;  // 结束
        // 游戏当前状态 默认0 开始状态
        int state = START;
        int score = 0; //玩家得分
     
        static BufferedImage bg = null; // 背景图片
        static BufferedImage start = null; //开始图片
        static BufferedImage ground_image = null; // 地面
        static BufferedImage bird_image = null; // 小鸟
        static BufferedImage column_image = null; // 柱子
        static BufferedImage gameOver_image = null; // game游戏
     
        // 静态代码块 一般用于加载静态资源(视频,音频,图片等)
        static {
            // 将本地的图片bg.png读取到程序中的bg
            try {
                bg = ImageIO.read(BirdGame.class.getResourceAsStream("bg.png"));
                start = ImageIO.read(BirdGame.class.getResourceAsStream("start.png"));
                ground_image = ImageIO.read(BirdGame.class.getResourceAsStream("ground.png"));
                column_image = ImageIO.read(BirdGame.class.getResourceAsStream("column.png"));
                bird_image = ImageIO.read(BirdGame.class.getResourceAsStream("0.png"));
                gameOver_image = ImageIO.read(BirdGame.class.getResourceAsStream("gameover.png"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        Ground ground;//声明地面
        Bird bird;
        Column column1;
        Column column2;
     
        // BirdGame 的构造方法
        public BirdGame() {
            bird = new Bird();
            ground = new Ground();
            column1 = new Column();
            column2 = new Column();
            // 柱子2的x坐标 = 柱子1的坐标基础上+244保持水平间距
            column2.x = column1.x + column1.distance;
     
        }
     
        /*
         * 用于在画板上绘制内容的方法
         * 想在画板上显示什么 在这个方法写就行了
         * @param g 画笔
         *  */
        @Override
     
        public void paint(Graphics g) {
            // g.fillRect(0,0,100,200); // 设置颜色落笔点 宽高
            g.drawImage(bg, 0, 0, null); // 画背景
            if (state == START) {
                g.drawImage(start, 0, 0, null);  // 开始图片
            }
            g.drawImage(column1.image, column1.x, column1.y, null); // 画柱子
            g.drawImage(column2.image, column2.x, column2.y, null); // 画柱子2
            g.drawImage(bird.image, bird.x, bird.y, null); //小鸟图片
            g.drawImage(ground.image, ground.x, ground.y, null);  // 地面图片
            if (state == GAME_OVER) {
                g.drawImage(gameOver_image, 0, 0, null); // 结束图片
     
            }
            // 画分数
            Font font = new Font("微软雅黑", Font.BOLD, 25); // 创建字体
            g.setFont(font);  // 给画笔设置字体
            g.setColor(Color.BLACK);  // 设置字体黑色颜色
            g.drawString("分数:  " + score, 30, 50);
            g.setColor(Color.WHITE);  // 设置字体白色颜色
            g.drawString("分数:  " + score, 28, 48);
        }
     
        // 判断小鸟与柱子是否相撞 游戏结束
        public boolean isGameOver() {
            boolean isHit = bird.hitGround(ground) || bird.hitCeiling() || bird.hitColumn(column1) || bird.hitColumn(column2);
            return isHit;
        }
     
     
        // 游戏流程控制的方法
        public void action() throws Exception {
            frame.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    System.out.println(e.getKeyCode());
                    if(e.getKeyCode() == 32){
                        if (state == START) {  // 如果是开始状态 单击转换运行
                            state = RUNNING;
                        }
     
                        if (state == RUNNING) {
                            bird.up(); //小鸟上升
                        }
                        if (state == GAME_OVER) {
                            bird = new Bird();
                            column1 = new Column();
                            column2 = new Column();
                            column2.x = column1.x + column1.distance;
                            score = 0;
                            state = START;
                        }
                    }
                }
            });
     
     
            // 给当前对象()添加鼠标单击事件
            this.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) { // 鼠标单击执行代码
                    if (state == START) {  // 如果是开始状态 单击转换运行
                        state = RUNNING;
                    }
     
                    if (state == RUNNING) {
                        bird.up(); //小鸟上升
                    }
                    if (state == GAME_OVER) {
                        bird = new Bird();
                        column1 = new Column();
                        column2 = new Column();
                        column2.x = column1.x + column1.distance;
                        score = 0;
                        state = START;
                    }
     
                }
            });
     
            // 死循环 {}的代码会一直反复执行
            while (true) {
                if (state == START) {
                    ground.step(); // 地面移动
                    bird.fly(); // 小鸟飞翔
                } else if (state == RUNNING) {
                    ground.step(); // 地面移动
                    column1.step(); // 柱子1移动
                    column2.step(); // 柱子2移动
                    bird.fly(); // 小鸟飞翔
                    bird.down(); // 小鸟下落
                    if (isGameOver() == true) {
                        state = GAME_OVER;
                    }
                    // 设置增加分数
                    if (bird.x == column1.x + column1.width + 1 || bird.x == column2.x + column2.width + 1) {
                        score +=5;
                    }
                }
     
                repaint(); //重画 即重新执行paint 方法
                Thread.sleep(10); //每隔10毫秒,让程序休眠一次
            }
        }
        static  JFrame frame = new JFrame();
        // main方法 - 程序的入口(即:有main方法 程序才能运行)
        public static void main(String[] args) throws Exception {
            BirdGame game = new BirdGame(); // 创建画板对象
            frame.setSize(432, 644);//设置宽高
            frame.setLocationRelativeTo(null); // 居中显示
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭窗口,同时使程序结束
            frame.setVisible(true); //设置可见性
            frame.add(game); // 将画板放到画框上
            frame.setTitle("飞翔的小鸟");// 设置标题
            frame.setResizable(false);// 设置不允许玩家拖动界面
     
            // 调用action
            game.action();
        }
     
    }

    package com.qiku.bird;
     
    import java.awt.image.BufferedImage;
     
    /*
     * 柱子类
     * */
    public class Column {
        int x;// 坐标
        int y;
        int width; // 宽高
        int height;
        BufferedImage image; // 图片
        int gap; //上下柱子之间的间隙
        int distance; //水平方向柱子之间的距离
        int min = -(1200 / 2 - 144 / 2);
        int max = 644 - 146 - 144 / 2 - 1200 / 2;
     
        public Column() {
            gap = 144;
            distance = 244;
            image = BirdGame.column_image;
            width = image.getWidth();
            height = image.getHeight();
            x = BirdGame.bg.getWidth();
            y = (int) (Math.random() * (max - min) + min);
     
        }
     
        public void step() {
            x--;
            if (x <= -width) {
                x = BirdGame.bg.getWidth();
                y = (int) (Math.random() * (max - min) + min);
            }
        }
    }
     

    package com.qiku.bird;
     
    import java.awt.image.BufferedImage;
     
    /*
    * 地面类
    * */
    public class Ground {
        int x ;// 地面坐标
        int y ;
        int width ; // 地面的宽高
        int height;
        BufferedImage image; // 地面图片
     
        public Ground(){
            image = BirdGame.ground_image;
            x = 0;
            y = BirdGame.bg.getHeight() - image.getHeight();
     
            width = image.getWidth();
            height = image.getHeight();
        }
        /*
        * 地面走一步的方法
        * */
        public void step(){
            x--;
            if(x <= 432 - width){
                x=0;
            }
        }
    }

    三.结果呈现

  • 相关阅读:
    Mac上几款免费的MySql客户端
    vulnhub blogger: 1
    (免费领源码)Java#SpringBoot#mysql高校实验室资产管理系统85189-计算机毕业设计项目选题推荐
    java继承,接口,抽象类
    关于数字类型的字符串,或者double,或者integer 相除得到百分数 并四舍五入保留两位小数的通用方法
    Promise——promise是什么?为什么要用promise?
    怎么把一个excel拆分成多个
    动力小帆船制作方法简单,电动小帆船制作方法
    【SCI征稿】2/3区智能类,仅2-3个月左右录用
    Java多线程之线程池
  • 原文地址:https://blog.csdn.net/m0_74422518/article/details/134564179