marvster Posted April 23, 2014 Share Posted April 23, 2014 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 More sharing options...
jflowers45 Posted April 23, 2014 Share Posted April 23, 2014 for one, you might be looking at old docs - look at clearworld and clearcache parameters http://docs.phaser.io/Phaser.StateManager.html#start in some cases I make variables global when it makes sense (attach them to window, or something like that) Link to comment Share on other sites More sharing options...
jackrugile Posted April 23, 2014 Share Posted April 23, 2014 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 More sharing options...
marvster Posted April 23, 2014 Author Share Posted April 23, 2014 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 More sharing options...
Riddik Posted June 25, 2014 Share Posted June 25, 2014 [sorry, please, del] Link to comment Share on other sites More sharing options...
JTronLabs Posted September 29, 2016 Share Posted September 29, 2016 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 More sharing options...
Recommended Posts