Jump to content

Velocity y is NaN


PabloK
 Share

Recommended Posts

Hi! I'm new to Phaser and have had great fun learning the engine. I recently started separating the code for my game into prefab files by extending Phaser.Sprite but I have run in to trouble. When Trying create the movement for the player I have a problem where the player starts moving randomly up or down on the y-scale. When inspecting my Player.prototype.update method in chrome I can see that this.body.velocity.y is NaN. I have no Idea how it got to be NaN pheraps some issue with the gravity? I have tried various fixes but I can't find the bug in my code. I have looked at numerous tutorials and they all look similar to what Im doing. Please help. Below is my code.

player.js

// Private
var leftKey;
var rightKey;
var jumpKey;
var speed = 150;
var jumpSpeed = 250;
// Constructor
function Player (game, x, y) {
  Phaser.Sprite.call(this, game, x, y, Player.key);
  this.anchor.set(0.5,0.5);
  game.physics.arcade.enableBody(this);
  this.body.bounce = 0;
  this.body.collideWorldBounds = true;
  this.body.allowGravity = true;

  leftKey = game.input.keyboard.addKey(Phaser.Keyboard.A);
  rightKey = game.input.keyboard.addKey(Phaser.Keyboard.D);
  jumpKey = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);

  game.add.existing(this);
}
Player.prototype = Object.create(Phaser.Sprite.prototype);
Player.prototype.constructor = Player;

// Static
Player.preload = function(game) {
  game.load.image(Player.key, "images/block.png");
};
Player.key = "Player";

Player.prototype.update = function() {
  this.body.velocity.x = 0;

  if (leftKey.isDown) {
    this.body.velocity.x = -speed;
  } else if (rightKey.isDown) {
    this.body.velocity.x = speed;
  }

  if (jumpKey.isDown && (this.body.onFloor() || this.body.touching.down)) {
    this.body.velocity.y = -jumpSpeed;
  }
};

module.exports = Player;
var Player = require('../models/player.js');
var destiny = {};

/* The main game */
destiny.create = function () {
  console.info("Find out your destiny!");
  // World
  this.game.stage.backgroundColor = "#5599CC";
  this.game.world.setBounds(0, 0, 1000, 500);
  this.game.physics.startSystem(Phaser.Physics.ARCADE);
  this.game.time.desiredFPS = 30;
  this.game.physics.arcade.gravity.y = 200;
  this.allSprites = {};

  // Player
  this.allSprites.destinyPlayer = new Player(this.game,2000,900);


  // Camera
  this.game.camera.follow(this.allSprites.destinyPlayer,Phaser.Camera.FOLLOW_PLATFORMER);

};

destiny.update = function() {
};

destiny.render = function() {
  this.game.debug.spriteInfo(this.allSprites.destinyPlayer,32,32);
  this.game.debug.cameraInfo(this.game.camera,32,128);
};

module.exports = destiny;

My game is loaded in a series of game states (boot, preload, startscreen, preload, game). I have previously not had any problems with that part but if you want to see that code please ask.

Here is the error in chrome.

NAN.png

Any help is appreciated.

Link to comment
Share on other sites

  • 4 months later...

I've experienced a velocity.y of NaN when one sprite collides with another. I'm on Phaser 2.6.1, by the way.

Here's a video of what is happening (with some debug info at the top). The "jitter" on the X access when they collide is a work-in-progress feedback action that happens when a player collides with an enemy. This problem happens with or without that "jitter" added to the player on collision with an enemy.

http://cloud.carlfurrow.com/2F2k423G0p2s

Here's some example code that is similar to what I'm running.

create() {
  player = new Player(100, 100);
  baddy = new Baddy(300, 100);

  game.physics.arcade.enable([player, baddy])

  game.world.add(player);
  game.world.add(baddy);
}

collideCallback(player, baddy) {
  console.log(player.body.velocity.y); // NaN
}

update() {
  game.physics.arcade.collide(player, baddy, collideCallback);
}

I have not found the cause of this yet, but would be curious if someone else understands what is going on.

Edited by Chazlodian
add phaser version
Link to comment
Share on other sites

NaN errors happen when you try to use a string or undefined variable as a number. In your case(2nd example)  it's because player and baddy are declared in the create function, and then used outside their scope in the update function, where they are undefined.

In essence it's a variable scope issue in both cases. You are trying to use a 'undefined' as a number.

Link to comment
Share on other sites

Thanks for taking the time to reply!

