Jump to content

Phaser States - Not working


remingtonink
 Share

Recommended Posts

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 game
game.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):
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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