//  Solution: https://phaser.discourse.group/t/textures-jittering/10217/9

var config = {
    type: Phaser.WEBGL,
    parent: 'game-container',
    scene: {
        preload: preload,
        create: create,
        update: update,
        physics: {
            matter: {
                gravity: { y: 0 },
                debug: false
            }
        }
        
    },
    scale: {
        parent: 'game-container',
        autoCenter: Phaser.Scale.CENTER_BOTH,
        mode: Phaser.Scale.FIT,
        width: 1920,
        height: 1080
    },
}

let shipFrame = 1;
let ship;
let game = new Phaser.Game(config);



function preload ()
{
    this.load.image('background', 'https://raw.githubusercontent.com/Merfyn007/phaser-test/main/nebula.jpg');
    this.load.image('stars', 'https://raw.githubusercontent.com/Merfyn007/phaser-test/main/stars.png');
    this.load.atlas('space', 'https://raw.githubusercontent.com/Merfyn007/phaser-test/main/space.png', 'https://raw.githubusercontent.com/Merfyn007/phaser-test/main/space.json');
    // Crée le vaisseau
    this.load.atlas('skyship', 'https://raw.githubusercontent.com/Merfyn007/phaser-test/main/spaceships/spaceship-sky02.png', 'https://raw.githubusercontent.com/Merfyn007/phaser-test/main/spaceships/spaceship-sky02.json');
    // Charge les formes des objects
    this.load.json('shapes', 'https://raw.githubusercontent.com/Merfyn007/phaser-test/main/spaceships/spaceship-sky02-collisions.json');

}


function create ()
{
    // Shapes
    shapes = this.cache.json.get('shapes');
    offsets = this.cache.json.get('offsets');
    //  Prepare some spritesheets and animations

    this.textures.addSpriteSheetFromAtlas('mine-sheet', { atlas: 'space', frame: 'mine', frameWidth: 64 });
    this.textures.addSpriteSheetFromAtlas('asteroid1-sheet', { atlas: 'space', frame: 'asteroid1', frameWidth: 96 });
    this.textures.addSpriteSheetFromAtlas('asteroid2-sheet', { atlas: 'space', frame: 'asteroid2', frameWidth: 96 });
    this.textures.addSpriteSheetFromAtlas('asteroid3-sheet', { atlas: 'space', frame: 'asteroid3', frameWidth: 96 });
    this.textures.addSpriteSheetFromAtlas('asteroid4-sheet', { atlas: 'space', frame: 'asteroid4', frameWidth: 64 });

    this.anims.create({ key: 'mine-anim', frames: this.anims.generateFrameNumbers('mine-sheet', { start: 0, end: 15 }), frameRate: 20, repeat: -1 });
    this.anims.create({ key: 'asteroid1-anim', frames: this.anims.generateFrameNumbers('asteroid1-sheet', { start: 0, end: 24 }), frameRate: 20, repeat: -1 });
    this.anims.create({ key: 'asteroid2-anim', frames: this.anims.generateFrameNumbers('asteroid2-sheet', { start: 0, end: 24 }), frameRate: 20, repeat: -1 });
    this.anims.create({ key: 'asteroid3-anim', frames: this.anims.generateFrameNumbers('asteroid3-sheet', { start: 0, end: 24 }), frameRate: 20, repeat: -1 });
    this.anims.create({ key: 'asteroid4-anim', frames: this.anims.generateFrameNumbers('asteroid4-sheet', { start: 0, end: 23 }), frameRate: 20, repeat: -1 });

    //  World size is 8000 x 6000

    bg = this.add.tileSprite(960, 540, 1920, 1080, 'background').setScrollFactor(0);

    //  Add our planets, etc

    this.add.image(512, 680, 'space', 'blue-planet').setOrigin(0).setScrollFactor(0.6);
    this.add.image(2833, 1246, 'space', 'brown-planet').setOrigin(0).setScrollFactor(0.6);
    this.add.image(3875, 531, 'space', 'sun').setOrigin(0).setScrollFactor(0.6);
    var galaxy = this.add.image(5345 + 1024, 327 + 1024, 'space', 'galaxy').setBlendMode(1).setScrollFactor(0.6);
    this.add.image(908, 3922, 'space', 'gas-giant').setOrigin(0).setScrollFactor(0.6);
    this.add.image(3140, 2974, 'space', 'brown-planet').setOrigin(0).setScrollFactor(0.6).setScale(0.8).setTint(0x882d2d);
    this.add.image(6052, 4280, 'space', 'purple-planet').setOrigin(0).setScrollFactor(0.6);

    for (var i = 0; i < 8; i++)
    {
        this.add.image(Phaser.Math.Between(0, 8000), Phaser.Math.Between(0, 6000), 'space', 'eyes').setBlendMode(1).setScrollFactor(0.8);
    }

      stars = this.add.tileSprite(960, 540, 1920, 1080, 'stars').setScrollFactor(0);


      cursors = this.input.keyboard.createCursorKeys();


      ship = this.matter.add.sprite(3600, 2400, 'skyship', 'spaceship1', {shape: shapes["spaceship1"]}).setDepth(2);


      this.cameras.main.startFollow(ship);
}
   
function update (time, delta)
{
    if (cursors.left.isDown)
    {
      // Apply setTexture before setBody (jittering)
      shipFrame++;
      let newShipFrame = "spaceship"+(shipFrame == 91 ? shipFrame=1 : shipFrame);
      ship.setTexture('skyship',  newShipFrame).setBody(shapes[newShipFrame]);

      //ship.setPosition(positionX, positionY);
      //ship.setVelocity(velocityX, velocityY);
    }
  
    else if (cursors.right.isDown)
    {
      // Apply setBody before setTexture
      shipFrame--;
      let newShipFrame = "spaceship"+(shipFrame == 0 ? shipFrame=90 : shipFrame);
      ship.setBody(shapes[newShipFrame]).setTexture('skyship',  newShipFrame);
      
      //ship.setPosition(positionX, positionY);
      //ship.setVelocity(velocityX, velocityY);
    }
    if (cursors.up.isDown)
    {
            ship.thrust(0.02);
    }
  

}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.min.js