Issue Related to new Container Strategy

Hi,

From what I can tell from many hours, the new 2.2.2 build does not allow an outer DIV around your gameCanvas. If you do use one, the inner DIV created at game start-up (id=“Cocos2dGameContainer” ) is not getting the updated information when the browser window is made larger - only when it is made smaller. This seems to be something to investigate.

It seems like the Cocos2dGameContainer margins on the left and right “eat up” all space when the browser is made bigger again. So instead of the game getting that space back it is taken by the margin.

The net effect is that the game will scale down, but not back up. You can test and prove this error easily by wrapping an empty DIV around your Hello World example.

This was using:
cc.ContainerStrategy.PROPORTION_TO_FRAME,cc.ContentStrategy.SHOW_ALL

Additional note: :
cc.ContainerStrategy.EQUAL_TO_FRAME,cc.ContentStrategy.SHOW_ALL

It seems like the above will scale back up after scaling down, but this is not a good choice because when it scales down it shows a scroll bar and the game seems to float downward.

If this is an implementation issue, perhaps the solution is to post more examples of how to implement the new container strategy. The Hello World example shows when there is nothing on the page except the game, and truthfully this is an unrealistic example for many. I believe an example case where the game is wrapped in div on a Web page is a far more common one.

I look forward to any insight provided.

Thank you,
Sean

Hi, Sean

This is the expected behavior, when you wrap your game into a div in your page, the engine won’t know how you want to control your div in your page. So we do nothing.
The container strategies: PROPORTIONTOFRAME, EQUALTOFRAME are both related to the direct parent of your game canvas, which in your case is the outer div, so it’s irrelevant to the window size.

For what you expected, you can listen to the window resize event, then adapte firstly your page to the new size, like scale your div. Then reapply the resolution policy to make the game canvas fit its outer div.

For more detail about the resolution policy design, please read this documentation: http://cocos2d-x.org/wiki/Understand_the_Resolution_Policy_in_Cocos2d-html5_222

Huabin

I would agree if this was true. However it does do something - it shrinks the game with the window/div when that shrinks.

The issue is that it does not do the opposite when the window/div is scaled back up.

I have read the new resolution design policy, and I understand creating good documentation is difficult and time-consuming, but it is not clear to me what to do in this case.

I have seen your screen shot in another post, and the reason of the behavior is your div is not styled.
If your div’s style is empty, then the div has the default behavior which is controlled by the page itself. So your game canvas has been scaled down is because your div has been scaled down by you html page.
The margin you have seen for the div is because, default margin value for div is “auto”, then it will be automatically centered by giving a margin value to the left and right of the div.

All those happens in the css level, it’s irrelevant to cocos2d-html5.
Try to set the style of your div as:

style="width: 640px; height: 480px;"

You will see the difference

Huabin

You have offered a solution to a different problem.

I understand how to make a fixed size DIV. And I understand that 2.2.2 works well if you want a fixed size game in that way.

But what if your game must sit inside a DIV, like on many Web sites and layouts, yet you want it to be able to scale up and down within that DIV and window?

Your solution and the way 2.2.2 works this cannot be done. This is what I am saying.

Ok, you want the game inside a DIV whose size changes with the window size?

First of all, for cocos2d-html5, if you choose container strategies: PROPORTIONTOFRAME, EQUALTOFRAME, only the origin outer DIV of game canvas matters. So when your window changes its size, it’s up to you to scale up and down the div and then reapply the resolution policy.
The idea is this: except the canvas element, the engine won’t change anything else in the original web page to ensure a stable experience for developers.

If you feel it doesn’t suit your need, then you can implement your own container strategy and do whatever you want. It’s also described in the doc: http://cocos2d-x.org/wiki/Understand_the_Resolution_Policy_in_Cocos2d-html5_222

var MyContainerStg = cc.ContainerStrategy.extend({
    preApply: function (view) {
        // This function is called before the process of adaptation,
        // you can remove this function if you don't need
    },

    apply: function (view, designedResolution) {
        // Apply process
    },

    postApply: function (view) {
        // This function is called after the process of adaptation,
        // you can remove this function if you don't need
    }
});

This is a advanced technique, so make sure you know what you are doing, and before doing so, you can see the source code of CCEGLView.js to learn how to do this.

Example of PROPORTIONTOFRAME strategy

