Java实例---flappy-bird实例解析
第一天: 实现背景图片和小鸟的动态飞行效果
package com.ftl.flappybird.day2; import java.awt.Color;//颜色 Color.class import javax.swing.JFrame;//窗口框 import javax.swing.JPanel;//面板 底板 import java.awt.Graphics; import java.awt.image.BufferedImage;//图片类型 import javax.imageio.ImageIO;//读取图片的工具 /** * flappyBird * @author Administrator * */ class MyPanel extends JPanel { // 声明了背景(background)图变量,没有图片对象 BufferedImage background; BufferedImage bird; BufferedImage ground; BufferedImage column1; BufferedImage column2; int x1 = 100; int y1 = -300; int x2 = 100 + 245; int y2 = -280; int x = 0; // 利用“构造器”初始化变量,读取图片 // 构造器名称与类名一致 public MyPanel() throws Exception { // 使用ImageIO的read(读)方法 // 将"bg.png"读取为一个图片类型的对象 // background 引用了这个图片对象 background = ImageIO.read(getClass().getResource("bg.png")); bird = ImageIO.read(getClass().getResource("0.png")); ground = ImageIO.read(getClass().getResource("ground.png")); column1 = ImageIO.read(getClass().getResource("column.png")); column2 = ImageIO.read(getClass().getResource("column.png")); } // 修改JPanel的绘制方法 // Graphics 图 // paint 涂画 // draw 绘 Image图片 public void paint(Graphics g) { // 在0,0位置绘制background图片 g.drawImage(background, 0, 0, null); g.drawImage(bird, 100, 300, null); g.drawImage(column1, x1, y1, null); g.drawImage(column2, x2, y2, null); g.drawImage(ground, x, 500, null); // int x1 = 100; // int y1 = -300; // int x2 = 100 + 245; // int y2 = -280; // int x = 0; } //行动 public void action() throws Exception{ while(true){ x--; //x减1 if(x == -109){ x = 0; } x1--; System.out.println("x1: " + x1); System.out.println("-colume1。getWidth" + -column1.getWidth()); if (x1 == -column1.getWidth()) { x1 = 245 * 2 - column1.getWidth(); } x2--; System.out.println("x2: " + x2); System.out.println("-colume2。getWidth" + -column2.getWidth()); if (x2 == -column2.getWidth()) { x2 = 245 * 2 - column2.getWidth(); } repaint(); Thread.sleep( 1000 / 30); } } } public class Demo2 { public static void main(String[] args) throws Exception { // 创建一个窗口框,被frame变量引用 JFrame frame = new JFrame(); // 创建面板,被panel变量引用 // new MyPanel()执行了构造器,装载照片 MyPanel panel = new MyPanel(); // Background 背景,设置背景色=蓝色 panel.setBackground(Color.BLUE); // 在frame引用的框中添加panel引用的面板 // 框添加面板 frame.add(panel); frame.setSize(432, 644 + 30); // setVisible执行的时候,尽快的执行了 // paint 方法 frame.setVisible(true); frame.setTitle("FlappyBird2017"); frame.setIconImage(ImageIO.read( Demo2.class.getResource("0.png"))); panel.action(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
第二天:实现小鸟的上下飞行的小狗
1 package com.ftl.flappybird.day3; 2 3 import java.awt.Color;//颜色 Color.class 4 import java.awt.Graphics; 5 import java.awt.image.BufferedImage;//图片类型 6 import java.util.Random; 7 8 import javax.imageio.ImageIO;//读取图片的工具 9 import javax.swing.JFrame;//窗口框 10 import javax.swing.JPanel;//面板 底板 11 12 13 /** 14 * flappyBird 15 * @author Administrator 16 * 17 */ 18 class MyPanel extends JPanel { 19 // 声明了背景(background)图变量,没有图片对象 20 BufferedImage background; 21 Bird bird; //鸟 22 Ground ground; //MyPanel中包含地面 23 Column column1; //为MyPanel添加柱子 24 Column column2; //为MyPanel添加柱子 25 26 27 // 利用“构造器”初始化变量,读取图片 28 // 构造器名称与类名一致 29 public MyPanel() throws Exception { 30 // 使用ImageIO的read(读)方法 31 // 将"bg.png"读取为一个图片类型的对象 32 // background 引用了这个图片对象 33 background = ImageIO.read(getClass().getResource("bg.png")); 34 ground = new Ground(); 35 //利用类来创造对象 36 column1 = new Column(1); 37 column2 = new Column(2); 38 bird = new Bird(); 39 System.out.println("Demo3"); 40 } 41 42 // 修改JPanel的绘制方法 43 // Graphics 图 44 // paint 涂画 45 // draw 绘 Image图片 46 47 48 //行动 49 // TODO 自动生成的方法存根 50 51 public void action() throws Exception{ 52 while(true){ 53 this.ground.step(); 54 this.column1.step(); 55 this.column2.step(); 56 this.bird.step(); 57 58 repaint(); 59 Thread.sleep( 1000 / 30); 60 } 61 } 62 63 public void paint(Graphics g) { 64 // 在0,0位置绘制background图片 65 g.drawImage(background, 0, 0, null); 66 g.drawImage(bird.image, bird.x - bird.width/2, 67 bird.y - bird.height/2, null); 68 g.drawImage(column1.image, 69 column1.x-column1.width/2, 70 column1.y-column1.height/2,null); 71 g.drawImage(column2.image, 72 column2.x-column2.width/2, 73 column2.y-column2.height/2,null); 74 g.drawImage(ground.image, ground.x, ground.y, null); 75 76 77 } 78 } 79 80 class Column{ 81 public int x,y; //x,y是柱子的缝隙中心点 82 public int width, height; //柱子的宽, 高 83 public BufferedImage image; //柱子的图片 84 public int gap; //缝隙 85 public int distance; //2个柱子之间的距离 86 87 //n 代表柱子的编号,如:1,2 88 public Column(int n) throws Exception{ 89 image = ImageIO.read(Demo3.class.getResource("column.png")); 90 this.distance = 245; 91 //这个不是一开始就直接小鸟进入图片,有118的距离 550 = 118 + 432 92 this.x = 550 + (n - 1) * distance; 93 Random random = new Random(); 94 this.y = random.nextInt(128) + 132; 95 this.gap = 144; 96 this.width = image.getWidth(); 97 this.height = image.getHeight(); 98 } 99 100 public void step(){ 101 this.x--; 102 if(this.x <= -this.width/2){ 103 this.x = this.distance * 2 - this.width / 2; 104 Random random = new Random(); 105 this.y = random.nextInt(128) + 132; 106 } 107 } 108 109 } 110 111 class Ground{ 112 public BufferedImage image; 113 public int x,y; 114 115 public Ground() throws Exception{ 116 image = ImageIO.read(getClass().getResource("ground.png")); 117 this.x = 0; 118 this.y = 500; 119 } 120 public void step(){ 121 this.x--; //x减1 122 if(this.x == -109){ 123 this.x = 0; 124 } 125 126 } 127 } 128 129 class Bird{ 130 public BufferedImage image; 131 public int x,y; //鸟的位置,按照鸟的中心点 132 public int width, height; 133 public int size; //鸟的大小,是鸟的碰撞检测范围 134 public double g; //重力加速度,是浮点类型(小数类型) 135 public double t; //间隔时间,两次移动的间隔时间 136 public double s; //两次间隔时间,移动的距离:位移 137 public double v0; //初始速度 138 public double speed; //经过时间t以后,的运动速度 139 public double alpha; //鸟的倾角, 以弧度制为单位 140 141 142 143 144 public Bird() throws Exception{ 145 this.image = ImageIO.read( 146 getClass().getResource("0.png")); 147 this.x = 132; 148 this.y = 280; 149 this.size = 40; 150 this.g = 4; 151 this.t = 0.25; 152 this.v0 = 35; 153 this.s = 0; 154 this.speed = this.v0; 155 this.alpha = 0; 156 this.width = this.image.getWidth(); 157 this.height = this.image.getHeight(); 158 } 159 public void step(){ 160 //当前的上抛初始速度 161 double v0 = speed; 162 //计算位移 163 this.s = v0 * t + g * t * t / 2; 164 this.y = this.y - (int)s; 165 //计算经过时间t以后的速度,是下次计算 166 //的初始速度 167 double v = v0 - g * t; 168 //将经过时间t以后的速度作为下次的初始速度 169 this.speed = v; 170 // System.out.println("位移:" + this.s + "y:" + this.y + "\tt:" + this.t + "\tspeed:" + this.speed); 171 if(this.y >= 280){ 172 this.y = 280; 173 this.speed = 35; 174 } 175 } 176 177 } 178 179 public class Demo3 { 180 public static void main(String[] args) throws Exception { 181 // 创建一个窗口框,被frame变量引用 182 JFrame frame = new JFrame(); 183 // 创建面板,被panel变量引用 184 // new MyPanel()执行了构造器,装载照片 185 MyPanel panel = new MyPanel(); 186 // Background 背景,设置背景色=蓝色 187 panel.setBackground(Color.BLUE); 188 // 在frame引用的框中添加panel引用的面板 189 // 框添加面板 190 frame.add(panel); 191 frame.setSize(432, 644 + 30); 192 //居中 Location位置 Relative相对 To于 空 193 frame.setLocationRelativeTo(null); 194 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 195 frame.setTitle("FlappyBird2017"); 196 frame.setIconImage(ImageIO.read( 197 Demo3.class.getResource("0.png"))); 198 // setVisible执行的时候,尽快的执行了 199 // paint 方法 200 frame.setVisible(true); 201 panel.action(); 202 } 203 }
第三天: 添加小鸟飞行时候的动态表情
1 package com.ftl.flappybird.day4; 2 3 import java.awt.Color;//颜色 Color.class 4 import java.awt.Graphics; 5 import java.awt.Graphics2D; 6 import java.awt.image.BufferedImage;//图片类型 7 import java.util.Random; 8 9 import javax.imageio.ImageIO;//读取图片的工具 10 import javax.swing.JFrame;//窗口框 11 import javax.swing.JPanel;//面板 底板 12 13 /** 14 * flappyBird 15 * 16 * @author Administrator 17 * 18 */ 19 public class Demo4 extends JPanel { 20 // 声明了背景(background)图变量,没有图片对象 21 BufferedImage background; 22 Bird bird; // 鸟 23 Ground ground; // MyPanel中包含地面 24 Column column1; // 为MyPanel添加柱子 25 Column column2; // 为MyPanel添加柱子 26 27 public Demo4() throws Exception { 28 background = ImageIO.read(getClass().getResource("bg.png")); 29 ground = new Ground(); 30 // 利用类来创造对象 31 column1 = new Column(1); 32 column2 = new Column(2); 33 bird = new Bird(); 34 } 35 36 /** 37 * 重新复写paint,增加旋转 38 */ 39 public void paint(Graphics g) { 40 g.drawImage(background, 0, 0, null); 41 g.drawImage(bird.image, bird.x - bird.width / 2, bird.y - bird.height 42 / 2, null); 43 g.drawImage(column1.image, column1.x - column1.width / 2, column1.y 44 - column1.height / 2, null); 45 g.drawImage(column2.image, column2.x - column2.width / 2, column2.y 46 - column2.height / 2, null); 47 g.drawImage(ground.image, ground.x, ground.y, null); 48 //旋转绘图坐标系 49 Graphics2D g2 = (Graphics2D) g;//向下转型 50 g2.rotate(-this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标 51 g.drawImage(bird.image, bird.x - bird.width / 2, 52 bird.y - bird.height / 2, null); 53 g2.rotate(this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标 54 55 56 } 57 58 public void action() throws Exception { 59 while (true) { 60 this.ground.step(); 61 this.column1.step(); 62 this.column2.step(); 63 this.bird.step(); 64 this.bird.fly(); 65 repaint(); 66 Thread.sleep(1000 / 60); 67 } 68 } 69 70 public static void main(String[] args) throws Exception { 71 // 创建一个窗口框,被frame变量引用 72 JFrame frame = new JFrame(); 73 // 创建面板,被panel变量引用 74 // new MyPanel()执行了构造器,装载照片 75 Demo4 panel = new Demo4(); 76 // Background 背景,设置背景色=蓝色 77 panel.setBackground(Color.BLUE); 78 // 在frame引用的框中添加panel引用的面板 79 // 框添加面板 80 frame.add(panel); 81 frame.setSize(432, 644 + 30); 82 //居中 Location位置 Relative相对 To于 空 83 frame.setLocationRelativeTo(null); 84 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 85 frame.setTitle("FlappyBird2017"); 86 frame.setIconImage(ImageIO.read( 87 Demo4.class.getResource("0.png"))); 88 // setVisible执行的时候,尽快的执行了 89 // paint 方法 90 frame.setVisible(true); 91 panel.action(); 92 93 } 94 } 95 96 class Column { 97 public int x, y; // x,y是柱子的缝隙中心点 98 public int width, height; // 柱子的宽, 高 99 public BufferedImage image; // 柱子的图片 100 public int gap; // 缝隙 101 public int distance; // 2个柱子之间的距离 102 103 // n 代表柱子的编号,如:1,2 104 public Column(int n) throws Exception { 105 image = ImageIO.read(Demo4.class.getResource("column.png")); 106 this.distance = 245; 107 // 这个不是一开始就直接小鸟进入图片,有118的距离 550 = 118 + 432 108 this.x = 550 + (n - 1) * distance; 109 Random random = new Random(); 110 this.y = random.nextInt(128) + 132; 111 this.gap = 144; 112 this.width = image.getWidth(); 113 this.height = image.getHeight(); 114 } 115 116 public void step() { 117 this.x--; 118 if (this.x <= -this.width / 2) { 119 this.x = this.distance * 2 - this.width / 2; 120 Random random = new Random(); 121 this.y = random.nextInt(128) + 132; 122 } 123 } 124 125 } 126 127 class Ground { 128 public BufferedImage image; 129 public int x, y; 130 131 public Ground() throws Exception { 132 image = ImageIO.read(getClass().getResource("ground.png")); 133 this.x = 0; 134 this.y = 500; 135 } 136 137 public void step() { 138 this.x--; // x减1 139 if (this.x == -109) { 140 this.x = 0; 141 } 142 143 } 144 } 145 146 class Bird { 147 public BufferedImage image; 148 public int x, y; // 鸟的位置,按照鸟的中心点 149 public int width, height; 150 public int size; // 鸟的大小,是鸟的碰撞检测范围 151 public double g; // 重力加速度,是浮点类型(小数类型) 152 public double t; // 间隔时间,两次移动的间隔时间 153 public double s; // 两次间隔时间,移动的距离:位移 154 public double v0; // 初始速度 155 public double speed; // 经过时间t以后,的运动速度 156 public double alpha; // 鸟的倾角, 以弧度制为单位 157 158 public int index; //动画帧数组元素的小标位置 159 public BufferedImage images[]; //一组图片作为鸟的动画帧 160 161 public Bird() throws Exception { 162 this.image = ImageIO.read(getClass().getResource("0.png")); 163 this.images = new BufferedImage[8]; 164 this.x = 132; 165 this.y = 280; 166 this.size = 40; 167 this.g = 4; 168 this.t = 0.25; 169 this.v0 = 35; 170 this.s = 0; 171 this.speed = this.v0; 172 this.alpha = 0; 173 this.width = this.image.getWidth(); 174 this.height = this.image.getHeight(); 175 for(int i = 0 ; i < 8; i++){ 176 images[i] = ImageIO.read(getClass().getResource(i + ".png")); 177 } 178 this.index = 0; 179 } 180 181 public void fly(){ 182 this.index++; 183 image = images[(index / 12) % 8]; 184 } 185 186 public void step() { 187 // 当前的上抛初始速度 188 double v0 = speed; 189 // 计算位移 190 this.s = v0 * t + g * t * t / 2; 191 this.y = this.y - (int) s; 192 // 计算经过时间t以后的速度,是下次计算 193 // 的初始速度 194 double v = v0 - g * t; 195 // 将经过时间t以后的速度作为下次的初始速度 196 this.speed = v; 197 // System.out.println("位移:" + this.s + "y:" + this.y + "\tt:" + this.t + 198 // "\tspeed:" + this.speed); 199 if (this.y >= 400) { 200 this.y = 280; 201 this.speed = 35; 202 } 203 //调用Java API提供的反正切函数,计算倾角 204 this.alpha = Math.atan(s / 8 ); 205 } 206 207 }
第四天: 添加鼠标控制小鸟的飞行
1 package com.ftl.flappybird.day5; 2 3 import java.awt.Color;//颜色 Color.class 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 17 /** 18 * flappyBird 19 * 20 * @author Administrator 21 * 22 */ 23 public class Demo5 extends JPanel { 24 // 声明了背景(background)图变量,没有图片对象 25 BufferedImage background; 26 BufferedImage gameoverImg; //游戏结束 27 Bird bird; // 鸟 28 Ground ground; // MyPanel中包含地面 29 Column column1; // 为MyPanel添加柱子 30 Column column2; // 为MyPanel添加柱子 31 int score; //游戏分数 32 boolean gameOver; 33 boolean started; 34 35 public Demo5() throws Exception { 36 background = ImageIO.read(getClass().getResource("bg.png")); 37 gameoverImg= ImageIO.read( 38 getClass().getResource("gameover.png")); 39 ground = new Ground(); 40 // 利用类来创造对象 41 column1 = new Column(1); 42 column2 = new Column(2); 43 bird = new Bird(); 44 this.score = 0; 45 this.gameOver = false; 46 } 47 48 /** 49 * 重新复写paint,增加旋转,增加分数 50 */ 51 public void paint(Graphics g) { 52 g.drawImage(background, 0, 0, null); 53 g.drawImage(column1.image, column1.x - column1.width / 2, column1.y 54 - column1.height / 2, null); 55 g.drawImage(column2.image, column2.x - column2.width / 2, column2.y 56 - column2.height / 2, null); 57 g.drawImage(bird.image, bird.x - bird.width / 2, bird.y - bird.height 58 / 2, null); 59 g.drawImage(ground.image, ground.x, ground.y, null); 60 61 //增加分数算法 62 Font font = new Font(Font.SANS_SERIF,Font.BOLD,40); 63 g.setFont(font); 64 g.drawString("" + score, 40 , 60); 65 g.setColor(Color.WHITE); 66 g.drawString(""+score, 40-3, 60-3); 67 68 g.drawImage(ground.image, ground.x,ground.y,null); 69 if(gameOver){ 70 g.drawImage(gameoverImg, 0, 0, null); 71 return; 72 } 73 74 //旋转绘图坐标系 75 Graphics2D g2 = (Graphics2D) g;//向下转型 76 g2.rotate(-this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标 77 g.drawImage(bird.image, bird.x - bird.width / 2, 78 bird.y - bird.height / 2, null); 79 g2.rotate(this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标 80 81 82 } 83 84 //增加鼠标控制 85 public void action() throws Exception { 86 MouseListener l = new MouseAdapter() { 87 public void mousePressed(MouseEvent e){ 88 started = true; 89 bird.flappy(); 90 } 91 }; 92 this.addMouseListener(l); 93 94 while (true) { 95 //增加积分逻辑 96 if(!gameOver || started){ 97 98 this.ground.step(); 99 this.column1.step(); 100 this.column2.step(); 101 this.bird.step(); 102 } 103 this.bird.fly(); 104 this.ground.step(); 105 106 //判断是否撞了 107 if(this.bird.hit(ground) || this.bird.hit(column1) || this.bird.hit(column2)){ 108 this.gameOver = true; //游戏结束 109 } 110 111 this.bird.fly(); 112 113 //增加计分操作,柱子的x坐标和鸟的x坐标重合 114 if(this.bird.x == this.column1.x || 115 this.bird.x == this.column2.x) 116 { 117 this.score++; 118 } 119 repaint(); 120 Thread.sleep(1000 / 60); 121 } 122 } 123 124 public static void main(String[] args) throws Exception { 125 // 创建一个窗口框,被frame变量引用 126 JFrame frame = new JFrame(); 127 // 创建面板,被panel变量引用 128 // new MyPanel()执行了构造器,装载照片 129 Demo5 panel = new Demo5(); 130 // Background 背景,设置背景色=蓝色 131 panel.setBackground(Color.BLUE); 132 // 在frame引用的框中添加panel引用的面板 133 // 框添加面板 134 frame.add(panel); 135 frame.setSize(432, 644 + 30); 136 //居中 Location位置 Relative相对 To于 空 137 frame.setLocationRelativeTo(null); 138 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 139 frame.setTitle("FlappyBird2017"); 140 frame.setIconImage(ImageIO.read( 141 Demo5.class.getResource("0.png"))); 142 // setVisible执行的时候,尽快的执行了 143 // paint 方法 144 frame.setVisible(true); 145 panel.action(); 146 147 } 148 } 149 150 class Column { 151 public int x, y; // x,y是柱子的缝隙中心点 152 public int width, height; // 柱子的宽, 高 153 public BufferedImage image; // 柱子的图片 154 public int gap; // 缝隙 155 public int distance; // 2个柱子之间的距离 156 Random random = new Random(); 157 // n 代表柱子的编号,如:1,2 158 public Column(int n) throws Exception { 159 image = ImageIO.read(Demo5.class.getResource("column.png")); 160 this.distance = 245; 161 // 这个不是一开始就直接小鸟进入图片,有118的距离 550 = 118 + 432 162 this.x = 550 + (n - 1) * distance; 163 this.y = random.nextInt(128) + 132; 164 this.gap = 144; 165 this.width = image.getWidth(); 166 this.height = image.getHeight(); 167 } 168 169 public void step() { 170 this.x--; 171 if (this.x == -this.width / 2) { 172 this.x = this.distance * 2 - this.width / 2; 173 this.y = random.nextInt(128) + 132; 174 } 175 } 176 177 } 178 179 class Ground { 180 public BufferedImage image; 181 public int x, y; 182 public int width,heigth; 183 public Ground() throws Exception { 184 image = ImageIO.read(getClass().getResource("ground.png")); 185 this.x = 0; 186 this.y = 500; 187 this.width = image.getWidth(); 188 this.heigth = image.getHeight(); 189 } 190 191 public void step() { 192 this.x--; // x减1 193 if (this.x == -109) { 194 this.x = 0; 195 } 196 197 } 198 } 199 200 class Bird { 201 public BufferedImage image; 202 public int x, y; // 鸟的位置,按照鸟的中心点 203 public int width, height; 204 public int size; // 鸟的大小,是鸟的碰撞检测范围 205 public double g; // 重力加速度,是浮点类型(小数类型) 206 public double t; // 间隔时间,两次移动的间隔时间 207 public double s; // 两次间隔时间,移动的距离:位移 208 public double v0; // 初始速度 209 public double speed; // 经过时间t以后,的运动速度 210 public double alpha; // 鸟的倾角, 以弧度制为单位 211 212 public int index; //动画帧数组元素的小标位置 213 public BufferedImage images[]; //一组图片作为鸟的动画帧 214 215 public Bird() throws Exception { 216 this.image = ImageIO.read(getClass().getResource("0.png")); 217 this.images = new BufferedImage[8]; 218 this.x = 132; 219 this.y = 280; 220 this.size = 10; 221 this.g = 1; 222 this.t = 0.25; 223 this.v0 = 10; 224 this.s = 0; 225 this.speed = this.v0; 226 this.alpha = 0; 227 this.width = this.image.getWidth(); 228 this.height = this.image.getHeight(); 229 for(int i = 0 ; i < 8; i++){ 230 images[i] = ImageIO.read(getClass().getResource(i + ".png")); 231 } 232 this.index = 0; 233 } 234 235 //实现鼠标控制 236 public void flappy() { 237 //重新设置初始速度,重新开始飞 238 this.speed = v0; 239 } 240 241 //鸟的撞地检查 242 public boolean hit(Ground ground){ 243 boolean hit = false; 244 hit = this.y + this.size / 2 > ground.y; 245 if(hit){ 246 //表示撞地 247 this.y = ground.y - this.size / 2; //鸟儿放在地上 248 this.alpha = -Math.PI / 2; //鸟儿旋转效果 249 } 250 return hit; 251 } 252 253 //鸟儿撞在柱子上 254 public boolean hit(Column col){ 255 //判断鸟儿在柱子的范围内(this.x 表示主子内的中心位置) 256 if(this.x > col.x - col.width / 2 - this.size / 2 257 && this.x < col.x + col.width / 2 + this.size / 2){ 258 //检查是否在间隙之间 259 if(this.y > col.y - col.gap / 2 + this.size / 2 260 && this.y < col.y + col.gap / 2 - this.size / 2){ 261 return false; 262 } 263 return true; 264 } 265 return false; 266 } 267 268 //实现鸟的动图 269 public void fly(){ 270 this.index++; 271 image = images[(index / 12) % 8]; 272 } 273 274 //实现鸟儿的移动 275 public void step() { 276 // 当前的上抛初始速度 277 double v0 = speed; 278 // 计算位移 279 this.s = v0 * t + g * t * t / 2; 280 this.y = this.y - (int) s; 281 // 计算经过时间t以后的速度,是下次计算 282 // 的初始速度 283 double v = v0 - g * t; 284 // 将经过时间t以后的速度作为下次的初始速度 285 this.speed = v; 286 // System.out.println("位移:" + this.s + "y:" + this.y + "\tt:" + this.t + 287 // "\tspeed:" + this.speed); 288 // if (this.y >= 400) { 289 // this.y = 280; 290 // this.speed = 35; 291 // } 292 //调用Java API提供的反正切函数,计算倾角 293 this.alpha = Math.atan(s / 8 ); 294 } 295 296 }
第五天:细节调整
1 package com.ftl.flappybird.day6; 2 3 import java.awt.Color;//颜色 Color.class 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 17 /** 18 * flappyBird 19 * 20 * @author Administrator 21 * 22 */ 23 public class Demo6 extends JPanel { 24 // 声明了背景(background)图变量,没有图片对象 25 BufferedImage background; 26 BufferedImage gameStartImg; //游戏开始 27 BufferedImage gameoverImg; //游戏结束 28 Bird bird; // 鸟 29 Ground ground; // MyPanel中包含地面 30 Column column1; // 为MyPanel添加柱子 31 Column column2; // 为MyPanel添加柱子 32 int score; //游戏分数 33 boolean gameOver; //游戏结束 34 boolean started; //游戏开始 35 36 //游戏状态 37 int state; 38 public static final int START = 0; 39 public static final int RUNNING = 1; 40 public static final int GAME_OVER = 2; 41 42 43 public Demo6() throws Exception { 44 state = START; //游戏一开始进入开始状态 45 gameStartImg = ImageIO.read(getClass().getResource("start.png")); 46 background = ImageIO.read(getClass().getResource("bg.png")); 47 gameoverImg= ImageIO.read( 48 getClass().getResource("gameover.png")); 49 ground = new Ground(); 50 // 利用类来创造对象 51 column1 = new Column(1); 52 column2 = new Column(2); 53 bird = new Bird(); 54 this.score = 0; 55 // this.gameOver = false; 56 } 57 58 /** 59 * 重新复写paint,增加旋转,增加分数 60 */ 61 public void paint(Graphics g) { 62 g.drawImage(background, 0, 0, null); 63 g.drawImage(column1.image, column1.x - column1.width / 2, column1.y 64 - column1.height / 2, null); 65 g.drawImage(column2.image, column2.x - column2.width / 2, column2.y 66 - column2.height / 2, null); 67 g.drawImage(bird.image, bird.x - bird.width / 2, bird.y - bird.height 68 / 2, null); 69 g.drawImage(ground.image, ground.x, ground.y, null); 70 71 //增加分数算法 72 Font font = new Font(Font.SANS_SERIF,Font.BOLD,40); 73 g.setFont(font); 74 g.drawString("" + score, 40 , 60); 75 g.setColor(Color.WHITE); 76 g.drawString(""+score, 40-3, 60-3); 77 78 g.drawImage(ground.image, ground.x,ground.y,null); 79 // if(gameOver){ 80 // g.drawImage(gameoverImg, 0, 0, null); 81 // return; 82 // } 83 switch (state) { 84 case GAME_OVER: 85 g.drawImage(gameoverImg, 0, 0, null); 86 break; 87 case START: 88 g.drawImage(gameStartImg, 0, 0, null); 89 break; 90 } 91 //旋转绘图坐标系 92 Graphics2D g2 = (Graphics2D) g;//向下转型 93 g2.rotate(-this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标 94 g.drawImage(bird.image, bird.x - bird.width / 2, 95 bird.y - bird.height / 2, null); 96 g2.rotate(this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标 97 98 99 } 100 101 //增加鼠标控制 102 public void action() throws Exception { 103 MouseListener l = new MouseAdapter() { 104 public void mousePressed(MouseEvent e){ 105 106 try { 107 switch (state) { 108 case GAME_OVER: 109 column1 = new Column(1); 110 column2 = new Column(2); 111 bird = new Bird(); 112 score = 0; 113 state = START; 114 break; 115 case START: 116 state = RUNNING; 117 case RUNNING: 118 bird.flappy(); 119 } 120 }catch (Exception e1) { 121 e1.printStackTrace(); 122 } 123 } 124 }; 125 this.addMouseListener(l); 126 127 while (true) { 128 // //增加积分逻辑 129 // if(!gameOver || started){ 130 // 131 // this.ground.step(); 132 // this.column1.step(); 133 // this.column2.step(); 134 // this.bird.step(); 135 // } 136 // this.bird.fly(); 137 // this.ground.step(); 138 // 139 // //判断是否撞了 140 // if(this.bird.hit(ground) || this.bird.hit(column1) || this.bird.hit(column2)){ 141 // this.gameOver = true; //游戏结束 142 // } 143 // this.bird.fly(); 144 // //增加计分操作,柱子的x坐标和鸟的x坐标重合 145 // if(this.bird.x == this.column1.x || 146 // this.bird.x == this.column2.x) 147 // { 148 // this.score++; 149 // } 150 switch (state) { 151 case START: 152 bird.fly(); 153 ground.step(); 154 break; 155 case RUNNING: 156 column1.step(); 157 column2.step(); 158 bird.step(); //上下移动 159 bird.fly(); //动图 160 ground.step(); 161 //增加计分操作,柱子的x坐标和鸟的x坐标重合 162 if(this.bird.x == this.column1.x || 163 this.bird.x == this.column2.x) 164 { 165 this.score++; 166 } 167 //判断是否撞了 168 if(this.bird.hit(ground) || this.bird.hit(column1) || this.bird.hit(column2)){ 169 state = GAME_OVER;//游戏结束 170 } 171 break; 172 } 173 174 repaint(); 175 Thread.sleep(1000 / 60); 176 } 177 } 178 179 public static void main(String[] args) throws Exception { 180 // 创建一个窗口框,被frame变量引用 181 JFrame frame = new JFrame(); 182 // 创建面板,被panel变量引用 183 // new MyPanel()执行了构造器,装载照片 184 Demo6 panel = new Demo6(); 185 // Background 背景,设置背景色=蓝色 186 panel.setBackground(Color.BLUE); 187 // 在frame引用的框中添加panel引用的面板 188 // 框添加面板 189 frame.add(panel); 190 frame.setSize(432, 644 + 30); 191 //居中 Location位置 Relative相对 To于 空 192 frame.setLocationRelativeTo(null); 193 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 194 frame.setTitle("FlappyBird2017"); 195 frame.setIconImage(ImageIO.read( 196 Demo6.class.getResource("0.png"))); 197 // setVisible执行的时候,尽快的执行了 198 // paint 方法 199 frame.setVisible(true); 200 panel.action(); 201 202 } 203 } 204 205 class Column { 206 public int x, y; // x,y是柱子的缝隙中心点 207 public int width, height; // 柱子的宽, 高 208 public BufferedImage image; // 柱子的图片 209 public int gap; // 缝隙 210 public int distance; // 2个柱子之间的距离 211 Random random = new Random(); 212 // n 代表柱子的编号,如:1,2 213 public Column(int n) throws Exception { 214 image = ImageIO.read(Demo6.class.getResource("column.png")); 215 this.distance = 245; 216 // 这个不是一开始就直接小鸟进入图片,有118的距离 550 = 118 + 432 217 this.x = 550 + (n - 1) * distance; 218 this.y = random.nextInt(128) + 132; 219 this.gap = 144; 220 this.width = image.getWidth(); 221 this.height = image.getHeight(); 222 } 223 224 public void step() { 225 this.x--; 226 if (this.x == -this.width / 2) { 227 this.x = this.distance * 2 - this.width / 2; 228 this.y = random.nextInt(128) + 132; 229 } 230 } 231 232 } 233 234 class Ground { 235 public BufferedImage image; 236 public int x, y; 237 public int width,heigth; 238 public Ground() throws Exception { 239 image = ImageIO.read(getClass().getResource("ground.png")); 240 this.x = 0; 241 this.y = 500; 242 this.width = image.getWidth(); 243 this.heigth = image.getHeight(); 244 } 245 246 public void step() { 247 this.x--; // x减1 248 if (this.x == -109) { 249 this.x = 0; 250 } 251 252 } 253 } 254 255 class Bird { 256 public BufferedImage image; 257 public int x, y; // 鸟的位置,按照鸟的中心点 258 public int width, height; 259 public int size; // 鸟的大小,是鸟的碰撞检测范围 260 public double g; // 重力加速度,是浮点类型(小数类型) 261 public double t; // 间隔时间,两次移动的间隔时间 262 public double s; // 两次间隔时间,移动的距离:位移 263 public double v0; // 初始速度 264 public double speed; // 经过时间t以后,的运动速度 265 public double alpha; // 鸟的倾角, 以弧度制为单位 266 267 public int index; //动画帧数组元素的小标位置 268 public BufferedImage images[]; //一组图片作为鸟的动画帧 269 270 public Bird() throws Exception { 271 this.image = ImageIO.read(getClass().getResource("0.png")); 272 this.images = new BufferedImage[8]; 273 this.x = 132; 274 this.y = 280; 275 this.size = 10; 276 this.g = 1; 277 this.t = 0.25; 278 this.v0 = 10; 279 this.s = 0; 280 this.speed = this.v0; 281 this.alpha = 0; 282 this.width = this.image.getWidth(); 283 this.height = this.image.getHeight(); 284 for(int i = 0 ; i < 8; i++){ 285 images[i] = ImageIO.read(getClass().getResource(i + ".png")); 286 } 287 this.index = 0; 288 } 289 290 //实现鼠标控制 291 public void flappy() { 292 //重新设置初始速度,重新开始飞 293 this.speed = v0; 294 } 295 296 //鸟的撞地检查 297 public boolean hit(Ground ground){ 298 boolean hit = false; 299 hit = this.y + this.size / 2 > ground.y; 300 if(hit){ 301 //表示撞地 302 this.y = ground.y - this.size / 2; //鸟儿放在地上 303 this.alpha = -Math.PI / 2; //鸟儿旋转效果 304 } 305 return hit; 306 } 307 308 //鸟儿撞在柱子上 309 public boolean hit(Column col){ 310 //判断鸟儿在柱子的范围内(this.x 表示主子内的中心位置) 311 if(this.x > col.x - col.width / 2 - this.size / 2 312 && this.x < col.x + col.width / 2 + this.size / 2){ 313 //检查是否在间隙之间 314 if(this.y > col.y - col.gap / 2 + this.size / 2 315 && this.y < col.y + col.gap / 2 - this.size / 2){ 316 return false; 317 } 318 return true; 319 } 320 return false; 321 } 322 323 //实现鸟的动图 324 public void fly(){ 325 this.index++; 326 image = images[(index / 12) % 8]; 327 } 328 329 //实现鸟儿的移动 330 public void step() { 331 // 当前的上抛初始速度 332 double v0 = speed; 333 // 计算位移 334 this.s = v0 * t + g * t * t / 2; 335 this.y = this.y - (int) s; 336 // 计算经过时间t以后的速度,是下次计算 337 // 的初始速度 338 double v = v0 - g * t; 339 // 将经过时间t以后的速度作为下次的初始速度 340 this.speed = v; 341 // System.out.println("位移:" + this.s + "y:" + this.y + "\tt:" + this.t + 342 // "\tspeed:" + this.speed); 343 // if (this.y >= 400) { 344 // this.y = 280; 345 // this.speed = 35; 346 // } 347 //调用Java API提供的反正切函数,计算倾角 348 this.alpha = Math.atan(s / 8 ); 349 } 350 351 }
完整版:Java实例---flappy-bird实例[最终版]
源码下载:点击下载
作者:小a玖拾柒
-------------------------------------------
个性签名: 所有的事情到最後都是好的,如果不好,那說明事情還沒有到最後~
本文版权归作者【小a玖拾柒】和【博客园】共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利!