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