0

Is anyone able to help please. I am following the tutorials in this book which are based on the Inheritance Pattern: https://books.google.co.uk/books?id=UpiJAwAAQBAJ&pg=PR4&lpg=PR4&dq=beginning+html5+games+with+createjs I am using Cordova to try to install it on iOS and Android. It seems to install okay however I cannot work out how to get it to fit the screen (on all devices) while not stretching the images. I have read that I need to resize the stage (canvas) and float the container but I can't work out how to do it with this sample. Would anyone be able to help please? Below I have extracted samples from the project which will hopefully illustrate the problem. I'd really appreciate any help with this....

Index.html

<!DOCTYPE html>
<html>
    <head>
        <!--CREATEJS-->
        <script src="js/lib/easeljs-0.8.2.min.js"></script>
        <script src="js/lib/preloadjs-0.6.2.min.js"></script>

    <body onload="init();">
        <div id="gameWrapper">
        <div>
            <canvas id="canvas" width="768" height="1024"></canvas>
        </div>
    </body>

    <script>
        var stage;
        var canvas;
        function init() {
            window.game = window.game || {};
            game.main = new game.TestGame();
        }
    </script>
</html>

Testgame.js

(function (window) {

window.game = window.game || {}

function TestGame() {
    this.initialize();
}

var p = TestGame.prototype = new createjs.Container();

p.Container_initialize = p.initialize;

p.initialize = function () {
    this.Container_initialize();

    canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    if (window.devicePixelRatio > 1) {
        ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
    }

    stage = new createjs.Stage(canvas);

    screen_width = canvas.width;
    screen_height = canvas.height;
    stage = new createjs.Stage(canvas);

    game.Device.prepare();
    //preload all assets using PreloadJS
    this.preloadAssets();
};

p.gameStateMainMenu = function () {  
    var w = window.innerWidth;
    var h = window.innerHeight;

    stage.canvas.width = w;
    stage.canvas.height = h; 

    var scene = new game.MainMenu();

    var ratio = screen_width / screen_height;
    var windowRatio = w/h;     

    //***** scaleX is making the image too small
    var scale = w / screen_width;

    if (windowRatio > ratio) {
        scale = h / screen_height;
    }

    // Scale up to fit width or height
    scene.scaleX = scene.scaleY = scale; 
    stage.addChild(scene);

    this.disposeCurrentScene();
    this.currentScene = scene;
    this.sceneName = 'MainMenu';
    this.changeState(game.GameStates.RUN_SCENE);
};

window.game.TestGame = TestGame;

}(window));

MainMenu.js

(function () {

window.game = window.game || {}

function MainMenu() {
    this.initialize();
};

var p = MainMenu.prototype = new createjs.Container();
p.Container_initialize = p.initialize;

 p.initialize = function () {
    this.Container_initialize();

    this.addBG();
    this.addGraphics();
};

p.addBG = function () {
    var bg = new createjs.Bitmap(game.assets.getAsset(game.assets.BG));
    this.addChild(bg);
};

p.addGraphics = function () {
    var circle = new createjs.Bitmap(game.assets.getAsset(game.assets.CIRCLE));
    circle.regX = circle.getBounds().width /2;
    circle.x = screen_width /2;
    circle.y = 50;
    this.addChild(circle);
}

window.game.MainMenu = MainMenu;
}());
user3805377
  • 27
  • 1
  • 8

1 Answers1

0

If you are drawing content with EaselJS, I do not recommend manually transforming the canvas context. Instead, just scale the content based on its original size, and the target viewport size.

Here is another question I answered: How should I create a responsive canvas with createJs to adapt different mobile device's screens?

And a quick fiddle showing how to scale content to fit a window: https://jsfiddle.net/lannymcnie/4yy08pax/

You can scale any DisplayObject by setting the scaleX and scaleY properties:

content.scaleX = content.scaleY = scale;

Hope that helps.

Community
  • 1
  • 1
Lanny
  • 11,244
  • 1
  • 22
  • 30
  • Thanks for your reply Lanny. I had already tried your post and your fiddle but I'm really struggling to get it working. I'm not drawing content with EaselJS, just using it to load Bitmaps and Sprites (all preloaded). Can you see anywhere were I'm going wrong with my code? I'd really appreciate some more help :) – user3805377 Mar 05 '16 at 16:20
  • Is anyone able to help please - I'm really stuck on this? I have followed Lanny's examples and although I can get the container (eg MainMenu) to scale to the device screen, the individual objects are always out of position? I have tried to use relative or absolute positions but no luck. Please could someone help me to work it through with my code? – user3805377 Mar 16 '16 at 23:01
  • Sorry Lanny, not easily. The project is huge and I use Cordova, so getting a demo that would behave exactly like what I'm experiencing would be very difficult. Does all the code I included in my original post not help? Basically I create prototype objects so I either resize a whole object (eg MainMenu) or scale each asset individually (eg addGraphics) and then wrap it into an object. The problem is that either way, the position of everything is knocked out when I scale. Hope that makes sense. – user3805377 Mar 17 '16 at 07:44
  • Sounds like you have to multiply the object's positions by the scale factor. Scaling a container has the benefit of scaling and translating that content for you, but if you hare manually scaling each asset, you have to also scale its position. – Lanny Mar 17 '16 at 15:40
  • That's the weird thing - when I scale the whole container (MainMenu) the content is scaled correctly, but the positioning is all changed.If I scale using scene.scaleX = scene.scaleY = ratioX; the Y positioning is out, and if I scaleY, X positioning is out. This is driving me nuts! – user3805377 Mar 17 '16 at 17:53
  • When you scale a container, it will scale the contents, including their position (for example, an item at [100,100] in a container scaled to 200% will be at [200,200] visually. If you *just* want to scale the contents, you will have to do it manually, or counter-scale their coordinates. – Lanny Mar 17 '16 at 17:54
  • I have updated the code above to show how I have implemented your code. If I scale using X (var scale = w / screen_width;) I end up with everything scaled smaller and positioned as designed, but everything is squashed in the top two thirds of screen. If I scale using Y, the container fills the screen correctly but everything is pushed over to the right by approx. half an asset width. – user3805377 Mar 17 '16 at 18:58
  • Okay I have just done some more testing - it looks like the assets have got the correct x position, it's the regX (circle.regX = circle.getBounds().width /2;) that is not scaling correctly. Have I implemented it correctly? Thanks for your help – user3805377 Mar 17 '16 at 19:14
  • regX and regY should be relative to their owners, so should not have to be scaled. – Lanny Mar 17 '16 at 19:37
  • I don't understand it - if I remove regX altogether and position the graphic using screen_width /2, roughly half of the graphic can be seen against the right edge of the screen. Presumably that would be caused by the original canvas being 768 x 1024, and the innerWidth/innerHeight of the device I am testing on is 360 x 640? – user3805377 Mar 17 '16 at 19:43
  • A simple demo would really help to illustrate the problem you are having. Any chance you can put together a JSFiddle? http://jsfiddle.net/lannymcnie/j1ju46r9/ – Lanny Mar 17 '16 at 20:37
  • I'll try to put together a JSFiddle but it's really difficult because I'm effectively using MVC and then add in Cordova/mobile and things get really complicated. Does my code in my original post look correct? – user3805377 Mar 17 '16 at 21:02