Ezelia

Tutorial : Handling game scenes and screen scaling with Pixi

Recommended Posts

This is my little contribution to Pixi : a tutorial about handling game scenes and auto scaling screen size.

 

the tutorial is not about how to make game or draw thing with pixi, it's about how to handle transitions between game screens, how to pause resume the game/scene, and how to seamlessly scale the display to fit screen resolution without handling ratios / proportions directly in your game logic.

 

I'm not a native english, so the tutorial may contain some language mistakes  ... you can help me to fix them ;)

 

http://ezelia.com/2013/05/pixi-tutorial/

 

 

[EDIT]

btw, the tutorial is also available in french (I know there is some French developers on this forum ;)http://ezelia.com/2013/05/tutorial-gestion-des-scenes-dun-jeu-des-transitions-et-de-la-mise-a-lechelle-avec-pixi-js/

Share this post


Link to post
Share on other sites

Maybe it's because it's in Typescript (which I haven't learned) but that was really complicated. I'll be trying pixi js after I finish my recent game.

 

For my recent  game I've been doing it the html5 rocks tutorial way http://www.html5rocks.com/en/tutorials/casestudies/gopherwoord-studios-resizing-html5-games/ He talks a bit about it in one of the comments. But basically I  update all my game logic using units, and then have a toPixels() method and a toUnits() method. The input converts pixels to units, and the drawing code converts the units to pixels. It means after I set it up I never had to think about scaling again.

 

Does Pixi do anything like this? It would be cool if it did. Or at least handle it someway. Scaling is the biggest headache for me i've found. My simple brain gets confused by all the ratio maths. lol

 

How do you decide how fast an object moves in a game? Do you have to multiple the velocity by the ratio everytime?  In my game I would just set the speed to a certain amount of units, and that would never change no matter the size of screen.

 

Anyway nice tutorial. It's not your fault I'm an idiot and couldn't follow it all. haha

Share this post


Link to post
Share on other sites

Ezelia, thank you so much for writing this tutorial. Scene handling is always the first thing I want to know when dealing with a new framework/library.

Even though it is written in Typescript, I have followed the tutorial using Javascript and I could get it to work without any problem :)

I will write a blog about Javascript version of this tutorial to, hoping that it will help out people who are not used to TypeScript yet.

 

Looking at how you handle the scene, I have some questions and found some problems as follow:

 

1.) You use multiple Stage instances. In your tutorial, you said that the buttons in the other scenes still accept touch event. Maybe using multiple Stage instances is the source of the problem?

While I'm not sure how Pixi work internally, I guess that since Stage is supposed to be the root object, it will always receive events and pass them through all of its children. 

I'll try another approach with 1 Stage instance, but the scene will be just a subclass of DisplayObjectContainer instead. Changing scene will done through adding and removing these container objects.

I'll let you know how it goes and if it still has the same problem or not.

 

2.) While playing with DisplayObjectContainer, it turns out that your scaling method scale the object twice. If you have an object without children, then that is fine. But once you have a DisplayContainerObject that has many children, the children will be scaled twice. This is because scaling the parent object also affect the children.

 

Maybe Stage class is an exception. Scaling it doesn't seem to affect its children at all. 

 

Again, thank you for writing this tutorial. Now I can get start with Pixi.js! :) 

Share this post


Link to post
Share on other sites

thank you for your comments hima :)

to be honest, I wrote this tutorial while learning Pixi.js, I'm not a Pixi expert too :D
for your first point, I wanted to separate scenes in different stages to make objects allways available in memory and reduce garbage collector action, my approach can be wrong :) but that was the idea.

for the second point I thought that DisplayObjectContainers has the same behaviour as Stages ... if scaling a DisplayObjectContainer also scale its children my code can be simplified by inheriting scenes from DisplayObjectContainer and removing all the added scalling/descaling routines :)

 

Share this post


Link to post
Share on other sites

A Stage *is* a DisplayObject, but you should only ever have 1 Stage on a page (using multiple stages was not intended).

 

Nearly all attributes of any DisplayObject (a Stage, a Sprite, a DisplayObjectContainer, etc are all DisplayObjects) are relative to their parent. Meaning scaling a DisplayObjectContainer will scale the children (since their scale of "1" is relative to the parent).

Share this post


Link to post
Share on other sites

A Stage *is* a DisplayObject, but you should only ever have 1 Stage on a page (using multiple stages was not intended).

 

Nearly all attributes of any DisplayObject (a Stage, a Sprite, a DisplayObjectContainer, etc are all DisplayObjects) are relative to their parent. Meaning scaling a DisplayObjectContainer will scale the children (since their scale of "1" is relative to the parent).

 

Is Stage an exception? I've tried changing the stage's scale and position, but nothing changed.

Share this post


Link to post
Share on other sites

Thanks for the tutorials, it got me up and going really quickly.

 

Im a bit of a js noob and was hoping you coudl explain wahts going here, in a little more detail?

 

var __extends = this.__extends || function (d, b) { //??

    function __() { this.constructor = d; }   //??

    __.prototype = b.prototype;//??

    d.prototype = new __();//no idea!!!

};

var tuto;

