Java实现经典游戏Flappy Bird的示例代码

作者:小虚竹and掘金 时间:2022-03-28 07:05:37 

前言

《布谷鸟闯关-简单版》是一个基于java的布谷鸟闯关游戏,摁上键控制鸟的位置穿过管道间的缝隙,需要做碰撞检测,监听键盘事件,背景图片的切换,障碍物管道产生时y轴上需要随机位置。

主要设计

  • 设计游戏界面,用swing实现

  • 设计背景

  • 设计移动墙

  • 设计布谷鸟

  • 设计障碍物

  • 设计背景音乐和音效

  • 由几个关键的布尔类型变量start,crash,over是产生键键盘事件时用来控制界面显示的弹框的

  • 操作:空格键开始游戏,enter键取消"game over"弹框,摁空格键继续,上键(up)是对鸟的控制

  • 工具类ImageMgr专用于读取图片

功能截图

游戏开始:

Java实现经典游戏Flappy Bird的示例代码

控制布谷鸟

Java实现经典游戏Flappy Bird的示例代码

飞过障碍物

Java实现经典游戏Flappy Bird的示例代码

撞到障碍物,游戏结束

Java实现经典游戏Flappy Bird的示例代码

代码实现

游戏启动类


public class Main {
   public static void main(String[] args) {
       Cuckoo frame = new Cuckoo();
       while (true){
           try {
               Thread.sleep(100);
               if(!frame.crash){
                   frame.repaint();
               }
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
   }
}

核心类

/**
* 1.窗口
* 2.背景
* 3.移动墙
* 4.布谷鸟
* 5.障碍物
* 6.背景音乐
* 7.音效
* 8.欢迎界面
* 9.game over
*/
public class Cuckoo extends Frame {
   private int step;
   private int score;
   private int height;
   private int moveLeft;
   private int pipeMove;

boolean crash = false;
   private boolean over = false;
   private boolean start = false;

private static int bird_y = 270;
   private static final int L_X = 800;
   private static final int L_Y = 200;
   private static final int SPEED = 2;
   private static final int BIRD_X = 100;
   private static final int GAME_X_Y_0 = 0;
   private static final int GAME_WIDTH = 288;
   private static final int GAME_HEIGHT = 512;
   private static final int PIPE_WIDTH = ImageMgr.pipe.getWidth();
   private static final int PIPE_HEIGHT = ImageMgr.pipe.getHeight();
   private static final int READY_WIDTH = ImageMgr.ready.getWidth();
   private static final int READY_HEIGHT = ImageMgr.ready.getHeight();
   private static final int START_WIDTH = ImageMgr.start.getWidth();
   private static final int BIRD_WIDTH = ImageMgr.bird[0].getWidth();
   private static final int BIRD_HEIGHT = ImageMgr.bird[0].getWidth();
   private static final int GROUND_HEIGHT = ImageMgr.ground.getHeight();
   private static final int GAME_OVER_WIDTH = ImageMgr.gameOver.getWidth();
   private static final int GAME_OVER_HEIGHT = ImageMgr.gameOver.getHeight();
   private static final int BACKGROUND_HEIGHT = ImageMgr.background.getHeight();

private static Image offScreenImage;
   private static Rectangle pipeRectangle1;
   private static Rectangle pipeRectangle2;
   private static Rectangle birdRectangle;

Cuckoo(){
       setVisible(true);
       setResizable(false);
       //setTitle("cuckoo");
       setBounds(L_X, L_Y,GAME_WIDTH,GAME_HEIGHT);

addKeyListener(new KeyAdapter() {
           @Override
           public void keyPressed(KeyEvent e) {
               switch (e.getKeyCode()){
                   case KeyEvent.VK_SPACE : start = true;break;
                   case KeyEvent.VK_ENTER : reopen();break;
               }
           }

@Override
           public void keyReleased(KeyEvent e) {
               if (e.getKeyCode() == KeyEvent.VK_UP) {
                   bird_y -= 20;
               }
           }
       });

addWindowListener(new WindowAdapter() {
           @Override
           public void windowClosing(WindowEvent e) {
               System.exit(0);
           }
       });
   }

@Override
   public void update(Graphics g) {
       if(offScreenImage == null){
           offScreenImage = this.createImage(GAME_WIDTH,GAME_HEIGHT);
       }
       Graphics gOffScreen = offScreenImage.getGraphics();
       Color c = gOffScreen.getColor();
       gOffScreen.setColor(Color.BLACK);
       gOffScreen.fillRect(0,0,GAME_WIDTH,GAME_HEIGHT);
       gOffScreen.setColor(c);
       paint(gOffScreen);
       g.drawImage(offScreenImage,0,0,null);
   }

@Override
   public void paint(Graphics g) {
       background(g);
       ground(g);
       start(g);

if(start){
           bird(g);
           pipe(g);
           colliedWith();
           gameOver(g);
           score(g);
       }

}

//如果碰撞后,可以嗯enter键重开
   private void reopen(){
       if(crash){
           score = 0;
           over = false;
           crash = false;
           start = false;
           moveLeft = 0;
           pipeMove = 0;
           //bird_y = 270;//继上次死的位置开始
       }
   }

private void score(Graphics g){
       Font font = new Font("微软雅黑",Font.BOLD,18);
       g.setFont(font);
       Color c = g.getColor();
       g.setColor(Color.lightGray);
       g.drawString("score " + score,20,70);
       g.setColor(c);
   }

private void background(Graphics g){
       g.drawImage(ImageMgr.background,
               GAME_X_Y_0 - moveLeft,GAME_X_Y_0,
               GAME_WIDTH - moveLeft,GAME_HEIGHT,
               GAME_X_Y_0,
               GAME_X_Y_0,
               GAME_WIDTH,
               GAME_HEIGHT, null);
       g.drawImage(ImageMgr.background,
               GAME_WIDTH-1 - moveLeft,GAME_X_Y_0,
               GAME_WIDTH*2 - moveLeft, GAME_HEIGHT,
               GAME_X_Y_0,
               GAME_X_Y_0,
               GAME_WIDTH,
               GAME_HEIGHT, null);
       moveLeft += SPEED;
       //游戏启动计分
       if(start && moveLeft % 100 == 0){
           score += 1;
       }
       if(moveLeft >= GAME_WIDTH){
           moveLeft = 0;
       }
   }

private void ground(Graphics g){
       g.drawImage(ImageMgr.ground,0,BACKGROUND_HEIGHT - GROUND_HEIGHT,null);
   }

private void bird(Graphics g){
       Color c = g.getColor();
       g.setColor(Color.BLUE);
       g.drawRect(BIRD_X, bird_y,BIRD_WIDTH,BIRD_HEIGHT);
       g.setColor(c);

g.drawImage(ImageMgr.bird[step++], BIRD_X, bird_y,null);
       if(step >= ImageMgr.bird.length){
           step = 0;
       }

if(start){
           bird_y += 4;
       }

birdRectangle = new Rectangle(BIRD_X,bird_y,BIRD_WIDTH,BIRD_HEIGHT);
   }

private void pipe(Graphics g){
       drawPipe(g);
       pipeMove += SPEED;
       if(pipeMove >= GAME_WIDTH + PIPE_WIDTH){
           pipeMove = 0;
           Random ran = new Random();
           height = ran.nextInt(10)*20;
           drawPipe(g);
       }

}

private void drawPipe(Graphics g){
       g.setColor(Color.RED);
//        g.drawRect(GAME_WIDTH - pipeMove,GAME_HEIGHT/5*3 - height,PIPE_WIDTH,PIPE_HEIGHT);
//        g.drawRect(GAME_WIDTH - pipeMove,-GAME_HEIGHT/5*4 - height,PIPE_WIDTH,PIPE_HEIGHT);

g.drawImage(ImageMgr.pipe,GAME_WIDTH - pipeMove,GAME_HEIGHT/5*3 - height,null);
       g.drawImage(ImageMgr.pipe,GAME_WIDTH - pipeMove,-GAME_HEIGHT/5*4 - height,null);

pipeRectangle1 = new Rectangle(GAME_WIDTH - pipeMove,GAME_HEIGHT/5*3 - height,PIPE_WIDTH,PIPE_HEIGHT);
       pipeRectangle2 = new Rectangle(GAME_WIDTH - pipeMove,-GAME_HEIGHT/5*4 - height,PIPE_WIDTH,PIPE_HEIGHT);
   }

private void gameOver(Graphics g){
       if(over){
           g.drawImage(ImageMgr.gameOver,GAME_WIDTH/2 - GAME_OVER_WIDTH/2, GAME_HEIGHT/2 - GAME_OVER_HEIGHT,null);
       }
   }

private void start(Graphics g){
       if(!start){
           g.drawImage(ImageMgr.ready,GAME_WIDTH/2 - READY_WIDTH/2, GAME_HEIGHT/2 - READY_HEIGHT,null);
           g.drawImage(ImageMgr.start,GAME_WIDTH/2 - START_WIDTH/2, GAME_HEIGHT/2,null);
       }
   }

private void colliedWith(){
       if(birdRectangle.intersects(pipeRectangle1) || birdRectangle.intersects(pipeRectangle2)){
           crash = true;
           over = true;
           //gameOver(g);
       }
   }
}

工具类

public class ImageMgr {
   static BufferedImage background,ground,pipe,gameOver,start,ready;
   static BufferedImage[] bird = new BufferedImage[3];
   private static final ImageMgr INSTANCE = new ImageMgr();
   //nothing
   private ImageMgr(){
       initImage();
   };

private void initImage(){
       try {
           background = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/bg_light.png")));
           ground = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/ground.png")));
           pipe = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/pipe.png")));
           gameOver = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/gameover.png")));
           start = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/start.png")));
           ready = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/ready.png")));

for(int i = 0;i < 3;i++){
               bird[i] = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/blueBird_" + (i+1) + ".png")));
           }
       } catch (IOException ex) {
           ex.printStackTrace();
       }
   }

public static ImageMgr getInstance(){
       return INSTANCE;
   }
}

来源:https://juejin.cn/post/7068587606967058463

标签:Java,Flappy,Bird,游戏
0
投稿

猜你喜欢

  • C# 调用C++写的dll的实现方法

    2022-10-25 11:36:56
  • Java设计模式之java装饰者模式详解

    2023-10-27 06:17:04
  • java多线程编程之join方法的使用示例

    2022-10-06 05:09:38
  • 详解Java中类的加载与其初始化

    2023-06-21 04:56:45
  • Java语言中cas指令的无锁编程实现实例

    2022-10-13 19:20:28
  • IDEA中的.iml文件和.idea文件夹

    2023-11-23 11:47:19
  • springboot验证码生成以及验证功能举例详解

    2023-11-19 03:14:23
  • Netty与NIO超详细讲解

    2022-08-16 00:44:37
  • 解析maven的用法和几个常用的命令(推荐)

    2022-04-16 23:31:15
  • 浅析C#静态类,静态构造函数,静态变量

    2022-04-10 03:33:14
  • java&javascript自定义加密数据传输代码示例

    2021-11-29 02:09:33
  • Java使用arthas修改日志级别详解

    2023-02-04 23:09:26
  • 详解Spring中的Environment外部化配置管理

    2023-11-23 05:24:24
  • C# MVC模式中应该怎样区分应用程序逻辑(Controller层)和业务逻辑(Model层)?

    2022-06-25 12:34:55
  • java多线程抓取铃声多多官网的铃声数据

    2023-12-18 23:20:05
  • C#实现单词本功能

    2021-11-06 13:08:23
  • Java中Future和FutureTask的示例详解及使用

    2023-01-29 11:48:42
  • Java解析json报文实例解析

    2023-07-18 21:33:58
  • Spring Cloud Hystrix 服务降级限流策略详解

    2022-05-02 15:20:27
  • 员工管理系统java版

    2022-05-04 23:33:18
  • asp之家 软件编程 m.aspxhome.com