Build a flappy bird copy with TypeScript & Pixi.js
Online demo link and the code repo(160 lines of TypeScript code).
This article is about what I learned from building a small project while learning Typescript & Pixi.js and having fun.
Before talking details of the implementation, here are my two cents about TypeScript and Pixi.js
The first benefit TypeScript provided strong type checking, the code below is an example:
If we are lucky, we can find the typo with locale in the development stage, but sometimes this kind of errors are being pushed into codebase’s master branch without being noticed and will waste a lot of time on debugging in the production environment.
The second benefit TypeScript provided is easing suffering from with developing a javascript library I’m unfamiliar with, very often I worry a lot whether I’m using the right signatures, and wasting a lot of time in checking the docs.
Now, I can rely on what TypeScript tells me:
Pixi.js is a lightweight 2D library.
The first benefit is it’s a WebGL wrapper (in short, WebGL allows us rendering graphics using GPU directly), it lets us using WebGL without worry touching WebGL API. (In my last article WebGL and Image Filter 101 I mentioned the power of WebGL, and there are a lot of boilerplate code we have to provide to make WebGL working since it’s a low-level API).
The second benefit is it unified all kinds of 2D content(image, text, shapes) to “Sprite”, we can apply the transformation and adding interactivity to these content the same way with the easy-to-use API.
We also can group different content with containers, and use batch effects quickly.
Rendering a flying bird
To start using Pixi.js, you can start with include script below in your HTML file (or npm install pixi.js
if you have bundle tools within your project): <script src='https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.4/pixi.min.js'></script>
Let’s start from creating a scene, after this setup, any changes happen inside the stage container can be rendered by using renderer.render(stage)
.
const renderer = PIXI.autoDetectRenderer(512, 512);
document.body.appendChild(renderer.view);
const stage = new PIXI.Container();
To create the flying bird, I found these assets from this link (Please use texture atlas if you have much more images in your project, which is also supported well by Pixi.js).
Then, what I did is creating a “Sprite” and update the Sprite’s texture with an interval timer.
With the code below, you will get an animating bird looks like flying.
In the reset
, we use x
and y
to control the position.
If you have the speedX
and speedY
, you can also update bird’s flying orientation by this.sptire.rotation=Math.atan(speedY / speedX)
.
Now we have a bird and can apply different transformation to it; you can try adding a new field speedY
to Bird
class and update bird’s position by updating sprite’s y
each draw
based on that field .
Rending Tubes
As I mentioned before, by using Pixi.js, all kinds of 2D content(image, text, shapes) can be treated as “Sprite”, for the tube, I’m simply drawing some rectangles.
Pixi.js provided 2d drawing API with PIXI.Graphics
, for example, to draw a “tube” and moving it horizontally:
const tube = new PIXI.Graphics();tube.beginFill(0xffffff);
//drawRect(x, y, width, height)
tube.drawRect(100, 0, 50, 120);
tube.drawRect(100, 200, 50, 512);
tube.endFill();tube.x = 200;
stage.addChild(tube);
renderer.render(stage);
And the tube class I made is like:
Checking Collision
After we have moving objects (tubes and bird), we can treat them as rectangles.
If we have their left topmost point, width and height(x1, y1, w1, h1 and x2, y2, w2, h2), then we can check whether two rectangles are hitting each other:
if((x1 + w1 < x2) || (x2 + w2 < x1) || (y1 + h1 < y2) || (y2 + h2 < y1))
No collision
So, that’s basically all parts of making a simple flappy bird copy.
Thanks for your reading :)