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 + "\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 }
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 + "\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 }
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 + "\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 }
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 + "\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 }
View Code

完整版:Java實例---flappy-bird實例[最終版]

源碼下載:點擊下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM