1

I have created 3 canvas textures:

    this.textures1 = this.textures.createCanvas('canvastextures1', 450, 170)
    this.textures2 = this.textures.createCanvas('canvastextures2', 410, 180)
    this.textures3 = this.textures.createCanvas('canvastextures3', 400, 210)
    this.land1 = this.textures.get(MAPOPTIONS.BASE1_NAME).getSourceImage()
    this.land2 = this.textures.get(MAPOPTIONS.BASE2_NAME).getSourceImage()
    this.land3 = this.textures.get(MAPOPTIONS.BASE3_NAME).getSourceImage()
    this.textures1.draw(0, 0, this.land1)
    this.textures2.draw(0, 0, this.land2)
    this.textures3.draw(0, 0, this.land3)
    this.textures1.context.globalCompositeOperation = 'destination-out'
    this.textures2.context.globalCompositeOperation = 'destination-out'
    this.textures3.context.globalCompositeOperation = 'destination-out'

then I add 3 canvas textures to 3 Sprite Objects by class Phaser.Physics.Arcade.Sprite and enable Physic for them. Finally, I group them by Phaser.GameObjects.Group

I call a overlap(groupSprite, object) function to ERASE canvas texture in groupSprite when the object overlap the group (a bullet vs land and creates a hole).

      this.activeTextures = this.textures.get('canvastextures3')
      this.activeTextures.context.beginPath()
      this.activeTextures.context.arc(Math.floor(overlap2.x), Math.floor(overlap2.y), 50, 0, Math.PI * 2)
      this.activeTextures.context.fill()
      this.activeTextures.update()

The problem is the Sprite object does not update following the canvas texture. Does anyone have any ideas? Thank you.

CS No.1
  • 115
  • 6

1 Answers1

2

An easy solution is to create a property (object) to store the canvas for each texture, with the texture-key as the key/id, and update the texture over the canvas, calling a method (in this demo-code it's the method demoHit).

It's not very elegant, but works. In the following short demo, you can see, how it works for just one texture, but adding more should be easy.

Demo Code:

// Minor formating for stackoverflow
document.body.style = "display: flex;flex-direction: column;";   
 
class FirstScene extends Phaser.Scene {
  constructor() {
    super('firstScene')
    this.canvasCollection = {};
  }
  
  create(){
    this.createTextures();
    this.scene.start('secondScene')
  }
  
  createTextures(){
      let helperGraphics = this.make.graphics({x:0, y: 0, add: false});
      helperGraphics.fillStyle(0xff0000);
      helperGraphics.fillRect(0, 0, 20, 20 );
      helperGraphics.generateTexture('helper', 20, 20);
      
      let img = this.textures.get('helper').getSourceImage()
      this.textures1 = this.textures.createCanvas('canvastextures1', 20, 20)
      this.textures1.draw(0, 0, img)
      this.textures1.context.globalCompositeOperation = 'destination-out'
      this.canvasCollection['canvastextures1'] = this.textures1
      // add here more textures ...
  }
  
  demoHit(textureKey, pos){
    let currentCanvas = this.canvasCollection[textureKey];
    currentCanvas.context.beginPath()
    currentCanvas.context.arc(pos.x, pos.y, 5, 0, Math.PI * 2, false)
    currentCanvas.context.fill()
    currentCanvas.update()
  }
}

class SecondScene extends Phaser.Scene {
  constructor() {
    super('secondScene')
  }
  
  create(){
    this.loadScene = this.scene.get('firstScene')       
    this.textureGroup = this.physics.add.group({
        immovable: true,
        allowGravity: false
    });  
    this.textureGroup.add(this.add.image(100, 85, 'canvastextures1'))
    // add here more textures ...

    this.ball = this.add.rectangle(100, 0, 10, 10, 0xffffff)  
    this.physics.add.existing(this.ball)
    this.physics.add.overlap(this.ball, this.textureGroup, this.overlap, null, this )
  }
  
  overlap(player, groupItem){
    groupItem.setTint(0xcdcdcd)
    let pos = {
        x: (player.body.center.x - groupItem.body.x),
        y: 0
    }
    this.loadScene.demoHit(groupItem.texture.key, pos)
    player.destroy();
  }
}

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 163,
    physics:{
        default: 'arcade',
        arcade:{ gravity:{y: 100} }
    },
    scene: [FirstScene, SecondScene]
}; 

new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.min.js">
</script>
winner_joiner
  • 12,173
  • 4
  • 36
  • 61
  • Thanks for the awesome response, winner_joiner. But it still does not update the Sprite object, because I also set the body size of the Sprite object for a player can move on it, I think it cause the problem – CS No.1 May 10 '22 at 13:58
  • 1
    @CSNo.1 thank you for your feedback. I'm sorry I could help. I don't really understand your project structure, but ofcourse cause as you mentioned, extra properties, can cause side effects. – winner_joiner May 10 '22 at 15:36
  • Thanks, winner_joiner, the Sprite has two dimensions: one is the canvas texture when I call this.textures.createCanvas('canvastextures1', 450, 170) and the other is when I call this.body.setSize(430, 50) (extends in class Phaser.Physics.Arcade.Sprite) – CS No.1 May 10 '22 at 15:41