In this multipart tutorial, I would like to walk the reader through the process of developing a simple HTML5 platform game. The game is written with TypeScript and uses PixiJS v5 as rendering engine.
This course is split into following parts:
- Part 1: Setup repository and create game assets (this part)
- Part 2: Setup state management
- Part 3: Setup collision detection
- Part 4: Create a bigger level and setup a camera
- Part 5: Add score and enemies
- Part 6: Manage multiple levels
For convenience each part corresponds to a branch in Github repository: https://github.com/MMMalik/platform-game-tutorial
The final result can be accessed under the following url: https://mmmalik.github.io/platform-game-tutorial
I expect the reader to be familiar with TypeScript and have some basic experience with PixiJS.
As a disclaimer, I would like to note that game development is not my main area of expertise. I am merely having fun developing games and learning about game development. If you find some of the ideas I share here as incomplete or simply wrong, I will be glad to know.
First, let’s setup the project’s repository.
We use webpack in order to build the project. It is important to note that we we do not bundle the game assets with webpack, because we need PixiJS to be able to manage these assets on its own. Webpack merely copies the assets from
dist/assets . Other than that, webpack helps us compile TypeScript and creates
index.html by leveraging
All assets are placed under
src/assets folder. Game components (Platform, Character, etc.) are placed under
src/components . Constants are placed under
src/constants folder. Utils which are of more general use are placed under
Please refer to webpack.config.js for more details.
Let’s start by browsing itch.io in order to find game assets suitable for a platform game. It’s not a big challenge since itch.io is full of beautiful game arts ready to use in a project. For the sake of this tutorial, we will use the following assets:
- Taiga platform tiles and background by vnitti: https://vnitti.itch.io/taiga-asset-pack
- Pixel adventurer by rvros: https://rvros.itch.io/animated-pixel-hero
In the first step, we need to create spritesheets out of those assets in such a way that they are recognizable by PixiJS. In order to achieve that, every asset in our game has to consist of two things:
- a .png spritesheet file
- a respective .json file holding information about that spritesheet: frames (position, width, and height of each frame), animations (order in which frames are played), meta data (version, source image name, spritesheet size, etc.)
Now, we need a proper tool to transform game assets from itch.io to fulfill these requirements. Recently, I have become a fan of Piskel, a simple web app for manipulating game assets. It’s not a perfect tool but it is free and easy to use. Let’s try it then!
Let’s start with ‘Taiga’ platform. Once the files from itch.io are downloaded and extracted, import
PNG\Tileset.png into new Piskel workspace (from the right-side panel click ‘Import’, then ‘Browse images’). Then choose ‘Import as spritesheet’ and change ‘Frame size’ to 16 x 16.
This action will divide the image into 16 x 16 tiles. Now, let’s export them in a format recognizable by PixiJS. From the right-side panel choose ‘Export’, ensure that resolution is set to 16 x 16, then choose ‘Download’ under ‘PixiJS Movie export’. Extract the archive.
You should find two files in the extracted archive: Tileset.json and Tileset.png. They both need to be copied to
Now, we have a set of tiles. How can we use them to make our first level? A free and convenient tool for building game levels is Tiled. Please go to their website and download the installer. Once the version suitable for your machine is downloaded and installed, open the app and choose ‘New Map’ and set ‘Map size’. For the sake of this tutorial, we will use map of 80 x 36 tiles size. Save file to a convenient location.
Once the map is created, let’s add a ‘New Tileset’. As a source image, set path to the Tileset.png created previously with Piskel. Save it to a convenient location.
Your workspace should consist of an empty grid on the right side and the imported set of tiles on the left side. You can toggle visibility of Tilesets by choosing ‘View’ / ‘Views and Toolbars’ / ‘Tilesets’.
Now we can start creating our first level. Just choose a tile and start drawing on the grid. Several minutes of effort should yield a simple platform. Save the file and export it as level1.json to
The created .json file holds information about our level. The most important part is
data array in
layers . It’s an array of tile ids, where
0 value is reserved for an empty space, while other values correspond to the order of tiles from Tileset.json file.
To sum up, we have created 3 files for our game so far:
- Tiles.png — a spritesheet with all platform tiles
- Tiles.json — a file which Pixi uses to know where each tile is located in Tiles.png
- level1.json — a file which holds data about the order of tiles to render as part of a level 1
In the next step, let’s create assets for main character. In Piskel, import the extracted assets, set tile size to 50 x 37 px.
Please notice that this spritesheet contains all animations for this character, such as jumping, fighting, idle, running, etc. For the purposes of this tutorial we will only use just a few of them.
Repeat steps for exporting PixiJS assets. As a result, you should get two files: a .png and a .json file. Unfortunately, the .json file does not contain
animations property out of the box. This is why we have to add that manually:
Finally, we need to add background asset. It is simpler than what we did so far since the background consists only of a single frame. For the background, I have chosen the
PNG/Background.png file from Taiga set. I am leaving details of creating respective PixiJS spritesheet and json files to the reader.
The creation of initial assets is done and we can focus on coding. Let’s start with creating a couple of helper functions for getting canvas element, creating an instance of PixiJS app and handling assets loading. Later on, more utils will be added here.
Let’s define a game component. Let it be a function which creates an instance of PixiJS sprite and sets some of its initial properties. For now, it’s enough if a component function returns an instance of PixiJS sprite, or an array of such instances. Later, the signature of this function will be changed to something a bit more complex.
Let’s take a look at game components then. There are 3 components for now: Background, Character, and Platform. Within Character component we create an AnimatedSprite based on main character spritesheet, then we set values such as x, y, and animation speed.
Platform component is a bit more complicated, since we need to parse level1.json file. Since our game is 2-dimensional, the parser slices 1-d array into 2-d one. This operation is useful to establish some properties of a tile, e.g. its neighbours (will be used in later parts of the tutorial). Inside Platform component, we also make a connection between tile id in level1.json file and its index in the spritesheet.
Finally, let’s move to Background component. It is merely a sprite scaled to fit the game size (which is fixed to 1280 x 578 px).
All the above pieces come together in the entry
index.ts file, where we create PixiJS app, load all required assets, initialize components, and finally start the game. The game components have to be added to the Pixi container in a specific order. Otherwise, some components might be simply covered by others. For instance, Background comes before Character.
Complete code for part 1 can be found under the following link:
Here is a gif of what has been achieved so far:
Stay tuned for next parts!