It seems `setVelocityX` doesn't agree with the keystrokes. Am I missing something?

Viewed 72

I'm learning Phaser3 following a tutorial.

Here is the code I ported from the tutorial.

class BootScene extends Phaser.Scene {
  constructor() {
    super({
      key: 'BootScene'
    });
  }

  preload() {
        // map tiles
        this.load.image('tiles', 'https://raw.githubusercontent.com/liyi93319/phaser3_rpg/main/part1/assets/map/spritesheet.png');
        
        // map in json format
        this.load.tilemapTiledJSON('map', 'https://raw.githubusercontent.com/liyi93319/phaser3_rpg/main/part1/assets/map/map.json');
        
        // our two characters
        this.load.spritesheet('player', 'https://raw.githubusercontent.com/liyi93319/phaser3_rpg/main/part1/assets/RPG_assets.png', { frameWidth: 16, frameHeight: 16 });
  }

  create() {
    this.scene.start('WorldScene');
  }
}

class WorldScene extends Phaser.Scene {
  constructor() {
    super({
      key: 'WorldScene'
    });
  }

  create() {
    // create your world here
    var map = this.make.tilemap({ key: 'map' });
    // creates a tileset image
    var tiles = map.addTilesetImage('spritesheet', 'tiles');
    var grass = map.createLayer('Grass', tiles, 0, 0);
    var obstacles = map.createLayer('Obstacles', tiles, 0, 0);
    obstacles.setCollisionByExclusion([-1]);
    this.player = this.physics.add.sprite(25, 25, 'player', 6);
    this.cursors = this.input.keyboard.createCursorKeys();
  }

  update(time, delta) {
    this.player.body.setVelocity(0);
    // Horizontal movement
    if (this.cursors.left.isDown) {
      this.player.body.setVelocityX(-80);
    }
    else if (this.cursors.right.isDown) {
      this.player.body.setVelocityX(80);
    }
    // Vertical movement
    if (this.cursors.up.isDown) {
      this.player.body.setVelocityY(-80);
    }
    else if (this.cursors.down.isDown) {
      this.player.body.setVelocityY(80);
    }
  }
}

var bootScene = new BootScene();
var worldScene = new WorldScene();

var config = {
  type: Phaser.AUTO,
  parent: 'content',
  width: 320,
  height: 240,
  zoom: 2,
  pixelArt: true,
  physics: {
    default: 'arcade',
    arcade: {
      gravity: { y: 0 }
    }
  },
  scene: [
    BootScene,
    WorldScene
  ]
};
var game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>

I'm confused about the setVelocityX method. Per the doc, the method sets

the velocity, in pixels per second.

To examine this, I moved the player to the left of a tree

enter image description here

and tapped right arrow key quickly. It took about 4 taps to move the player from the left to the right.

enter image description here

I guess the tree I used as the reference could count as a tile, which has width of 16, per map.json. So, one keystroke represents about 3~4 pixels whereas the code

this.player.body.setVelocityX(-80);

set the velocity 80 pixels per second.

It seems setVelocityX doesn't agree with the keystrokes. Am I missing something?

PS: I did hold the key for 1 full second but the player didn't move 80 pixels either.

1 Answers

Well if you only tap, it doesn't move for a full second. just how long the key is hold down (can be some milliseconds).

And it also depends on the update rate of the update function, it is not always constant. (you can see that through the parameter delta passed to the update function, update(time, delta)) Here the link to the documentation

If you want to test it, just hold the key for 1 second. btw.: drag and acceleration can come also into play, if set.

Edited so that is logs the position after 1 second:
the results will vary depending on the computer, but for me it is about 80px

class BootScene extends Phaser.Scene {
  constructor() {
    super({
      key: 'BootScene'
    });
  }

  preload() {
        // map tiles
        this.load.image('tiles', 'https://raw.githubusercontent.com/liyi93319/phaser3_rpg/main/part1/assets/map/spritesheet.png');
        
        // map in json format
        this.load.tilemapTiledJSON('map', 'https://raw.githubusercontent.com/liyi93319/phaser3_rpg/main/part1/assets/map/map.json');
        
        // our two characters
        this.load.spritesheet('player', 'https://raw.githubusercontent.com/liyi93319/phaser3_rpg/main/part1/assets/RPG_assets.png', { frameWidth: 16, frameHeight: 16 });
  }

  create() {
    this.scene.start('WorldScene');
  }
}

class WorldScene extends Phaser.Scene {
  constructor() {
    super({
      key: 'WorldScene'
    });
  }

  create() {
    // create your world here
    var map = this.make.tilemap({ key: 'map' });
    // creates a tileset image
    var tiles = map.addTilesetImage('spritesheet', 'tiles');
    var grass = map.createLayer('Grass', tiles, 0, 0);
    var obstacles = map.createLayer('Obstacles', tiles, 0, 0);
    obstacles.setCollisionByExclusion([-1]);
    this.player = this.physics.add.sprite(25, 25, 'player', 6);
    this.cursors = this.input.keyboard.createCursorKeys();
  }

  update(time, delta) {
    this.player.body.setVelocity(0);
   
    // Horizontal movement
    if (this.cursors.left.isDown) {
      this.player.body.setVelocityX(-80);
      if(!this._press){
       this.start = (new Date()).getTime();
       this.startX = this.player.body.x; 
        this._press = true;
       setTimeout(()=>{
        console.info(`Started at x-Position: ${this.startX} -> Ended at x-Position: ${this.player.body.x} = distance: ${ Math.abs(this.player.body.x - this.startX) }`);
       }, 1000)
       }
    }
    else if (this.cursors.right.isDown) {
      this.player.body.setVelocityX(80);
    }
    // Vertical movement
    if (this.cursors.up.isDown) {
      this.player.body.setVelocityY(-80);
    }
    else if (this.cursors.down.isDown) {
      this.player.body.setVelocityY(80);
    }
  }
}

var bootScene = new BootScene();
var worldScene = new WorldScene();

var config = {
  type: Phaser.AUTO,
  parent: 'content',
  width: 320,
  height: 240,
  zoom: 2,
  pixelArt: true,
  physics: {
    default: 'arcade',
    arcade: {
      gravity: { y: 0 }
    }
  },
  scene: [
    BootScene,
    WorldScene
  ]
};
var game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>

My result was: Started at x-Position: 135.66666666666652 -> Ended at x-Position: 55.66666666666669 = distance: 79.99999999999983

Related