JavaSE實戰項目:飛翔的小鳥(完整版)


 

1.前言

首先,我先說一下這個項目,這個項目題材的來自牛客網的開源項目
我在這里做一個我自己在開發此項目的心得體會和經驗交流,並且帶領大家了解從0去入手一個項目的完整思路

 

2.分析

 

①素材准備

 

在開發此項目之前,我們需要去先下載一些關於飛翔的小鳥素材圖片
小鳥的飛翔圖片
地面背景圖片
柱子圖片
以及開始結束圖片

 

那么這里我為大家提供百度網盤鏈接,大家需要可自行下載
鏈接:https://pan.baidu.com/s/12ww0HQ6KluVP-fcC40iXXQ
提取碼:zjd8
復制這段內容后打開百度網盤手機App,操作更方便哦

 

②代碼構思

 

本項目主要針對JAVASE剛學完想鞏固練習,卻沒有項目着手的同學,用的都是一些基礎性的知識
運用到的知識點:
1.面向對象:封裝繼承多態
2.數組
3.常用類Math
4.swing組件:圖形界面工具
5.鼠標監聽
6.IO流
7.多線程
邏輯步驟分析:
1.先實現窗口的制作,並且將背景圖放入窗口面板

 

2.設計地面類,實現游戲背景地面移動

 

3.設計柱子類,實現游戲背景柱子移動

 

4.設計小鳥類,在類中添加小鳥相關方法
初始化小鳥相關參數, 判斷小鳥是否碰撞柱子與地面

 

5.把小鳥放在面板中

 

6.鼠標監聽控制小鳥飛行的軌跡

 

7.添加計分和游戲結束游戲開始的畫面
代碼分類:
由上述的分析,我們可以大致分析計划創建4個類
1.小鳥類:設置小鳥參數,添加小鳥判斷方法
2.柱子類:設置柱子參數,添加柱子移動方法
3.地面類:設置地面參數,添加地面移動方法
4.測試類:添加開始結束、鼠標監聽等方法

 

3.代碼實現及展示

①小鳥類:

  1 package FlyBirdGame;
  2 
  3 import javax.imageio.ImageIO;
  4 import java.awt.image.BufferedImage;
  5 import java.io.File;
  6 
  7 class Bird {
  8     //圖片
  9     BufferedImage image;
 10     //位置
 11     int x,y;
 12     //寬,高
 13     int width,height;
 14     //大小
 15     int size;
 16 
 17     //重力加速度
 18     double g;
 19     //位移的間隔時間
 20     double t;
 21     //最初上拋速度
 22     double v0;
 23     //當前上拋速度
 24     double speed;
 25     //經過時間t后的位移
 26     double s;
 27     //小鳥的傾角
 28     double alpha;
 29 
 30     //一組圖片,記錄小鳥的動畫幀
 31     BufferedImage[] images;
 32     //動畫幀數組的下標
 33     int index;
 34 
 35     //初始化小鳥
 36     public  Bird() throws Exception{
 37         //初始化基本參數
 38         image = ImageIO.read(new File("0.png"));
 39         width = image.getWidth();
 40         height = image.getHeight();
 41         x=132;
 42         y=280;
 43         size =40;
 44 
 45         //初始化位移參數
 46         g=4;
 47         v0=20;
 48         t=0.25;
 49         speed = v0;
 50         s = 0;
 51         alpha = 0;
 52 
 53         //初始化動畫幀參數
 54         images = new BufferedImage[8];
 55         for(int i = 0;i<8;i++){
 56             images[i] = ImageIO.read(new File(i+".png"));
 57         }
 58         index = 0;
 59     }
 60 
 61     //飛行動作(變化一幀)
 62     public void fly(){
 63         index++;
 64         image = images[(index/12)%8];
 65     }
 66 
 67     //移動一步
 68     public void step(){
 69         double v0 =speed;
 70         //計算上拋運動位移
 71         s=v0*t + g*t*t/2;
 72         //計算小鳥的坐標位置
 73         y=y-(int)s;
 74         //計算下次移動速度
 75         double v = v0 -g*t;
 76         speed = v;
 77         //計算傾角
 78         alpha = Math.atan(s/8);
 79     }
 80 
 81     //向上飛翔
 82     public void flappy(){
 83         //重疊速度
 84         speed =v0;
 85     }
 86 
 87     //檢查小鳥是否碰撞到地面
 88     public boolean hit(Ground ground ){
 89         boolean hit = y+size/2 > ground.y;
 90         if(hit){
 91             y = ground.y - size/2;
 92             alpha = -3.14159265358979323 / 2;
 93         }
 94         return hit;
 95     }
 96 
 97     //檢查小鳥是否碰到柱子
 98     public boolean hit(Column column){
 99         //先檢測是否在柱子范圍內
100         if(x>column.x - column.width /2 - size /2
101             && x<column.x + column.width/2 + size/2){
102             //檢查是否在柱子的縫隙種
103             if(y>column.y - column.gap/2 + size /2
104             && y<column.y + column.gap /2 -size/2){
105                 return false;
106             }
107             return true;
108         }
109         return false;
110     }
111 }

