DEV Community

Cover image for Build A Flappy Bird Game In Few Lines Of Code
OpenReplay Tech Blog
OpenReplay Tech Blog

Posted on • Originally published at blog.openreplay.com

Build A Flappy Bird Game In Few Lines Of Code

by Emmanuel Uchenna

Building games used to be a hard task, but today many libraries can help you. This article will show you how to use TypeScript, PixiJS, and Parcel to build a flappy-bird-style game in a few lines of code.

Session Replay for Developers

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — an open-source session replay suite for developers. It can be self-hosted in minutes, giving you complete control over your customer data.

OpenReplay

Happy debugging! Try using OpenReplay today.


2D Game development does not have to be complex, thanks to modern tools and technologies like PixiJS and Parcel. While crafting engaging games was once reserved for seasoned programmers, these advancements have opened the door for anyone with a creative vision and a basic understanding of code to bring their ideas to life.

In this article, we will delve into the world of 2D game development using PixiJS and Parcel as a bundler. I will guide you through building a classic favorite - Flappy Bird - showcasing the ease and efficiency of this powerful combination.

Before delving in, we will establish a solid foundation by understanding the individual features and benefits of PixiJS and Parcel.

Overview of PixiJS

PixiJS is a free, lightweight 2D library that allows you to create beautiful digital content (images and other 2D visual content) with the fastest, most flexible 2D WebGL (Canvas) renderer. The library will be the engine that powers your game's visuals. It simplifies creating and manipulating graphics, handling tasks like animation, and rendering easily. It is a replacement for the now deprecated-Adobe Flash in the modern HTML5 world but provides better performance and pixel-level effects that go beyond what Adobe Flash could achieve.

Overview of Parcel

Parcel, on the other hand, is an open-source bundler designed to simplify the front-end development experience. Unlike traditional bundlers that often require extensive configuration, Parcel boasts an intuitive approach, allowing developers to focus on writing code rather than setting up complex build processes. This is achieved through its built-in support for various languages and file types, including popular choices like TypeScript and SASS and assets like images and fonts.

Parcel handles the behind-the-scenes work, bundling your code, images, and other resources into a single, optimized package. This streamlines the development process and ensures a smooth and performant experience for your game's players.

Setting Up Your Project

This section will guide you through setting the foundation for your Flappy Bird game using PixiJS and Parcel. We will cover the installation process, project structure, and configuration steps.

Initialize the Project

Open your terminal or command prompt and navigate to your desired project directory.

Run the command npm init to create a package.json file, which will store project information. Running this command will ask you a series of questions about your project. You can simply press ENTER to accept the suggested answers or customize them to your liking. Once you're done, you will end up with a file called package.json. This file contains important information about your project, which you can view using any text editor.

{
  "name": "flappy-bird-game-pixijs-parcel",
  "version": "1.0.0",
  "description": "This repository accompanies the technical article on `Building a Flappy Bird Game with PixiJS and Parcel` published on the OpenReplay Blog",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Eunit",
  "license": "MIT"
}
Enter fullscreen mode Exit fullscreen mode

Install Dependencies

Install the required tools using npm with the --save-dev flag to save them as development dependencies:

npm install --save-dev parcel typescript
Enter fullscreen mode Exit fullscreen mode

or

yarn add --dev parcel typescript
Enter fullscreen mode Exit fullscreen mode

The above command installs Parcel and TypeScript (for type safety).

Next, install PixiJS (the 2D library) and its type definition by running this command:

npm install pixi.js && npm install @types/pixi.js --save-dev
Enter fullscreen mode Exit fullscreen mode

Project Structure

Here is a recommended project structure to organize your code effectively. Create the following files in their appropriate folders as demonstrated below:

flappy-bird-game-pixijs-parcel/
  ├── src/
  │   ├── index.html
  │   ├── assets/  (for images, fonts, etc.)
  │   ├── js/
  │   │   ├── app.ts  (main application entry point)
  │   │   ├── app.js  (TypeScript generated file)
  │   │   └── ... other JavaScript/TypeScript files
  │   └── css/
  |       └── styles.css
  ├── package.json
  └── tsconfig.json  (for TypeScript configuration)
Enter fullscreen mode Exit fullscreen mode

Below is an image that shows the initial project structure:

Initial project structure

Configuring TypeScript and Parcel

In the following sections, you will learn the reasons why we are using TypeScript and Parcel to build our Flappy Bird 2D game application. I will also walk you through configuring TypeScript and Parcel.