(function (tuto) {

  

    (function (Ezelia) {

        // Class

        var GameScene = (function (_super) {

            __extends(GameScene, _super);//whats going on here?

            function GameScene() {

                        _super.call(this);//whats this?

Share this post


Link to post
Share on other sites

the code you are looking at is the generated JavaScript from TypeScript compiler, you don't have to understand this, look at .ts source files instead :)

but if you still want to understand what that code do, it's just an implementation of Object Oriented Programming in Javascript.
the __extend methode allows a child to inherit its parent's methods.
the _super method allow to call the parent constructor

Share this post


Link to post
Share on other sites

Hi,
i've make fadeIn, fadeOut and wait function (based on JQuery) for your scenes ;)

 

PIXI.DisplayObject.prototype.addVarEffect = function () {if (this.inAnim == undefined){this.inAnim = false;}}/*** Creates a fadeIn Effect on this DisplayObject** @method fadeIn* @param speed {Number} The fadeIn duration* @param callback {Function} A callback function* @return {DisplayObject}*/PIXI.DisplayObject.prototype.fadeIn = function (speed, callback) {// Add this.inAnimthis.addVarEffect();// Scopevar _this = this;// If Object is not animated actuallyif (!this.inAnim){// Object is actually animatedthis.inAnim = true;var opacityInc = (10 / speed);var timer = setInterval(function () {_this.alpha += opacityInc;if (_this.alpha >= 1 || _this.alpha >= 1.0) {_this.alpha = 1;clearInterval(timer);if (callback != undefined)callback();_this.inAnim = false;}}, 10);}elsesetTimeout(function () { _this.fadeIn(speed, callback); }, 20)return this;}/*** Creates a fadeOut Effect on this DisplayObject** @method fadeOut* @param speed {Number} The fadeOut duration* @param callback {Function} A callback function* @return {DisplayObject}*/PIXI.DisplayObject.prototype.fadeOut = function (speed, callback) {this.addVarEffect();var _this = this;if (!this.inAnim) {this.inAnim = true;var opacityDec = (10 / speed);var timer = setInterval(function () {_this.alpha -= opacityDec;if (_this.alpha <= 0 || _this.alpha <= 0.0) {_this.alpha = 0;clearInterval(timer);if (callback != undefined)callback();_this.inAnim = false;}}, 10);}elsesetTimeout(function () { _this.fadeOut(speed, callback); }, 20)return this;}/*** Creates a wait Effect on this DisplayObject** @method wait* @param speed {Number} The wait duration* @param callback {Function} A callback function* @return {DisplayObject}*/PIXI.DisplayObject.prototype.wait = function (time, callback) {this.addVarEffect();var _this = this;if (!this.inAnim) {this.inAnim = true;setTimeout(function () {if (callback != undefined)callback();_this.inAnim = false;}, time);}elsesetTimeout(function () { _this.wait(time, callback); }, 20);return this;}

 

And you can use it in you scene on :

this.logo.fadeIn(5000).wait(1000).fadeOut(5000, function () { ScenesManager.goToScene('GameMenu'); });

Share this post


Link to post
Share on other sites

Hello @omarojo, please note that this Tutorial is very old and outdated :)
it's about Pixijs 1.6 and the last Pixijs version is 3 !

 

I'll be surprised if it's still working with new Pixi version :D

 

 

about Typescript usage, I used it because the structure of the code is Object Oriented and TypeScript support OOP very well, the code logic itself do not differ ...

I'll update the tutorial for new Pixi version when I have some time, and I'll write it in both TypeScript and Javascript

Share this post


Link to post
Share on other sites

Hello @omarojo, please note that this Tutorial is very old and outdated :)

it's about Pixijs 1.6 and the last Pixijs version is 3 !

 

I'll be surprised if it's still working with new Pixi version :D

 

 

about Typescript usage, I used it because the structure of the code is Object Oriented and TypeScript support OOP very well, the code logic itself do not differ ...

I'll update the tutorial for new Pixi version when I have some time, and I'll write it in both TypeScript and Javascript

 

Yeah man.. I think this is the issue everyone is having right now....  Phaser.io is very good at managing states or scenes. But in PIXI, all tutorials use just 1 file.

and no one seems to suggest a strategy to manage scenes in PIXI. You know.. best practices or something, thats why I decided to move to Phaser just because of that reason. But then I found that Phaser doesnt support video playing. :(

Share this post


Link to post
Share on other sites

Well I think that thing are much easier with the PixiV3.

 

I mainly wrote this tutorial by the time where Pixi.Stage was a special container, now with Pixi v3, Stage no more exist, it's just a container like others.

 

so the easiest way to handle scenes is to crete a container for each scene, and put all your stuff into it, then hide/show the container depending on what scene you wan't to display.

 

it's really very simple with Pixi v3.

are you having some specific issue which is adressed by the tutorial but not with the method described above ?

Share this post


Link to post
Share on other sites

Hi guys,

I love that you can simply scale the stage and it all just works :)

I am unsure what the default renderer width and heights should be though

Keep in mind: my game is a top-down multiplayer scroller with a world size of 8000px2

new PIXI.Application(game.width, game.height);

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.