Gagarina

Gagarina is a quite simple, arcade type game that Margo and I developed.
It is created in HTML5 canvas and already on the Play Store.
I have been wanting to share some of my side projects, so I figured a blog post would do.

The Idea

The idea of Gagarina came to us as we were talking about creating a website for Margo.
We started looking at content she wanted to showcase when we came over an instagram post she made a year earlier.
It would be cool to recreate it in canvas and add it to her website so of course like any geeks would, we did.
We added some interactions and the ball just kept rolling until we had a full game.

Game development by web developer

Developing for games is quite different from developing for web.
I'm a front-end developer, so my code will have some patterns that might look more like web apps than games.

There are many good libraries for game development out there, I checked out several before landing on PixiJS.
PixiJS is well documented and has some useful examples. For a web-developer it was also quite intuitive to use.
Since it's not too opinionated it's also a lot of fun to write all the code that is needed.

To utalize PixiJS, you will still need to build the frame around it and manage the state and stages.
Each stage has many layers and buttons, the easiest way to manage that was creating classes around each of them.
Here are the main building blocks:

class StartScreen { constructor() { // Every stage has it's own container this.container = new PIXI.Container(); this.addBackground(); this.addGagarina(); this.addMenu(); // ... } // We share the container to parents so they can add them getContainer() { return this.container; } addGagarina() { // We get the size of the screen once and share it with getSize function const { height, width } = getSize(); // Reusing another class where Gagarina is jumping this.jumping = new Jumping(); // Every class has a start function // This will set a start position and add a function to the main loop this.jumping.start({ x: width / 2, y: height * 0.45 }); // We get the Pixi container from the class and add an onClick function to it const jumper = this.jumping.getContainer(); jumper.interactive = true; jumper.click = jumper.touchstart = toggleSkin; // Lastly we add Gagarina to our container this.container.addChild(jumper); } // ... destroy() { // Every class knows only about it's children, so it's the one that has to destroy them this.background.destroy(); this.jumping.destroy(); this.menu.destroy(); // Lastly we destroy the container this.container.destroy(); } }

In the previous code we used the class "Jumping", which is Gagarina jumping up and down used on the main menu.
The code is a bit long so I had to cut it down for this post, but this is the gist of it.

export class Jumping { constructor() { // Setup; // getPlayerTexture will return with the current chosen skin in the given position (2 in this case) this.player = new PIXI.Sprite(getPlayerTexture("2")); this.current = 0; // This is the movement we want Gagarina to use in the menues this.animation = ["1", "2", "3", "4", "3", "2", "7", "8", "6", "5"]; // Binding the loop to the class this.onTick = this.onTick.bind(this); } // We use the same getContainer throughout the game to make it easier getContainer() { return this.player; } // The start function we called earlier start({ x, y }) { this.player.anchor.set(0.5); this.player.x = x; this.player.y = y; // Finally we add our ticker to the main loop getApp().ticker.add(this.onTick); } destroy() { getApp().ticker.remove(this.onTick); this.player.destroy(); } onTick(delta) { // The animation // It's a bit long to put here with some if's // But it is just moving gagarina and changing position this.player.texture = getPlayerTexture(this.animation[this.current]); this.player.y = this.startpos - this.current \* 10; } }

There is a High-score list as well, both local and online.
After a colleague of mine got 6 out of 8 top spots I changed it so each device only shows up once in the global high-score.

Since I'm not a fan of ads or trackers, there is neither in the game. To keep track of which score is yours on the global list,
the game will create a random ID the first time you get a high-score. This is just based on the current time and some randomness.
This way I can not track anyone and if you reinstall or clear the cache of the game, you have a new ID.

All in all the game is 3820 lines of code including white spaces.

Screenshots

Here are some screenshots of the game, but the best way to see it is clearly to try it out!

Where to get it?

Since Gagarina is built on web-technologies she will be available on most devices

Try it out