Jump to content

How to align game to center screen without jumping?


Tweeper
 Share

Recommended Posts

Hello guys,

I have a problem about scaling / centering my game that's driving me nuts by now, so it's time to ask for some help...
 

I'm trying to center my game on screen using the scaleManagers properties pageAlignHorizontally and pageAlignVertically. But wherever I put the lines to set those parameters, the game jumps from the left of the screen to the center everytime at startup.

* At first I was hoping I could put the centering properties inside the gameConfig. But I can't find a way to do that. Is this even possible? 
* Then I was guessing where exactly to put the centering settings; it wasn't possible inside the constructor, 'cause game.scale is null at that point
* So I put the scaling settings inside the bootState init method. That works, but only after the original (left) position of the game was first drawn unto the screen. In other words: the game jumps from the left alignment to the center :(   Then I tried to put a scale refresh directly after it, but that doesn't fix it.

The game works with states.

So this  my guestions:
- Would it be possible to set the alignment (horizontal/vertical) to center from inside the gameConfig? (that would be the best!)
- Or else: where to put the alignment settings in my code so that the game doesn't jump at first drawing?
- And: Why is game.scale null after creating a new game? I would expect it to be ready 


Hope one of you guys can help me with this!

Here's a simplified version of my code:
 

Quote

var gameConfig: {
    width: 1920,
    height: 1080,
    renderer: phs.AUTO,
    parent: 'gameWrapper',
    scaleMode: Phaser.ScaleManager.SHOW_ALL,
    fullScreenScaleMode: Phaser.ScaleManager.SHOW_ALL,
    transparent: false,
    antialias: false
}  
 
 
// CONSTRUCTOR
(function() {
      game = new Phaser.Game(gameConfig);

      // ADD STATES
      game.state.add('boot', bootState); 
      game.state.add('load', loadState);
      game.state.add('menu', menuState);
      game.state.add('play', playState);

      // START BOOT STATE
      game.state.start('boot');
})(); 

var bootState = {
    init: function() {
        // STAGE BACKGROUND
        game.stage.backgroundColor = 0x34495f;

        // PREVENT PHASER FROM STOP WHEN IFRAME IS OUT OF FOCUS
        game.stage.disableVisibilityChange = true; 

        // SMOOTH GRAPHICS
        game.stage.smoothed = true;

        // CENTER GAME ON SCREEN
        game.scale.pageAlignHorizontally = true;
        game.scale.pageAlignVertically = true;
    },

    create: function() {
        // CALL LOAD STATE
        game.state.start('load');
    }
};

...
 

 

Link to comment
Share on other sites

I really dont know how Phaser manages that stuff but if its jumping then it renders something before your centering code runs. Have you tried setting the scale before entering the boot state?

It really depends on when Phaser appends the canvas to the DOM. I'd have thought it probably does that in the constructor so maybe there is a config option for it.

Aren't all the Phaser examples centered on screen? Do they jump?

Link to comment
Share on other sites

I'm not sure how to do it with Phaser functionality, but is there any reason you can't just use CSS?

in my index.html I have a div around my div that the canvas is injected into. And on that outer div I have the css:

 

#container {
  1. width: 100%;
  2. text-align: center;
}

 

and on the content div inside that I have

#content {
  1. margin: 0 auto;
}
 
 
Link to comment
Share on other sites

18 hours ago, mattstyles said:

I really dont know how Phaser manages that stuff but if its jumping then it renders something before your centering code runs. Have you tried setting the scale before entering the boot state?

Thanks for your response Matt. I understand this. As I wrote above I tried setting the centering directly after the instantiation of game (in the 'constructor' of my game, so even before boot state). But at that point the scalemanager is still undefined.... I tried creating a new ScaleManager object with game as a parameter, but that didn't work either. The init function inside the boot state should be the very first function to be executed according to what I can find in the docs. But that still seems to be 'too late' in the code, 'cause there is a visible jump from left to center.
I looked everywhere in the docs and Phaser code, but I can't find any information about putting the centering values inside the gameconfig object. That would be my prefered choice and a logical place to me, 'cause the scaling can be set there too...

 

18 hours ago, mattstyles said:

Aren't all the Phaser examples centered on screen? Do they jump?

Good point. I've looked at the examples, but unfortunately they are not

 

17 hours ago, LogicaLinsanity said:

I'm not sure how to do it with Phaser functionality, but is there any reason you can't just use CSS?

Thanks LogicaLinsanity. That's a good alternative indeed.
My first choice would be to use the Phaser scaleManager, because there IS this Phaser functionality build in, so why not take advantage of it instead of build extra code (wich probably can cause conflicts or do same things twice)? Next to this, the centering I want is not only horizontally, but also vertically. And I don't know of any (generic) method for vertical centering a game in css (both for use inside an scaling iframe as for use on fullscreen. where sometimes the maximum width is used and other times the maximum height, according to the orientation of the device).
In other projects, where I don't use Phaser, I use my own resize-function for this in javascript and it works great, but with Phaser projects I think it's a little silly to create an extra/own function to scale/center while there is this beatiful scaleManager build into Phaser for exactly and only this purpose.

But anyway... I building my own resize function is my only option at this point at the moment, 'cause it seems like this is a bug in Phaser. I looked in the Phaser code and it seems the renderer (canvas) gets created BEFORE the centering is done. So whereever I put the centering settings in my code, it always jumps... I posted my findings on Phasers github issues (https://github.com/photonstorm/phaser/issues/2311). 

For now I will put my own resize function back into the code.

Thanks for your responses!

Link to comment
Share on other sites

I had a quick butchers at this, although bare in mind I've never used Phaser for anything.

I couldnt get rid of the flash by fair means, it doesnt seem to want to do anything with the scale page alignment until after the first render call, even more strangely the canvas element exists fairly early in the DOM but not attached to Phaser (this leads me to believe that something is fundamentally wrong with mine, and hence your, setup—I'm just copying your method).

However, the parent object you attach to is available and you can manipulate the style directly. Yes, this is a hack. Yes, it is dirty, and yes, I believe there is a correct Phaser way to do this (I'm sure someone will pop along with proper help). There is one more hurdle, but first, kill the opacity on the parent

var game = new Phaser.Game( config )
game.parent.style.opacity = 0

Now, as I said earlier, it looks like scale is only calculated after the first render so you’ll have to make sure you apply the opacity change after that. Just upping the opacity in the preload, create or render functions wont help. As a hack execute on the next tick:

preload: function() {
  setTimeout( () => {
    game.parent.style.opacity = 1
  }, 0 )
  ...
}

I tried a couple of different methods, but couldnt stop the flash without this hack.

As with all hacks, I'd recommend finding out the best way to do this, Phaser surely solves this problem, the config has all the bits it needs to reposition the element correctly. It also looks like the positioning code runs every tick (and re-evaluates the state of the DOM), but after the render, maybe there is a reason it is not run before the render.

Link to comment
Share on other sites

Thanks for your efford @mattstyles, I looked inside the phaser code and I'm sure this is a bug inside Phaser that can't be solved by changing the place of the alignment settings in the code. So it seems like our findings are the same. I created an issue entrence on github a few days ago:  https://github.com/photonstorm/phaser/issues/2311). Hopefully this gets attention for the 2.4.5 version. Would be great, 'cause that scaleManager is a nice thing to have in Phaser. 'Till then your workaround seems like a good alternative, thanks.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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