②地面類:

 1 package FlyBirdGame;
 2 
 3 import javax.imageio.ImageIO;
 4 import java.awt.image.BufferedImage;
 5 import java.io.File;
 6 
 7 public class Ground {
 8     //圖片
 9     BufferedImage image;
10     //位置
11     int x,y;
12     //寬高
13     int width,height;
14 
15     //初始化地面
16     public Ground() throws Exception {
17         image = ImageIO.read(new File("ground.png"));
18         width = image.getWidth();
19         height = image.getHeight();
20         x=0;
21         y=500;
22     }
23 
24     //向左移動一步
25     public void step(){
26         x--;
27         if(x==-109){
28             x = 0;
29         }
30     }
31 }

③柱子類:

 1 package FlyBirdGame;
 2 
 3 import javax.imageio.ImageIO;
 4 import java.awt.image.BufferedImage;
 5 import java.io.File;
 6 import java.util.Random;
 7 
 8 public class Column {
 9     //圖片
10     BufferedImage image;
11     //位置
12     int x,y;
13     //寬高
14     int width,height;
15     //柱子間縫隙
16     int gap;
17     //柱子間距離
18     int distance;
19     //隨機數工具
20     Random random = new Random();
21 
22     /**
23      * 初始化第n個柱子
24      */
25     public Column(int n) throws  Exception{
26         image = ImageIO.read(new File("column.png"));
27         width = image.getWidth();
28         height = image.getHeight();
29         gap = 144;
30         distance = 245;
31         x= 550 + (n-1) * distance;
32         y = random.nextInt(218)+132;
33     }
34 
35     //向左移動一步
36     public void step(){
37         x--;
38         if(x==-width/2){
39             x = distance * 2 - width/2;
40             y = random.nextInt(218) + 132;
41         }
42     }
43 }

