remingtonink Posted May 21, 2014 Share Posted May 21, 2014 Hi, I decided to join the forum since I cannot find a solution to my problem in the docs. I created a minigame that works perfectly without the use of states (see link below), but for expansion reasons I want to add States and there is where I've stumbled upon a hurdle. Working protoype (what it should look like): http://ihatestatistics.com/VU/chris/phaser-master/puzzleGame/index.php The code without states:var game = new Phaser.Game(240, 320, Phaser.AUTO, 'game_div', { preload: preload, create: create, update: update }); var player;var balls;var bombs;var cursors;var scoreCounter = 0;var text; function preload() { game.load.image('paddle', 'assets/player.png'); game.load.image('bullets', 'assets/player.png'); game.load.image('bomb', 'assets/bomb.png');} function create() { game.physics.startSystem(Phaser.Physics.ARCADE); game.stage.backgroundColor = '#2d2d2d'; balls = game.add.group(); balls.createMultiple(250, 'bullets', 0, false); bombs = game.add.group(); bombs.createMultiple(1000, 'bomb', 0, false); player = game.add.sprite(game.world.centerX, game.world.height-10, 'paddle'); player.scale.setTo(8,2); game.physics.arcade.gravity.y = 400; // Enable physics on everything added to the world so far (the true parameter makes it recurse down into children) game.physics.arcade.enable(game.world, true); player.body.allowGravity = 0; player.body.immovable = true; cursors = game.input.keyboard.createCursorKeys(); game.time.events.loop(150, fireBall, this); game.time.events.loop(600, fireBomb, this); text = game.add.text(16, 16, '', { fill: '#ffffff' });} function fireBall() { var ball = balls.getFirstExists(false); if (ball){ ball.frame = game.rnd.integerInRange(0,6); ball.exists = true; ball.reset(game.world.randomX, 0); }} function fireBomb() { var bomb = bombs.getFirstExists(false); if (bomb){ bomb.frame = game.rnd.integerInRange(0,6); bomb.exists = true; bomb.reset(game.world.randomX, 0); }} function catchBall(a, ball) { scoreCounter++; text.text = scoreCounter; ball.kill();} function catchBomb(a, ball) { scoreCounter=0; text.text = scoreCounter; ball.kill();} function update() { game.physics.arcade.collide(player, balls, null, catchBall, this); game.physics.arcade.collide(player, bombs, null, catchBomb, this); player.body.velocity.x = 0; if (cursors.left.isDown){ player.body.velocity.x = -200; } else if (cursors.right.isDown){ player.body.velocity.x = 200; } balls.forEachAlive(checkBounds, this); bombs.forEachAlive(checkBounds, this); } function checkBounds(ball) { if (ball.y > 330){ ball.kill(); }} function render() {} Code with states:var game = new Phaser.Game(240, 320, Phaser.AUTO, 'game_div'); var player;var balls;var bombs;var cursors;var scoreCounter = 0;var text; var main_state = { preload: function() { game.load.image('paddle', 'assets/player.png'); game.load.image('bullets', 'assets/player.png'); game.load.image('bomb', 'assets/bomb.png');}, create: function() { game.physics.startSystem(Phaser.Physics.ARCADE); game.stage.backgroundColor = '#2d2d2d'; balls = game.add.group(); balls.createMultiple(250, 'bullets', 0, false); bombs = game.add.group(); bombs.createMultiple(1000, 'bomb', 0, false); player = game.add.sprite(game.world.centerX, game.world.height-10, 'paddle'); player.scale.setTo(8,2); game.physics.arcade.gravity.y = 400; // Enable physics on everything added to the world so far (the true parameter makes it recurse down into children) game.physics.arcade.enable(game.world, true); player.body.allowGravity = 0; player.body.immovable = true; cursors = game.input.keyboard.createCursorKeys(); game.time.events.loop(150, fireBall, this); game.time.events.loop(600, fireBomb, this); text = game.add.text(16, 16, '', { fill: '#ffffff' });}, fireBall: function() { var ball = balls.getFirstExists(false); if (ball){ball.frame = game.rnd.integerInRange(0,6);ball.exists = true;ball.reset(game.world.randomX, 0); }}, fireBomb: function() { var bomb = bombs.getFirstExists(false); if (bomb){bomb.frame = game.rnd.integerInRange(0,6);bomb.exists = true;bomb.reset(game.world.randomX, 0); }}, catchBall: function(a, ball) { scoreCounter++; text.text = scoreCounter; ball.kill();}, catchBomb: function(a, ball) { scoreCounter=0; text.text = scoreCounter; ball.kill();}, update: function(){game.physics.arcade.collide(player, balls, null, catchBall, this);game.physics.arcade.collide(player, bombs, null, catchBomb, this); player.body.velocity.x = 0; if (cursors.left.isDown){player.body.velocity.x = -200;}else if (cursors.right.isDown){player.body.velocity.x = 200;}balls.forEachAlive(checkBounds, this);bombs.forEachAlive(checkBounds, this);}, checkBounds: function(ball) { if (ball.y > 330){ball.kill(); }}, render: function() {}}; // Add and start the 'main' state to start the gamegame.state.add('main', main_state); game.state.start('main'); Basically what I've done is:- Encompass the entire code within a var main_state = {} block- added two lines of code at the bottom:game.state.add('main', main_state); game.state.start('main'); - changed every "function <name> (){}" to "<name>: function(){}" I've been using the Flappy Bird code from Lessmilk's tutorial and I have also tried s-niambar.com's phaser tutorial (link below):source: http://s-nambiar.com/tutorials/managing-game-states-phaser/ Link to comment Share on other sites More sharing options...
Videlais Posted May 21, 2014 Share Posted May 21, 2014 Hi, remingtonink. Building off s-niambar's example (and the way I do it too), your code might look something like the following:var game = new Phaser.Game(240, 320, Phaser.AUTO, 'game_div');// I'm making an assumption here that 'player' will be used// across multiple states, so I'm leaving its reference// in a higher (function) scopevar player;var main_state = function(game) { // All of the variables that were defined in the // same scope as 'game' are now defined inside the 'main_state' // object itself. this.balls; this.bombs; this.cursors; this.scoreCounter = 0; this.text;};// Instead of properties of 'main_state', I am// adding these to its 'prototype'.// The reason for this is because all properties of// an object's prototype share the same function// execution scope as the object itself.//// In other words, we can reference 'this' variables// that are defined in one places across all// prototype properties.main_state.prototype = { preload: function() { game.load.image('paddle', 'assets/player.png'); game.load.image('bullets', 'assets/player.png'); game.load.image('bomb', 'assets/bomb.png'); }, create: function() { game.physics.startSystem(Phaser.Physics.ARCADE); game.stage.backgroundColor = '#2d2d2d'; // Since all the variables earlier are 'this' now, // all of their references become this.variableName this.balls = game.add.group(); this.balls.createMultiple(250, 'bullets', 0, false); this.bombs = game.add.group(); this.bombs.createMultiple(1000, 'bomb', 0, false); player = game.add.sprite(game.world.centerX, game.world.height-10, 'paddle'); player.scale.setTo(8,2); game.physics.arcade.gravity.y = 400; // Enable physics on everything added to the world so far (the true parameter makes it recurse down into children) game.physics.arcade.enable(game.world, true); player.body.allowGravity = 0; player.body.immovable = true; this.cursors = game.input.keyboard.createCursorKeys(); game.time.events.loop(150, fireBall, this); game.time.events.loop(600, fireBomb, this); this.text = game.add.text(16, 16, '', { fill: '#ffffff' }); }, fireBall: function() { var ball = balls.getFirstExists(false); if (ball) { ball.frame = game.rnd.integerInRange(0,6); ball.exists = true; ball.reset(game.world.randomX, 0); } }, fireBomb: function() { var bomb = bombs.getFirstExists(false); if (bomb){ bomb.frame = game.rnd.integerInRange(0,6); bomb.exists = true; bomb.reset(game.world.randomX, 0); } }, catchBall: function(a, ball) { this.scoreCounter++; this.text.text = this.scoreCounter; this.ball.kill(); }, catchBomb: function(a, ball) { this.scoreCounter = 0; this.text.text = this.scoreCounter; this.ball.kill(); }, update: function(){ game.physics.arcade.collide(player, this.balls, null, this.catchBall, this); game.physics.arcade.collide(player, this.bombs, null, this.catchBomb, this); player.body.velocity.x = 0; if (this.cursors.left.isDown){ player.body.velocity.x = -200; } else if (this.cursors.right.isDown){ player.body.velocity.x = 200; } balls.forEachAlive(checkBounds, this); bombs.forEachAlive(checkBounds, this); }, checkBounds: function(ball) { if (this.ball.y > 330){ this.ball.kill(); } },};// Add and start the 'main' state to start the gamegame.state.add('main', main_state); game.state.start('main');The difference between this and your code is that I'm creating a variable instance instead of passing an object literal as the game state. The assigning of the anonymous function --var main_state = function(game) { ... }-- creates it as a Function (and thus Object). Then, using your code but adding 'prototype', I am augmenting the object by adding properties to its prototype chain. As I wrote in my comment, this allows for creating 'this'-scoped properties in its initial definition and the ability to reference them in the functions and other properties defined as part of the prototype chain. Nambiar and ComprehendGames 2 Link to comment Share on other sites More sharing options...
Recommended Posts