游戏背景

这款游戏的起源是越南独立开发者开发的手机游戏,短时间竟占领了全球各大AppStore免费排行榜首位。游戏中,玩家控制一只小鸟飞过一个个柱子的间隙。飞得越远分数越高,看玩家能使小鸟在空中坚持多久。初始界面如图-1所示。

玩家在如图-1所示的界面的任意位置,按下鼠标左键,开始游戏。

游戏开始以后,玩家需要不断控制电机屏幕的频率来调节小鸟的飞行高度和降落速度,让小鸟顺利的通过画面右端的柱子间隙。如果玩家不小心擦碰到了柱子或掉落到地面上,则游戏宣告结束。如图-2所示:

如图-2所示的左上角显示了用户的得分,每通过一个柱子的间隙得1分。另外,此时玩家可以在如图-2所示的界面的任意位置,按下鼠标左键,重新开始游戏。

类的设计

完整代码

BirdGame的完整代码如下所示:

package com.itkzhan.bird;import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.util.Random;import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BirdGame extends JPanel {Bird bird;Column column1, column2; Ground ground;BufferedImage background;/** 游戏结束状态 */boolean gameOver;BufferedImage gameOverImage;/** 游戏开始状态 */boolean started;BufferedImage startImage;//分数int score;/** 初始化 BirdGame 的属性变量 */public BirdGame() throws Exception {started = false;startImage = ImageIO.read(getClass().getResource("start.png"));gameOver = false;gameOverImage = ImageIO.read(getClass().getResource("gameover.png"));score = 0;bird = new Bird();column1 = new Column(1);column2 = new Column(2);ground = new Ground();background = ImageIO.read(getClass().getResource("bg.png")); }/** "重写(修改)"paint方法实现绘制 */public void paint(Graphics g){g.drawImage(background, 0, 0, null);g.drawImage(column1.image, column1.x-column1.width/2, column1.y-column1.height/2, null);g.drawImage(column2.image, column2.x-column2.width/2, column2.y-column2.height/2, null);//在paint方法中添加绘制分数的算法Font f = new Font(Font.SANS_SERIF,Font.BOLD, 40);g.setFont(f);g.drawString(""+score, 40, 60);g.setColor(Color.WHITE);g.drawString(""+score, 40-3, 60-3);g.drawImage(ground.image, ground.x, ground.y, null);//旋转(rotate)绘图坐标系,是API方法Graphics2D g2 = (Graphics2D)g;g2.rotate(-bird.alpha, bird.x, bird.y);g.drawImage(bird.image, bird.x-bird.width/2, bird.y-bird.height/2, null);g2.rotate(bird.alpha, bird.x, bird.y);//在paint方法中添加显示游戏结束状态代码if(gameOver){g.drawImage(gameOverImage,0,0,null);}if(! started){g.drawImage(startImage, 0, 0, null);}//添加调试的方框
//      g.drawRect(bird.x-bird.size/2,
//              bird.y-bird.size/2,
//              bird.size, bird.size);
//      g.drawRect(column1.x-column1.width/2,
//              column1.y-column1.height/2,
//              column1.width,
//              column1.height/2-column1.gap/2);
//      g.drawRect(column1.x-column1.width/2,
//              column1.y+column1.gap/2,
//              column1.width,
//              column1.height/2-column1.gap/2);        }//paint方法的结束//BirdGame中添加方法action()public void action() throws Exception {MouseListener l=new MouseAdapter(){//Mouse 老鼠 Pressed按下public void mousePressed(MouseEvent e){try{if(gameOver){synchronized(BirdGame.this){column1 = new Column(1);column2 = new Column(2);bird = new Bird();started = false;gameOver = false;score = 0;}}else{started = true;//鸟向上飞扬bird.flappy();}}catch(Exception ex){ex.printStackTrace();}}};//将l挂接到当前的面板(game)上addMouseListener(l);while(true){if( !gameOver ){//如果没有结束就走一步if(started){column1.step();column2.step();bird.step();}bird.fly();ground.step();//计分逻辑if( bird.x == column1.x ||bird.x == column2.x ){score++;}}synchronized(BirdGame.this){//如果鸟撞上地面游戏就结束了if( bird.hit(ground)  ||bird.hit(column1) ||bird.hit(column2) ){gameOver = true;}}repaint();Thread.sleep(1000/60);}}/** 启动软件的方法 */public static void main(String[] args)throws Exception {JFrame frame = new JFrame();BirdGame game = new BirdGame();frame.add(game);frame.setSize(440, 670);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);game.action();}
}
/** 地面 */
class Ground{BufferedImage image;int x, y;int width;int height;public Ground() throws Exception {image = ImageIO.read(getClass().getResource("ground.png"));width = image.getWidth();height = image.getHeight();x = 0;y = 500;}//地面的构造器结束//地面的类体中,添加方法,地面移动一步public void step(){x--;if(x==-109){x = 0;}}
}//地面类的结束
/** 柱子类型,x,y是柱子的中心点的位置 */
class Column{BufferedImage image;int x,y;int width, height;/** 柱子中间的缝隙 */int gap;int distance;//距离,两个柱子之间的距离Random random = new Random();/** 构造器:初始化数据,n代表第几个柱子 */public Column(int n) throws Exception {image=ImageIO.read(getClass().getResource("column.png"));width = image.getWidth();height = image.getHeight();gap=144;distance = 245;x = 550+(n-1)*distance;y = random.nextInt(218)+132;}//在Column中添加方法 step,在action调用此方法public void step(){x--;if(x==-width/2){x = distance * 2 - width/2;y = random.nextInt(218)+132;}}
}//Column类的结束
/** 鸟类型, x,y是鸟类型中心的位置 */
class Bird{BufferedImage image;int x,y;int width, height;int size;//鸟的大小,用于碰撞检测//在Bird类中增加属性,用于计算鸟的位置double g;//  重力加速度double t;//  两次位置的间隔时间double v0;// 初始上抛速度double speed;// 是当前的上抛速度double s;//     是经过时间t以后的位移double alpha;// 是鸟的倾角 弧度单位//在Bird类中定义//定义一组(数组)图片,是鸟的动画帧BufferedImage[] images;//是动画帧数组元素的下标位置int index;public Bird() throws Exception {image=ImageIO.read(getClass().getResource("0.png"));width = image.getWidth();height = image.getHeight();x = 132;y = 280;size = 40;g = 4;v0 = 20;t = 0.25;speed = v0;s = 0;alpha=0;//创建数组,创建8个元素的数组//是8个空位置,没有图片对象,//8个位置的序号: 0 1 2 3 4 5 6 7images = new BufferedImage[8];for(int i=0; i<8; i++){//i = 0 1 2 3 4 5 6 7 images[i] = ImageIO.read(getClass().getResource(i+".png"));}index = 0;}//在Bird中添加飞翔(fly)的代码public void fly(){index++;image = images[(index/12) % 8];}//在Bird中添加鸟的移动方法public void step(){double v0 = speed;s = v0*t + g*t*t/2;//计算上抛运动位移y = y-(int)s;//计算鸟的坐标位置double v = v0 - g*t;//计算下次的速度speed = v;
//      if(y>=500){//如果到达地面,就重新抛起
//          y = 280;
//          speed = 35;
//      }//调用Java API提供的反正切函数,计算倾角alpha = Math.atan(s/8);}//在Bird中添加方法public void flappy(){//重新设置初始速度,重新向上飞speed = v0;}//在鸟中添加方法 hit//检测当前鸟是否碰到地面ground//如果返回true表示发送碰撞//否则返回false表示没有碰撞public boolean hit(Ground ground){boolean hit = y + size/2 > ground.y;if(hit){y = ground.y-size/2;alpha = -3.14159265358979323/2;}return hit;}//检测当前的鸟是否撞到柱子public boolean hit(Column column){//先检测是否在柱子的范围以内if(x>column.x-column.width/2-size/2 &&x<column.x+column.width/2+size/2){//检测是否在缝隙中if(y>column.y-column.gap/2+size/2 &&y<column.y+column.gap/2-size/2){return false;}return true;}return false;}
}

