15

Hi please help me to find out how trully responsive game can be created with Phaser3.

Respnsiveness is critical because game (representation layer of Blockly workspace) should be able to be exapanded to larger portion on screen and shrinked back many times during the session.

The question is How I can change dimentions of the game in runtime?

--- edited ---

It turns out there is pure css solution, canvas can be ajusted with css zoom property. In browser works well (no noticeable effect on performance), in cordova app (android) works too.

Here is Richard Davey's answer if css zoom can break things:

I've never actually tried it to be honest. Give it a go and see what happens! It might break input, or it may carry on working. That (and possibly the Scale Manager) are the only things it would break, though, nothing else is likely to care much.

// is size of html element size that needed to fit 
let props = { w: 1195, h: 612, elementId: 'myGame' };

// need to know game fixed size
let gameW = 1000, gameH = 750;

// detect zoom ratio from width or height
let isScaleWidth = gameW / gameH > props.w / props.h ? true : false;

// find zoom ratio
let zoom = isScaleWidth ? props.w / gameW : props.h / gameH;

// get DOM element, props.elementId is parent prop from Phaser game config
let el = document.getElementById(props.elementId);

// set css zoom of canvas element
el.style.zoom = zoom;
bFunc
  • 1,370
  • 1
  • 12
  • 22

8 Answers8

7

Resize the renderer as you're doing, but you also need to update the world bounds, as well as possibly the camera's bounds.

// the x,y, width and height of the games world
// the true, true, true, true, is setting which side of the world bounding box
// to check for collisions

this.physics.world.setBounds(x, y, width, height, true, true, true, true);

// setting the camera bound will set where the camera can scroll to
// I use the 'main' camera here fro simplicity, use whichever camera you use

this.cameras.main.setBounds(0, 0, width, height);

and that's how you can set the world boundary dynamically.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Coned_Stoding
  • 135
  • 1
  • 3
  • 10
6
window.addEventListener('resize', () => {
    game.resize(window.innerWidth, window.innerHeight);
});
pushkin
  • 9,575
  • 15
  • 51
  • 95
ofelixx4
  • 85
  • 1
  • 2
4

There is some builtin support for resizing that can be configured in the Game Config. Check out the ScaleManager options. You have a number of options you can specify in the scale property, based on your needs.

I ended up using the following:

 var config = {
            type: Phaser.AUTO,
            parent: 'game',
            width: 1280, // initial width that determines the scaled size
            height: 690,
            scale: {
                mode: Phaser.Scale.WIDTH_CONTROLS_HEIGHT ,
                autoCenter: Phaser.Scale.CENTER_BOTH
            },
            physics: {
                default: 'arcade',
                arcade: {
                    gravity: {y: 0, x: 0},
                    debug: true
                }
            },
            scene: {
                key: 'main',
                preload: preload,
                create: this.create,
                update: this.update
            },
            banner: false,
        };


Edwin Daniels
  • 346
  • 2
  • 11
3

Just in case anybody else still has this problem, I found that just resizing the game didn't work for me and physics didn't do anything in my case.

To get it to work I needed to resize the game and also the scene's viewport (you can get the scene via the scenemanager which is a property of the game):

game.resize(width,height)
scene.cameras.main.setViewport(0,0,width,height)
jcbdrn
  • 995
  • 6
  • 9
2

For Phaser 3 the resize of the game now live inside the scale like this:

window.addEventListener('resize', () => {
    game.scale.resize(window.innerWidth, window.innerHeight);
});

But if you need the entire game scale up and down only need this config:

const gameConfig: Phaser.Types.Core.GameConfig = {
    ...
    scale: {
        mode: Phaser.Scale.WIDTH_CONTROLS_HEIGHT,
    },
    ...
};

export const game = new Phaser.Game(gameConfig);
Damian
  • 2,752
  • 1
  • 29
  • 28
doreancl
  • 56
  • 4
  • mode: Phaser.Scale.WIDTH_CONTROLS_HEIGHT did the trick for me, to replace .FIT. with .FIT the canvas shakily re-zoomed 3-4 times – ssstofff May 21 '20 at 19:40
0

Take a look at this article.

It explains how to dynamically resize the canvas while maintaining game ratio.

Note: All the code below is from the link above. I did not right any of this, it is sourced from the article linked above, but I am posting it here in case the link breaks in the future.

It uses CSS to center the canvas:

canvas{
    display:block;
    margin: 0;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

It listens to the window 'resize' event and calls a function to resize the game.

Listening to the event:

window.onload = function(){
    var gameConfig = {
       //config here
    };
    var game = new Phaser.Game(gameConfig);
    resize();
    window.addEventListener("resize", resize, false);
}

Resizing the game:

function resize() {
    var canvas = document.querySelector("canvas");
    var windowWidth = window.innerWidth;
    var windowHeight = window.innerHeight;
    var windowRatio = windowWidth / windowHeight;
    var gameRatio = game.config.width / game.config.height;
    if(windowRatio < gameRatio){
        canvas.style.width = windowWidth + "px";
        canvas.style.height = (windowWidth / gameRatio) + "px";
    }
    else{
        canvas.style.width = (windowHeight * gameRatio) + "px";
        canvas.style.height = windowHeight + "px";
    }
}

I have used and modified this code in my phaser 3 project and it works great.

If you want to see other ways to resize dynamically check here

Fabadiculous
  • 554
  • 6
  • 11
  • 2
    thx for response, but this does not helps, because game physics is unaware about changes of canvas size in that way. Looks like some props in game instance should be updated as well – bFunc Mar 02 '18 at 08:28
  • This is another tutorial I used: https://www.emanueleferonato.com/2018/02/16/how-to-scale-your-html5-games-if-your-framework-does-not-feature-a-scale-manager-or-if-you-do-not-use-any-framework/ . I think it is better than the one I posted in my answer, and I am using it in my current project. – Fabadiculous Jul 25 '18 at 07:31
  • 1
    The emanuele Feronato article does work in phaser 3. I have used it, and phaser3 is used in the article I linked in the above comment. I will update my answewr to use that link as it is better. – Fabadiculous Aug 22 '18 at 00:49
0

Put this in your create function:

  const resize = ()=>{
    game.scale.resize(window.innerWidth, window.innerHeight)
  }
        
    window.addEventListener("resize", resize, false);

Important! Make sure you have phaser 3.16+

Or else this won't work!!!

Coder Gautam YT
  • 1,044
  • 7
  • 20
-4

Use the game.resize function:

// when the page is loaded, create our game instance
window.onload = () => {
    var game = new Game(config);

    game.resize(400,700);
};

Note this only changes the canvas size, nothing else.

matthy
  • 8,144
  • 10
  • 38
  • 47