Why TypeScript?

TypeScript provides numerous benefits that improve the development experience, particularly for larger projects. Its core strength lies in type checking, a process that identifies potential errors related to data types early on in the development process. This proactive approach significantly reduces bugs by preventing type mismatches that might go unnoticed until runtime.

For this reason and more, we will be using TypeScript instead of directly writing JavaScript codes. TypeScript will compile our code to JavaScript because the browser does not understand TypeScript codes.

Configuring TypeScript

Create a tsconfig.json file at the root of your project with the following minimal configuration:

{
  "compilerOptions": {
    "target": "es5", // Adjust target as needed
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "src/**/*.spec.ts",
    "dist",
    ".parcel-cache"
  ]
}
Enter fullscreen mode Exit fullscreen mode

This configuration file tells the TypeScript compiler to:

  • only compile files in the src folder. This is specified in the "include": [] block.
  • ignore files in the node_modules, dist, and .parcel-cache folders while also ignoring files that are spec files.

The TypeScript compiler must ignore the dist folder because it holds the dynamically generated files that Parcel created for you.

The dist folder contains dynamically generated files created by Parcel, including your HTML, CSS, and JavaScript files. These files all have the name index followed by random characters and may also include .map files.

These .map files are source maps generated by Parcel when you use the npx parcel command. They help browsers connect the bundled code back to the source code for easier debugging during development and production.

Why Parcel?

We are using Parcel because it stands out as a developer-centric bundler, offering a streamlined development experience. Here are some reasons why we are using Parcel:

  • Effortless Setup: Unlike other bundlers, Parcel requires minimal to no configuration, making it perfect for beginners and saving experienced developers valuable time.
  • Built-in Powerhouse: Parcel handles various assets like images and CSS without additional setup, eliminating the need for complex configurations.
  • Smart Dependencies: Parcel automatically tracks and bundles necessary dependencies, freeing you from manual configuration.
  • Speed Demon: Using multi-core processing, Parcel boasts lightning-fast build times, boosting development efficiency.
  • Effortless Code Splitting: Parcel automatically optimizes your code for performance through its "magic import" strategy, requiring no extra effort from you.
  • Real-time Updates: Parcel's hot module replacement feature allows you to see changes reflected instantly in the browser, eliminating the need for manual refreshes.
  • Multiple Languages: Parcel welcomes a variety of programming languages, including JavaScript and TypeScript, making it a versatile choice.
  • Developer-First: Parcel prioritizes a smooth and enjoyable development experience, allowing you to focus on writing code instead of wrestling with complex configurations.

Configuring Parcel

Parcel requires almost no configuration to get started. It is the self-proclaimed “blazing fast, zero configuration web application bundler.” To bundle your application, you only need to pass some flags while using the Parcel CLI.

With these steps, you have established a solid foundation for building your Flappy Bird game using PixiJS and Parcel. The next sections will delve into specific game development aspects.

Running Our Application On a Development Server

Instead of opening your HTML directly and manually refreshing whenever you make changes, Parcel offers a built-in development server. This server runs on your computer and automatically updates your application in the browser whenever you modify your code. This is called Hot Reloading, and it saves you the hassle of stopping, restarting, and refreshing every time you make an edit.

For instance, imagine changing the background color in your styles.css file to green. With the development server running, you will see this change reflected in your browser instantly, without any manual intervention.

Getting Started With Our Application

In this section, we will make sure our application is bundled by Parcel. I will walk you through the changes and updates you need to make to your files to get started.

First of all, open package.json and update it as follows:

