skip to Main Content

I think I actually want the graphics I place on the screen to scale itself appropriately on different devices.
So when I use scale.fit, I am not achieving this.
Does scale.fit not work because the tile map has fixed values?
In general, I would appreciate if you can offer a solution for these.

I am developing a game with phaser3, I extracted tile map from 2D mapeditor as json. level-1.json :

{ "compressionlevel":-1,
 "height":20,
 "infinite":false,
 "layers":[
        {
         "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
         "height":20,
         "id":1,
         "name":"background",
         "opacity":1,
         "type":"tilelayer",
         "visible":true,
         "width":30,
         "x":0,
         "y":0
        }, 
        {
         "data":[81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 81, 81,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 81, 81, 81, 81, 81,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81],
         "height":20,
         "id":2,
         "name":"wall",
         "opacity":1,
         "type":"tilelayer",
         "visible":true,
         "width":30,
         "x":0,
         "y":0
        }],
 "nextlayerid":3,
 "nextobjectid":1,
 "orientation":"orthogonal",
 "renderorder":"right-down",
 "tiledversion":"1.10.2",
 "tileheight":16,
 "tilesets":[
        {
         "columns":10,
         "firstgid":1,
         "image":"grass.png",
         "imageheight":128,
         "imagewidth":160,
         "margin":0,
         "name":"grass",
         "spacing":0,
         "tilecount":80,
         "tileheight":16,
         "tilewidth":16
        }, 
        {
         "columns":8,
         "firstgid":81,
         "image":"wall",
         "imageheight":128,
         "imagewidth":128,
         "margin":0,
         "name":"wall",
         "spacing":0,
         "tilecount":64,
         "tileheight":16,
         "tilewidth":16
        }],
 "tilewidth":16,
 "type":"map",
 "version":"1.10",
 "width":30
}

My config.bas.ts script like this :

import Phaser, { Types } from "phaser";

const ratio = window.innerWidth < 600 ? 2 : 1;

const baseGameConfig: Types.Core.GameConfig = {
  type: Phaser.WEBGL,
  scale: {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH,
    width: window.innerWidth * ratio,
    height: window.innerHeight * ratio,
  },
  render: {
    antialias: true,
  },
};

export default baseGameConfig;

and config.ts like this :

import { Types } from "phaser";

import baseGameConfig from "@games/config.base";

import Scenes from "./src/scenes";

const gameConfig: Types.Core.GameConfig = {
  ...baseGameConfig,
  title: "monkeygo",
  scene: Scenes.BootScene.scene,
  physics: {
    default: "arcade",
    arcade: {
      debug: process.env.NODE_ENV !== "production",
      gravity: {
        y: 600,
      },
    },
  },
};

export default gameConfig;

I have 2 config scripts because I manage more than one game so I needed baseconfig

and ı have game.ts :

import { Scene } from "phaser";

import Scenes from "./";

export default class GameScene extends Scene {
  // tilemap
  private declare map: Phaser.Tilemaps.Tilemap;

  // tilesets
  private declare grassTileset: Phaser.Tilemaps.Tileset;
  private declare wallTileset: Phaser.Tilemaps.Tileset;

  // tilemap layers
  private declare layer: Phaser.Tilemaps.TilemapLayer;
  private declare bgLayer: Phaser.Tilemaps.TilemapLayer;
  private declare wallsLayer: Phaser.Tilemaps.TilemapLayer;
  private declare player: Phaser.GameObjects.Rectangle;
  constructor() {
    super({
      key: Scenes.GameScene.key,
    });
  }

  create() {
    this.createTiles();
    this.createLayers();
    this.createPlayer();
    this.map.setCollision([81]);
    this.createFullscreenButton();
  }
  private createFullscreenButton() {
    const fullscreenButton = this.add
      .sprite(
        this.cameras.main.width - 32,
        this.cameras.main.height - 32,
        "fullScreen"
      )
      .setInteractive();

    fullscreenButton.on("pointerup", () => {
      this.toggleFullscreen();
    });
  }

  private toggleFullscreen() {
    if (this.scale.isFullscreen) {
      this.scale.stopFullscreen();
    } else {
      this.scale.startFullscreen();
    }
  }
  update(time: number, delta: number): void {
    this.move();
    this.physics.collide(this.player, this.wallsLayer);
  }

  private createTiles(): void {
    this.map = this.make.tilemap({
      key: "level-1",
    });

    console.log(this.map);
    this.grassTileset = this.map.addTilesetImage("grass")!;
    this.wallTileset = this.map.addTilesetImage("wall")!;
  }

  private createLayers() {
    this.bgLayer = this.map.createLayer("background", this.grassTileset, 0, 0)!;

    this.wallsLayer = this.map.createLayer("wall", this.wallTileset, 0, 0)!;
  }

  private createPlayer() {
    this.player = this.add.rectangle(50, 0, 24, 38, 0xffff00);
    this.physics.add.existing(this.player);
  }

  private move() {
    if (this.player.body) {
      this.player.body.velocity.x = 0;
    }

    const touchX = this.input.pointer1.x;

    if (this.input.pointer1.isDown) {
      if (touchX > this.cameras.main.width / 2 && this.player.body) {
        console.log("sağ");
        this.player.body.velocity.x = 200;
      } else {
        console.log("sol");
        if (this.player.body) this.player.body.velocity.x = -200;
      }
    }
  }
}

Here is my images from mobile device and chrome :

Chrome : Chrome image how it’s look like

Mobile Device : Mobile device image how it’s look like

Note :
This is just an example, in every different device, that is, in size change, these scale rates change or whatever.

2

Answers


  1. Chosen as BEST ANSWER

    Thank you for your answer. I tried every option.

    Option 3: Only the camera approached, I tried different values, but it did not solve my main problem of capturing the same image on each device.

    Option 1 : Moves out of the screen when I use more tiles.

    Option 2 : This leads to the same result as option 1


  2. Yes, it doesn’t display more because, the map is smaller than the canvas.
    There are 3 "easy" solutions (that I can see), if you want to fill the whole canvas.

    1. Option 1: making the map bigger, currently max width = 30 * 16 = 480 and height = 20 * 16 = 320. So use more tiles for width and height.

    2. Option 2: make the tiles bigger this increases the size, from 16px to 32px or higher.

    3. Option 3: zoom manual the scene, something like this:

       let maxMapWidth = 120;
       let config = {
           // ...
           scale: {
               mode: Phaser.Scale.NONE,
               autoCenter: Phaser.Scale.CENTER_BOTH,
               width: maxMapWidth,
               height:(window.innerHeight / window.innerWidth  ) * maxMapWidth,
               zoom: (window.innerWidth ) / maxMapWidth 
           },
           backgroundColor: '#000000',
           scene: [ SampleScene ],
           banner: false
       };
      
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search