代码分析

解析版: Java实例---flappy-bird实例解析

完整版:

TestBirdFly.java

  1. package testfly;
  2.  
  3. import java.awt.Color;
  4. import java.awt.Font;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import java.awt.event.MouseAdapter;
  8. import java.awt.event.MouseEvent;
  9. import java.awt.event.MouseListener;
  10. import java.awt.image.BufferedImage;
  11. import java.util.Random;
  12.  
  13. import javax.imageio.ImageIO;
  14. import javax.swing.JFrame;
  15. import javax.swing.JPanel;
  16. public class TestBirdFly extends JPanel {
  17. Bird bird;
  18. Column column1, column2;
  19. Ground ground;
  20. BufferedImage background;
  21. boolean gameOver;
  22. boolean started;
  23. BufferedImage gameoverImg;
  24. //分数
  25. int score;
  26. /** 初始化 BirdGame 的属性变量 */
  27. public TestBirdFly() throws Exception {
  28. score = 0;
  29. bird = new Bird();
  30. column1 = new Column(1);
  31. column2 = new Column(2);
  32. ground = new Ground();
  33. gameOver=false;
  34. background = ImageIO.read(
  35. getClass().getResource("bg.png"));
  36. gameoverImg= ImageIO.read(
  37. getClass().getResource("gameover.png"));
  38. }
  39.  
  40. /** "重写(修改)"paint方法实现绘制 */
  41. public void paint(Graphics g){
  42. g.drawImage(background, 0, 0, null);
  43. g.drawImage(column1.image,
  44. column1.x-column1.width/2,
  45. column1.y-column1.height/2, null);
  46. g.drawImage(column2.image,
  47. column2.x-column2.width/2,
  48. column2.y-column2.height/2, null);
  49. //在paint方法中添加绘制分数的算法
  50. Font f = new Font(Font.SANS_SERIF,
  51. Font.BOLD, 40);
  52. g.setFont(f);
  53. g.drawString(""+score, 40, 60);
  54. g.setColor(Color.WHITE);
  55. g.drawString(""+score, 40-3, 60-3);
  56.  
  57. g.drawImage(ground.image, ground.x,
  58. ground.y, null);
  59. if (gameOver){
  60. g.drawImage(gameoverImg,0,0,null);
  61. return;
  62. }
  63. //旋转(rotate)绘图坐标系,是API方法
  64. Graphics2D g2 = (Graphics2D)g;
  65. g2.rotate(-bird.alpha, bird.x, bird.y);
  66. g.drawImage(bird.image,
  67. bird.x-bird.width/2,
  68. bird.y-bird.height/2, null);
  69. g2.rotate(bird.alpha, bird.x, bird.y);
  70. }//paint方法的结束
  71. //BirdGame中添加方法action()
  72. public void action() throws Exception {
  73. MouseListener l=new MouseAdapter(){
  74. //Mouse 老鼠 Pressed按下
  75. public void mousePressed(
  76. MouseEvent e){
  77. //鸟向上飞扬
  78. started=true;
  79. bird.flappy();
  80.  
  81. }
  82. };
  83. //将l挂接到当前的面板(game)上
  84. addMouseListener(l);
  85.  
  86. while(true){
  87.  
  88. //计分逻辑
  89. if(!gameOver||started){
  90. ground.step();
  91. column1.step();
  92. column2.step();
  93. bird.step();
  94. }
  95. bird.fly();
  96. ground.step();
  97.  
  98. if(bird.hit(ground) ||bird.hit(column1)||bird.hit(column2)){
  99. gameOver=true;
  100. }
  101. bird.fly();
  102. if (bird.x==column1.x||bird.x==column2.x){
  103. score++;
  104. }repaint();
  105.  
  106. Thread.sleep(1000/60);
  107. }
  108. }
  109.  
  110. /** 启动软件的方法 */
  111. public static void main(String[] args)
  112. throws Exception {
  113. JFrame frame = new JFrame();
  114. TestBirdFly game = new TestBirdFly();
  115. frame.add(game);
  116. frame.setSize(440, 670);
  117. frame.setLocationRelativeTo(null);
  118. frame.setDefaultCloseOperation(
  119. JFrame.EXIT_ON_CLOSE);
  120. frame.setVisible(true);
  121. game.action();
  122. }
  123. }
  124. /** 地面 */
  125. class Ground{
  126. BufferedImage image;
  127. int x, y;
  128. int width;
  129. int height;
  130. public Ground() throws Exception {
  131. image = ImageIO.read(
  132. getClass().getResource("ground.png"));
  133. width = image.getWidth();
  134. height = image.getHeight();
  135. x = 0;
  136. y = 500;
  137. }//地面的构造器结束
  138. //地面的类体中,添加方法,地面移动一步
  139. public void step(){
  140. x--;
  141. if(x==-109){
  142. x = 0;
  143. }
  144. }
  145. }//地面类的结束
  146. /** 柱子类型,x,y是柱子的中心点的位置 */
  147. class Column{
  148. BufferedImage image;
  149. int x,y;
  150. int width, height;
  151. /** 柱子中间的缝隙 */
  152. int gap;
  153. int distance;//距离,两个柱子之间的距离
  154. Random random = new Random();
  155. /** 构造器:初始化数据,n代表第几个柱子 */
  156. public Column(int n) throws Exception {
  157. image=ImageIO.read(
  158. getClass().getResource("column.png"));
  159. width = image.getWidth();
  160. height = image.getHeight();
  161. gap=144;
  162. distance = 245;
  163. x = 550+(n-1)*distance;
  164. y = random.nextInt(218)+132;
  165. }
  166. //在Column中添加方法 step,在action调用此方法
  167. public void step(){
  168. x--;
  169. if(x==-width/2){
  170. x = distance * 2 - width/2;
  171. y = random.nextInt(218)+132;
  172. }
  173. }
  174. }//Column类的结束
  175. /** 鸟类型, x,y是鸟类型中心的位置 */
  176. class Bird{
  177. BufferedImage image;
  178. int x,y;
  179. int width, height;
  180. int size;//鸟的大小,用于碰撞检测
  181.  
  182. //在Bird类中增加属性,用于计算鸟的位置
  183. double g;// 重力加速度
  184. double t;// 两次位置的间隔时间
  185. double v0;// 初始上抛速度
  186. double speed;// 是当前的上抛速度
  187. double s;// 是经过时间t以后的位移
  188. double alpha;// 是鸟的倾角 弧度单位
  189. //在Bird类中定义
  190. //定义一组(数组)图片,是鸟的动画帧
  191. BufferedImage[] images;
  192. //是动画帧数组元素的下标位置
  193. int index;
  194.  
  195. public Bird() throws Exception {
  196. image=ImageIO.read(
  197. getClass().getResource("0.png"));
  198. width = image.getWidth();
  199. height = image.getHeight();
  200. x = 132;
  201. y = 280;
  202. size = 10;
  203. g = 1;
  204. v0 = 10;
  205. t = 0.25;
  206. speed = v0;
  207. s = 0;
  208. alpha=0;
  209. //创建数组,创建8个元素的数组
  210. //是8个空位置,没有图片对象,
  211. //8个位置的序号: 0 1 2 3 4 5 6 7
  212. images = new BufferedImage[8];
  213. for(int i=0; i<8; i++){
  214. //i = 0 1 2 3 4 5 6 7
  215. images[i] = ImageIO.read(
  216. getClass().getResource(i+".png"));
  217. }
  218. index = 0;
  219. }
  220. //在Bird中添加飞翔(fly)的代码
  221. public void fly(){
  222. index++;
  223. image = images[(index/12) % 8];
  224. }
  225. //在Bird中添加鸟的移动方法
  226. public void step(){
  227. double v0 = speed;
  228. s = v0*t + g*t*t/2;//计算上抛运动位移
  229. y = y-(int)s;//计算鸟的坐标位置
  230. double v = v0 - g*t;//计算下次的速度
  231. speed = v;
  232. // if(y>=500){//如果到达地面,就重新抛起
  233. // y = 280;
  234. // speed = 35;
  235. // }
  236. //调用Java API提供的反正切函数,计算倾角
  237. alpha = Math.atan(s/8);
  238. }
  239. //在Bird中添加方法
  240. public void flappy(){
  241. //重新设置初始速度,重新向上飞
  242. speed = v0;
  243. }
  244. //在鸟中添加方法hit
  245. // 检测当前鸟是否碰到地面ground
  246. //如果返回true表示发生碰撞
  247. //否则返回false表示没有碰撞
  248.  
  249. public boolean hit (Ground ground){
  250. boolean hit =y+size/2>ground.y;
  251. if(hit){
  252. y=ground.y-size/2;
  253.  
  254. }
  255. return hit;
  256. }
  257. //检测当前鸟是否撞倒柱子
  258. public boolean hit(Column column){
  259. //先检查是否在柱子的范围以内
  260. if (x>column.x-column.width/2-size/2&&x<column
  261. .x+column.width/2+size/2){
  262. if(y>column.y-column.gap/2+size/2&&y<column.y+column.gap/2-size/2){
  263. return false;
  264.  
  265. }
  266. return true;
  267.  
  268. }
  269. return false;
  270. }
  271. }

