
In this article, we will build the famous Flappy Bird Game in Java with Swing. We all have played this game on our phones, here we will create the desktop version of this application. Flappy Bird is a game where the bird must keep flying in the air without hitting the ground or the obstacles in the way.
Project Overview: Flappy Bird Game in Java
Project Name: | Flappy Bird Game in Java |
Abstract: | It’s a GUI-based project used with the swing library to organize all the elements that work under the Flappy Bird Game. |
Language Used: | Java |
IDE: | VS Code |
Java version (Recommended): | Java SE 18.0. 2.1 |
Database: | None |
Type: | Desktop Application |
Recommended for: | Beginners of Java |
Time to build: | 1-2 hours |
What you will learn?
- Building logic with the help of functions, loops, conditionals, and variables
- Handling Classes and Object creations
- Java Swing and Java AWT for creating a user-friendly GUI
Features:
- Use the spacebar key to fly high
- Create obstacles and birds with the help of Java Swing
- Keep updating the current score and the high score as the bird passes by an obstacle
Complete Code for the Flappy Bird game in Java
To create the shape of the bird, wall, and background we have used these images (download below). Now, Create a folder for the project and add all the images in it. Create a file named Game.java and add the below lines of code to it.
Click here to download resources used in this game
To detect collision between the bird and the wall or ground, nested if-else conditions are used to compare each object’s coordinates. Appropriate comments are provided in the code for explanation.
import javax.swing.*;import java.awt.*;import java.awt.event.*;import javax.swing.JPanel;import javax.swing.Timer;import java.awt.image.ImageObserver;import javax.swing.ImageIcon;import java.util.ArrayList;import java.util.List;import java.util.Random;// Bird class is used to create a bird object in the game and to move it around the screenclass Bird extends GameObject {private ProxyImage proxyImage; // ProxyImage object used to load the image of the birdprivate Tube[] tube; // Array of Tube objects used to create the walls in the game// Constructorpublic Bird(int x, int y){super(x, y);if(proxyImage == null) {proxyImage = new ProxyImage("bird.png"); // Load the image of the bird}this.image = proxyImage.loadImage().getImage();this.width = image.getWidth(null); //Set the width and height of the birdthis.height = image.getHeight(null);this.x -= width; // Adjust the x position of the birdthis.y -= height; // Adjust the y position of the birdtube = new Tube[1]; // Create a new array of Tube objectstube[0] = new Tube(900, Window.HEIGHT - 60); // Create the first wallthis.dy = 2; // Set the initial speed of the bird}// Method used to move the birdpublic void tick() {if(dy < 5) { // If the speed of the bird is less than 5dy += 2; // Increase the speed of the bird}this.y += dy; // Move the bird down the screentube[0].tick(); // Move the wall down the screencheckWindowBorder(); // Check if the bird has hit the top or bottom of the screen}public void jump() {if(dy > 0) { // If the speed of the bird is greater than 0dy = 0; // Set the speed of the bird to 0}dy -= 15; // Move the bird up the screen}// Method used to check if the bird has hit the top or bottom of the screenprivate void checkWindowBorder() {if(this.x > Window.WIDTH) { // If the bird has moved off the right side of the screenthis.x = Window.WIDTH; // Set the x position of the bird to the right side of the screen}if(this.x < 0) { // If the bird has moved off the left side of the screenthis.x = 0; // Set the x position of the bird to the left side of the screen}if(this.y > Window.HEIGHT - 50) { // If the bird has moved off the bottom of the screenthis.y = Window.HEIGHT - 50; // Set the y position of the bird to the bottom of the screen}if(this.y < 0) { // If the bird has moved off the top of the screenthis.y = 0; // Set the y position of the bird to the top of the screen}}// Method used to check if the bird has hit the wallpublic void render(Graphics2D g, ImageObserver obs) {g.drawImage(image, x, y, obs); // Draw the birdtube[0].render(g, obs); // Draw the wall}public Rectangle getBounds() {return new Rectangle(x, y, width, height);}}// Tube class is used to create a wall object in the game and to move it around the screenclass TubeColumn {private int base = Window.HEIGHT - 60;private List<Tube> tubes;private Random random;private int points = 0; // Variable used to keep track of the scoreprivate int speed = 5; // Variable used to set the speed of the wallprivate int changeSpeed = speed;public TubeColumn() {tubes = new ArrayList<>();random = new Random();initTubes();}// Method used to create the wallprivate void initTubes() {int last = base;int randWay = random.nextInt(10);// Create the first wall in the game and set the position of the wall to the right side of the screenfor (int i = 0; i < 20; i++) {Tube tempTube = new Tube(900, last); // Create a new Tube objecttempTube.setDx(speed); // Set the speed of the walllast = tempTube.getY() - tempTube.getHeight(); // Set the position of the wallif (i < randWay || i > randWay + 4) { // If the wall is not in the middle of the screentubes.add(tempTube); // Add the wall to the array of Tube objects}}}// Method used to check the position of the walls and to create new wallspublic void tick() {for (int i = 0; i < tubes.size(); i++) { // Loop through the array of Tube objectstubes.get(i).tick(); // Get the position of the wallif (tubes.get(i).getX() < 0) { // If the wall has moved off the left side of the screentubes.remove(tubes.get(i)); // Remove the wall from the array of Tube objects}}if (tubes.isEmpty()) { // If the array of Tube objects is emptythis.points += 1; // Increase the score by 1if (changeSpeed == points) {this.speed += 1; // Increase the speed of the wall by 1changeSpeed += 5;}initTubes(); // Create a new wall}}// Method used to draw the wallspublic void render(Graphics2D g, ImageObserver obs) {for (int i = 0; i < tubes.size(); i++) { // Loop through the array of Tube objectstubes.get(i).render(g, obs); // Draw the wall}}public List<Tube> getTubes() {return tubes;}public void setTubes(List<Tube> tubes) {this.tubes = tubes;}public int getPoints() {return points;}public void setPoints(int points) {this.points = points;}}interface IStrategy {public void controller(Bird bird, KeyEvent kevent);public void controllerReleased(Bird bird, KeyEvent kevent);}// Controller class is used to control the movement of the birdclass Controller implements IStrategy {public void controller(Bird bird, KeyEvent kevent) {}public void controllerReleased(Bird bird, KeyEvent kevent) {if(kevent.getKeyCode() == KeyEvent.VK_SPACE) { // If the space bar is pressed bird jumpsbird.jump();}}}interface IImage {public ImageIcon loadImage();}// ProxyImage class is used to load the image of all the objectsclass ProxyImage implements IImage {private final String src;private RealImage realImage;public ProxyImage(String src) {this.src = src;}public ImageIcon loadImage() {if(realImage == null) { // If the image has not been loadedthis.realImage = new RealImage(src); // Load the image}return this.realImage.loadImage();}}class RealImage implements IImage {private final String src;private ImageIcon imageIcon;public RealImage(String src) {this.src = src;}@Overridepublic ImageIcon loadImage() {if(imageIcon == null) {this.imageIcon = new ImageIcon(getClass().getResource(src));}return imageIcon;}}// this class is used to create the window for the gameabstract class GameObject {protected int x, y;protected int dx, dy;protected int width, height;protected Image image;public GameObject(int x, int y) {this.x = x;this.y = y;}public int getX() {return x;}public int getY() {return y;}public int getDx() {return dx;}public int getDy() {return dy;}public int getWidth() {return width;}public int getHeight() {return height;}public Image getImage() {return image;}public void setX(int x) {this.x = x;}public void setY(int y) {this.y = y;}public void setDx(int dx) {this.dx = dx;}public void setDy(int dy) {this.dy = dy;}public void setWidth(int width) {this.width = width;}public void setHeight(int height) {this.height = height;}public void setImage(Image image) {this.image = image;}public abstract void tick();public abstract void render(Graphics2D g, ImageObserver obs);}// this class is used to create the walls for the gameclass Tube extends GameObject {private ProxyImage proxyImage;public Tube(int x, int y) {super(x, y);if (proxyImage == null) { // If the image has not been loadedproxyImage = new ProxyImage("TubeBody.png"); // Load the image}this.image = proxyImage.loadImage().getImage(); // Get the imagethis.width = image.getWidth(null); // set the width of the imagethis.height = image.getHeight(null); // set the height of the image}@Overridepublic void tick() {this.x -= dx;}@Overridepublic void render(Graphics2D g, ImageObserver obs) {g.drawImage(image, x, y, obs);}public Rectangle getBounds() {return new Rectangle(x, y, width, height);}}// this class is used to create the background for the gameclass Game extends JPanel implements ActionListener {private boolean isRunning = false; // Variable used to check if the game is runningprivate ProxyImage proxyImage; // Variable used to load the imageprivate Image background; // Variable used to store the imageprivate Bird bird; // Variable used to store the bird objectprivate TubeColumn tubeColumn; // Variable used to store the wall objectprivate int score;private int highScore;public Game() {proxyImage = new ProxyImage("background.jpg"); // Load the imagebackground = proxyImage.loadImage().getImage(); // Get the imagesetFocusable(true);setDoubleBuffered(false);addKeyListener(new GameKeyAdapter());Timer timer = new Timer(15, this);timer.start();}@Overridepublic void actionPerformed(ActionEvent e) {Toolkit.getDefaultToolkit().sync(); // Synchronize the display on some systemsif (isRunning) {bird.tick(); // Update the birdtubeColumn.tick(); // Update the wallcheckColision(); // Check if the bird has collided with the wallscore++; // Increase the score by 1}repaint();}@Overridepublic void paint(Graphics g) {Graphics2D g2 = (Graphics2D) g;g2.drawImage(background, 0, 0, null);if (isRunning) {this.bird.render(g2, this);this.tubeColumn.render(g2, this);g2.setColor(Color.black);g.setFont(new Font("MV Boli", 1, 30));g2.drawString("Current score: " + this.tubeColumn.getPoints(), 10, 50);} else {g2.setColor(Color.black);g.setFont(new Font("MV Boli", 1, 50));g2.drawString("Press Enter to Start Game", Window.WIDTH / 2 - 350, Window.HEIGHT / 2);g2.setColor(Color.black);g.setFont(new Font("MV Boli", 1, 15));}g2.setColor(Color.black);g.setFont(new Font("MV Boli", 1, 30));g2.drawString("High Score: " + highScore, Window.WIDTH - 230, 50);g.dispose();}private void restartGame() {if (!isRunning) {this.isRunning = true;this.bird = new Bird(Window.WIDTH / 2, Window.HEIGHT / 2); // Create the bird object in the middle of the screenthis.tubeColumn = new TubeColumn(); // Create the wall object}}private void endGame() {this.isRunning = false;if (this.tubeColumn.getPoints() > highScore) { // If the current score is higher than the high scorethis.highScore = this.tubeColumn.getPoints(); // Set the high score to the current score}this.tubeColumn.setPoints(0); // Set the current score to 0}private void checkColision() {Rectangle rectBird = this.bird.getBounds(); // Get the bounds of the birdRectangle rectTube; // Create a variable to store the bounds of the wallfor (int i = 0; i < this.tubeColumn.getTubes().size(); i++) { // Loop through all the wallsTube tempTube = this.tubeColumn.getTubes().get(i); // Get the current wallrectTube = tempTube.getBounds(); // Get the bounds of the current wallif (rectBird.intersects(rectTube)) { // If the bird has collided with the wallendGame(); // End the game}}}class GameKeyAdapter extends KeyAdapter {private final Controller controller;public GameKeyAdapter() {controller = new Controller();}@Overridepublic void keyPressed(KeyEvent e) {if (e.getKeyCode() == KeyEvent.VK_ENTER) {restartGame();}}@Overridepublic void keyReleased(KeyEvent e) {if (isRunning) {controller.controllerReleased(bird, e);}}}}class Window {public static int WIDTH = 900; // Set the width of the windowpublic static int HEIGHT = 600; // Set the height of the windowpublic Window(int width, int height, String title, Game game) {JFrame frame = new JFrame();frame.add(game);frame.setTitle(title);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Close the window when the user clicks the close buttonframe.setMaximumSize(new Dimension(width, height)); // Set the maximum size of the windowframe.setPreferredSize(new Dimension(width, height)); // Set the preferred size of the windowframe.setMinimumSize(new Dimension(width, height));frame.setLocationRelativeTo(null);frame.setResizable(false);frame.setVisible(true);}// Run the application from herepublic static void main(String[] args) {Game game = new Game();try {javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {java.util.logging.Logger.getLogger(Window.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);}java.awt.EventQueue.invokeLater(() -> {Window window = new Window(WIDTH, HEIGHT, "Flappy Bird", game);});}}
Output:
Hope you enjoyed building this project. You can try changing the controls of the game or adding your own colors and changing the dimensions according to you.
Also Read:
- Dino Game in Java
- Java Games Code | Copy And Paste
- Supply Chain Management System in Java
- Survey Management System In Java
- Phone Book in Java
- Email Application in Java
- Inventory Management System Project in Java
- Blood Bank Management System Project in Java
- Electricity Bill Management System Project in Java
- CGPA Calculator App In Java
- Chat Application in Java
- 100+ Java Projects for Beginners 2023
- Airline Reservation System Project in Java
- Password and Notes Manager in Java
- GUI Number Guessing Game in Java
- How to create Notepad in Java?
- Memory Game in Java
- Simple Car Race Game in Java
- ATM program in Java
- Drawing Application In Java
- Tetris Game in Java
- Pong Game in Java
- Hospital Management System Project in Java
- Ludo Game in Java
- Restaurant Management System Project in Java
- Flappy Bird Game in Java
- ATM Simulator In Java
- Brick Breaker Game in Java
- Best Java Roadmap for Beginners 2023
- Snake Game in Java