飞翔的鸟。

news2025/1/4 17:16:27

一.准备工作
首先创建一个新的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;
        }
    }
}

三.结果呈现

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flask学习三:模型操作

ORM flask 通过Model操作数据库&#xff0c;不管你的数据库是MySQL还是Sqlite&#xff0c;flask自动帮你生成相应数据库类型的sql语句&#xff0c;所以不需要关注sql语句和类型&#xff0c;对数据的操作flask帮我们自动完成&#xff0c;只需要会写Model就可以了 flask使用对象关…

105基于matlab的阶次分析算法

基于matlab的阶次分析算法&#xff0c;用于变转速机械故障特征提取&#xff0c;可运行&#xff0c;包含寻找脉冲时刻&#xff0c;等角度时刻。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 105阶次分析变转速信号处理 (xiaohongshu.com)

Java 基础学习(十一)File类与I/O操作

1 File类 1.1 File类概述 1.1.1 什么是File类 File是java.io包下作为文件和目录的类。File类定义了一些与平台无关的方法来操作文件&#xff0c;通过调用File类中的方法可以得到文件和目录的描述信息&#xff0c;包括名称、所在路径、读写性和长度等&#xff0c;还可以对文件…

『K8S 入门』二:深入 Pod

『K8S 入门』二&#xff1a;深入 Pod 一、基础命令 获取所有 Pod kubectl get pods2. 获取 deploy kubectl get deploy3. 删除 deploy&#xff0c;这时候相应的 pod 就没了 kubectl delete deploy nginx4. 虽然删掉了 Pod&#xff0c;但是这是时候还有 service&#xff0c…

时序预测 | Python实现CNN-LSTM电力需求预测

时序预测 | Python实现CNN-LSTM电力需求预测 目录 时序预测 | Python实现CNN-LSTM电力需求预测预测效果基本描述程序设计参考资料预测效果 基本描述 该数据集因其每小时的用电量数据以及 TSO 对消耗和定价的相应预测而值得注意,从而可以将预期预测与当前最先进的行业预测进行比…

C语言:猜数字游戏

#include<stdio.h> #include<time.h> #include<stdlib.h> void menu() {printf("********************************\n");printf("****** 1.开始 2.退出 ******\n");printf("********************************\n"); } voi…

【Linux】驱动

驱动 驱动程序过程 系统调用 用户空间 内核空间 添加驱动和调用驱动 驱动程序是如何调用设备硬件 驱动 在计算机领域&#xff0c;驱动&#xff08;Driver&#xff09;是一种软件&#xff0c;它充当硬件设备与操作系统之间的桥梁&#xff0c;允许它们进行通信和协同工作。驱动程…

基于linux系统的Tomcat+Mysql+Jdk环境搭建(三)centos7 安装Tomcat

Tomcat下载官网&#xff1a; Apache Tomcat - Which Version Do I Want? JDK下载官网&#xff1a; Java Downloads | Oracle 中国 如果不知道Tomcat的哪个版本应该对应哪个版本的JDK可以打开官网&#xff0c;点击Whitch Version 下滑&#xff0c;有低版本的&#xff0c;如…

Android studio中文汉化教程

相比于jetbrains的软件直接在软件内搜索chinese 就可以找到中文包相比&#xff0c;Android studio需要手动安装&#xff0c;接下来就给大家介绍下如何汉化 一、确认版本号 根据版本下载对应的中文汉化包&#xff0c;如果安装的汉化包版本不对应&#xff0c;可能会导致安装失败。…

前端视角看 Docker :在国内的基础配置教程(含国内镜像源)

引言 在国内使用Docker时&#xff0c;直接从Docker Hub拉取镜像可能会遇到网络速度慢的问题。配置国内的镜像加速器可以显著提升拉取速度。本教程将指导您完成安装Docker后的基础配置&#xff0c;特别是设置国内镜像加速器。 1. 安装Docker 确保您已在系统上安装Docker。根…

LCR 180. 文件组合

解题思路&#xff1a; 利用滑动窗口 class Solution {public int[][] fileCombination(int target) {int i 1; // 滑动窗口的左边界int j 1; // 滑动窗口的右边界int sum 0; // 滑动窗口中数字的和List<int[]> res new ArrayList<>();while (i < target / …

Kafka-Kafka核心参数详解

Kafka的HighLevel API使用是非常简单的&#xff0c;所以梳理模型时也要尽量简单化&#xff0c;主线清晰&#xff0c;细节慢慢扩展。 Kafka提供了两套客户端API&#xff0c;HighLevel API和LowLevel API。 HighLevel API封装了kafka的运行细节&#xff0c;使用起来比较简单&…

基于JavaEE智能实时疫情监管服务平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

ES6 面试题 | 02.精选 ES6 面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

springMVC-Restful风格

基本介绍 REST&#xff1a;即Representational State Transfer。&#xff08;资源&#xff09;表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便&#xff0c;所以正得到越来越多网站的采用. 1.HTTP协议里面&#xff0c;四个表示操…

网络入门---守护进程

目录标题 什么是守护进程会话的理解setsid函数daemonSelf函数模拟实现测试 什么是守护进程 在前面的学习过程中我们知道了如何使用TCP协议和UDP协议来实现通信&#xff0c;比如说登录xshell运行了服务端&#xff1a; 然后再登录一个xshell运行客户端并向服务端发送信息&#…

C#基础知识 - 基本语法篇

C#基础知识-基本语法篇 第2节 C#基本语法2.1 C#程序结构2.2 C# 结构解析2.3 命名空间及标识符、关键字2.3.1 别名的使用2.3.2 标识符2.3.3 C#关键字 更多C#基础知识详解请查看&#xff1a;C#基础知识 - 从入门到放弃 第2节 C#基本语法 2.1 C#程序结构 “Hello, World”程序历…

CSS复合选择器(在基础选择器上元素选择的方式不同)

后代选择器&#xff1a; ------------ 此情况下&#xff0c;红色的可以划去 子&#xff08;元素&#xff09;选择器&#xff1a; 并集选择器&#xff1a; 伪类选择器&#xff1a; 如放上字符会变色。 链接伪类选择器&#xff1a; foucus伪类选择器&#xff1a;

时序预测 | Python实现LSTM-Attention电力需求预测

时序预测 | Python实现LSTM-Attention电力需求预测 目录 时序预测 | Python实现LSTM-Attention电力需求预测预测效果基本描述程序设计参考资料预测效果 基本描述 该数据集因其每小时的用电量数据以及 TSO 对消耗和定价的相应预测而值得注意,从而可以将预期预测与当前最先进的行…

AutoSAR(基础入门篇)1.3-AutoSAR的概述

目录 一、到底什么是AutoSAR 1、大白话来讲 2、架构上来讲 应用软件层(APPL) 实时运行环境&#xff08;RTE&#xff09; 基础软件层(BSW) 3、工具链上来讲 二、AutoSAR的目标 一、到底什么是AutoSAR 1、大白话来讲 AUTOSAR 就是AUTomotive Open System ARchitecture的…