<footer><div id=version></div></footer>
html, body {
  height: 100%;
}

body {
  margin: 0;
  padding: 0;
  background: #111 url(https://labs.phaser.io/assets/sprites/phaser3-logo-small.png) no-repeat 0 20px;
  color: #eee;
  font: caption;
}

#version {
  position: absolute;
  left: 0;
  top: 580px;
  padding: 0;
  background: rgba(0, 0, 0, 0.5)
}
/* global colors, Phaser */

// These are Matter's defaults (60 fps).
const DELTA_MIN = 1000 / 60;
const DELTA_MAX = 1000 / 30;

const { red, yellow, green, blue, white } = colors.cssColors;

function getColor(delta) {
  if (delta < DELTA_MIN) return blue;
  if (delta > DELTA_MAX) return red;
  
  return green;
}

function preload() {
  this.load.image("block", "assets/sprites/block.png");
  this.load.image("platform", "assets/sprites/platform.png");
  this.load.bitmapFont(
    "gem",
    "assets/fonts/bitmap/gem.png",
    "assets/fonts/bitmap/gem.xml"
  );
}

function create() {
  // The cumulative difference of the game loop and Matter deltas.
  this.error = 0;
  
  this.matter.add.image(325, -100, "block").setAlpha(0.5);
  this.matter.add.image(400, 300, "block").setAlpha(0.5);
  this.matter.add.image(450, 50, "block").setAlpha(0.5);

  this.matter.add.image(400, 550, "platform", null, { isStatic: true }).setAlpha(0.5);

  this.text = this.add.bitmapText(0, 0, "gem");
  this.historyText = this.add.bitmapText(750, 0, "gem").setScale(0.5).setVisible(false);
  
  this.canvas = this.textures.createCanvas("history", 200, 60);
  
  this.add.image(700, 0, this.canvas).setOrigin(0, 0).setScale(1, 10);
  
  console.log('this.matter.world.runner', this.matter.world.runner);
}

function update(time, delta) {
  const { engine, runner } = this.matter.world;
  
  // Wait for the delta to stabilize a bit.
  if (time > (this.time.startTime + 2000)) {
    this.error += (engine.timing.lastDelta - this.game.loop.delta);
  }
  
  this.text.setText(
    JSON.stringify(
      {
        "this.matter.world.runner": Phaser.Utils.Objects.Pick(runner, ["deltaMin", "deltaMax", "fps"]),
        "this.matter.world.engine.timing": engine.timing,
        "this.game.loop": Phaser.Utils.Objects.Pick(this.game.loop, ["actualFps", "delta"]),
        "this.error": this.error
      },
      null,
      2
    )
  );
  
  this.historyText.setText(runner.deltaHistory.join("\n"));
  
  this.canvas.clear();
  
  const ctx = this.canvas.getContext();
    
  ctx.fillStyle = colors.cssColors.yellow;
  
  let x = 0;
  let y = 0;
  
  for (const delta of runner.deltaHistory) {
    ctx.fillStyle = getColor(delta);
    ctx.fillRect(x, y, delta, 1);
    
    y++;
  }
  
  const { lastDelta } = engine.timing
  
  ctx.fillStyle = white;
  ctx.fillRect(~~lastDelta, 0, 1, 60);
  
  this.canvas.refresh();
}

document.getElementById("version").textContent = `Phaser v${Phaser.VERSION}`;

new Phaser.Game({
  width: 800,
  height: 600,
  pixelArt: true,
  scene: { preload, create, update },
  fps: {
    // Skip the game loop cooldown.
    // panicMax: 0
  },
  loader: {
    baseURL: "https://labs.phaser.io",
    crossOrigin: "anonymous"
  },
  physics: {
    default: "matter",
    matter: {
      runner: {
        deltaMin: DELTA_MIN,
        deltaMax: DELTA_MAX
      }
    }
  }
});
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.jsdelivr.net/npm/phaser@3.60.0/dist/phaser.js
  2. https://cdn.jsdelivr.net/npm/@samme/colors@1.2.0/dist/colors.umd.js