Java实现飞翔的鸟小游戏
Java实现飞翔的鸟小游戏
1.准备工作
创建一个新的Java项目命名为“飞翔的鸟”,并在src中创建一个包命名为“com.qiku.bird",在这个包内分别创建4个类命名为**“Bird”、“BirdGame”、“Column”、“Ground”,并向需要的图片**素材导入到包内。
2.代码内容
Bird类
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 / 2int 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);}}
BirdGame类
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读取到程序中的bgtry {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 画笔* */@Overridepublic 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); // 画柱子2g.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() {@Overridepublic 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() {@Overridepublic 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);// 设置不允许玩家拖动界面// 调用actiongame.action();}}
Column类
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 = 150;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);}}
}
Ground类
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;}}}
3.运行结果
相关文章:

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

Python网络请求初级篇:使用Requests库抓取和解析数据
在网络编程中,请求和接收数据是最常见的任务之一。Python的Requests库提供了丰富的功能,使得HTTP请求变得非常简单。在本文中,我们将了解如何使用Requests库发起HTTP请求,并解析返回的数据。 一、安装Requests库 首先࿰…...

详解API开发【电商平台API封装商品详情SKU数据接口开发】
1、电商API开发 RESTful API的设计 RESTful API是一种通过HTTP协议发送和接收数据的API设计风格。它基于一些简单的原则,如使用HTTP动词来操作资源、使用URI来标识资源、使用HTTP状态码来表示操作结果等等。在本文中,我们将探讨如何设计一个符合RESTfu…...

后端项目连接数据库-添加MyBatis依赖并检测是否成功
一.在pom.xml添加Mybatis相关依赖 在Spring Boot项目中,编译时会自动加载项目依赖,然后使用依赖包。 需要在根目录下pom.xml文件中添加Mybatis依赖项 <!-- Mybatis整合Spring Boot的依赖项 --> <dependency><groupId>org.mybatis.s…...

C++ CryptoPP使用RSA加解密
Crypto (CryptoPP) 是一个用于密码学和加密的 C 库。它是一个开源项目,提供了大量的密码学算法和功能,包括对称加密、非对称加密、哈希函数、消息认证码 (MAC)、数字签名等。Crypto 的目标是提供高性能和可靠的密码学工具,以满足软件开发中对…...

从实践角度深入探究数据驱动和关键字驱动测试方法!
数据驱动 数据驱动,指在软件测试领域当中的数据驱动测试(Data-Driven Testing,简称DDT)是⼀种软件测试⽅法,在不同的数据下重复执⾏相同顺序的测试步骤,测试脚本从数据源读取测试数据,⽽不使⽤…...

Unity收费对谁影响最大
Unity的收费政策对以下几类人群影响最大: 游戏开发商:Unity收费政策中最直接的影响对象就是游戏开发商。对于那些使用Unity引擎制作游戏的开发商来说,他们将需要考虑新的许可证费用和服务费用,这可能会对他们的盈利和发展产生影响…...

信号收尾.
sigaction 信号捕捉 它也是信号捕捉,不仅能处理普通信号还能处理实时信号,但我们不管实时信号 我们发现函数名和形参中结构体名一样都是sigaction,这在c/c中允许吗? 不建议,但是可以 signo你要捕捉几号信号 输入型参…...

maven 常用命令解析
目录 maven 是什么 Maven 目录结构 maven 常用命令解析 mvn clean mvn validate mvn compile mvn test mvn package mvn verify mvn install mvn site mvn deploy maven 是什么 Maven 是一个流行的项目管理和构建工具,用于帮助开发人员管理 Java 项目的…...

ESP32-Web-Server编程-JS 基础 1
ESP32-Web-Server编程-JS 基础 1 概述 前述分别在 HTML 基础 和 CSS 基础 中介绍了 HTML、CSS 的基本内容。HTML 定义了网页中包含哪些对象,CSS 定义了对象的显示样式。JavaScript(LiveScript)是一种运行于客户端的解释性脚本语言,使 HTML 页面更具动态…...
代码随想录算法训练营第23天|● 669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树 ● 总结篇
108. 将有序数组转换为二叉搜索树 简单 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 示例 1: …...
UniApp 中的 u-input 属性讲解
在 UniApp 中,u-input 是一个常用的组件,用于接收用户的输入。它具有多种属性,用于控制输入框的样式和行为。下面我将为您讲解一些常用的 u-input 属性。 基本属性 value:表示输入框的初始值,可以使用 v-model 进行双…...

解决方案:新版WPS-右键粘贴值到可见单元格没有了
WPS筛序后复制,并且粘贴到可见单元格 (如果直接粘贴数据会乱掉) 旧版WPS,右键就能出现 但是新版WPS不是在这里(方法1) 新版WPS(方法2) 视频详细教程链接:解决方案&…...
pat模拟题—7-11 两个序列的中位数
一个长度为n(n⩾1)的升序序列S,处在第2n个位置的数称为序列S的中位数(median number),例如,序列S1{10,13,14,16,18,19}的中位数是14。两个序列的中位数是它们所有元素的升序序列的中位数,例如,S2{2,4,8,9,20,21},则S1和S2的中位数是13。现有…...
Java中的i++是原子操作吗?
我们都知道i分为三步进行,分别是1:取到当前i的值,2:,3:将最终结果赋值 因此我们可通过创建两个线程,对同一个变量count,一个线程对count进行递增操作,另一个线程对count进行递减操作。每个线程…...
git commit message 书写规范
在使用 Git 提交时,遵循良好的提交消息规范可以提高代码的可读性和可维护性。以下是一些常见的 Git 提交消息书写规范: 提交消息格式:一个提交消息通常包含三个部分:标题、空行和正文。它们之间使用空行分隔。 复制 <标题>&…...
sql 注入 ctf wiki
部分转载ctf-wiki 判闭合形式: 哪个报错就是哪种 1,1’,1’‘,1’,1’(双引号带括号) 万能密码: admin’ – admin’ # admin’/* ’ or 11– ’ or 11# ’ or 11/* ) or ‘1’1– ) or (‘1’1– 数据库名: SEL…...

Flutter创建TabBar
使用TabBar和TabBarView来创建一个包含"首页"、"分类"和"我的"的TabBar。每个Tab对应一个Tab控件,TabBarView中的每个页面对应一个Widget。 1.Tab使用自定义图标和颜色 一般UI设计的图会带渐变色之类的,应该保持图片的原…...

双流网络论文精读笔记
精读视频:双流网络论文逐段精读【论文精读】_哔哩哔哩_bilibili Two-Stream Convolutional Networks for Action Recognition in Videos 传统的神经网络难以学习到物体的运动信息,双流网络则通过光流将物体运动信息抽取出来再传递给神经网络 给模型提供…...

机器人与3D视觉 Robotics Toolbox Python 一 安装 Robotics Toolbox Python
一 安装python 库 前置条件需要 Python > 3.6,使用pip 安装 pip install roboticstoolbox-python测试安装是否成功 import roboticstoolbox as rtb print(rtb.__version__)输出结果 二 Robotics Toolbox Python样例程序 加载机器人模型 加载由URDF文件定义…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...