GregP

Phaser + CocoonJS vs. WebGL scaling finally solved

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:

 

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

I'm using this method for scaling up, but for some reason sprites are off screen?

 

Anyone know why this might be happening?

 

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

Share this post


Link to post
Share on other sites

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). 

Share this post


Link to post
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');    }};

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.