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;
        }
    }
}

三.结果呈现

         

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/177002.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HuggingFace-利用BERT预训练模型实现中文情感分类(下游任务)

准备数据集 使用编码工具 首先需要加载编码工具&#xff0c;编码工具可以将抽象的文字转成数字&#xff0c;便于神经网络后续的处理&#xff0c;其代码如下&#xff1a; # 定义数据集 from transformers import BertTokenizer, BertModel, AdamW # 加载tokenizer token Ber…

关于AssetBundle禁用TypeTree之后的一些可序列化的问题

1&#xff09;关于AssetBundle禁用TypeTree之后的一些可序列化的问题 2&#xff09;启动Unity导入变动的资源时&#xff0c;Singleton ScriptableObject 加载不到 3&#xff09;Xcode15构建Unity 2022.3的Xcode工程&#xff0c;报错没有兼容的iPhone SDK 这是第361篇UWA技术知识…

NLP学习

参考&#xff1a;NLP发展之路I - 从词袋模型到Transformer - 知乎 (zhihu.com) NLP大致的发展历史。从最开始的词袋模型&#xff0c;到RNN&#xff0c;到Transformers和BERT&#xff0c;再到ChatGPT&#xff0c;NLP经历了一段不断精进的发展道路。数据驱动和不断完善的端到端的…

Spring+Mybatis解析

源码执行流程 通过MapperScan导入MapperScannerRegistrar类MapperScannerRegistrar类实现了ImportBeanDefinitionRegistrar接口&#xff0c;Spring启动会调MapperScannerRegistrar类中的registerBeanDefinitions方法在registerBeanDefinitions方法中注册一个MapperScannerConf…

盖雅绩效应用通过SAP认证并斩获创新方案奖

近日&#xff0c;在「不啻微芒 造炬成阳」为主题的SAP合作伙伴创新大赛上&#xff0c;盖雅工场「G移动绩效创新方案」荣获创新解决方案奖。该方案核心是一款基于SAP SuccessFactors套件及SAP BTP平台的扩展应用&#xff0c;主要针对一线人员绩效管理场景&#xff0c;借助简洁的…

国民新旅游时代,OTA们如何制胜新周期?

文 | 螳螂观察&#xff08;TanglangFin&#xff09; 作者 | 图霖 消费全面复苏的大背景下&#xff0c;旅游业正迎来预期中的拐点。 一个显著表现是&#xff0c;旅游消费正在从可选消费转化成必选消费。 国内消费者旅游需求的不降反增&#xff0c;就是最好的印证。 同程研究…

哈希表之开散列的实现

回顾与引出 我们在上一节用闭散列的开放定址法实现了哈希表。不难看出这种方法有明显的缺点&#xff1a;一旦发生哈希冲突&#xff0c;所有的冲突连在一起&#xff0c;容易产生数据“堆积”&#xff0c;即&#xff1a;不同 关键码占据了可利用的空位置&#xff0c;使得寻找某关…

秋招如何准备?有什么建议?

秋招&#xff0c;是毕业生最好的求职渠道&#xff0c;没有之一。尽管还有春招&#xff0c;社招......都不如秋招重要&#xff0c;因为秋招的机会更多..... 如何准备秋招&#xff1f; 1、简历很重要 一个好的简历&#xff0c;就是敲门砖&#xff0c;这是你跟企业HR的第一次亲…

如何使用SD-WAN提升物流供应链网络效率

案例背景 本次分享的物流供应链企业是一家国际性的大型企业&#xff0c;专注于提供全球范围内的物流和供应链解决方案。案例用户在不同国家和地区均设有多个分支机构和办公地点&#xff0c;以支持客户需求和业务运营。 在过去&#xff0c;该企业用户使用传统的MPLS网络来连接各…

【grep】从html表格中快速定位某个数据

文章目录 1 背景2 参考知识2.1 grep2.2 HTML基础语言标签 3 解决方案 1 背景 在html中是一堆表格、图片、文字什么的&#xff0c;想从表格中提取关键词为“GJC”后对应的数字&#xff0c;怎么办呢&#xff1f; 逐个打开html文件&#xff0c;“ctrlF”搜一下&#xff0c;然后复…

