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);
    }
}
View Code

第二天:实现小鸟的上下飞行的小狗

  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 + "	t:" + this.t + "	speed:" + 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 }
View Code

第三天: 添加小鸟飞行时候的动态表情

  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 + "	t:" + this.t +
198         // "	speed:" + 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 }
View Code

第四天: 添加鼠标控制小鸟的飞行

  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 + "	t:" + this.t +
287         // "	speed:" + 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 }
View Code

第五天:细节调整

  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 + "	t:" + this.t +
342         // "	speed:" + 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 }
View Code

完整版:Java实例---flappy-bird实例[最终版]

源码下载:点击下载

原文地址:https://www.cnblogs.com/ftl1012/p/9347708.html