没错,一个类就搞定了,就是这么简单。

关注“猴子学编程”公众号,回复“飞扬的小鸟”,获取工程源码(内含图片)

Java飞扬的小鸟游戏相关推荐

  1. c++飞扬的小鸟游戏_通过建立一个飞扬的鸟游戏来学习从头开始

    c++飞扬的小鸟游戏 Learn how to use Scratch 3.0 by building a flappy bird game in this course developed by W ...

  2. Android60分钟搞定《FlappyBird》飞扬的小鸟游戏

    自定义控件系列,前前后后分享了三四篇了,其实,在自定义控件的道路中,我们只仅仅迈出了一小步,未来的时间我们仍需走在路上,去探索那些未知的自定义领域.今天,是个周末的时刻,少些烦躁的代码,来一起实现一个 ...

  3. 【源码+图片素材+详细教程】Java游戏开发_Java开发经典游戏飞翔的小鸟_飞扬的小鸟_Java游戏项目Flappy Bird像素鸟游戏_Java课程设计项目

    课程目标: 1.通过本课程的学习巩固Java的相关基础知识,例如循环判断,数组和集合的使用,对象的继承,接口的实现,窗口的创建,事件监听,图形绘制. 2.完成小鸟的移动,管道自动生成.碰撞死亡,计分系 ...

  4. python之flappy bird(飞扬的小鸟)小游戏分享,内附源码哦~

    导语: 哈喽,哈喽~今天小编又来分享小游戏了--flappy bird(飞扬的小鸟),这个游戏非常的经典,游戏中玩家必须控制一只小鸟,跨越由各种不同长度水管所组成的障碍.这个游戏能对于小编来说还是有点 ...

  5. JAVA项目:Java实现飞扬的小鸟(Flappy Bird)

    飞扬的小鸟(Flappy Bird) 需求描述 游戏加载完毕点击界面即可开始游戏. 鼠标点击控制小鸟飞行,或者通过键盘控制小鸟的前后上下也可以,不要撞到管道哦! 控制好小鸟越过障碍飞得更远,获得更高的 ...

  6. Java SpringMVC+H5飞翔的小鸟游戏微信小程序源码

    源码介绍 Java SpringMVC+H5飞翔的小鸟游戏微信小程序源码 试验性质的一个微信小程序,用canvas做的一个类似flappy-bird的小游戏. 包含一些基本的功能:躲避障碍物.计分.排 ...

  7. android愤怒小鸟游戏、自定义View、掌上餐厅App、OpenGL自定义气泡、抖音电影滤镜效果等源码...

    2019独角兽企业重金招聘Python工程师标准>>> Android精选源码 精练的范围选择器,范围和单位可以自定义 自定义View做的小鸟游戏 android popwindow ...

  8. Star Way To Heaven (prim最小生成树) // [ NOIP提高组 2014]飞扬的小鸟(DP)

    文章目录 T1:Star Way To Heaven 题目 题解 代码实现 T2:飞扬的小鸟 题目 题解 代码实现 T1:Star Way To Heaven 题目 小 w 伤心的走上了 Star w ...

  9. [DP]Luogu 2014NOIP提高组 飞扬的小鸟题解

    2014NOIP提高组飞扬的小鸟题解 题目描述 Flappy Bird是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一 ...

