Jump to content

Switching states with preserving objects


Recommended Posts


in my game I will be very often switching states - for example Intro and Office. In each state user can kill some objects, which were created in init function when the state was started for the first time. Lets assume that in the Office state user killed two objects, then he goes to Intro state and then back to Office - is there some way to preserve that state as it was before the state change? Without holding some global array with informations about all objects if they were killed or not?

My sample code:


MyGame.intro = function (game) {    this.background;    this.character;};MyGame.intro.prototype = {    create: function () {        this.background = this.add.sprite(0, 0, 'loadingBackground');        this.character = game.add.sprite(game.world.centerX, game.world.centerY, 'aml_1', 'aml_avatar_hindus.jpg');        var left = game.add.sprite(game.world.centerX-232, game.world.centerY - 200, 'aml_1', 'strzalka_lewo.png');        var right = game.add.sprite(game.world.centerX+200, game.world.centerY - 200, 'aml_1', 'strzalka_prawo.png');        this.character.anchor.setTo(0.5,0.5);        var startBtn = game.add.sprite(game.world.centerX, game.world.centerY+300, 'aml_1', 'letsstart.png');        startBtn.anchor.set(0.5);        startBtn.inputEnabled = true;        startBtn.events.onInputDown.add(this.startClicked, this);                game.scale.pageAlignHorizontally = true;		game.scale.pageAlignVertically = true;		// using RESIZE scale mode		game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;		game.scale.setScreenSize(true);       },              startClicked: function () {            this.state.start('Office', false, false);       }            };


MyGame.office = function (game) {    this.background;    this.character;    this.sheet;    this.btn;    this.zszywacz;};MyGame.office.prototype = {    init: function () {        this.background = this.add.sprite(0, 0, 'officeBackground');        this.sheet = this.add.sprite(game.world.centerX, game.world.centerY, 'aml_1', 'pole.png');        this.sheet.anchor.set(0.5);        this.btn = this.add.sprite(game.world.centerX, game.world.centerY + 300, 'aml_1', 'play.png');        this.btn.anchor.set(0.5);        this.btn.inputEnabled = true;        this.btn.events.onInputDown.add(this.btnClicked, this);                this.spawnHiddenObjects();            },        create: function() {            },        btnClicked: function() {        this.sheet.kill();        this.btn.kill();        console.log(this.sheet);    },        spawnHiddenObjects: function() {        this.zszywacz = this.add.sprite(1302, 587, 'aml_1', 'zszywacz.png');        this.zszywacz.inputEnabled = true;        this.zszywacz.events.onInputDown.add(this.zszywaczClicked, this);    },        zszywaczClicked: function() {        this.state.start('Intro', false, false);    }    };

Any help would be appreciated, thanks.

Link to comment
Share on other sites

In your 'constructors' you're appending properties to the `MyGame` object but you're setting them to `undefined`, there is no need to re-declare them in state constructors, if they are declared ONCE in your initialisation code they'll be available from `MyGame` in each state.


MyGame is simply a namespace, conceptually its exactly the same as having them global, with the only real difference being that you (and Phaser) are arbiters of the MyGame object, which you are not of Window.


Theres also nothing wrong with creating a new global, `myState` fro example, that holds state away from the `myGame` object. Yeah, it creates a new global but without a module system you'll just end up using MyGame as a dumping ground as you are now.


But either way is fine, just stop redeclaring (effectively clearing) your variables and you'll be good to go!

Link to comment
Share on other sites

Thanks for your reply, I'll correct it in my code, but anyways either I didn't fully understand your answer, or you didn't understand my problem :)

I dont have problems reaching some data between states. In Office state on button click I'm killing this.sheet and this.btn. After that if I change state to Intro, and then back to Office I would like to have this.sheet and this.btn still killed without storing informations about them if they were previously killed or not. Is it possible using states?

In other words when changing back to some state, I do not want to fully create it from beginning, but to restore it as it previously was (when talking about objects, sprites etc.). 

Link to comment
Share on other sites

I'm not sure that Phaser will help you specifically with restoring old state, keeping representations of state efficiently can be tricky and usually its not necessary for something that changes state so frequently (such as games).


If you need to create a new object for a state then do that in the state constructor. If it is a game-wide object (effectively global) then declare it once in the game constructor and re-use it.


Additionally, you might like to check if that variable has already been set and only declare it if it has not been set, this would give you persistence between states

MyGame.Office = function( game ) {  this.foo = this.foo || 'my new value'}

There are a couple of things you have to be aware of here:


1) `this` is shared across states, you have to consider variable naming very carefully. In the example above if a different state sets `this.foo` then 'my new value' will not be assigned, even though this could be the first time you hit the `Office` state. This is a weakness in dumping all state into MyGame, but you can probably get away with it.


2) If you are assigning objects with multiple keys then you have to consider which keys change as you re-enter previously visited states.



However, those concerns aside, this system will give you some persistence across state changes. The first time you hit Office and `this.foo` is undeclared so will be set to `my new value`, if you leave Office and re-enter the Office state then the check will pass as `this.foo` has been declared. Now, if you change `this.foo` somewhere else and leave and re-enter Office then the check will still pass and `this.foo` will be as it previously was.


Sorry this is not particularly clear, I hope the code example helps if you can not understand me very well!



edit: I am assuming Office.init() only gets called once during the lifecycle of the app, I suspect you could get away with deleting everything in your constructor and you would get persistence across state.

Link to comment
Share on other sites

Thank you for all the hints and infos - working with Phaser for about a month, I'm still a little bit lost in it :)

Actually your hint with this.foo works exactly as I wanted - thanks again! :) When changing back to the state where object was previously killed, it has alive == false and is not displayed :)

Link to comment
Share on other sites


  • Recently Browsing   0 members

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