Let’s Animate Your PixiJS v5 Game With Spine

Anatoly Voevodin
anvoevodin
Published in
6 min readOct 4, 2019

--

Animation in games is almost the main thing that makes your games alive and fun. The better you visualize it — the better a player can feel and enjoy the gameplay. Looking on this I always choose Spine over Frame Animation and below I want to explain why, also showing how we can use it in PixiJS v5! 👇

What is Frame Animation and what is Spine?

Frame Animation

Frame Animation speaks for itself and usually it’s 2 files: .png and .json:

  • .png — an image of frames of an animation;
  • .json — the description of the PNG (how big the frames are and in which coordinates they are located). So that using JSON we can “cut” PNG into frames and create an animation just changing images.
This is how the PNG of an animated object looks like for Frame Animation

Spine

Spine is the most popular software for creating skeletal animation for games, but frequently people may mean the idea of the skeletal animation itself (since there are alternatives to Spine), and the main criterion here is eventually to have following 3 files:

  • .png an image of parts of an animation;
  • .atlas the description of the PNG (how big the parts are and in which coordinates they are located);
  • .json — the description of the animated object (its skins, bones, animations, etc).
This is how the PNG of an animated object looks like for Spine Animation

Why Spine?

Images size

The example of .png for Frame Animation that I showed you above is 2.56 MB (original, high quality, no compress, 30 FPS)+ 14.7 KB of .json file. Total: ~2.57 MB 🤨.

At the same time the example of .png for Spine Animation that I showed you above is 85.9 KB (original, high quality, no compress, no FPS limit)+ 15.1 KB of .json file + 1.7 KB of .atlas file. Total: ~102.7 KB 😍.

Spine Animation size is 25 times less!

FPS

If you want to have smooth animations (as in the demo at the end of the article) then it’s better to run them in 60 fps. With Spine it’s not a problem, you can set 60, or 5, or 240, it’s up to you, the eventual size of your assets won’t change. But what about Frame Animation? It’s pretty obvious that if you want to have more frames in a frame animation, for instance 60 instead of 30, then the PNG file is going to be twice larger.

It’s undoubtedly great, but there is a bonus: with Spine Animation you can manage speed of your animation on the run still having it smooth. Just imagine all those slow motion features you can implement in your game! 🤩

Ok, how to create a spine animation?

The best way, of course, is to use Spine itself (which is not free), but there are worthy alternatives. For instance, we successfully used Dragons Bones in various projects and, despite some little bugs, I consider it the best alternative to Spine. You can find more software on the internet searching something like “spine alternatives” and reading some articles about it.

I’m convinced. How do I use it in PixiJS v5?

As easy as create a sprite and add it on the stage! We’re going to use pixi-spine package in order to work with Spine Animation but let’s start from the PixiJS v5 setup, and I have a few words to say here.

There are 2 ways of using PixiJS v5:

  1. Import the whole bundle.
  2. Import consumable components only (available in PixiJS v5).

Notice that if you use PixiJS v5 and import consumable components only (@pixi/display, @pixi/core etc.) to reduce your eventual bundle size then, to be honest, with pixi-spine it doesn’t make much sense since we need to use so many of PixiJS so that it’s easier to import the whole bundle.

In my demo for this article I went the way with consumable components (here is my article about super lightweight and easy setup for PixiJS v5)since it’s a bit harder and maybe somebody would find it helpful, but exactly in case of Spine I suggest to use whole pixi.js package.

Versions of pixi-spine

Spine (or any another alternative) can export files in different versions, and depending on it you have to know, which version of pixi-spine you need. It’s easier to go to the official page of the package and get more info, so here just briefly:

  • If your assets were exported with v3.7, you need pixi-spine v2.05;
  • If your assets were exported with v3.8, you need pixi-spine v2.1.3 (latest currently).

In my case I have exported files (.png, .atlas, .json) from spine v3.7 so I’ll install pixi-spine@2.0.5.

Let’s code!

I assume that you’ve already set up your project (here is an example with consumable components) and we can go on with Spine.

If you import the whole PixiJS bundle

Then all you need is to install pixi-spine:

npm i pixi-spine

or if your assets version is not 3.8, then:

npm i pixi-spine@2.0.5

and import it at the place where you initialize the app (in my case it’s index.js in the root):

import 'pixi-spine'

If you import consumable components only

Here is a bit more work, but still nothing complex. pixi-spine doesn’t work with PixiJS v5 consumable components and there was only one proof of concept that isn’t ready yet and accordingly wasn’t added to the package officially. I tried it but expectedly it worked only partially (failed on uglifying with uglifyjs-webpack-plugin) but everything else worked well which means that the solution is coming!

Meanwhile I decided to make a temporary solution and write a little script which fixes it:

Just save this script in a folder like “utils” or similar.

The idea of the script is simple. pixi-spine expects that it can find PIXI engine in global (window) object, but when we use consumable components it isn’t there. I just imported all packages that pixi-spine needs and put them into global PIXI object. Yes, it’s a bit ugly, but it works right now (and probably will work for a long time since imports don’t seem to change). Just wait for a new version of pixi-spine with the solution.

So, as long as we have the “Spine Preparer” we need to install all packages that it imports. Here is the complete command:

npm i @pixi/constants @pixi/display @pixi/core @pixi/sprite @pixi/math @pixi/graphics @pixi/mesh @pixi/loaders @pixi/utils

Then add new imports into our app initialization (in my case it’s index.js file):

Don’t import ‘pixi-spine’ inside of the Spine Preparer! “Imports” are executed first and only then the rest of the code, even if “imports” are at the end of the file! So if import ‘pixi-spine’ would be inside the Spine Preparer then pixi-spine would try to access window.PIXI earlier than we created it 🤔

From this moment the difference between “importing the whole bundle” and “importing consumable components” is over and we go along.

Load the assets

We’ve done with all tricky stuff and now we can easily and without fear use the package. pixi-spine automatically handles your spine assets so all you need to do is to show it where you store your .json file (the rest .png and .atlas have to be at the same folder with the same name). I use the loader from the PIXI.Application instance:

If you don’t have spine assets you can get the same I use from the repo of this article’s demo (at the end of the article) in build/assets folder.

So, in the “draw” method we now can create a spine object using the data we’ve just loaded:

“spineData” was generated by pixi-spine when the spine assets loaded.

Finally! The spine object is on the stage, walking and all that and… that’s actually all!

If you want to know more (how to work with speed or how to handle events of start/end of an animation etc) don’t hesitate to write me about it and subscribe, it’ll be a pleasure to me! 🙂

If you can’t wait, again — the official pixi-spine page where you can find some docs.

Enjoy demo with 19 skins and 21 animation for each character (the wider the screen the more characters is shown 😉)!

Demo: https://anvoevodin.name/demos/pixijs_v5_spine
Git repo: https://github.com/ANVoevodin/pixijs_v5_spine

There will be more articles on PixiJS v5 so don’t miss them and subscribe here, on LinkedIn and Twitter!

BTW, if you ever wondered, then here is How To Create A Facebook Instant Game With PixiJS v5.

--

--