Jump to content

Best Practice for Stage Setup


Recommended Posts

It has been a year since i last tried out PIXI and i wanted to use it in a new project but organizing my code a bit better (last year i used it for LD27 and the code was a bit of a mess).


I tried the ezelia example, but with the update from the PIXI version used in the example to the latest one the mouse events did not work anymore. I tried the whole day to fix it, rewrote the example in pure JS but i still have the problem that once i switch from one stage to the other and then back (calling the renderer with the different stages), the mouse events of the first Stage do not work anymore, even when i reset them after the switch.


Is there a best practice on how to deal with different views / Stages of an app?


Lets say i have the intro screen, the game / app itself and a couple of other views with highscore / help and such things. How would one go about with the latest PIXI version while trying to keep the code organized?


I thought it would make sense to initialize the views and then switch freely between them, but somehow i am missing something there (i guess there is a hierarchy problem or sth?)


So is the way one should go about it to just have one stage at a time and destroy it after use, reinitializing when it is needed again? That does not seem to be very efficient.


Or should everything go into one stage object which then has to handle all the different states of the game / app? That seems to be very cluttered and not easy to maintain?

Link to comment
Share on other sites

No do not initialize all views at the same time. My advice...


Create a stage -> scene (display objectContainer) and then add views to it. The scene will be a wrapper for all of your elements! A good practice is to call different views every time you need! Here is my code. What you can do is to clear the scene in order to free some memory.



