Jump to content

Phaser + CocoonJS vs. WebGL scaling finally solved


GregP
 Share

Recommended Posts

Hi Guys, 

Just wanted to share with you the result of my recent struggling with Phaser and CocoonJS - I finally managed to scale my game properly while running in WebGL mode!  :)

I spent some time digging in Phaser and Pixi.js source codes, also this thread was really helpful.

 

And here's the code:

(function () {    'use strict';    var width = navigator.isCocoonJS ? window.innerWidth : 320,        height = navigator.isCocoonJS ? window.innerHeight : 480,        game, nanoha;    game = new Phaser.Game(width, height, Phaser.WEBGL, '', {        preload: preload,        create: create,        update: update    });    function preload() {        game.load.image('bg', 'assets/bg.png');        game.load.image('nanoha', 'assets/nanoha.png');    }    function getRatio(type, w, h) {        var scaleX = width / w,            scaleY = height / h,            result = {                x: 1,                y: 1            };        switch (type) {        case 'all':            result.x = scaleX > scaleY ? scaleY : scaleX;            result.y = scaleX > scaleY ? scaleY : scaleX;            break;        case 'fit':            result.x = scaleX > scaleY ? scaleX : scaleY;            result.y = scaleX > scaleY ? scaleX : scaleY;            break;        case 'fill':            result.x = scaleX;            result.y = scaleY;            break;        }        return result;    }    function create() {        var ratio = getRatio('all', 320, 480);        if (navigator.isCocoonJS) {            game.world._container.scale.x = ratio.x;            game.world._container.scale.y = ratio.y;            game.world._container.updateTransform();        } else {            game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL;            game.stage.scale.minWidth = 320;            game.stage.scale.minHeight = 480;            game.stage.scale.pageAlignHorizontally = true;            game.stage.scale.setScreenSize(true);        }        game.add.sprite(0, 0, 'bg');        nanoha = game.add.sprite(160, 240, 'nanoha');        nanoha.anchor.x = 0.5;        nanoha.anchor.y = 0.5;    }    function update() {        nanoha.angle -= 2;    }})();

All the magic happens at the top of the create function - scaling world._container does the trick - the scale factor is applied to all it's children.

 

As a result I came from this:

https://dl.dropboxusercontent.com/u/30342997/Screenshot_2013-11-22-23-10-20.png

 

To this:

https://dl.dropboxusercontent.com/u/30342997/Screenshot_2013-11-22-23-08-55.png

 

I also tested touch events and these work as expected  :)

 

Complete sample app can be downloaded here: https://dl.dropboxusercontent.com/u/30342997/scale_test.zip

 

Please let me know what you think about such approach, maybe there's a better way around?

 

 

 

By the way, it would be soooo great to have Phaser supporting CocoonJS by default with no additional hacks... just tellin'  :rolleyes:

 

Link to comment
Share on other sites

GregP,

 

Thank you for sharing! :)

 

I zipped this up, put it on my phone, and tried launching it with the CacoonJS Launcher.  I recieved a black screen only???

 

I'm using a Samsung Galaxy S 4 to test on.

 

This is similiar results to what I am seeing with my own app.  I was hoping you had solved it! :)

 

Any ideas?

 

Thanks,

Shawn Bless

Rocket Star

Link to comment
Share on other sites

  • 2 months later...
  • 2 weeks later...

That happens to me too, In web browser works really fine, but when i tried to play it on a device, the sprites are off screen

 

Yep, same here. On a device, not only are some of the sprites off screen (even when game dimensions are set to the device window width and height), but the collisions do not work properly (e.g. sometimes not happening at all, sometimes happening when sprites are already overlapping). Does anyone have any ideas? Is what was recommended above not a good way to scale phaser games?

game.world._container.scale.x = ratio.x;game.world._container.scale.y = ratio.y;game.world._container.updateTransform();

I am trying to scale my phaser game to fit the screen of an android device (using cocoonjs). 

Link to comment
Share on other sites

Hi, with the 1.4.7 CocoonJS release, you need to take into consideration the device pixel ratio. Here's how I do it:

 

index.html:

<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"><head>    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>    <meta charset="utf-8"/>	    <script src="libs/phaser.js"></script>    <script src="game.js"></script></head><body>    <script type="text/javascript">        var width = navigator.isCocoonJS ? window.innerWidth : 640;        var height = navigator.isCocoonJS ? window.innerHeight : 960;        var dips = window.devicePixelRatio;        width = width * dips;        height = height * dips;        var myGame = new Phaser.Game(width, height, Phaser.AUTO, '');        myGame.state.add('boot', Screen.Boot, true);        myGame.state.add('preloader', Screen.Preloader);        myGame.state.add('splashscreen', Screen.SplashScreen);        myGame.state.add('mainmenu', Screen.MainMenu);        myGame.state.add('gamescreen', Screen.GameScreen);    </script></body></html>

Boot.js: (Note - written for the latest Phaser 1.2 release)

Boot = function (game) {    this.game = game;};Boot.prototype = {    getRatio: function (type, w, h) {        var width = navigator.isCocoonJS ? window.innerWidth : w,            height = navigator.isCocoonJS ? window.innerHeight : h;        var dips = window.devicePixelRatio;        width = width * dips;        height = height * dips;        var scaleX = width / w,            scaleY = height / h,            result = {                x: 1,                y: 1            };        switch (type) {            case 'all':                result.x = scaleX > scaleY ? scaleY : scaleX;                result.y = scaleX > scaleY ? scaleY : scaleX;                break;            case 'fit':                result.x = scaleX > scaleY ? scaleX : scaleY;                result.y = scaleX > scaleY ? scaleX : scaleY;                break;            case 'fill':                result.x = scaleX;                result.y = scaleY;                break;        }        return result;    },    setupScaling: function () {        if (navigator.isCocoonJS) {                        var ratio = this.getRatio('fill', 640, 960);            this.game.world.scale.x = ratio.x;            this.game.world.scale.y = ratio.y;            this.game.world.updateTransform();        }        else {            if (this.game.device.desktop) {                this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;                this.game.scale.pageAlignHorizontally = true;                this.game.scale.pageAlignVertically = true;                this.game.scale.setScreenSize(true);            }            else {                this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;                this.game.scale.pageAlignHorizontally = true;                this.game.scale.pageAlignVertically = true;                this.game.scale.forceOrientation(false, true, 'orientation');                this.game.scale.setScreenSize(true);            }        }        this.game.world.setBounds(0, 0, 640, 960);    },        create: function () {        this.setupScaling();        this.game.state.start('preloader');    }};
Link to comment
Share on other sites

  • 6 months later...
  • 1 month later...
  • 2 months later...
 Share

  • Recently Browsing   0 members

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