var ProportionalToFrame = cc.ContainerStrategy.extend({
    apply: function (view, designedResolution) {
        var frameW = view._frameSize.width, frameH = view._frameSize.height, containerStyle = cc.container.style,
            designW = designedResolution.width, designH = designedResolution.height,
            scaleX = frameW / designW, scaleY = frameH / designH,
            containerW, containerH;

        scaleX < scaleY ? (containerW = frameW, containerH = designH * scaleX) : (containerW = designW * scaleY, containerH = frameH);

        // Adjust container size with integer value
        var offx = Math.round((frameW - containerW) / 2);
        var offy = Math.round((frameH - containerH) / 2);
        containerW = frameW - 2 * offx;
        containerH = frameH - 2 * offy;

        this._setupContainer(view, containerW, containerH);
        // Setup container's margin
        containerStyle.marginLeft = offx + "px";
        containerStyle.marginRight = offx + "px";
        containerStyle.marginTop = offy + "px";
        containerStyle.marginBottom = offy + "px";
    }
});

I will give this a try, thanks for posting an example.

This is indeed an annoying issue (let’s keep the discussion in this thread and let my old one die down).

Please do tell if you have success with that!

Hi ZippoLag,

No success with this yet… I agree this change is annoying and really frustrating. It seems overly complicated. The previous method worked simply.

I’m also actually seeing other display issues around consistency between browsers. I have been spending countless hours trying to get a consistent experience across browsers and platforms with very little luck. It is becoming a big reason we are looking at other options.

Let me know if you have any recommendations on how to implement.

Thanks and good luck

@sixtyfivecaddy

Actually, I don’t understand what you need that can’t be accomplished by the resolution policy.
Let’s use an example, image we want the game be located with its parent which is an article, and the game takes 80% width of the article, while the article must be resized with the window’s size. Well, a complicated case

Since it’s complicated to post html code here, I’m using a screen caption and the index file is uploaded too
Index.html:

In your applicationDidFinishLaunching function, you can add these codes to make the adaptation work:

var view = cc.EGLView.getInstance();
view.resizeWithBrowserSize(true);
view.setResizeCallback(function() {
    var elem = document.getElementById("mygame");
    var height = elem.clientWidth * 450 / 800;
    elem.style.height = height + "px";
});
view.setDesignResolutionSize(800, 450, cc.RESOLUTION_POLICY.SHOW_ALL);

So the basic idea is to update the size of the div which contains your game with the screen resize call back, and then the resolution policy SHOW_ALL will readapt your game to its container automatically.

Hope this makes thing more clear.

Huabin

That looks promising!

PS: what about using pastebin ( http://pastebin.com/ ) for sharing code for the time being? The links of what’s pasted there rarely die for what I know.

Huabin,

This was a huge help, thank you very much. The extra information was much appreciated.

I did need to add some of the steps you used within “setResizeCallback” to identify the current DIV size when the game first loads. Otherwise the game was loading at a very small size initially.

In case anyone else needs the info, here is what I have in main.js after “applicationDidFinishLaunching” up until “setDisplayStats”:

var director = cc.Director.getInstance();
	    
var view = cc.EGLView.getInstance();
view.resizeWithBrowserSize(true);

var designSize = cc.size(720, 440);
        
//detect the size of the initial div
var elem = document.getElementById("mygamedivID"); // this is wrapping div
var height = ~~(elem.clientWidth * designSize.height) / designSize.width;
elem.style.height = height + "px";
                
// this detects change to browser size or orientation change
        view.setResizeCallback(function() {
            var elem = document.getElementById("mygamedivID"); // this is wrapping div
            var height = ~~(elem.clientWidth * designSize.height) / designSize.width;
            elem.style.height = height + "px";
        });
        
view.setDesignResolutionSize(designSize.width, designSize.height, cc.RESOLUTION_POLICY.SHOW_ALL);

Thanks again,
Sean

You are welcome Sean,

The solution we are discussing here is all about CSS and DOM element control, and that what meant to be done by the design of Resolution Policy. So remember the game element of Cocos2d-html5 cares only its parent, and it won’t cross the line to control it.

Huabin

The only issue I am seeing is that safari on iOS6 and iOS7 on the iPhone seem to ignore the settings. I am unsure why, but it jumps straight to the largest size.