_li.define(    'bitwars.views',    function (                        renderer,             scene,             loading,             mainRouter,             main,             game,             choseName,             gamesList,             gameRoom                    ) { //, loading, main, game        'use strict';        var init,            view,            _renderer,            _scene;        init = function (data) {                                    console.log('data inside views', data);                        if(!_renderer){ _renderer = renderer(); };            if(!_scene){ _scene = scene(); };            if(data.clear === true){                                 for(var ele in _scene.children){                                        _scene.children[ele].interactive = false;                    _scene.removeChild(_scene.children[ele]);                };                                  _scene.children = [];                        };            if(data.view === 'loading'){                                view = loading(data.percent);                            }else if(data.view === 'mainRouter'){                                view = mainRouter();            }else if(data.view === 'main'){                                view = main();            }else if(data.view === 'game'){                                view = game();            }else if(data.view === 'chooseName'){                                view = choseName();            }else if(data.view === 'gamesList'){                                view = gamesList();            }else if(data.view === 'gameRoom'){                                view = gameRoom(data.data);            }else if(typeof data.view === 'undefined'){                                return view;            }            _renderer.renderer.render(_renderer.stage);                        return view;                    };        return init;    },    [        'bitwars.renderer',         'bitwars.scene',         'bitwars.views.loading',         'bitwars.views.mainRouter',         'bitwars.views.main',         'bitwars.views.game',        'bitwars.views.chooseName',        'bitwars.views.gamesList',        'bitwars.views.gameRoom'    ]);


_li.define(    'bitwars.views.gameRoom',    function (texture, renderer, scene, audioController, sockets, views) {        'use strict';        var init,            _renderer,            _scene,            _audioController,            _sockets,            _game,            view = 'gameRoom';        init = function (data) {                        if(typeof data === 'undefined'){                                views({                    view: 'gamesList',                    clear: true                });                                return false;                            }                        _game = data;            if(!_renderer){ _renderer = renderer(); };            if(!_scene){ _scene = scene(); };            if(!_audioController){ _audioController = audioController(); };            if(!_sockets){ _sockets = sockets(); };                        var dim = (Math.sqrt( (_renderer.canvas.height * _renderer.canvas.height) + (_renderer.canvas.width * _renderer.canvas.width) ) )/10;                        var playButtonTexture = PIXI.Texture.fromImage('assets/images/screens/button1.png');            var playButtonTextureOver = PIXI.Texture.fromImage('assets/images/screens/button2.png');            var playButtonTextureDown = PIXI.Texture.fromImage('assets/images/screens/button3.png');            var back = {                position: {                                        x: 0,                    y: 0                                    },                dimensions: {                                        height: _renderer.canvas.height,                    width: _renderer.canvas.width                                    },                asset: 'assets/images/screens/main.png'            };                        texture(back);                         var gameName = new PIXI.Text('Game: ' + data, {font : '50px Arial', fill : '#0490FF'});                gameName.anchor.x = 0;		gameName.anchor.y = 0;		gameName.position.x = (_renderer.canvas.width * 0.05);  		gameName.position.y = (_renderer.canvas.height * 0.05);                gameName.width = (_renderer.canvas.width * 0.2);                gameName.height = (_renderer.canvas.height * 0.1);                            var back = new PIXI.Sprite(playButtonTexture);                back.buttonMode = true;		back.anchor.x = 0.5;		back.anchor.y = 0.5;		back.position.x = (_renderer.canvas.width * 0.15);  		back.position.y = (_renderer.canvas.height * 0.9);                back.width = (_renderer.canvas.width * 0.2);                back.height = (_renderer.canvas.height * 0.075);		back.interactive = true;                                var backText = new PIXI.Text('Leave', {fill : 'white'});                backText.anchor.x = 0.5;		backText.anchor.y = 0.5;		backText.position.x = (_renderer.canvas.width * 0.15);  		backText.position.y = (_renderer.canvas.height * 0.9);                backText.width = (_renderer.canvas.width * 0.2);                backText.height = (_renderer.canvas.height * 0.1);            back.mouseover = function(data) { this.setTexture(playButtonTextureOver); };            back.mouseout = function(data) { this.setTexture(playButtonTexture); };                        back.click = function(data){                          _sockets.emit('playerLeaveRoom');                        };                   var test = new PIXI.Sprite(playButtonTexture);                test.buttonMode = true;		test.anchor.x = 0.5;		test.anchor.y = 0.5;		test.position.x = (_renderer.canvas.width * 0.5);  		test.position.y = (_renderer.canvas.height * 0.9);                test.width = (_renderer.canvas.width * 0.2);                test.height = (_renderer.canvas.height * 0.075);		test.interactive = true;                                test.mouseover = function(data) { this.setTexture(playButtonTextureOver); };                test.mouseout = function(data) { this.setTexture(playButtonTexture); };                                test.click = function(data){                                         _audioController['hud']['click'].play();                                        if(typeof input.value == 'undefined' || input.value == ''){                                                                    }else{                                                console.log(input.value);                                                    _sockets.emit('chatMessage', {message : input.value, room : _game});                                            };                                                                        };                                   var testText = new PIXI.Text('test', {fill : 'white'});                testText.anchor.x = 0.5;		testText.anchor.y = 0.5;		testText.position.x = (_renderer.canvas.width * 0.5);  		testText.position.y = (_renderer.canvas.height * 0.9);                testText.width = (_renderer.canvas.width * 0.2);                testText.height = (_renderer.canvas.height * 0.1);                            var element = {                type : 'input',                id : 'chatTest',                position : {                  x : _renderer.canvas.width/2 - 100,                  y : (_renderer.canvas.height/10) * 6                },                width: 200,                height: 22,                backgroundColor : '0xFFFFFF',                borderRadius: 5,                borderWidth : 1,                borderColor : '0x0099CC'            };                        _sockets.on('chatMessage', function(data){                                console.log(data);                            });                        _sockets.on('', function(){                                                                            });            var input = PIXI.INPUT.createElement(element);            _scene.addChild(input);            _scene.addChild(gameName);            _scene.addChild(back);            _scene.addChild(backText);                        _scene.addChild(test);            _scene.addChild(testText);                        return view;                    };        return init;    },    [        'bitwars.renderer.texture',        'bitwars.renderer',        'bitwars.scene',        'bitwars.audio.audioController',        'bitwars.sockets',        'bitwars.views'    ]);

And based on the mediator pattern I simply just call the view and it is returned by my view router. I have to specify if I want to clear the scene or leave it as it is.

views({ view : 'main',clear : true});

I hope this will help you. The cleaning of the scene is additioanally unseting the buttons to interactive.false since I know there was some kind of bug there (just to be 100% sure!)




Link to comment
Share on other sites

Hi Hubert, thanks a lot for the extensive source code :)


I looked into it a bit and if i understand you correctly, you use one renderer with ONE stage (scene) only and then add / remove / hide / show DisplayObjects to it as necessary?


So that does not give any performance or other problem with the rendering?


EDIT: ok, i just found this page where they say the same, multiple stages DO NOT WORK correctly yet, they describe the same problem i had with the loosing of interactivity after switching stages.

Link to comment
Share on other sites

  • 8 months later...

So Im new to PIXI. but I see in PIXI v3. The entire project is about using  PIXI.Container() for everything, and load as many as you wish, and put them inside anything else that you wish. There no stage really.


What I would like your suggestion on, is how to accommodate javascript files for PIXI. 

I see the examples and tutorials but all of them are focused on just showing the basics of PIXI. I will be building a more robust game but that means using separate files and not having the entire code in one file only. 


What would it be a best practice to manage "scenes" of a game in PIXI. Should I make a separate file that handles one scene and then load a different scene, etc.. should I put all my model classes one file for each model ? stuff like that. I am still learning Javascript, but it would be very useful to read a recommendation so I don't end having spaguetti code all over the place.




(maybe I should put this post in a different topic? since this question has already been answered )

Link to comment
Share on other sites

Seems off topic for this thread.  I am not sure how tolerant this forum is about such things, so I'm not sure if I would respond here and permit this practice or make you create a new thread.


Well the question is related to the Topic.. regarding the proper way to have a Scene Manager. Separate files for the game, etc...

PIXI tutorials dump all the game in one file... full of functions and global variables. And the example posted above seems quite advance. 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...