• Java实例---flappy-bird实例[最终版]


    代码分析

    解析版: Java实例---flappy-bird实例解析

    完整版:

    TestBirdFly.java

      1 package testfly;
      2 
      3 import java.awt.Color;
      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 public class TestBirdFly extends JPanel {
     17     Bird bird;
     18     Column column1, column2; 
     19     Ground ground;
     20     BufferedImage background;
     21     boolean gameOver;
     22     boolean started;
     23     BufferedImage gameoverImg;
     24     //分数
     25     int score;
     26     /** 初始化 BirdGame 的属性变量 */
     27     public TestBirdFly() throws Exception {
     28         score = 0;
     29         bird = new Bird();
     30         column1 = new Column(1);
     31         column2 = new Column(2);
     32         ground = new Ground();
     33         gameOver=false;
     34         background = ImageIO.read(
     35             getClass().getResource("bg.png")); 
     36         gameoverImg= ImageIO.read(
     37                 getClass().getResource("gameover.png"));
     38     }
     39     
     40     /** "重写(修改)"paint方法实现绘制 */
     41     public void paint(Graphics g){
     42         g.drawImage(background, 0, 0, null);
     43         g.drawImage(column1.image, 
     44             column1.x-column1.width/2, 
     45             column1.y-column1.height/2, null);
     46         g.drawImage(column2.image, 
     47             column2.x-column2.width/2, 
     48             column2.y-column2.height/2, null);
     49         //在paint方法中添加绘制分数的算法
     50         Font f = new Font(Font.SANS_SERIF,
     51                 Font.BOLD, 40);
     52         g.setFont(f);
     53         g.drawString(""+score, 40, 60);
     54         g.setColor(Color.WHITE);
     55         g.drawString(""+score, 40-3, 60-3);
     56         
     57         g.drawImage(ground.image, ground.x, 
     58             ground.y, null);
     59         if (gameOver){
     60         g.drawImage(gameoverImg,0,0,null);
     61         return;
     62         }
     63         //旋转(rotate)绘图坐标系,是API方法
     64         Graphics2D g2 = (Graphics2D)g;
     65         g2.rotate(-bird.alpha, bird.x, bird.y);
     66         g.drawImage(bird.image, 
     67             bird.x-bird.width/2, 
     68             bird.y-bird.height/2, null);
     69         g2.rotate(bird.alpha, bird.x, bird.y);
     70     }//paint方法的结束
     71     //BirdGame中添加方法action()
     72     public void action() throws Exception {
     73         MouseListener l=new MouseAdapter(){
     74             //Mouse 老鼠 Pressed按下
     75             public void mousePressed(                      
     76                     MouseEvent e){
     77                 //鸟向上飞扬
     78                 started=true;
     79                 bird.flappy();
     80                 
     81             }
     82         };
     83         //将l挂接到当前的面板(game)上
     84         addMouseListener(l);
     85         
     86         while(true){
     87             
     88             
     89             //计分逻辑
     90             if(!gameOver||started){
     91                 ground.step();
     92                 column1.step();
     93                 column2.step();
     94                 bird.step();
     95             }
     96             bird.fly();
     97             ground.step();
     98             
     99             if(bird.hit(ground) ||bird.hit(column1)||bird.hit(column2)){
    100                 gameOver=true;
    101             }
    102             bird.fly();
    103             if (bird.x==column1.x||bird.x==column2.x){
    104                 score++;
    105             }repaint();
    106             
    107             Thread.sleep(1000/60);
    108         }
    109     }
    110     
    111     /** 启动软件的方法 */
    112     public static void main(String[] args)
    113         throws Exception {
    114         JFrame frame = new JFrame();
    115         TestBirdFly game = new TestBirdFly();
    116         frame.add(game);
    117         frame.setSize(440, 670);
    118         frame.setLocationRelativeTo(null);
    119         frame.setDefaultCloseOperation(
    120                 JFrame.EXIT_ON_CLOSE);
    121         frame.setVisible(true);
    122         game.action();
    123     }
    124 }
    125 /** 地面 */
    126 class Ground{
    127     BufferedImage image;
    128     int x, y;
    129     int width;
    130     int height;
    131     public Ground() throws Exception {
    132         image = ImageIO.read(
    133           getClass().getResource("ground.png"));
    134         width = image.getWidth();
    135         height = image.getHeight();
    136         x = 0;
    137         y = 500;
    138     }//地面的构造器结束
    139     //地面的类体中,添加方法,地面移动一步
    140     public void step(){
    141         x--;
    142         if(x==-109){
    143             x = 0;
    144         }
    145     }
    146 }//地面类的结束
    147 /** 柱子类型,x,y是柱子的中心点的位置 */
    148 class Column{
    149     BufferedImage image;
    150     int x,y;
    151     int width, height;
    152     /** 柱子中间的缝隙 */
    153     int gap;
    154     int distance;//距离,两个柱子之间的距离
    155     Random random = new Random();
    156     /** 构造器:初始化数据,n代表第几个柱子 */
    157     public Column(int n) throws Exception {
    158         image=ImageIO.read(
    159           getClass().getResource("column.png"));
    160         width = image.getWidth();
    161         height = image.getHeight();
    162         gap=144;
    163         distance = 245;
    164         x = 550+(n-1)*distance;
    165         y = random.nextInt(218)+132;
    166     }
    167     //在Column中添加方法 step,在action调用此方法
    168     public void step(){
    169         x--;
    170         if(x==-width/2){
    171             x = distance * 2 - width/2;
    172             y = random.nextInt(218)+132;
    173         }
    174     }
    175 }//Column类的结束
    176 /** 鸟类型, x,y是鸟类型中心的位置 */
    177 class Bird{
    178     BufferedImage image;
    179     int x,y;
    180     int width, height;
    181     int size;//鸟的大小,用于碰撞检测
    182     
    183     //在Bird类中增加属性,用于计算鸟的位置
    184     double g;//  重力加速度
    185     double t;//  两次位置的间隔时间
    186     double v0;// 初始上抛速度
    187     double speed;// 是当前的上抛速度
    188     double s;//     是经过时间t以后的位移
    189     double alpha;// 是鸟的倾角 弧度单位
    190     //在Bird类中定义
    191     //定义一组(数组)图片,是鸟的动画帧
    192     BufferedImage[] images;
    193     //是动画帧数组元素的下标位置
    194     int index;
    195     
    196     public Bird() throws Exception {
    197         image=ImageIO.read(
    198             getClass().getResource("0.png"));
    199         width = image.getWidth();
    200         height = image.getHeight();
    201         x = 132;
    202         y = 280;
    203         size = 10;
    204         g = 1;
    205         v0 = 10;
    206         t = 0.25;
    207         speed = v0;
    208         s = 0;
    209         alpha=0;
    210         //创建数组,创建8个元素的数组
    211         //是8个空位置,没有图片对象,
    212         //8个位置的序号: 0 1 2 3 4 5 6 7
    213         images = new BufferedImage[8];
    214         for(int i=0; i<8; i++){
    215             //i = 0 1 2 3 4 5 6 7 
    216             images[i] = ImageIO.read(
    217                 getClass().getResource(i+".png"));
    218         }
    219         index = 0;
    220     }
    221     //在Bird中添加飞翔(fly)的代码
    222     public void fly(){
    223         index++;
    224         image = images[(index/12) % 8];
    225     }
    226     //在Bird中添加鸟的移动方法
    227     public void step(){
    228         double v0 = speed;
    229         s = v0*t + g*t*t/2;//计算上抛运动位移
    230         y = y-(int)s;//计算鸟的坐标位置
    231         double v = v0 - g*t;//计算下次的速度
    232         speed = v;
    233 //        if(y>=500){//如果到达地面,就重新抛起
    234 //            y = 280;
    235 //            speed = 35;
    236 //        }
    237         //调用Java API提供的反正切函数,计算倾角
    238         alpha = Math.atan(s/8);
    239     }
    240     //在Bird中添加方法
    241     public void flappy(){
    242         //重新设置初始速度,重新向上飞
    243         speed = v0;
    244     }
    245 //在鸟中添加方法hit
    246     // 检测当前鸟是否碰到地面ground
    247     //如果返回true表示发生碰撞
    248     //否则返回false表示没有碰撞
    249 
    250     
    251 public boolean hit (Ground ground){
    252     boolean hit =y+size/2>ground.y;
    253     if(hit){
    254         y=ground.y-size/2;
    255         
    256     }
    257     return hit;
    258 }
    259 //检测当前鸟是否撞倒柱子
    260 public boolean hit(Column column){
    261     //先检查是否在柱子的范围以内
    262    if  (x>column.x-column.width/2-size/2&&x<column
    263            .x+column.width/2+size/2){
    264        if(y>column.y-column.gap/2+size/2&&y<column.y+column.gap/2-size/2){
    265        return false;
    266        
    267   
    268    
    269                }
    270        return true;
    271     
    272            }
    273    return false;
    274     }
    275 }
    View Code

    截图

    源码下载

    点击下载

  • 相关阅读:
    Vue.Draggable 文档总结
    JS深度判断两个对象字段相同
    vue防止按钮在短时间内被多次点击的方法
    设计模式学习-单例模式
    设计模式学习---策略模式
    C#7.0中的解构功能---Deconstruct
    讲一下Asp.net core MVC2.1 里面的 ApiControllerAttribute
    .NET Core 使用RabbitMQ
    IL指令详细表
    redis 4.0.13 -- 哨兵模式
  • 原文地址:https://www.cnblogs.com/ftl1012/p/flappyBird.html
Copyright © 2020-2023  润新知