Java实现简单飞翔小鸟游戏

一、创建新项目

首先创建一个新的项目,并命名为飞翔的鸟。

其次在飞翔的鸟项目下创建一个名为images的文件夹用来存放游戏相关图片。

用到的图片如下:0~7:

bg:

column:

gameover:

ground:

start:

然后再在项目的src文件下创建包和类如下所示:

二、游戏代码

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 = 10000;distance = 250;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;}}
}

三、运行效果

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

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

相关文章

记QListWidget中QPushButton QSS样式失效的“bug”

一、场景 有一个QListWidget的列表&#xff1b;里面存放了若干QListWidgetItem&#xff1b;每个QListWidgetItem与一个自定义类对象绑定——通过QListWidget的setItemWidget()实现。自定义对象继承于QWidget&#xff0c;且内含QPushButton。 二、bug描述 在该QListWidget的外…

Mybatis 分页查询的三种实现

Mybatis 分页查询 1. 直接在 sql 中使用 limit2. 使用 RowBounds3. 使用 Mybatis 提供的拦截器机制3.1 创建一个自定义拦截器类实现 Interceptor3.2 创建分页查询函数 与 sql3.3 编写拦截逻辑3.4 注册 PageInterceptor 到 Mybatis 拦截器链中3.5 测试 准备一个分页查询类 Data…

Clion调试QTQString看不到值问题处理

环境 Clion &#xff1a;2019.3.6 Qt &#xff1a;5.9.6&#xff08;MinGW&#xff09; 环境搭建参考&#xff1a;https://blog.csdn.net/qq_27953479/article/details/132338745 调试时QString看不到值问题处理 下载文件 qt.py : https://github.com/KDE/kdevelop/blob/…

CIS|安森美微光近红外增强相机论文解析

引言 在之前的文章中&#xff0c;我们介绍了索尼、安森美以及三星等Sensor厂家在车载领域中的技术论文&#xff0c;分析了各个厂家不同的技术路线、Sensor架构以及差异点。今天&#xff0c;笔者借豪威科技在移动端200Mega Pixels产品的技术论文&#xff0c;讲解消费级CIS传感器…

高级软件工程15本书籍

如果您想学习软件工程技能并提高您的专业知识&#xff0c;那么这里是您的最佳选择。我们有一本很棒的书&#xff0c;可以极大地增强您在软件工程方面的知识。 1&#xff09;干净的代码 Robert C. Martin 写了一本名为“干净代码&#xff1a;敏捷软件工艺手册”的书。在本书中&…

如何在WordPress中批量替换图片路径?

很多站长在使用WordPress博客或者搬家时&#xff0c;需要把WordPress文章中的图片路径进行替换来解决图片不显示的问题。总结一下WordPress图片路径批量替换的过程&#xff0c;方便有此类需求的站长们学习。 什么情况下批量替换图片路径 1、更换了网站域名 有许多网站建设初期…

面试 Java 基础八股文十问十答第二期

面试 Java 基础八股文十问十答第二期 作者&#xff1a;程序员小白条 ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 11.什么是反射&#xff1f;反射有哪些作用&#xff1f;反射在Sping中的体现 (1): 什么是反射? 反射可以在运行时获取到一个类的所有信息&#xff0c;包括(成员变量&am…

关于qiankun沙箱sandbox(面试题)

为什么要有js资源隔离机制&#xff1f; 主应用和子应用&#xff0c;相同的全局变量&#xff0c;可能会发生冲突&#xff0c;子应用和子应用之间&#xff0c;相同的全局变量&#xff0c;也可能会发生冲突。在这里我们主要指的就是window。 思路&#xff1a;打开沙箱时能够修改…

Spring中@Transactional注解

在Spring框架中&#xff0c;Transactional 是一个注解&#xff0c;用于声明事务性的方法。这个注解可以被应用在方法级别或类级别上。它提供了一种声明式的事务管理方式&#xff0c;避免了在代码中直接编写事务管理相关的代码。Transactional 注解能够将一个方法纳入到一个事务…