{
  "name": "flappy-bird-game-pixijs-parcel",
  "version": "1.0.0",
  "description": "This repository accompanies the technical article on `Building a Flappy Bird Game with PixiJS and Parcel` published on the OpenReplay Blog",
  "main": "index.js", //=> remove this block
  "source": "src/index.html", //=> add this block
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "npx tsc && parcel", //=> add this block
    "build": "parcel build --dist-dir public" //=> Add this script
  },
  "author": "Eunit",
  "license": "MIT",
  "devDependencies": {
    "@types/pixi.js": "^5.0.0",
    "parcel": "^2.12.0",
    "typescript": "^5.3.3"
  },
  "dependencies": {
    "pixi.js": "^7.4.0"
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Remove "main": "index.js"
  • Add "source": "src/index.html". You replaced "main": "index.js" with "source": "src/index.html". "source" indicates the input, or source file, of your application and the specific path to the file.
  • Add this script: start": "npx tsc && parcel": Here, when you run npm start, it will first run npx tsc to compile your file and then run the parcel command.
  • "build": "parcel build --dist-dir public": Similar to the "start" command, you can create a custom command named "build" (or anything you prefer) that uses the parcel build command to optimize your code for production. This is typically done after development is complete. While Parcel's default output directory is called "dist", this command specifies a different output directory named "public" using the --dist-dir flag. This is done to avoid confusion with the default directory. We will cover running this command in a later step.

Populating Files with Initial Codes

Since we have our project properly set up, we will now start with populating and writing codes in our different files.

In src/index.html, paste the following code:

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="description" content="Building a Flappy Bird Game with PixiJS and Parcel" />
    <link rel="stylesheet" href="./css/styles.css">
    <title>Building a Flappy Bird Game with PixiJS and Parcel</title>
  </head>

  <body>

    <h1>
      Building a Flappy Bird Game with PixiJS and Parcel
    </h1>
    <script type="module" src="./js/app.js"></script>
  </body>

</html>
Enter fullscreen mode Exit fullscreen mode

In the above snippet, we bootstrapped an HTML file and then linked our stylesheet and script file. Note the type="module" in the script.

In src/css/styles.css, paste the following code:

html, body {
  overflow: hidden;
  position: fixed;
  width: 100%;
  height: 100%;
  padding: 0px;
  margin: 0;
  background: #fff;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

button {
  margin-bottom: 30px;
  font-size: 20px;
  background-color: skyblue;
  border: none;
  color: white;
  cursor: pointer;
  padding: 10px 15px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
}

.hide {
  visibility: hidden;
}

canvas {
  -webkit-tap-highlight-color: transparent;
}
Enter fullscreen mode Exit fullscreen mode

In src/js/app.ts, paste the following code to create an instance of the Pixi application.
You will instantiate the application with the required parameters: width, height, and backgroundColor that the canvas element will have when inserted into the HTML document.

For this example, we will use a "lightblue" background color to distinguish the element from the background of the HTML document.

import * as PIXI from 'pixi.js'

// create the PIXI application
let app = new PIXI.Application({
  width: 1440,
  height: 840,
  backgroundColor: 0xADD8E6,
  antialias: true,
  resolution: 1,
});

// append the canvas to the document
document.body.appendChild(app.view as any);
Enter fullscreen mode Exit fullscreen mode

Folder structure

To run your application, go to your project directory in the terminal and run the following command:

npm start
Enter fullscreen mode Exit fullscreen mode

This command starts the development server and builds your application. The output will tell you the server is running at http://localhost:1234.

Application running on http://localhost:1234

Simply open your web browser and visit this address to see your application running in real-time, with any changes automatically reflected.

Loaded application

NOTE 📝

Do not edit the .parcel-cache and dist folders. These folders are automatically generated and updated by Parcel when you run the npx parcel command.

Troubleshooting tip: If changes aren't showing in your browser, try refreshing the page first. If issues persist, stop the server (Ctrl+C in your terminal) and delete both .parcel-cache and dist folders. The .parcel-cache might hold outdated code, and deleting it can resolve problems. Then, run npx parcel src/index.html again. This will recreate the folders with your updated code.

Building the Bird Animation Using Bird Assets

I used assets from Open Game Art then, a "Sprite" object was created in Pixi.js and used an interval timer to update its texture. This creates the illusion of a flying bird animation. Download all images used in the game here.

Bird Animation Using Bird Assets

The provided code showcases the animation implementation details. Paste the following code in src/app.ts

Check out the complete code hosted on GitHub Gist

Next, it is time to run our app. Run the following command to let Parcel bundle your application. This will first run the TypeScript compiler script, which will cause TypeScript to compile the app.ts to app.js , before spinning the Parcel bundler:

npm start
Enter fullscreen mode Exit fullscreen mode

Command to run our application

Your application should be running on http://localhost:1234/

Below is a demo of our game:

Flappy-Bird-Demo GIF

Alternatives to PixiJS

There are several other alternatives for HTML5 Canvas game frameworks out there such as:

Resources and Further Readings

The accompanying repository for this article can be found on GitHub.

Other resources:

Conclusion

This article is a concise guide to building a Flappy Bird game using PixiJS and Parcel. PixiJS is a lightweight library for creating 2D visuals, while Parcel is a user-friendly tool that streamlines the development process.

Through this article, you have learned how to set up a Parcel and PixiJS project, you learned how to configure the tools required for your Flappy Bird game.

Top comments (0)