Jump to content

Multi-resolution questions for 3 different targets.


gsynuh
 Share

Recommended Posts

Hello Everyone,

First time post on this forum, and first Phaser project.

I researched for this, and have had results but not complete results so I decided to post a topic.
I'm not at all looking for a solution with code as I'm not looking to waste anyone's time here, but guidance will be much appreciated given my 'noob' status with phaser.

My background might be helpful : I'm coming from actionscript/starling here, where
1. stage can be scaled
2. textures can have scales as well so that a texture of scale 1 that reports a size of 100x100, would also report a size of 100x100 when at scale .5, it's just that the original image would be twice smaller, starling would handle upscaling the texture. With that, placing objects dynamically is easy as I would not have to change the code used to place objects on stage because width/height of objects would not change, and the stage being scaled would also allow me to place things in absolute values and still get a proportionally similar result on different 'screens' at least when the ratio of the stage is the same.

What I want is "best fitting" the base dimensions of my game to the current "container" dimensions (as well as centering it).

The topic is mostly about two things : fitting the game in those "3 different target containers" and also handling multi-resolution.

So I'm creating a game for 3 "target containers". By that I mean :

1.  a variable width/height div, in a desktop browser (inside a website that I won't be in control of so the dimensions are not fixed)
2. in a mobile browser, this time full window (nothing but the div containing phaser will be on this page)
3. in cocoonJs

 

As I would've done with a flash project, I've prepared a set of different sized assets.
I'm detecting whether I'm in cocoonjs with the following

//initisCocoon = Reflect.hasField(Browser.navigator,'isCocoonJS');

The game is designed (at scale 1x) for a base 'screen' of size
 

base = new Rectangle(0, 0, 2048, 1536);

this is a Rectangle I can access everytime.

So all my assets of scale 1x are prepared for this base screen size (for cocoonJs actually). and I have other sets of downscaled assets, here is the list of scales I have  :

scales = [0.25,0.375,0.5,0.75,1];

also an array that I can access anywhere in case that matters.
 

Now for cocoonJs and a full browser version of the game on desktop, I have the following setup , and it works fine :

    function init()    {                isCocoon = Reflect.hasField(Browser.navigator,'isCocoonJS') ? true : false;                game.scale.scaleMode =  isCocoon ? ScaleManager.USER_SCALE : ScaleManager.RESIZE;                game.scale.canExpandParent = true;                game.scale.setResizeCallback(onResize, this);                if (isCocoon) {            trace("[Main] is CocoonJS");        }else            trace("[Main] is not CocoonJS");                game.scale.setScreenSize();    }function onResize()    {        if (isCocoon) {                        var w = Browser.window.innerWidth;            var h = Browser.window.innerHeight;                        game.renderer.resize(w, h);            game.scale.setScreenSize();        }    }

This works fine.
Also in init and onResize, I also calculate the "scale factor" of my game
 

realScaleFactor = game.width / base.width; //that's assuming the game is always in landscape and it is.

and look for the closest Float to that Float in my "scales" array , in order to find the right scale assets for my "screen"...
 

if my game.width is 1024, i'll be at a scale of 0.5 compared to my original dimensions for my game, and since I have such a downscaled version for my assets, i'll preload stuff from my assets/0.5x/ folder instead of the assets/1.0x/

I guess that all makes sense (unless there's a more obvious way to do this).


Now the problem with my multi-resolution paragdim that I'm trying to "port" from starling .
The basic idea again is to be able to use absolute values whenever possible, and relative values when placing ui stuff (because obviously some screens are larger than the ratio of the "base" rectangle).

I would scale down the stage, and starling would scale up images with the scale property. that means I can download smaller textures, still have stuff appear at the right scale and an image would always be the right size when I read the width/height values.
 

I just tried placing every Sprite I need in a container (group), scaling that container down. it's like a Show_All I guess. yet the images are 2x too small when I'm at a .5x scale so it's probably useless to go this way.

Could I make those 3 targets work , and load different sized assets, using the SHOW_ALL technique and how can I tell the scale manager the "base dimensions" or ratio of my game it should respect in order to SHOW_ALL.  - and does that work with cocoonjs.

How are you guys handling multi-resolution , without having to manually scale images, or hardcoding screen values.
And how can I setup the ScaleManager for the three "targets" I have... The problem being the div with the fixed width/height the game could run in and I don't know in advance its dimensions.

---

I'm very confused and very sorry if the solution is obvious. My problem is being convinced that something needs to be done a certain way and not having the necessary knowledge to do it the Phaser Way so in that regard I thank you in advance for any links and suggestions to help me for both the "3 target" and the "applying multiresolution" problems I currently have.

Link to comment
Share on other sites

Hi.

I've read the guide.

Though it does solve most misunderstandings I had with the ScaleManager, it mentions using different texture resolution, or different asset sizes per target screen at the beginning but in one or two sentences only and never goes further with that and explains how to go about reconciling this process with using the ScaleManager and so on.

I know I'm probably overthinking things, and the fact that I have trouble changing my perspective and workflow from flash/starling to html5 is not helping at all.

One possibly dirty solution I found for the different asset sizes I have, is like virtualizing or abstracting the workflow I used to have by shoving stuff in a container and resizing it myself... and just forget about not being able to have "texture scales" a la Starling.

I have read that the camera is not able to zoom (maybe I'm wrong), nor that we can scale up or down the stage, so , still using the RESIZE scale method, I decided to create a base State called MultiResState which on a state basis will help me.

Now bear with me :
- I still have different scales for my assets : scales = [0.25,0.375,0.5,0.75,1]; (some we could get rid of in the end)
- I have a "base" dimension for my game which is 2048x1536 , so in a 1024x768 cocoonjs app I would load up the .5 assets, and in the entire Android world, I would find the nearest scale to my "real scale factor" I mentioned above and grab that asset 'pack'.

That means sometimes, when the game's ratio hits my base ratio perfectly, everything is great. but most of the time it doesn't and that's where my main issue was.

I will put all my game objects inside a container. and everything that needs an absolute position (according to my base game dimensions and layout i've planned) will have their position multiplied by the asset size i've chosen.
So essentially what I'll have on screen, when my scale factor is .5x, is the exact replica of my game, twice smaller and at the "right ratio". So its annoying to have to multiply positions, but I have found no other way, I guess we could actually create a custom Sprite maybe to simulate "texture scale" .

Now I also want to fit that to the game dimensions while keeping the same base ratio of my game.

So to make everything work together , my MultiResState basically looks like this (in HAXE) :

 

class MultiResState extends State{    var container:Group;    var baseRect:Rectangle;        var bestFitRatio:Float = 1;        public function new()    {        super();    }        override function preload():Void {        super.preload();        trace("ScaleFactor: ", Main.scaleFactor, " realScaleFactor: ", Main.realScaleFactor);    }        override function create() {        super.create();        baseRect = new Rectangle(0,0,Main.base.width * Main.realScaleFactor, Main.base.height * Main.realScaleFactor);        game.scale.onSizeChange.add(onResize);        container = add.group();    }    function onResize()    {        baseRect.setTo(0, 0, Main.base.width * Main.scaleFactor, Main.base.height * Main.scaleFactor);        bestFitRatio = getBestFitRatio(baseRect , new Rectangle(0, 0, game.width, game.height));        container.scale.x = container.scale.y = bestFitRatio;        container.x = game.width / 2 - baseRect.halfWidth;        container.y = game.height / 2 - baseRect.halfHeight;    }        override function shutdown():Void {        game.scale.onSizeChange.remove(onResize);        super.shutdown();    }    //this function is actually somewhere else     function getBestFitRatio(rect:Rectangle, into:Rectangle):Float    {        if (into.height / into.width > rect.height / rect.width)                return into.width / rect.width;            else                return into.height / rect.height;    }    }

It works so far, as whatever asset size I load up, it will fit correctly and in a fake letterbox way since the game actually resize to fit horizontally and vertically yet the content of the game/state I have will fit and center itself as well - so I could technically fill in whatever background image I want inside the container by doing a little more calculations in the opposite direction.


Things I still find annoying :

- I still have to manually multiply positions of my objects with a scaleFactor. I'm not talking about dynamic positioning of ui elements, of course that's normal and I can use them outside of the container anyway. This could be fixed if like starling, textures could have "scales" and just appear at the right size whatever their scale is, the only thing to change would be its actual resolution.

- Though I can now make this work in a fixed width/height div thanks to the reading material and missing concepts I had, and cocoonjs or "full browser" on desktop work like a charm, I've yet to find the right ScaleManager stuff to make it work on mobile browser ... will try fullscreen API but I just wanted to update this topic with new info.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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