Multiscreen development in phaser 2.4.2

Earlier, I posted a tutorial on scaling the game and assets for multiple devices. But it does not work very well in latest phaser version 2.4.2(as if the time of writing). So I thought it will be good to post an updated version for the latest phaser.

The idea is simple, Create a group and add all of your game objects into that group. After that, scale and position the group correctly to display the game fully inside the browser/device. The scaling and positioning is done such a way that there will be no black bars around the game and it will be in the correct aspect ratio.

Let’s take a look into the code. For this purpose, I downloaded the FullScreen Mobile template from the phaser github project templates folder.

The first thing is to add a css style to the body tag in the main.css file.

body {
    margin: 0px 0px 1px 0px; /* the extra 1px allows the iOS inner/outer check to work */
    background: #000;
    overflow: hidden; /*Edit*/
}

After that, we need to set the game size to the window width and height in the index.html page.

var game = new Phaser.Game(960,540, Phaser.AUTO, 'game');

This will make sure the canvas will be always fit to the browser window. Then inside the Boot.js there are some scaling codes written. We are going to comment them and introduce our own scaling properties.

Also Read:   Start Developing HTML5 games in Phaser using TypeScript

First we need to create a function to find the scale which will be called on every resize.

BasicGame = {

    /* Here we've just got some global level vars that persist regardless of State swaps */
    score: 0,

    /* If the music in your game needs to play through-out a few State swaps, then you could reference it here */
    music: null,

    /* Your game can check BasicGame.orientated in internal loops to know if it should pause or not */
    orientated: false,

    updateScaleRatio: function () {
        BasicGame.realWidth = Math.max(window.innerWidth,window.innerHeight);
        BasicGame.realHeight = Math.min(window.innerWidth,window.innerHeight);
        var ws = BasicGame.realWidth/(960*BasicGame.assetScale);
        var wh = BasicGame.realHeight/(540*BasicGame.assetScale);
        BasicGame.scaleRatio = Math.max(ws,wh);
    }

};
init: function () {

        this.input.maxPointers = 1;
        this.stage.disableVisibilityChange = true;
        this.scale.scaleMode = Phaser.ScaleManager.RESIZE;

        this.scale.forceOrientation(true,false);

        var assetScale = 1;

        BasicGame.realWidth = Math.max(window.innerWidth,window.innerHeight);
        BasicGame.realHeight = Math.min(window.innerWidth,window.innerHeight);

        if(BasicGame.realWidth>960 || BasicGame.realHeight>540){
            assetScale = 2;
        }
        var ws = BasicGame.realWidth/(960*assetScale);
        var wh = BasicGame.realHeight/(540*assetScale);
        BasicGame.assetScale = assetScale;
        BasicGame.scaleRatio = Math.max(ws,wh);
        //this.scale.setResizeCallback(this.gameResized, this);
        this.scale.enterIncorrectOrientation.add(this.enterIncorrectOrientation, this);
        this.scale.leaveIncorrectOrientation.add(this.leaveIncorrectOrientation, this);


    },

We are assuming our game’s base resolution will be 960×540. For devices upto this resolution, the assetScale will be 1. After that, the assetScale will be 2. Feel free to change the values yourselves.

To understand better, I will explain with an example. Suppose our game has a bg of size 960×540 which is the same size as the game. This image is in 1x resolution. If we want to scale the game upwards for devices larger than 960×540, we need to have the same the bg in 1920×1080 resolution also which is the 2x resolution. So first create the maximum of ‘x’ resolution and create smaller ones.

Also Read:   Godot Engine game tutorial for beginners – Create a 2D Racing Game 3

BasicGame.assetScale is the scale of the asset used. BasicGame.scaleRatio is the scale value of the game. We need to scale the group to this value. So inside our other scenes such as Menu,Game etc. we need to put the root group and add all other game objects into it.

Let’s open MainMenu.js and in the create method, add this.

create: function () {

  // We've already preloaded our assets, so let's kick right into the Main Menu itself.
  // Here all we're doing is playing some music and adding a picture and button
  // Naturally I expect you to do something significantly better 🙂

  ///this.music = this.add.audio('titleMusic');
  //this.music.play();


  this.group = this.game.add.group();
        this.group.create(0,0,'bg'+BasicGame.assetScale);

        this.group.scale.setTo(BasicGame.scaleRatio);
        this.group.x = BasicGame.realWidth/2 - 960*BasicGame.assetScale*this.group.scale.y/2;
        this.group.y = BasicGame.realHeight/2 - 540*BasicGame.assetScale*this.group.scale.x/2;

  this.scale.setResizeCallback(this.gameResized, this);

 },

 gameResized: function (width,height) {
  BasicGame.updateScaleRatio();
  this.group.scale.setTo(BasicGame.scaleRatio);
        this.group.x = BasicGame.realWidth/2 - 960*BasicGame.assetScale*this.group.scale.y/2;
        this.group.y = BasicGame.realHeight/2 - 540*BasicGame.assetScale*this.group.scale.x/2;
 },

Then, we can add all other game objects into this group. All things will be perfectly scaled in aspect ratio. One thing we need to take note is that, when placing objects, we need to multiply the x and y positions with the assetScale. In 1x devices, 200px is 200px, but in 2x devices 200px of 1x is 400px.

So for eg:

ball.x = 200;//This won't work
ball.x = 200*BasicGame.assetScale;

You can check the full source code here.
That’s it. Happy coding.

Never miss any content from Codetuto!

Subscribe to Codetuto Newsletter and be the first to recieve our latest posts and tutorials

Subscribe Now For Free

[Total: 0    Average: 0/5]