JAVA实现flappy bird游戏

图片素材

实现代码

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.io.IOException;public class BackGroundView extends JPanel {BufferedImage bgImage; //背景图片BufferedImage groundImg;//地面图片BufferedImage imgStart;//开始游戏图片BufferedImage imgEnd;//GameOVer图片public int bg_width;//背景图片宽度public int bg_height;//背景图片高度public int ground_width;//地面图片宽度public int ground_height;//地面图片高度public int ground_x,ground_y;//地面绘制起始坐标public int speed = 0;//管道和地面移动的速度public int state = 0;//游戏状态,0表示未开始,1表示正在玩,2表示GameOverpublic static final int MOVE_SPEED1 = 50;// 地面及柱子移动初始速度,当积分累加,速度会递增public static final int jframeWidth = 432;//窗口宽度(bg.png宽度)public static final int jframeHeight = 644;//窗口高度(bg.png高度)public static final String PATH_PIC = "\\pictures\\";public static final String PATH_BG = PATH_PIC + "bg.png";//背景图片路径public static final String PATH_GROUND = PATH_PIC + "ground.png";public static final String PATH_IMGSTART = PATH_PIC + "start.png";public static final String PATH_IMGEND = PATH_PIC + "gameover.png";public static final int FONT_SIZE = 30;//得分字体大小public static final int SCORE_X = 20;public static final int SCORE_Y = 40;public int score;public JFrame jframeMain;public GameBoard gameBoard;public Bird bird;public Pipe pipe1,pipe2;public BackGroundView(){initFrame();//初始化窗口}public void initFrame(){jframeMain = new JFrame("Flappy Bird");jframeMain.setSize(jframeWidth, jframeHeight);jframeMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jframeMain.setLocationRelativeTo(null);//居中显示jframeMain.setResizable(false);//窗口Size固定gameBoard = new GameBoard();//初始化内部类GameBoardjframeMain.add(gameBoard);Thread moveAll = new Thread(gameBoard);moveAll.start();}//游戏面板class GameBoard extends JPanel implements Runnable{public GameBoard(){initGame();//初始化游戏}public void initGame(){//原则:先加载后绘制try{//1、加载背景图片bgImage = ImageIO.read(this.getClass().getResource(PATH_BG));//根据当前路径加载图片进内存//获取图片宽度与高度bg_width = bgImage.getWidth();bg_height = bgImage.getHeight();System.out.println("bg_width:" + bg_width + ",bg_height:" + bg_height);//2、加载地面图片,注意大的图片要先加载,否则会遮住之前加载的groundImg = ImageIO.read(this.getClass().getResource(PATH_GROUND));ground_width = groundImg.getWidth();ground_height = groundImg.getHeight();ground_x = 0;ground_y = bg_height - ground_height;System.out.println("ground_width:" + ground_width + ",ground_height:" + ground_height);System.out.println("ground_x:" + ground_x + ",ground_y:" + ground_y);//3、加载开始和结束图片imgStart = ImageIO.read(this.getClass().getResource(PATH_IMGSTART));imgEnd = ImageIO.read(this.getClass().getResource(PATH_IMGEND));//4、加载小鸟图片,并在绘制中绘制小鸟,在run中让小鸟飞动bird = new Bird();//5、加载管道图片,一个窗口中最多显示两个管道pipe1 = new Pipe(bg_width, bg_height, ground_height);pipe1.x = bg_width;//第一根管道位置pipe2 = new Pipe(bg_width, bg_height, ground_height);pipe2.x = bg_width + Pipe.PIPE_DISTANCE;//第二跟管道位置}catch (IOException e){ }//3、让地面移动speed = MOVE_SPEED1;//速度初始化}@Overridepublic void run() {action();//处理键盘事件//移动while(true){try{if (state == 0) {groundMove();//地面移动,初始化窗口未开始游戏地面和小鸟就要动bird.fly();//小鸟飞动}else if (state == 1){groundMove();//地面移动,初始化窗口未开始游戏地面和小鸟就要动bird.fly();//小鸟飞动bird.down();//仅游戏开始时下降pipe1.move();//让两根管子动起来pipe2.move();//小鸟撞到地面,天空,柱子都GameOverif (bird.hitPipe(pipe1) || bird.hitPipe(pipe2) || bird.hitGround(bg_height, ground_height) || bird.hitSky()){state = 2;}else {if (bird.addScore(pipe1) || bird.addScore(pipe2)){//每次通过一个得分加10分,速度也增加score += 10;speed += 2;}}}else if (state == 2){}Thread.sleep(1000 / speed);//speed越大线程休眠时间越少,执行次数越多,速度就越快this.repaint();//刷新,会自动重新调用paint()方法}catch (InterruptedException e){ }}}public void groundMove(){ground_x--;//地面左移,可以实现小鸟右移if (ground_x == bg_width - ground_width + 9){//9为修正值,自己调的,保证移动更流畅ground_x = 0;}}public void action(){//设置监听事件this.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {super.mouseClicked(e);switch(state){case 0://游戏未开始点击,就切换为开始游戏state = 1;bird.x = Bird.BIRD_FLY_X;bird.y = Bird.BIRD_FLY_Y;break;case 1://游戏开始bird.up();//游戏中点击就是上升break;case 2://切换到未开始状态,得分清零,小鸟与管道位置重置state = 0;score = 0;bird.x = Bird.BIRD_X;bird.y = Bird.BIRD_Y;pipe1.x = bg_width;pipe2.x = bg_width + Pipe.PIPE_DISTANCE;break;default:break;}}});}@Overridepublic void paint(Graphics g) {super.paint(g);//System.out.println("paint方法被调用时间:" + getCurrentTime());g.drawImage(bgImage,0,0,null);//绘制背景if (state == 0){//游戏未开始g.drawImage(imgStart,0,0,null);g.drawImage(bird.img, bird.x, bird.y, null);}else if (state == 1){//游戏开始g.drawImage(bird.img, bird.x, bird.y, null);//点击开始后,初始坐标也同时变g.drawImage(pipe1.img, pipe1.x, pipe1.y, null);g.drawImage(pipe2.img, pipe2.x, pipe2.y, null);}else if (state == 2){//游戏结束g.drawImage(imgEnd,0,0,null);}g.drawImage(groundImg , ground_x, ground_y, null);//绘制地面//绘制分数Graphics2D gg = (Graphics2D) g;Font scoreFont = new Font("微软雅黑", Font.BOLD, FONT_SIZE);//得分字体//下面两句是抗锯齿模式,消除文字锯齿,字体更清晰顺滑gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);gg.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);gg.setFont(scoreFont);gg.setColor(Color.WHITE);gg.drawString("" + score, SCORE_X, SCORE_Y);}//当前时间public String getCurrentTime() {Date day = new Date();SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");return df.format(day);}}public void showView(){jframeMain.setVisible(true);}
}
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;//小鸟类
public class Bird {public static final int BIRD_PIC_COUNT = 8;//小鸟图片个数,8张图片轮播形成飞行时的样子public static final int BIRD_X = 190;//初始化小鸟坐标(游戏未开始小鸟位置)public static final int BIRD_Y = 220;public static final int BIRD_FLY_X = 120;//开始游戏后小鸟初始坐标public static final int BIRD_FLY_Y = 240;public static final int BIRD_UP_SPEED = 6;public static int index = 0;//当前小鸟图片序号public int x,y;//小鸟坐标public int width;//小鸟宽度public int height;//小鸟高度public double g = 9.8;//重力加速度public double t = 0.05;//自然下降时间public double v,h;//下降速度与下降距离BufferedImage img;BufferedImage[] imgs = new BufferedImage[BIRD_PIC_COUNT];public Bird(){try{for (int i = 0; i < 8; i++) {imgs[i] = ImageIO.read(this.getClass().getResource(BackGroundView.PATH_PIC + i + ".png"));}img = imgs[0];//获取小鸟宽高width = img.getWidth();height = img.getHeight();//初始化小鸟位置x = BIRD_X;y = BIRD_Y;}catch (IOException e){ }}// 小鸟飞翔的图片切换public void fly() {index++;// 小鸟图形切换的频率,index/x,x越大,翅膀切换频率越慢,index到48完成一次轮播img = imgs[index / 6 % BIRD_PIC_COUNT];//除以6是调整速度if (index == 6 * BIRD_PIC_COUNT) {index = 0;}}//上升public void up(){v = BIRD_UP_SPEED;//上升,鼠标点击小鸟上升20}//下降public void down() {v = v - g*t;// Vt=Vo-gth = v - g*t*t/2;// h=Vot-gt²/2y = y - (int)h;}// 碰撞检测// 是否碰撞地面public boolean hitGround(int bg_height, int ground_height) {if (y + height >= (bg_height - ground_height)) {return true;}return false;}// 碰撞到舞台顶部public boolean hitSky() {if (y <= 0) {return true;}return false;}// 碰到柱子时的检测public boolean hitPipe(Pipe p) {// x方向小鸟和柱子碰撞的条件if ((x + width) >= p.x && x <= p.x + p.width) {if (y <= p.y + (p.height - Pipe.PIPE_GAP) / 2|| y >= p.y + (p.height + Pipe.PIPE_GAP) / 2 - height) {return true;}}return false;}// 增加积分,通过管道后调用该方法public boolean addScore(Pipe p) {if (x == p.x + p.width) {return true;}return false;}
}
public class Main {public static void main(String[] args) {new BackGroundView().showView();}
}
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;public class Pipe {public static int PIPE_GAP = 144;//中间可通过的缺口大小public static int PIPE_DISTANCE = 244;//管道之间的间距BufferedImage img;//管道图片public int x,y;//坐标public int width,height;//柱子宽高private int max, min;//保证管道完全能显示在屏幕上,所以要设置max与minRandom random = new Random();//管道随机出现public int bg_width;public Pipe(int bg_width, int bg_height, int ground_height){this.bg_width = bg_width;try{img = ImageIO.read(this.getClass().getResource(BackGroundView.PATH_PIC + "pipe.png"));width = img.getWidth();height = img.getHeight();System.out.println("Pipe_width = " + width + ",Pipe_height = " + height);//width=74,height=1200x = bg_width;//管道在不在初始背景出现,在背景"右边"max = (height - PIPE_GAP) / 2;//图片有上下两管道,这个max表示一个管道的高度min = (height - PIPE_GAP) / 2 - (bg_height - PIPE_GAP - ground_height);//管道出现的最小长度y = -(min + random.nextInt(max - min));//管道随机出现的坐标}catch (IOException e){ }}//游戏开始,柱子就要向左移动public void move(){x--;//若柱子走出最左边窗口,管道就重新初始化if (x == -width){x = bg_width;y = -(min + random.nextInt(max - min));//管道随机出现的坐标}}}

 游戏界面与实现效果

 

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

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

相关文章

微电子专业词汇汇总,芯片人必备!

在芯片行业&#xff0c;很多相关的技术术语都是用英文表述。在这里为大家整理了一些常用的微电子专业词汇&#xff0c;希望对大家有所帮助。&#xff08;文末可领全部文档&#xff09; Abrupt junction 突变结 Accelerated testing 加速实验 Acceptor 受主 Acceptor atom 受主…

某基金公司赵哥“逆袭”了!!!

赵哥&#xff0c;在上海一家基金公司做运维主管。 平时工作的首要任务&#xff0c;就是保障公司各项信息系统的安全运行。 万一系统运行中出现了一些重要问题&#xff0c;他还要负责进行调查、记录与汇报... 总之&#xff0c;责任很重&#xff0c;该说不说&#xff0c;搞不好…

【攻防世界-misc】pure_color

1.方法一&#xff1a;用画图工具打开图片&#xff0c;将图片拷贝至虚拟机win7桌面&#xff0c; 点“属性”&#xff0c;颜色设置为“黑白”&#xff0c; 出现flag值。 2.方法二&#xff1a;使用Stegsilve打开&#xff0c;分析图片 将图片打开&#xff0c;按左右键查找&#xff…

Hive 定义变量 变量赋值 引用变量

Hive 定义变量 变量赋值 引用变量 变量 hive 中变量和属性命名空间 命名空间权限描述hivevar读写用户自定义变量hiveconf读写hive相关配置属性system读写java定义额配置属性env只读shell环境定义的环境变量 语法 Java对这个除env命名空间内容具有可读可写权利&#xff1b; …

高通Camera HAL3: CamX、Chi-CDK要点

目录 一、概述 二、目录 三、CamX组件之前的关系 一、概述 高通CamX架构是高通实现的相机HAL3架构&#xff0c;被各OEM厂商广泛采用。 二、目录 代码位于vendor/qcom/proprietary下&#xff1a; camx&#xff1a;通用功能性接口的代码实现集合chi-cdk&#xff1a;可定制化…

系列六、多线程集合不安全

一、多线程List集合不安全 1.1、List集合不安全案例代码 /*** Author : 一叶浮萍归大海* Date: 2023/11/20 12:38* Description: 多线层环境下List集合不安全案例代码*/ public class NotSafeListMainApp {public static void main(String[] args) {List<String> list …

微信小程序其他环境都能显示在正式环境显示不出来

踩坑日记 用了uni.getImageInfo 用了uni.getImageInfo 本地开发环境&#xff0c;测试环境全都可以&#xff0c;就是更新到正式环境不显示。后面看代码百度了这个api发现图片所涉及的地址需要在小程序配置download域名白名单 https://uniapp.dcloud.net.cn/api/media/image.ht…

用uniapp在微信小程序实现画板(电子签名)功能

目录 一、效果展示 二、插件推荐与引入 三、代码具体应用 四、h5端将base64转换为url 一、效果展示 二、插件推荐与引入 手写板、签字板&#xff1b;<zwp-draw-pad /> - DCloud 插件市场 这个在微信小程序引入时内容简单&#xff0c;且涉及的方法很多&#xff0c;…

如何设置实现本地JumpServer远程访问管理界面

文章目录 前言1. 安装Jump server2. 本地访问jump server3. 安装 cpolar内网穿透软件4. 配置Jump server公网访问地址5. 公网远程访问Jump server6. 固定Jump server公网地址 前言 JumpServer 是广受欢迎的开源堡垒机&#xff0c;是符合 4A 规范的专业运维安全审计系统。JumpS…

【图像分类】基于深度学习的垃圾分类系统的设计与实现(ResNet网络,附代码和数据集)

写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。(专栏订阅用户订阅专栏后免费提供数据集和源码一份,超级VIP用户不在服务范围之内,不想订阅专栏的兄弟们可以私信…

竞赛选题 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题

文章目录 1 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的垃圾邮件分类 该项目…

基于C#实现树状数组

有一种数据结构是神奇的&#xff0c;神秘的&#xff0c;它展现了位运算与数组结合的神奇魅力&#xff0c;太牛逼的&#xff0c;它就是树状数组&#xff0c;这种数据结构不是神人是发现不了的。 一、概序 假如我现在有个需求&#xff0c;就是要频繁的求数组的前 n 项和&#x…

电动汽车充放电V2G模型MATLAB代码

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 主要内容&#xff1a; 本程序主要建立电动汽车充放电V2G模型&#xff0c;采用粒子群算法&#xff0c;在保证电动汽车用户出行需求的前提下&#xff0c;为了使工作区域电动汽车尽可能多的消纳供给商场基础负荷…

投标文件的注意事项

一、检查标书 1.1有时候标书需要从别的地方复制黏贴文件&#xff0c;记住复制内容可以&#xff0c;但是不要复制“落款和时间”的格式&#xff0c;落款和时间的格式借鉴你的招标文件中给响应文件格式的落款和时间&#xff0c;切记&#xff01; 1.2检查标书是否有空页&#xf…

红队攻防之Goby反杀

若结局非我所愿&#xff0c;那就在尘埃落定前奋力一搏。 本文首发于先知社区&#xff0c;原创作者即是本人 一、弹xss 为了方便&#xff0c;本次直接使用 PhpStudy 进行建站&#xff0c;开启的web服务要为MySQLNginx&#xff0c;这里的 PhpStudy 地址为 http://x.x.x.x&…

原始类型 vs. 对象(基本类型 vs. 引用类型)

原始类型 首先我们先看一段代码&#xff1a; let age 30; let oldAge age; age 31; console.log(age); console.log(oldAge);在 JavaScript 中&#xff0c;原始类型的赋值是通过值复制的方式进行的&#xff0c;而不会相互影响。只有对象类型的值才是通过引用复制的方式进行…

获取ip属地(ip2region本地离线包-超简单)

背景 最近有涉及要显示ip属地&#xff0c;但我想白嫖&#xff0c;结果就是白嫖的api接口太慢了&#xff0c;要延迟3到4秒左右&#xff0c;很影响体验&#xff0c;而且不一定稳定。 结果突然看到了这个【ip2region】开源项目&#xff0c;离线识别ip属地&#xff0c;精度自己测…

广播组播、本地套接字通信、wireshark、以太网帧格式、三次握手四次挥手

广播&#xff08;使用 UDP 套接字&#xff09; 广播地址&#xff1a;主机号最大的地址。 广播&#xff1a;给所在局域网的所有主机发送数据报。&#xff08;之前的数据报发送方式是单播。&#xff09; 以下情况中使用广播&#xff1a; 局域网 搜索协议。 比如家中的智能产品&a…

centos7安装MySQL—以MySQL5.7.30为例

centos7安装MySQL—以MySQL5.7.30为例 本文以MySQL5.7.30为例。 官网下载 进入MySQL官网&#xff1a;https://www.mysql.com/ 点击DOWNLOADS 点击链接&#xff1b; 点击如上链接&#xff1a; 选择对应版本&#xff1a; 点击下载。 安装 将下载后的安装包上传到/usr/local下…

Eclipse常用设置-乱码

在用Eclipse进行Java代码开发时&#xff0c;经常会遇到一些问题&#xff0c;记录下来&#xff0c;方便查看。 一、properties文件乱码 常用的配置文件properties里中文的乱码&#xff0c;不利于识别。 处理流程&#xff1a;Window -> Preferences -> General -> Ja…