Press enter to see results or esc to cancel.

Tutorial : Handling game scenes and screen scaling with Pixi

Most game tutorials I've read speak about how to draw things or write game logic ...etc,ย  but when you develop a game,beside the game itself there is also UI and scene transitions that need to be implemented. This tutorial I will show you how to handle game scenes, pause/resume your game and automatically scale the display to make your game mobiles/tablets friendly ๐Ÿ™‚  

//The goal of this tutorial is to get this result //


as a rendering engine I'll use Pixi ; a powerful and well designed HTML5 renderer that provide a common API for both canvas2D and WebGL. Pixi can autodetect the presence of WebGL capabilities and use it, but you can also force it to use Canvas2D or WebGL. I'll use TypeScript as programming language, and Visual Studio 2012 for Web as IDE. to use Pixi with TypeScript I highly recommend this TS definition : pixi.d.ts here is how I organized my code code-tree Note that this is the final structure engine folder contains common classes game folder contain classes specific to our project lib folder contains third party libraries (here we have pixi and its TS definition file)                

Game scenes

Scene class

Let's start by creating the scene class. a scene is basically a Pixi Stage object, witch can be paused/resumed/updated
Note how we extended PIXI.Stage object using TypeScript extends keyword even if Pixi has not been written in TypeScript
the onUpdate() method will register the update callback witch will be used to update game objects states. (will see later that we can use the onUpdate() method or override update() method in a subclass).  

ScenesManager class

To handle scenes will create a ScenesManager Since we are supposed to have only one ScenesManager in the game, I declared all it's functions as static.The create() method will initiate Pixi renderer and starts the gameloop immediately. The loop() method will check if a current Scene exists and is not paused, the update and render it. now we'll add two more methods to the ScenesManager to create and switch scenes. the following code replace "//# next code block" above here, the names are explicit, and don't need further explanation I think ๐Ÿ˜‰ not the goToScene() method will pause the current scene before switching to another scene, so we preserve the scene state.   let's test this code ๐Ÿ™‚ create an html file and add references to Pixi.js, ScenesManager.class.js and Scene.class.js then add this script block before </body> result :  

Switch scenes

  you noticed that we added our game logic (the moving bunny) to a Scene instance, in a real life case, where you have thosands of lines of code, this aproach will make your code unreadable (don't forget that we'll add our menus and scenes logic aswell). so a cleaner aproach is to extend our Scene Class and allow ScenesManager to create classes of different types. this need a modification in createScene method, witch becomes what we did here is replacing "new Scene()" with a more generic call "new TScene()" where TScene is declared as "TScene: new () => Scene = Scene", this syntax only means that we accept here a Class of Type Scene, and it's default value is Scene. we can get the same result by just declaring the function like this : public static createScene(id: string, TScene:any): Scene {...}ย  but well lose TypeScript compile type type checking. now we'll create a GameScene witch extends Scene and have all game logic. and our script main script block becomes see how all game logic is now hidden , and the code becomes mutch cleaner. result :  

Intro scene and menu scene.

Now we'll create two scenes to show our logo with a nice fade effect then show a menu with a clickable button before starting the game. the game scene will contain a button allowing us to go back to the menu.

intro scene


Menu scene

almost everything in the following class is taken from this pixi sample, I just added a control on event to not trigger them if the current scene is not active . note : while writing this tutorial, Pixi seems to interact with objects even if they are no more visible, this is why I added a if (_this.isPaused()) return; control. there is a pull request on pixi github repository to fix this, so the control will no more be necessary. no magic here ๐Ÿ™‚ just make sure you set interactive your scene and all buttons you add by calling setInteractive(true)  

Game scene

here I'll just add a button, when clicked will go back to the menu scene. in the GameScene constructor we'll add   and finally we need to add new scenes to the main script   click here to see the result    

Scaling to screen size

we have now a working scenes transitions, and interactive elements. The last step in this tutorial is to scale the scenes so they allways fits the display while keeping aspect ratio. here we'll need to maintain default width and height, current with and height and a ratio to rescale all other objects, so first let's add some variables to ScenesManager class ... and a private function that will calculate the ratio and resize Pixi display accordingly we also need to modify ScenesManager.create() method to handle both cases : when we need automatic rescale and when we don't need it
while writing this tutorial, I thought that scaling a Pixi Stage (remember our scenes extends PIXI.Stage) was enought to scale all its children so I only had to multiply my scenes scale.x/y value by ratio to get everything scaled .... I was wrong ๐Ÿ™‚ actually, this don't seem to work, don't know if it's a normal behaviour or an issue ... any whay I came up with a workaround.
let's handle the scaling of game objects first we'll add a method to rescale all children of a Pixi DisplayObject (the parent of all PIXI objects) then we'll modify the ScenesManager.loop() method so that we apply the ratio before rendering and restore it back after, so everything is transparent while manipulating your game objectsย  :     everything is now ready, we just need to modify our main html file to ask the ScenesManager to rescale display   Click here to open the final result , resize the window and see how the display size is automatically scaled ๐Ÿ™‚    

Download the full source code

  I hope that this tutorial will help you in your mobile game devย  ๐Ÿ™‚ ... comments and/or suggestions are welcome      
  • Hannibal Lecter

    thanks รงa tombe bien ^^ le typing dans js le rend encore plus interessant avec le typescript il est temps pour moi de focuser la dessus

  • doobdargent

    I decided yesterday that I will use pixi for my next games to come. This tutorial is really helpful and the scene change tutorial was exactly what I was looking for.
    I’m so glad I stumbled on this!
    Now I also want to learn TypeScript.
    Thanks Ezelia.

  • Nenek

    Hello, first of all, great tip. But I have question, how about performance when you scale down and up every loop step, Did you test it somehow?

    anyway thanks.

  • Lee

    Nice tutorial. Thanks for the tips. The scene scaling might be a problem if the sprites have their own animated scale. It might be better to place everything in a wrapping container and scale that. I wonder why you can’t scale the stage? Hmmm…

  • mehdi

    Hi thanks a lot for tutorial.
    there is a problem .
    when i use pixi v1.6.0 there is problem.
    that is: click game -> i am going to game scene and click menu -> go to back and show game button. but not working again.

  • Hi Alaa, thanks for this article… Do you have any example with Phaser Framework? ๐Ÿ™‚