Lens door entrance effect

Lens door effect in Phaser (as seen in Super Mario Bros 3 and Super Mario World

by Marcel

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/3.18.1/phaser.min.js"></script>
<div id="content"></div>

JavaScript

const SCREENWIDTH = 800
const SCREENHEIGHT = 500

class Door extends Phaser.GameObjects.Sprite {
    constructor(config, destination) {
        super(config.scene, config.x, config.y, 'level', 'door')
        config.scene.add.existing(this)
        this.myscene = config.scene

        this.destination = destination
    }

    gotoDestination() {
        this.myscene.scene.start(this.destination)
    }
}

// a generic scene that we can customize
class BaseLevel extends Phaser.Scene {
  constructor() {
    super()
  }

  // pass in our settings
  init(config) {
    this.bgname = config.bg
    this.groundname = config.ground
    this.destinationscene = config.destination
    this.showtext = config.showtext
  }

  create() {
    // this bg colour will affect the circle effect.
    this.cameras.main.setBackgroundColor('#000000')

    this.ignoreInput = true

    // build a level
    this.buildLevel()
    
    // setup the intro effect
    this.setupIntroEffect()

    // start the intro effect
    this.startIntroEffect()
  }

  setupIntroEffect() {
    
    // big blank growing circle mask - could be any shape really. Star, square, whatever
    this.spotlight = this.make.sprite({
        x: SCREENWIDTH / 2,
        y: 400,
        key: 'bigcircle',
        add: false
    })

    // start small
    this.spotlight.setScale(0.03, 0.03)

    // make sure we apply the mask to everything in our scene.
    // anything omitted will show on top of the mask
    this.ground.mask = new Phaser.Display.Masks.BitmapMask(this, this.spotlight)
    this.bg.mask = new Phaser.Display.Masks.BitmapMask(this, this.spotlight)
    this.door.mask = new Phaser.Display.Masks.BitmapMask(this, this.spotlight)
    this.player.mask = new Phaser.Display.Masks.BitmapMask(this, this.spotlight)
    if(this.showtext) {
      this.text.mask = new Phaser.Display.Masks.BitmapMask(this, this.spotlight)
    }
  }

  startIntroEffect() {
    const t = this.tweens.add({
        targets: this.spotlight,
       ...