截图

源码下载

点击下载

Java实例---flappy-bird实例[最终版]的更多相关文章

  1. java邮件工具类【最终版】

    http://www.xdemo.org/java-mail/ 对比链接中,添加了抄送和暗抄送功能(已解决,如图代码:抄送不能多个用户,会报错,未解之谜) sendHtmlmail方法可以发送附件以及 ...

  2. Java变量类型,实例变量 与局部变量 静态变量

    实例变量: 实例变量在类中声明,但在方法的外面,构造函数或任何块. 当空间分配给某个对象在堆中,插槽为每个实例变量创建值. 当一个对象与使用关键字 “new” 来创建,在对象被销毁销毁创建的实例变量. ...

  3. 教你从头到尾利用DQN自动玩flappy bird(全程命令提示,GPU+CPU版)【转】

    转自:http://blog.csdn.net/v_JULY_v/article/details/52810219?locationNum=3&fps=1 目录(?)[-] 教你从头到尾利用D ...

  4. C语言版flappy bird黑白框游戏

    在此记录下本人在大一暑假,2014.6~8这段时间复习C语言,随手编的一个模仿之前很火热的小游戏----flappy bird.代码bug基本被我找光了,如果有哪位兄弟找到其他的就帮我留言下吧,谢谢了 ...

  5. 也来山寨一版Flappy Bird (js版)

    随着Flappy Bird的火爆,各种实现的版也不断出现,于是也手痒简单实现了一版. 其实本来只是想实现一下这只笨鸟的飞翔运动的,后来没忍住,就直接实现一个完整游戏了…… 因为这个游戏本身实现起来就没 ...

  6. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  7. Java的位运算符实例——与(&)、非(~)、或(|)、异或(^)

    一.Java的位运算符实例——与(&).非(~).或(|).异或(^) 1.与(&) 0 & 2 = 0 0 0 0 0 1 0 0 1 0 2.非(~) ~0 = 7 0 0 ...

  8. Java-Runoob-高级教程-实例-环境设置实例:4.Java 实例 – 如何查看当前 Java 运行的版本?

    ylbtech-Java-Runoob-高级教程-实例-环境设置实例:4.Java 实例 – 如何查看当前 Java 运行的版本? 1.返回顶部 1. Java 实例 - 如何查看当前 Java 运行 ...

  9. Java-Runoob-高级教程-实例-环境设置实例:3.Java 实例 - 如何执行指定class文件目录(classpath)?

    ylbtech-Java-Runoob-高级教程-实例-环境设置实例:3.Java 实例 - 如何执行指定class文件目录(classpath)? 1.返回顶部 1. Java 实例 - 如何执行指 ...

  10. Java-Runoob-高级教程-实例-环境设置实例:2.Java 实例 – Java 如何运行一个编译过的类文件?

    ylbtech-Java-Runoob-高级教程-实例-环境设置实例:2.Java 实例 – Java 如何运行一个编译过的类文件? 1.返回顶部 1. Java 实例 - 如何执行编译过 Java ...

