Phaser 3: Rotate a sprite and automatically rotate all subsequent sprites

67 Views Asked by At

I have a series of horizontally-lined sprites in Phaser 3:

const sprite1 = this.add.sprite(20, 40, 'diamonds');
const sprite2 = this.add.sprite(50, 40, 'diamonds');
const sprite3 = this.add.sprite(80, 40, 'diamonds');
const sprite4 = this.add.sprite(110, 40, 'diamonds');
const sprite5 = this.add.sprite(140, 40, 'diamonds');
const sprite6 = this.add.sprite(170, 40, 'diamonds');

which produce the following:

enter image description here

When I rotate sprite3 by 90 degrees, I want the subsequent sprites to be rotated as well as shown below:

enter image description here

If I then rotate sprite5 by 90 degrees, I want the following output:

enter image description here

I have unsuccessfully tried using Phaser.Container. Any help?

1

There are 1 best solutions below

1
winner_joiner On BEST ANSWER

Well that what you want to achieve is not really possible out-of-the-box or with a container, since you would have to nest them several times. This approach can only "work" if you always rotate those specific sprites, but I assume this is not the goal. So a solution, could be to calculate the new positions of the following sprites.

Using Vectors and an Array should make this task easy.

Here a short demo:
(this is just a proof of concept an would/should be optimized)

document.body.style = 'margin:0;';

var config = {
    width: 536,
    height: 183,
    scene: {
        create,
        preload,
    }
}; 

function preload () {
    this.load.spritesheet('diamonds', 'https://labs.phaser.io/assets/sprites/diamonds32x24x5.png', { frameWidth: 32, frameHeight: 24 });
}

function create () {
    this.label = this.add.text(10,10, '3 Sprite and following, will Rotate in few moments...')
        .setScale(1.15)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
        
    this.diamonds = [];
    
    for(let i = 0; i < 7; i++){
         let helperSprite = this.add.sprite(100 + 40 * i, 60, 'diamonds');
         this.diamonds.push(helperSprite);
    }
    
    // First rotation
    this.time.delayedCall(1000, rotateSpriteThree90DegRight, [2], this);
    
    // Second rotation
    this.time.delayedCall(2000, rotateSpriteThree90DegRight, [4], this); 

    // Final message
    this.time.delayedCall(2500, () => this.label.setText('...Demo ended!') , null, this);
        
}

function rotateSpriteThree90DegRight( firstSpriteToRotateIdx ){
    let firstDiamond = this.diamonds[firstSpriteToRotateIdx];
    
    this.label.setText( 'will rotate again in a few moments...')
    
    for(let idx = firstSpriteToRotateIdx; idx < this.diamonds.length; idx++ ){
        let diamond = this.diamonds[idx];
        diamond.angle += 90;
        
        if(idx > firstSpriteToRotateIdx){
            let vector = new Phaser.Math.Vector2( diamond.x - firstDiamond.x, diamond.y - firstDiamond.y  );
            vector.normalizeRightHand();
            diamond.x = firstDiamond.x + vector.x;
            diamond.y = firstDiamond.y + vector.y;
        }
    }
}

new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>