④測試類:

  1 package FlyBirdGame;
  2 
  3 import javax.imageio.ImageIO;
  4 import javax.swing.*;
  5 import java.awt.*;
  6 import java.awt.image.BufferedImage;
  7 import java.awt.event.MouseAdapter;
  8 import java.awt.event.MouseEvent;
  9 import java.awt.event.MouseListener;
 10 import java.io.File;
 11 
 12 public class BirdGame  extends JPanel {
 13     //背景圖片
 14     BufferedImage background;
 15     //開始圖片
 16     BufferedImage startImage;
 17     //結束圖片
 18     BufferedImage gameOverImage;
 19 
 20     //地面
 21     Ground ground;
 22     //柱子
 23     Column column1,column2;
 24     //小鳥
 25     Bird bird;
 26 
 27     //游戲分數
 28     int score;
 29 
 30     //游戲狀態
 31     int state;
 32 
 33     //狀態常量
 34     public  static  final int START = 0;//開始
 35     public  static  final int RUNNING = 1;//運行
 36     public  static  final int GAME_OVER = 2;//結束
 37 
 38     /**
 39      * 初始化游戲
 40      */
 41     public BirdGame() throws Exception{
 42         //初始化
 43         background = ImageIO.read(new File("bg.png"));
 44         startImage = ImageIO.read(new File("start.png"));
 45         gameOverImage = ImageIO.read(new File("gameover.png"));
 46 
 47         //初始化地面,柱子,小鳥
 48         ground = new Ground();
 49         column1 = new Column(1);
 50         column2 = new Column(2);
 51         bird = new Bird();
 52 
 53         //初始化分數
 54         score = 0;
 55         //初始化狀態
 56         state = START;
 57     }
 58     /**
 59      * 繪制界面
 60      */
 61     public void paint(Graphics g){
 62         //繪制背景
 63         g.drawImage(background,0,0,null);
 64 
 65         //繪制地面
 66         g.drawImage(ground.image,ground.x,ground.y,null);
 67         //繪制柱子
 68         g.drawImage(column1.image,column1.x - column1.width/2,column1.y
 69                     -column1.height/2,null);
 70         g.drawImage(column2.image,column2.x - column2.width/2,column2.y
 71                 -column2.height/2,null);
 72 
 73         //繪制小鳥
 74         Graphics2D g2 = (Graphics2D) g;
 75         g2.rotate(-bird.alpha,bird.x,bird.y);
 76         g2.drawImage(bird.image,bird.x-bird.width/2,bird.y-bird.height/2,null);
 77         g2.rotate(bird.alpha,bird.x,bird.y);
 78 
 79         //繪制分數
 80         Font f = new Font(Font.SANS_SERIF,Font.BOLD,40);
 81         g.setFont(f);
 82         g.drawString(""+score,40,60);
 83         g.setColor(Color.WHITE);
 84         g.drawString(""+score,40-3,60-3);
 85 
 86         //繪制開始和結束界面
 87         switch (state) {
 88             case START:
 89                 g.drawImage(startImage, 0, 0, null);
 90                 break;
 91             case GAME_OVER:
 92                 g.drawImage(gameOverImage, 0, 0, null);
 93                 break;
 94         }
 95     }
 96     // 開始游戲
 97     public void action() throws Exception {
 98         // 鼠標監聽器
 99         MouseListener l = new MouseAdapter() {
100             // 鼠標按下事件
101             public void mousePressed(MouseEvent e) {
102                 try {
103                     switch (state) {
104                         case START:
105                             // 在開始狀態,按下鼠標則轉為運行狀態。
106                             state = RUNNING;
107                             break;
108                         case RUNNING:
109                             // 在運行狀態,按下鼠標則小鳥向上飛行。
110                             bird.flappy();
111                             break;
112                         case GAME_OVER:
113                             // 在結束狀態,按下鼠標則重置數據,再次轉為開始態。
114                             column1 = new Column(1);
115                             column2 = new Column(2);
116                             bird = new Bird();
117                             score = 0;
118                             state = START;
119                             break;
120                     }
121                 } catch (Exception ex) {
122                     ex.printStackTrace();
123                 }
124             }
125         };
126         // 將監聽器添加到當前的面板上
127         addMouseListener(l);
128         // 不斷的移動與重繪
129         while (true) {
130             switch (state) {
131                 case START:
132                     // 小鳥做出飛行動作
133                     bird.fly();
134                     // 地面向左移動一步
135                     ground.step();
136                     break;
137                 case RUNNING:
138                     // 地面向左移動一步
139                     ground.step();
140                     // 柱子向左移動一步
141                     column1.step();
142                     column2.step();
143                     // 小鳥做出飛行動作
144                     bird.fly();
145                     // 小鳥上下移動一步
146                     bird.step();
147                     // 計算分數
148                     if (bird.x == column1.x || bird.x == column2.x) {
149                         score++;
150                     }
151                     // 檢測是否發生碰撞
152                     if (bird.hit(ground) || bird.hit(column1) || bird.hit(column2)) {
153                         state = GAME_OVER;
154                     }
155                     break;
156             }
157             // 重新繪制界面
158             repaint();
159             // 休眠 1000/60 毫秒
160             Thread.sleep(1000 / 60);
161         }
162     }
163     /**
164      * 啟動方法
165      */
166     public static void main(String[] args) throws Exception {
167         JFrame frame = new JFrame();
168         BirdGame game = new BirdGame();
169         frame.add(game);
170         frame.setSize(440, 670);
171         frame.setLocationRelativeTo(null);
172         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
173         frame.setVisible(true);
174         game.action();
175     }
176 
177 }

4.心得分享

對於一些剛入門java的小伙伴來說,可能里面用到的一些方法,不是很熟悉這里建議大家可以通過API查詢可以學習了解一下swing、鼠標監聽以及ImageIO等代碼中涉及到的知識幫助大家順利完成本次的小項目!!!

 


免責聲明!

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



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