Jump to content

Need help in understanding state switch


Recommended Posts

Hi everybody,


the documentation says that:


If a previous state was already running, it is cleared as the new state starts (actually a single object related to the game and called StateManager is in charge of this housework). This means the previous state world is erased : sprites, groups, tweens, collision callback, everything related to the world but the cache. Its destroy function is also called at his very moment.
So you currently can't pass world related objects through states.


Is this still true and if, how can I workaround? At the moment I need two things to happen while switching states:

1. the previous state needs to be paused but keep alive, because if I open the menu (as state) on a world map (as state) and exit (return), I will not calculate the position of player, camera and every object before.

2. some objects need to be passed through, e.g. the player. I always need his stats (menu & combat), inventory (menu, worldmap, & combat) and other attached flags (worldmap as event condition).

Link to comment
Share on other sites

I've ran into this issue as well. Like jflowers45, I just resort to a global variable to store all of my custom data that always needs to be available throughout all states. Also, instead of actual global variables, I just make an object on game.global to access. This way, it won't conflict with anything. So, it would look something like this:

var game = new Phaser.Game(800, 600, Phaser.AUTO, '');game.global = {  playerPosition: { x: 0, y: 0 },  cameraPosition: { x: 0, y: 0 },  playerStats: null,  playerInventory: null  }

Then, you can set and get those at any point, without worrying about state changes obliterating the data. 


You can call the property on game whatever you want, I just use "global" to remind me of its purpose.

Link to comment
Share on other sites

Thank you very much so far.


I figured out, that with the two additional parameter for clearWorld and clearCache set to false the data structure preserves after switching back, but loaded sprites may get lost.

In my very example:

WorldMap.prototype = {    preload: function() {    },    create: function() {      /* show state */      console.log(this.game.state.current);      this.menuKey = this.game.input.keyboard.addKey(Phaser.Keyboard.ONE);      this.menuKey.onDown.add(this.switchToMenu, this);      /*camera*/      this.camera = {x:0, y:0, direction:'', isMoving:false};      /*player*/      if (!this.hasOwnProperty("player")) {          this.player = new Player(this.game, 160, 160);          this.game.add.existing(this.player);      }      /*debug*/      (this.player.hasOwnProperty("test")) ? this.player.test++ : this.player.test = 0;      console.log(this.player.test);      console.log('player.x: '+this.player.x);      console.log('player.y: '+this.player.y);    },    update: function() {      // state update code      this.game.physics.arcade.collide(this.player, this.layer3);      this.game.physics.arcade.collide(this.player, this.layer2);      this.moveCamera();      this.movePlayer();    },    moveCamera: function() {	[..]    },    movePlayer: function() {	[..]    },    switchToMenu: function() {        this.game.state.start('gameMenu', false, false);    }  };
function GameMenu() {}  GameMenu.prototype = {    preload: function() {    },    create: function() {      console.log(this.game.state.current);      this.cursor = this.game.input.keyboard.createCursorKeys();      this.menuKey = this.game.input.keyboard.addKey(Phaser.Keyboard.TWO);      this.menuKey.onDown.add(this.switchToWorldMap, this);      if (!this.hasOwnProperty("player")) {          this.player = new Player(this.game, 160, 160);          this.game.add.existing(this.player);      }      (this.player.hasOwnProperty("test")) ? this.player.test++ : this.player.test = 0;      console.log(this.player.test);      console.log('player.x: '+this.player.x);      console.log('player.y: '+this.player.y);	},    switchToWorldMap: function() {        this.game.state.start('worldMap', false, false);    }  };
var Player = function(game, x, y, frame) {  Phaser.Sprite.call(this, game, x, y, 'player', frame);  this.scale.x = 0.5;  this.scale.y = 0.5;  this.anchor.setTo(0.5, 0.5);  this.game.physics.arcade.enable(this);};

After switching back the sprite of player is no longer displayed (but still navigable).

And it seems that both states merge functions after calling it twice; if I use the same key to change the state (e.g. Phaser.Keyboard.ONE) after the third hit I can no longer switch to state to, even the call differs. Maybe bug coded by myself...

Link to comment
Share on other sites

  • 2 months later...
  • 2 years later...

I had the same issue. I set `clearWorld=false` but my sprites were invisible after state switch (but were still actively moving & colliding & updating). The overall goal is to initialize my sprite pools in preload state instead of game state to avoid a performance hit when starting the game.

I was recreating the background upon state switch, which was then overlaid on top of the old sprites. To fix this I call `this.game.world.bringToTop(spritePool)` at the beginning of the state. 

Link to comment
Share on other sites


  • Recently Browsing   0 members

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