In this case, scope is not the issue. The example above was a "toy" one, because the variables are all declared in the same scope, at the same level as the functions are defined.

let game, player, baddy = null;

create() {
//..snip
}

collideCallback(player, baddy) {
//..snip
}

update() {
//..snip
}

I agree that at some point either `undefined` or a string is attempting to be added/multiplied/whatever to a number, but exactly where is the mystery, because I do no such manipulations myself other than movement. I'm simply adding velocity to X to move the player left/right, and then on "jump", the player gets a negative Y velocity to counter-act the gravity. Jumping and movement work and have always worked, the problem comes into play during the collision between the player and the "baddy". The player collides appropriately with the tiles I've setup, but somehow the collision with the other sprite entity (which also has arcade physics enabled on it) is causing an issue *somewhere*. I'll continue to do  more investigation, but I am assured it is not a scoping issue within my own code, as I'm well-aware of what that looks like and where it could arise. Thank you all the same.

 

 

Link to comment
Share on other sites

I don't know why people insist it's not scope when it is.

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let

You are using let, the scope of let is not like the scope of var. You are also declaring baddy = null which is 'undefined'.

 

var game;
var player;
var baddy;

create() {
  player = new Player(100, 100);
  baddy = new Baddy(300, 100);

  game.physics.arcade.enable([player, baddy])

  game.world.add(player);
  game.world.add(baddy);
}

collideCallback(player, baddy) {
  console.log(player.body.velocity.y);
}

update() {
  game.physics.arcade.collide(player, baddy, collideCallback);
}

Another good practice is to not have variables declared on the same line unless they share some traits. Game, Player and Baddy are in noway alike so you should place them on different lines. Javascript might not care, but people reading your code will appreciate it.

Link to comment
Share on other sites

Hey again symof, thanks for the reply and the link. I've copied the relevant content below.

Quote

Variables declared by let have as their scope the block in which they are defined, as well as in any contained sub-blocks . In this way, let works very much like var. The main difference is that the scope of a var variable is the entire enclosing function:

function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // different variable
    console.log(x);  // 2
  }
  console.log(x);  // 1
}

 

Again, the code I've supplied in previous replies is toy code that is representative of the issues I'm seeing. I will update said toy code to further illustrate the layout of my own code:

window.onload = function() {
  let game,
      preload,
      create,
      update,
      baddyCollide,
      player,
      baddy;

  preload = function() {
    // do preload things
  };

  create = function() {
    // snip... do create stuff
    player = new Player(game, 50, 100);
    baddy = new Baddy(game, 250, 200);
    game.physics.arcade.enable([player, baddy]);

    game.world.add(stickman);
    game.world.add(baddy);
  };

  baddyCollide = function(player, baddy) {
    console.log(player);
    console.log(baddy);
  };

  update = function() {
    game.physics.arcade.collide(player, baddy, collideCallback);
    stickman.update();
    baddy.update();
  };

  game = new Phaser.Game(640, 480, Phaser.AUTO, '', {
      preload: preload,
      create: create,
      update: update
  });
}

I hope that clears up the confusion around scope. Since all the variables are declared (with let or otherwise) inside of the onload function, they are sharing the same scope at this time.

The `baddyCollide` method is called on collision, and outputs each sprite to the console. They are not null, or undefined, but sprites.

I appreciate the time you're taking to sort out the scope issue, but I do believe it is misplaced at this time. It seems to be upsetting you, and I don't want it to be a bother.

 

 

Link to comment
Share on other sites

I may have found an issue. I see that I enable gravity at the game-level in my create method:

create = function(){
  game.physics.startSystem(Phaser.Physics.ARCADE);
  game.physics.arcade.gravity.y = 250;
  //snip
}

But I also was incorrectly setting gravity on the baddy object, during it's initialization, after physics was enabled on its body.

this.body.gravity = 250;

It should have been "this.body.gravity.y". That is probably where the undefined is coming into play. When the physics bodies were colliding, the physics system didn't know how to apply force against the incoming body, since gravity was invalid. Awesome.

Link to comment
Share on other sites

On April 5, 2016 at 8:20 PM, PabloK said:

When inspecting my Player.prototype.update method in chrome I can see that this.body.velocity.y is NaN. […]

body.bounce should be a Point, not a number:

this.body.bounce = 0;

this.body.bounce.set(0);
// or
this.body.bounce.x = this.body.bounce.y = 0
// or
this.body.bounce = new Phaser.Point(0, 0);

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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