Dang_Khoa Posted September 10, 2013 Share Posted September 10, 2013 Hello everyone, I'm trying to make a simple title screen with Phaser and javascript, it works, but I don't know how to switch from one state to another. For example, when player click 'New Game' button, the screen changes from title state to character selection state. I'm much appreciated if someone show me a simple demo. Thank you and sorry for my bad english . Link to comment Share on other sites More sharing options...
rich Posted September 10, 2013 Share Posted September 10, 2013 You basically just call game.switchState() and pass it the new State you want to switch to. Link to comment Share on other sites More sharing options...
Dang_Khoa Posted September 10, 2013 Author Share Posted September 10, 2013 Thank you, rich, I tried but I there isn't game.switchState() function I'm using version 1.00JS. Here is a screenshot: Link to comment Share on other sites More sharing options...
casensio Posted September 10, 2013 Share Posted September 10, 2013 Would have appreciated an example like this in the forum, so I will paste my approach: This code is for version 0.9.5 so maybe you will need to modify it to fit the new version. I hope it is usefull to you. var kGAME_SCALE_FACTOR = 2; var kSCREEN_WIDTH = 320; var kSCREEN_HEIGHT = 240; var __extends = this.__extends || function (d, { function __() { this.constructor = d; } __.prototype = b.prototype; d.prototype = new __(); }; //-- var fnMainGame = (function (base) { __extends(gameName, base); function gameName(e) { base.call(this, e); } // ... DEFINE HERE YOUR GAME LOGIC ... return gameName; })(Phaser.State); //-- var fnPreloader = (function (base) { __extends(loadScreen, base); function loadScreen(e) { base.call(this, e); } loadScreen.prototype.init = function () { this.logo = this.createSprite(0, 0, "preloader"); this.logo.x = this.stage.centerX - (this.logo.bounds.width * 0.5); this.logo.y = this.stage.centerY - (this.logo.bounds.height * 0.5); this.loadBar = this.createSprite(this.logo.x, this.logo.y + this.logo.bounds.height, "loadBar"); this.loadBar.width = 0; // ... LOAD HERE WHAT YOUR GAME NEEDS .. this.loader.addTextureAtlas('id_atlas', 'graphics/img1.png', 'graphics/tiles.json'); this.loader.addTextFile('id_file', 'map/map00.json'); this.loader.addImageFile('id_image', 'graphics/img2.png'); this.loader.load(this.fileLoaded); }; loadScreen.prototype.fileLoaded = function (progress, previousKey, success) { this.loadBar.width = (this.logo.width / 100) * progress; }; loadScreen.prototype.create = function () { this.game.switchState(gameObject.MainGame); }; return loadScreen; })(Phaser.State); //-- var fnBoot = (function (base) { __extends(bootScreen, base); function bootScreen(e) { base.call(this, e); } bootScreen.prototype.init = function () { // Initialize the stage this.stage.maxScaleX = kSCREEN_WIDTH * kGAME_SCALE_FACTOR; this.stage.maxScaleY = kSCREEN_HEIGHT * kGAME_SCALE_FACTOR; this.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; this.loader.addImageFile("preloader", "graphics/load.png"); this.loader.addImageFile("loadBar", "graphics/loadBar.png"); this.loader.load(this.fileLoaded); }; bootScreen.prototype.create = function () { this.game.switchState(gameObject.Preloader); }; return bootScreen; })(Phaser.State); // Create the game object that holds the different game states var gameObject = {}; gameObject.Preloader = fnPreloader; gameObject.Boot = fnBoot; gameObject.MainGame = fnMainGame; // Load the first state window.onload = function () { var myGame = new Phaser.Game(this, 'game', kSCREEN_WIDTH, kSCREEN_HEIGHT); myGame.switchState(gameObject.Boot); }; Link to comment Share on other sites More sharing options...
rich Posted September 10, 2013 Share Posted September 10, 2013 Thank you, rich, I tried but I there isn't game.switchState() function I'm using version 1.00JS. That would be why it didn't work then In 1.00JS you do: game.state.add(key, state, autoStart); Where "key" is a reference (like "MainMenu") and "state" is the State object. This can be an instance of Phaser.State or just a plain JS object. You can add multiple states when your game boots if you like (just make sure autoStart is false, the default is 'true') and then start them with game.state.start("key") Link to comment Share on other sites More sharing options...
Dang_Khoa Posted September 11, 2013 Author Share Posted September 11, 2013 Thank rich, I did: game.state.start('key', true, true) ; but it didn't clear the sprites from the previous state, what's wrong with my code? <!DOCTYPE HTML><html><head> <title>phaser.js - a new beginning</title> <?php require('js.php'); ?></head><body><input type="button" id="menu" value="Main Menu"/><input type="button" id="select" value="Level Select"/><br><script type="text/javascript"> (function () { var mainMenu = { preload: function () { game.load.image('nocooper', 'assets/pics/1984-nocooper-space.png'); }, create: function () { var nocooper = game.add.sprite(10, 10, 'nocooper'); } } var levelSelect = { preload: function () { game.load.image('touhou', 'assets/pics/aya_touhou_teng_soldier.png'); }, create: function () { var touhou = game.add.sprite(10, 10, 'touhou'); } } var game = new Phaser.Game(640, 480); game.state.add('menu', mainMenu, true); game.state.add('select', levelSelect); var b1 = document.getElementById('menu').onclick = function () { game.state.start('menu', true, true); }; var b2 = document.getElementById('select').onclick = function () { game.state.start('select', true, true); }; })();</script></body></html> Link to comment Share on other sites More sharing options...
rich Posted September 11, 2013 Share Posted September 11, 2013 I'm looking at State swapping at the moment and will post an example in the next push. I suspect it's just not clearing the textures properly, but will investigate tonight. Link to comment Share on other sites More sharing options...
Dang_Khoa Posted September 12, 2013 Author Share Posted September 12, 2013 Glad to hear that, thank you very much, rich Link to comment Share on other sites More sharing options...
rich Posted September 13, 2013 Share Posted September 13, 2013 Just to add that I fixed the issue of the World not tidying up when you swap states and have produced a test case to show it working. Grab the final 1.0 release from master Link to comment Share on other sites More sharing options...
Dang_Khoa Posted September 13, 2013 Author Share Posted September 13, 2013 Amazing, thank you for all your works, rich Link to comment Share on other sites More sharing options...
onedayitwillmake Posted September 20, 2013 Share Posted September 20, 2013 How does this work, if you have say a pause state - which causes an overlay to show up over the game - however you don't want to destroy the running game. For example I want to do a loop such as: run GameState, push PausedState, run PausedState, pop PausedState, run GameState Link to comment Share on other sites More sharing options...
rich Posted September 20, 2013 Share Posted September 20, 2013 There's no support for 'persistent' states at the moment, sorry - but the more I look at it, the more useful I know it will be, so I plan on bumping it up the todo list. I suspect you may need 2 things: 1) Non-destructive swapping of states. So swapping to a State without destroying the current one. Your Pause screen is a good example of this. Although when you swap back to a non-destroyed state it ought to bypass 'preloader' entirely and probably even 'create' actually. Perhaps it needs a startup function? Open to ideas. 2) Simultaneously running states. So literally having 2 or more states running in sequence. The issue with this is that there is only one central display list, it's not state specific. So a background running state could add a sprite that appears on-top of whatever the top-most state might be doing. I don't think this matters though. It means you could have a UI state controlling buttons, icons, etc and a Game state, and maybe a Shop state too for an in-game shop, all updating in sequence every frame. It's up to the developer to be careful to control which state owns which objects. jerome 1 Link to comment Share on other sites More sharing options...
powerfear Posted September 20, 2013 Share Posted September 20, 2013 What about for example being able to have a pause screen in the middle of the screen but that doesn't cover up all the game. Could it be possible to make it so you can have 2 boolean, one to tell if the state should be destroyed, and another optional one to stop update being called for the state if you decide not to destroy it. This would be really useful to make all kind of rpg styles menus or even small minigame. Not sure if input events could be stopped for objects belonging to the unactive state thought. Link to comment Share on other sites More sharing options...
rich Posted September 21, 2013 Share Posted September 21, 2013 Hmm it's not quite as simple as that though - Phaser has a global tween, sound and physics manager (and other subsystems), they are not State specific. So parallel states would all share the same subsystems. This means that displaying a pause menu over a game, but actually literally 'pausing' the game state, would be impossible without each state having its own set of subsystems (or each subsystem being changed to accept state values with every object, but then I'd have to do state object checks for every single object, in every system, every frame - which seems nuts really). Open to suggestions on how to achieve this, but I'm leaning more towards allowing simultaneous states but if you want to pause something in one, it's your responsibility to do that. Link to comment Share on other sites More sharing options...
onedayitwillmake Posted September 22, 2013 Share Posted September 22, 2013 I think that is a good solution once you take those subsystem problems into account. Let the user worry about pausing animations once their state is exited. In fact sometimes u might want to keep some animations going for effect, or animate things out etx.The way I usually do it in my games is have 3 properties:CurrentState Previous stateNext state.Which have 4 main methodsOnEnterUpdateOnExitDestroyOnly the current state has its update method called.When changeState is called the old previous state has destroy called and the current state has onExit called and is set to the new previousState OnExit a state can remove input handlers or stop animations it wants to, that it can readd in OnEnter. Kind of like the ios model for view controllersJust my two cents on it. (Typed from phone excuse typos Gabbar Sisodiya 1 Link to comment Share on other sites More sharing options...
nicotr014 Posted January 3, 2014 Share Posted January 3, 2014 Is it possible that each state can have an "initialized" flag that becomes set after the initial preload/create? That way when a new state is called in, it can preload/create, and when an old state is called in it can just go straight back to "update" loop? That would be nice . That way each state can pause/resume without having to preload/create, essentially restarting every time it becomes the current state. Link to comment Share on other sites More sharing options...
rich Posted January 3, 2014 Share Posted January 3, 2014 States are just JavaScript objects, so you could easily add a 'loaded' flag to it and check it in your own preload / create functions. Link to comment Share on other sites More sharing options...
BunBunBun Posted January 3, 2014 Share Posted January 3, 2014 Here is a screenshot: Do anyone know what is an editor on the screen? Link to comment Share on other sites More sharing options...
rich Posted January 3, 2014 Share Posted January 3, 2014 Looks like WebStorm. Pretty sure it's an eclipse based editor anyway. Link to comment Share on other sites More sharing options...
BunBunBun Posted January 3, 2014 Share Posted January 3, 2014 rich, yes, you are right, thanks! Link to comment Share on other sites More sharing options...
shrdlu Posted December 29, 2014 Share Posted December 29, 2014 Hi all, I know this thread is old, but hopefully I'll get a response.I am currently building a simple sidescroller that has a Die state and a Game state. I call the Die state from Game, but then I'm not able to return to the Game state. The console gives me errors that should not be there like, 'this.state not defined'. Please help! Here is my code: Game.js:var SideScroller = SideScroller || {}; SideScroller.Game = function(){}; SideScroller.Game.prototype = { preload: function() { this.game.time.advancedTiming = true; }, create: function() { this.music = this.game.add.audio('music', 1, true); this.music.play(); this.map = this.game.add.tilemap('level1'); //the first parameter is the tileset name as specified in Tiled, the second is the key to the asset this.map.addTilesetImage('tiles_spritesheets', 'gameTiles'); //create layers this.backgroundlayer = this.map.createLayer('backgroundLayer'); this.backgroundLayer2 = this.map.createLayer('backgroundLayer2'); this.blockedLayer = this.map.createLayer('blockedLayer'); this.deathLayer = this.map.createLayer('deathLayer'); //collision on blockedLayer this.map.setCollisionBetween(1, 100000, true, 'blockedLayer'); this.map.setCollisionBetween(1, 100000, true, 'deathLayer'); //resizes the game world to match the layer dimensions this.backgroundlayer.resizeWorld(); //create player this.player = this.game.add.sprite(20, 215, 'player'); this.player.scale.setTo(0.5); //enable physics on the player this.game.physics.arcade.enable(this.player); //player gravity this.player.body.gravity.y = 1000; //camera follows player this.game.camera.follow(this.player); //move player with cursor keys this.cursors = this.game.input.keyboard.createCursorKeys(); this.spacebar = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR); }, update: function() { //collision this.game.physics.arcade.collide(this.player, this.blockedLayer, this.playerHit, null, this); this.game.physics.arcade.collide(this.player, this.deathLayer, this.playerDie, null, this); if(this.cursors.right.isDown) { this.playerMoveRight(); } else if(this.cursors.left.isDown) { this.playerMoveLeft(); } else { this.playerStay(); } if(this.cursors.up.isDown) { this.playerJump(); } if(this.spacebar.isDown) { this.playerTransform(); } if(this.player.y > 215) { this.player.y = 170; } if(this.player.x < 5) { this.player.x = 10; } }, render: function() { this.game.debug.text(this.game.time.fps || '--', 20, 70, "#000", "40px Courier"); }, playerTransform: function() { if(this.player.texture == 'player') { if(this.player.texture == 'player2') { this.player.loadTexture('truck'); } } else { this.player.loadTexture('player'); } }, playerHit: function(player, blockedLayer) { }, playerJump: function() { if(this.player.body.blocked.down) { this.player.body.velocity.y -= 500; } }, playerMoveRight: function() { this.player.body.velocity.x = 300; this.player.loadTexture('player'); }, playerMoveLeft: function() { this.player.body.velocity.x -= 20; this.player.loadTexture('player2'); }, playerStay: function() { this.player.body.velocity.x = 0; }, playerDie: function() { this.music.stop(); this.game.switchState('Die'); }};Die.js:var SideScroller = SideScroller || {}; SideScroller.Die = function(){}; SideScroller.Die.prototype = { preload: function() { this.game.time.advancedTiming = true; }, create: function() { this.endMusic = this.game.add.audio('endMusic', 1, true); this.endMusic.play(); this.game.stage.backgroundColor = '#000'; this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL; this.scale.pageAlignHorizontally = true; this.scale.pageAlignVertically = true; this.scale.setScreenSize(true); this.restart = this.game.add.text(this.game.world.centerX, this.game.world.height/4*3, 'Click to\nRestart'); this.restart.anchor.setTo(0.5, 0.5); this.dead = this.game.add.sprite(this.game.world.centerX, this.game.world.height/4, 'gameOver'); this.dead.scale.setTo(0.5); this.dead.anchor.setTo(0.5, 0.5); this.restart.inputEnabled = true; this.restart.events.onInputDown.add(this.restartGame); this.game.camera.follow(this.dead); }, update: function() { }, restartGame: function() { this.state.start('Game'); }, render: function() { }}; Link to comment Share on other sites More sharing options...
Recommended Posts