最新文章

  1. python-如何解决python执行pip install 命令的时候出现 File“<stdin>“,line 1 pip install XXX的问题
  2. 中科大博士带头搬砖!这家上市公司其实是最隐秘的AI高手
  3. Android内核开发:学会分析系统的启动log
  4. wamp编写html页面空白,Win10安装wampserver后打开localhost出现空白怎么办
  5. Linux iptables用法与NAT
  6. 【AI视野·今日Robot 机器人论文速览 第十四期】Thu, 24 Jun 2021
  7. python生成一圈数包裹一圈数的数组
  8. 微软中文论坛2010新年Party手记
  9. 打开运行PS、AI等软件时卡在启动窗口的解决办
  10. TeeChart插入
  11. 【freeradius】使用radclient调试radius协议
  12. 移动光猫怎么设置虚拟服务器设置,移动光纤怎么设置无线路由器?
  13. 使用PE工具制作U盘启动盘
  14. ClickHouse和他的朋友们(5)存储引擎技术进化与MergeTree
  15. cs,ds,ss,es?即cs,ds,ss,es的区别
  16. 遨博机械臂——末端工具ROS驱动
  17. 健翔语录——意大利对澳大利亚
  18. yoman yo a:b_Yo API:无限可能
  19. noip2014飞扬的小鸟
  20. 谈谈 微软 鲍尔默退休,他错在哪里?该怎么做!

热门文章

  1. IIS服务器配置文件路径及相关说明
  2. 2021年质量员-市政方向-通用基础(质量员)免费试题及质量员-市政方向-通用基础(质量员)考试技巧
  3. 据说这是字节、阿里等大厂最新Java面试问题(技术面试)
  4. CUDA并行编程概述
  5. 维沃手机有没有智能机器人_vivonex人工智能是什么
  6. uniapp引入iconfont图标
  7. 玖逸云黑1.0-更高级的云黑系统
  8. 基于stm32cubeMX配置生成RT-thread-nano的工程、实现shell指令串口控制台(nucleo-g070rb开发板为例)
  9. ios自动订阅服务器,任何(早期)iOS自动续订订阅体验
  10. Standard 1.1.x VM与Standard VM的区别