基于SSM的生鲜在线销售系统

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

亚马逊云科技推出新一代自研芯片

北京——2023 年12月1日 亚马逊云科技在2023 re:Invent全球大会上宣布其自研芯片家族的两个系列推出新一代&#xff0c;包括Amazon Graviton4和Amazon Trainium2&#xff0c;为机器学习&#xff08;ML&#xff09;训练和生成式人工智能&#xff08;AI&#xff09;应用等广泛的工…

Linux: 退出vim编辑模式

一、使用快捷键进行退出 1、按“Esc”键进入命令模式 当我们在vim编辑模式下输入完毕需要进行退出操作时&#xff0c;首先需要按下“Esc”键&#xff0c;将vim编辑器从插入模式或者替换模式切换到命令模式。 ESC 2、输入“:wq”保存并退出 在命令模式下&#xff0c;输入“:…

锐捷RG-UAC应用网关 前台RCE漏洞复现

0x01 产品简介 锐捷RG-UAC系列应用管理网关是锐捷自主研发的应用管理产品。 0x02 漏洞概述 锐捷RG-UAC应用管理网关 nmc_sync.php 接口处存在命令执行漏洞&#xff0c;未经身份认证的攻击者可执行任意命令控制服务器权限。 0x03 复现环境 FOFA&#xff1a;app"Ruijie-R…

JavaWeb | JavaScript基础

目录: 1.JavaScript简介2.JavaScript注释3.JavaScript语法 :变量的定义函数的定义 4.JavaScript内置对象4.1 window的作用 &#xff1a;出现提示框打开关闭窗口定时器 4.2 history的作用4.3 document的作用 &#xff1a;在网页上输出设置网页属性访问文档元素&#xff0c;特别是…

jni子线程回调java实例

背景 最近有项目需求&#xff0c;需要在jni中创建多个子线程&#xff0c;并在子线程中&#xff0c;回调java将byte[]数据上报给java处理 demo实例 关键代码 static jmethodID method_callback; jclass global_class NULL; jclass myClass NULL; JavaVM* gJavaVM NULL;ji…

6.8 Windows驱动开发:内核枚举Registry注册表回调

在笔者上一篇文章《内核枚举LoadImage映像回调》中LyShark教大家实现了枚举系统回调中的LoadImage通知消息&#xff0c;本章将实现对Registry注册表通知消息的枚举&#xff0c;与LoadImage消息不同Registry消息不需要解密只要找到CallbackListHead消息回调链表头并解析为_CM_NO…

基于Java SSM人才市场管理系统

随着人才流动的正常化以及大专院校毕业生就业人数的增长&#xff0c;人才市场的业务越来越红火。人才市场管理系统实现对人才市场业务的规范化管理。系统主要管理的信息及操作如下&#xff1a; 用人单位&#xff1a;编号、名称、联系人、电话、招聘人数、学历要求、职称要求。 …

【Java面试——基础题】

Java基础部分&#xff0c;包括语法基础&#xff0c;泛型&#xff0c;注解&#xff0c;异常&#xff0c;反射和其它&#xff08;如SPI机制等&#xff09;。 1.1 语法基础 面向对象特性&#xff1f; 封装 利用抽象数据类型将数据和基于数据的操作封装在一起&#xff0c;使其构成…

kubelet漏洞CVE-2020-8559复现与分析

首先下载源码 git clone --branch v1.17.1 --single-branch https://github.com/kubernetes/kubernetes.git 参考 移花接木&#xff1a;看CVE-2020-8559如何逆袭获取集群权限-腾讯云开发者社区-腾讯云

React Router(用法介绍)

React Router 是一个用于在 React 应用中处理路由的库。它允许你定义应用程序中的多个页面&#xff0c;并在 URL 改变时显示不同的内容。 要使用 React Router&#xff0c;你需要首先安装它&#xff1a; npm install react-router-dom然后&#xff0c;在你的应用中引入所需的…