<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: 768px;
  padding: 0;
  background: rgba(0, 0, 0, 0.5)
}
/* global colors, Phaser */

class Example extends Phaser.Scene {
  preload() {
    this.load.image("tiles", "assets/tilemaps/tiles/catastrophi_tiles_16.png");
    this.load.tilemapCSV("map", "assets/tilemaps/csv/catastrophi_level2.csv");
    this.load.spritesheet("player", "assets/sprites/spaceman.png", {
      frameWidth: 16,
      frameHeight: 16
    });
  }

  create() {
    // CanvasTexture

    const canvasTexture = this.textures.createCanvas("canvas", 448, 80);

    canvasTexture.drawFrame("tiles");

    // Map

    this.map = this.make.tilemap({ key: "map", tileWidth: 16, tileHeight: 16 });
    const tileset = this.map.addTilesetImage("canvas");
    const layer = this.map.createLayer(0, tileset, 0, 0);
    layer.setScale(2);

    this.map.setCollisionBetween(54, 83);

    // Sketch

    this.add.rectangle(0, 0, 480, 112, 0).setOrigin(0, 0).setScrollFactor(0, 0);

    const tilesetCanvas = this.add
      .image(16, 16, "canvas")
      .setOrigin(0, 0)
      .setScrollFactor(0, 0);

    tilesetCanvas
      .setInteractive({ cursor: "crosshair" })
      .on("pointermove", function (pointer, x, y) {
        if (!pointer.isDown) return;

        const ctx = canvasTexture.getContext();

        ctx.fillStyle = "fuchsia";
        ctx.fillRect(x, y, 1, 1);

        canvasTexture.refresh();
      });

    // etc.

    this.anims.create({
      key: "left",
      frames: this.anims.generateFrameNumbers("player", { start: 8, end: 9 }),
      frameRate: 10,
      repeat: -1
    });
    this.anims.create({
      key: "right",
      frames: this.anims.generateFrameNumbers("player", { start: 1, end: 2 }),
      frameRate: 10,
      repeat: -1
    });
    this.anims.create({
      key: "up",
      frames: this.anims.generateFrameNumbers("player", { start: 11, end: 13 }),
      frameRate: 10,
      repeat: -1
    });
    this.anims.create({
      key: "down",
      frames: this.anims.generateFrameNumbers("player", { start: 4, end: 6 }),
      frameRate: 10,
      repeat: -1
    });

    this.player = this.physics.add.sprite(128, 128, "player", 1).setScale(2);
    this.player.setSize(10, 10, false);

    this.physics.add.collider(this.player, layer);

    this.cameras.main.setBounds(
      0,
      0,
      this.map.widthInPixels,
      this.map.heightInPixels
    );
    this.cameras.main.startFollow(this.player);

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

    this.helpText = this.add.text(0, 0, "🖌 Draw on the tileset below", {
      font: "18px cursive",
      fill: "white"
    });
    this.helpText.setScrollFactor(0);
  }

  update(time, delta) {
    this.player.body.setVelocity(0);

    // Horizontal movement
    if (this.cursors.left.isDown) {
      this.player.body.setVelocityX(-192);
    } else if (this.cursors.right.isDown) {
      this.player.body.setVelocityX(192);
    }

    // Vertical movement
    if (this.cursors.up.isDown) {
      this.player.body.setVelocityY(-192);
    } else if (this.cursors.down.isDown) {
      this.player.body.setVelocityY(192);
    }

    // Update the animation last and give left/right animations precedence over up/down animations
    if (this.cursors.left.isDown) {
      this.player.anims.play("left", true);
    } else if (this.cursors.right.isDown) {
      this.player.anims.play("right", true);
    } else if (this.cursors.up.isDown) {
      this.player.anims.play("up", true);
    } else if (this.cursors.down.isDown) {
      this.player.anims.play("down", true);
    } else {
      this.player.anims.stop();
    }
  }
}

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

new Phaser.Game({
  scene: Example,
  pixelArt: true,
  loader: {
    baseURL: "https://labs.phaser.io",
    crossOrigin: "anonymous"
  },
  physics: {
    default: "arcade",
    arcade: {}
  }
});
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