直线导轨在自动锁螺丝机的作用及注意事项

直线导轨在自动锁螺丝机中具有重要作用&#xff0c;可以提供精确的导向&#xff0c;使滑块能够沿固定轨迹移动&#xff0c;确保螺丝准确无误地进入螺丝孔并被锁定&#xff0c;因此&#xff0c;选择高品质的直线导轨对于自动锁螺丝机的性能和精度至关重要&#xff01;那么&#…

拿下!这些证书可以帮你职场晋升!(PMP/CSPM/NPDP)

PMP证书为项目管理道路打好基础&#xff0c;建立规划思维&#xff0c;整合思维&#xff0c;提高解决问题效率。中国也有自己的项目管理认证CSPM&#xff0c;与PMP相比难度较小&#xff0c;可用已获得的证书免考。NPDP认证拓宽视野&#xff0c;帮助项目经理提升技能。 01PMP为项…

常见树种(贵州省):006栎类

摘要&#xff1a;本专栏树种介绍图片来源于PPBC中国植物图像库&#xff08;下附网址&#xff09;&#xff0c;本文整理仅做交流学习使用&#xff0c;同时便于查找&#xff0c;如有侵权请联系删除。 图片网址&#xff1a;PPBC中国植物图像库——最大的植物分类图片库 一、麻栎 …

【狂神说】CSS3详解

目录 CSS概述什么是CSSCSS发展史快速入门CSS的三种导入方式 2 选择器2.1 基本选择器标签选择器类选择器id选择器 2.2 层次选择器2.3 结构伪类选择器2.4 属性选择器&#xff08;常用&#xff09; 3 美化网页元素3.1 为什么要美化网页3.2 字体样式3.3 文本样式 视频课程见链接&am…

口碑好的猫罐头有哪些?宠物店受欢迎的5款猫罐头推荐!

快到双十二啦&#xff01;铲屎官们是时候给家里猫主子囤猫罐头了。许多铲屎官看大促的各种品牌宣传&#xff0c;看到眼花缭乱&#xff0c;不知道选哪些猫罐头好&#xff0c;胡乱选又怕踩坑。 口碑好的猫罐头有哪些&#xff1f;作为一个经营宠物店7年的老板&#xff0c;活动期间…

c语言编程(模考2)

简答题1 从键盘输入10个数&#xff0c;统计非正数的个数&#xff0c;并且计算非正数的和 #include<stdio.h> int main() {int i,n0,sum0;int a[10];printf("请输入10个数&#xff1a;");for(i0;i<10;i){scanf("%d",&a[i]);}for(i0;i<10…

Android使用Kotlin利用Gson解析多层嵌套Json数据

文章目录 1、依赖2、解析 1、依赖 build.gradle(app)中加入 dependencies { implementation com.google.code.gson:gson:2.8.9 }2、解析 假设这是要解析Json数据 var responseStr "{"code": 200,"message": "操作成功","data&quo…

vue3 iconify 图标几种使用 并加载本地 svg 图标

iconify iconify 与 iconify/vue 使用 下载 pnpm add iconify/vue -D使用 import { Icon } from "iconify/vue";<template><Icon icon"mdi-light:home" style"color: red; font-size: 43px" /><Icon icon"mdi:home-flo…

11.6AOP

一.AOP是什么 是面向切面编程,是对某一类事情的集中处理. 二.解决的问题 三.AOP的组成 四.实现步骤 1.添加依赖(版本要对应): maven仓库链接 2.添加两个注解 3.定义切点 4.通知 5.环绕通知 五.excution表达式 六.AOP原理 1.建立在动态代理的基础上,对方法级别的拦截. 2. …

python实现鼠标实时坐标监测

python实现鼠标实时坐标监测 一、说明 使用了以下技术和库&#xff1a; tkinter&#xff1a;用于创建GUI界面。pyperclip&#xff1a;用于复制文本到剪贴板。pynput.mouse&#xff1a;用于监听鼠标事件&#xff0c;包括移动和点击。threading&#xff1a;用于创建多线程&…