Jump to content

Phaser scale manager - Forcing orientation


Codenburger
 Share

Recommended Posts

Hi,

I am developing an app, where I would like to see the orientation of the screen kept to Portrait.

After many searches on google, I gave up and just went ahead with building a simple prototype of my app idea.

I have now come to a stage where I should deal with the orientation aspect of the app.

After studying the book: Phaser Scale manager for Phaser 2.2.2, I have tried to use the following code in my app:

if (game.device.desktop === false)    {        game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;        game.scale.pageAlignHorizontally = true;        game.scale.pageAlignVertically = true;        game.scale.forceOrientation(true, false);        game.scale.enterIncorrectOrientation.add(this.enterIncorrectOrientation, this);        game.scale.leaveIncorrectOrientation.add(this.leaveIncorrectOrientation, this);    }
I am new to Phaser and programming generally. I earned a distinction in the Coursera: Intro to computer programming in Python.

I have found that what I have learn't in that course is easily transferable to JavaScript and Phaser, yet, I am still learning.

Maybe if this problem can be resolved, it would help other people new to Phaser on the forums also.

Codenburger

Link to comment
Share on other sites

Hi, generally, you can not "lock" orientation, but usual solution is to alert user to turn device (implemented in Phaser mobile template). Then comes scaling issues - I spent some time with it and my solution is:
 
I have this global method (MyGame object stores important global variables). My "desired" resolution for game is 1280x800 in landscape. But the game can work with any resolution and preserve aspect ratio - this is reason why there is offsetX and offsetY calculated. If dimension is too crazy I am preserving aspect ratio by creating either X or Y offset. Game design allows me to fill additional area with single color - see attached image.

 

post-12887-0-82788800-1424462402.png
    var calculateDimensions = function() {        var targetWidth = 1280;        var targetHeight = 800;        var targetAspect = targetWidth / targetHeight;        var winWidth = window.innerWidth;        var winHeight = window.innerHeight;        MyGame.origW = winWidth;        MyGame.origH = winHeight;        // check if user started in portrait - if so, flip        if (winWidth < winHeight) {            var tmp = winWidth;            winWidth = winHeight;            winHeight = tmp;        }        var aspect = winWidth / winHeight;        if (aspect < targetAspect) {            MyGame.canvasWidth = targetWidth;            MyGame.canvasHeight = Math.floor(targetWidth / aspect + 0.5);            MyGame.offsetY = Math.floor((MyGame.canvasHeight - targetHeight) / 2);        } else if (aspect > targetAspect) {            MyGame.canvasWidth = Math.floor(targetHeight * aspect + 0.5);            MyGame.canvasHeight = targetHeight;            MyGame.offsetX = Math.floor((MyGame.canvasWidth - targetWidth) / 2);        }        console.log("window W x H = " + winWidth + " x " + window.winHeight +                ", target W x H = " + MyGame.canvasWidth + " x " + MyGame.canvasHeight +                ", offset x = " + MyGame.offsetX + ", y = " + MyGame.offsetY);    };

 I call this method before I create Phaser.Game:

    MyGame.calculateDimensions();        var game = new Phaser.Game(MyGame.canvasWidth, MyGame.canvasHeight, Phaser.AUTO, 'content');    MyGame.game = game;

 This was working great until I tried it with iPad. What was the problem: iPad has resolution 1024x768 ... If you start in landscape mode and call calculateDimensions you will get game dimensions 1280x960, so there will be 80 offsetY ((800 - 960) / 2). Still working great - aspect ration preserved, no deformation. If you start in portrait mode the resolution is flipped by calculateDimensions, so there should not be problem. But here navigation bar comes into play. If you are in portrait then part of the height is eaten by it. So iPad dimension shrinks to 768x960 (in portrait) ... result of calculateDimensions is 1280x1024 (in landscape). If you turn your device into landscape (only landscape is supported - in portrait there is message: turn device) then game comes to landscape mode, but also navigation bar changes its position, so it is eating part of height that was width before rotation! As a result dimension is wrong and bottom part of the game is not visible. If navigation bar eats 64 pixels then area for game is 1024x704 - it means correct game area should be 1280x880, but from previous calculation is 1280x1024, so 144 pixels is not visible in the bottom.

 

 After a while I solved it in My boot state:

    // -------------------------------------------------------------------------    Boot.prototype.enterIncorrectOrientation = function() {        MyGame.orientated = false;        document.getElementById("orientation").style.display = "block";    };    // -------------------------------------------------------------------------    Boot.prototype.leaveIncorrectOrientation = function() {        MyGame.orientated = true;        document.getElementById("orientation").style.display = "none";                MyGame.calculateDimensions();        this.scale.updateDimensions(MyGame.canvasWidth, MyGame.canvasHeight, true);    };

 I just recalculate dimension and re-set game's dimensions to newly calculated.

 

 To make the answer complete, this is my init method of Boot state (notice I started with Phaser mobile template from Phaser_2.2.2\resources\Project Templates\Full Screen Mobile\):

    Boot.prototype.init = function() {        this.input.maxPointers = 1;        this.stage.disableVisibilityChange = true;        var minX = Math.floor(MyGame.canvasWidth * 0.25);        var minY = Math.floor(MyGame.canvasHeight * 0.25);        var maxX = Math.floor(MyGame.canvasWidth * 2.0);        var maxY = Math.floor(MyGame.canvasHeight * 2.0);        if (this.game.device.desktop)        {            MyGame.mobile = false;            this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;            this.scale.setMinMax(minX, minY, maxX, maxY);            this.scale.pageAlignHorizontally = true;            this.scale.pageAlignVertically = true;        }        else        {            this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;            this.scale.setMinMax(minX, minY, maxX, maxY);            this.scale.pageAlignHorizontally = true;            this.scale.pageAlignVertically = true;            this.scale.forceOrientation(true, false);            this.scale.setResizeCallback(this.gameResized, this);            this.scale.enterIncorrectOrientation.add(this.enterIncorrectOrientation, this);            this.scale.leaveIncorrectOrientation.add(this.leaveIncorrectOrientation, this);        }    };

 Hope this helps! And yes, screenshot used is from our game Annihilate - first almost finished puzzle game made with Phaser :-)

post-12887-0-82788800-1424462402.png

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...