随机推荐

  1. 通过java代码给log4j指定appender

    工具代码 import org.apache.log4j.ConsoleAppender; import org.apache.log4j.LogManager; import org.apache. ...

  2. Android开源项目xUtils HttpUtils模块分析(转)

    xUtils是github上的一个Android开源工具项目,其中HttpUtils模块是处理网络连接部分,刚好最近想整理下Android网络编程知识,今天学习下xUtils中HttpUtils. x ...

  3. c++ 网络编程(十一) LINUX下 初步制作基于HTTP的WEB服务器

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9663028.html HTTP概要 理解Web服务器端: 编写HTTP(超文本传输协议)服务器 ...

  4. 使用github oauth 出现 OpenSSL::SSL::SSLError - SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 解决

    A top level initializer is highly recommended to use: conf/initializer/tls_settings.rb OpenSSL::SSL: ...

  5. Java reflect 反射 3 Class.forname

    Class.forName("xxx.xx.xx") 1 作用:加载类文件Class.forName(xxx.xx.xx) 返回的是一个类 而非对象 作用就是把对象的模板加载到内存 ...

  6. Flex Graphics

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  7. Http协议之Content-Length

    前言 http协议是互联网中最重要的协议之一,虽然看上去很简单,但是实际中经常遇到问题,我们就已经遇到好几次了.有长连接相关的,有报文解析相关的.对http协议不能一知半解,必须透彻理解才行.所以就写 ...

  8. Linux笔记-Makefile伪指令解析

    本文是我在博客里面找到的,觉得对makefile的伪指令介绍得非常详细了!也提到了伪指令为何要用.PHONY:来声明!希望我的这篇转过来的文章能够帮助大家理解makefile的伪指令! 我的理解: 拿 ...

  9. jquery对象与dom对象之间互相转换的方法

    本文主要讲述jquery对象和js里的dom对象之间互相转换的方法,使jquery对象可以直接使用js里的方法,或js里的dom对象使用jquery里的方法. jquery对象和dom对象是不一样的, ...

  10. 使用FileSystemWatcher监视指定目录

    使用 FileSystemWatcher 监视指定目录中的更改.可监视指定目录中的文件或子目录的更改. 以下是一个简单的实例,用来监控指定目录下文件的新增.删除.重命名等情况(文件内容更改会触发多次, ...