Daniel Belohlavek Posted January 10, 2015 Share Posted January 10, 2015 My never ending battle with scaling continues. I was reading the ebook "A guide to the scale manager" and I was tryng to replicate the behaviour seen in Spice Quest by goodboydigital: http://www.goodboydigital.com/client/razorfish/McD_PeriPeri/ That game has 3 key features I'd like to implement: Responsive scaling. Try to resize the browser and you will see that the game will respond.Aspect ratio. The canvas will only grow if the window.innerWidth/height values respect the original game ratio.Full screen support.This seems to be the system used in Spice Quest: App.prototype.resize = function(w, h) { this.options.resizeMode === App.resizeModes.DEFUALT ? (this.renderer.resize(w, h), this.view.style.width = "auto", this.view.style.height = "auto") : this.thisoptions.resizeMode === App.resizeModes.CSS_RESIZE_PRESERVE_RATIO || this.options.resizeMode === App.resizeModes.CSS_RESIZE && (this.view.style.width = w + "px", this.view.style.height = h + "px")} Reading the guide I mentioned, I believed that I could achieve this with SHOW_ALL, horizontal and vertical alignment and finally fullscreen activation when the player taps a button. Sadly I was not able to reproduce these features and SHOW_ALL scales outside the viewport. Was anyone able to implement this? Is there any code example somewhere explaining how to do this? Thanks for reading P.S. My apologies to GoodboyDigital for snooping around your code. Please tell me if you wish me to remove it from the post. Link to comment Share on other sites More sharing options...
d13 Posted January 10, 2015 Share Posted January 10, 2015 I don't know how your specific game or framework (Phaser?) is set up, but here's some general code that will center and scale an HTML canvas to the maximum browser window size:var scaleX, scaleY, scale, center; //1. Scale the canvas to the correct size//Figure out the scale amount on each axisscaleX = window.innerWidth / canvas.width;scaleY = window.innerHeight / canvas.height;//Scale the canvas based on whichever value is less: `scaleX` or `scaleY`scale = Math.min(scaleX, scaleY);canvas.style.transformOrigin = "0 0";canvas.style.transform = "scale(" + scale + ")";//2. Center the canvas.//Decide whether to center the canvas vertically or horizontally.//Wide canvases should be centered vertically, and //square or tall canvases should be centered horizontallyif (canvas.width > canvas.height) { center = "vertically";} else { center = "horizontally";}//Center horizontally (for square or tall canvases)if (center === "horizontally") { var margin = (window.innerWidth - canvas.width * scaleY) / 2; canvas.style.marginLeft = margin + "px"; canvas.style.marginRight = margin + "px";}//Center vertically (for wide canvases) if (center === "vertically") { var margin = (window.innerHeight - canvas.height * scaleX) / 2; canvas.style.marginTop = margin + "px"; canvas.style.marginBottom = margin + "px";}//3. Remove any padding from the canvas and set the canvas//display style to "block"canvas.style.paddingLeft = 0;canvas.style.paddingRight = 0;canvas.style.display = "block";Also, if you have some kind of mouse or touch pointer, you'll need to scale the pointer's x/y values by the same amount as the canvas.Something like this:pointer.x / scale;pointer.y / scale;This is the general idea - but you'll need to adapt this code to your own environment. To dynamically re-scale the canvas whenever the browser window is re-sized, call your scaling code in a window resize event.window.addEventListener("resize", function(event){ yourCustomScaleFunction();}); Link to comment Share on other sites More sharing options...
Daniel Belohlavek Posted January 10, 2015 Author Share Posted January 10, 2015 Thank you for replying. I'm using Phaser, aren't parts of that code already built-in as Phaser functions? Link to comment Share on other sites More sharing options...
Smrdis Posted January 10, 2015 Share Posted January 10, 2015 SHOW_ALL is not working as expected for me, I use USER_SCALE instead. game.scale.scaleMode = Phaser.ScaleManager.USER_SCALE;game.scale.setResizeCallback(this.gameResized, this); gameResized(manager: Phaser.ScaleManager, bounds: Phaser.Rectangle){ var scale = Math.min(window.innerWidth / this.game.width, window.innerHeight / this.game.height); manager.setUserScale(scale, scale, 0, 0);} Maras, michaelcalkins, ptotheaul and 2 others 5 Link to comment Share on other sites More sharing options...
Daniel Belohlavek Posted January 11, 2015 Author Share Posted January 11, 2015 @Smrdis' solution worked fine, I just tweaked it a little bit to fit my needs:static resize(context: any, logging?: boolean) { var _this = context; // A value of 1 means no scaling 0.5 means half size, 2 double the size and so on. var scale = Math.min(window.innerWidth / _this.game.width, window.innerHeight / _this.game.height); // Resize parent div in order to vertically center the canvas correctly. document.getElementById("game-canvas").style.minHeight = window.innerHeight.toString() + "px"; // Resize the canvas keeping the original aspect ratio. _this.game.scale.setUserScale(scale, scale, 0, 0); if (logging == true) { var w = Math.floor(_this.game.width * scale), h = Math.floor(_this.game.height * scale); console.info("The game has just been resized to: " + w + " x " + h); }}Now, when I try to call game.scale.startFullScreen() the game fails to resize and the canvas seems to go outside of the viewport. I'm calling my resize utility method from setResizeCallback(), so why is it failing to update? In fact, the result should be the same, as the width would stay intact and the aspect ratio would be respected, thus the height wouldn't change: only the vertical alignment. This would be different in an real mobile device because the address bar would go away and the height _would_ change. But that's not the case with Chrome's mobile emulation tool. Thanks for the help so far! Link to comment Share on other sites More sharing options...
Filozofer Posted January 11, 2015 Share Posted January 11, 2015 (edited) I worked this afternoon on a game basic template. It's far to be finish yet but I think you will love what I was able to create ! My work is here: Edit: Here's the link updated: https://mega.nz/#!q8g3nTCQ!b0l3dgR7GMBosBekEZ-gBwoU6E0qh_S2RAgVZkoamyo Phaser has probably evolve a lot since 1 year so I don't know if it's still working. But at least you will be able to figure out how to do it by adapting what I've done. You can simply launch the game by typing the command "grunt" when you're in the folder (install grunt with "npm install -g grunt-cli" command). You will see you can resize the window and the game will keep the same size ratio as we all except You can define the resolution (and by the way the ratio of your game) in config.js. Let me now if you got any questions PS: I've use the ebook "A guide to the scale manager" too for create this ! Edited September 24, 2016 by Filozofer Download link update Daniel Belohlavek 1 Link to comment Share on other sites More sharing options...
Daniel Belohlavek Posted January 11, 2015 Author Share Posted January 11, 2015 Nice work @mad, I got the same result with my own implementation of @Smrdis' code in Typescript, but your work will sure be a lot of help for those who don't use TS (most people around here i think) Any luck implementing fullscreen support? Link to comment Share on other sites More sharing options...
Filozofer Posted January 11, 2015 Share Posted January 11, 2015 Humm I'm not able to make it work too !My console say : "Phaser.ScaleManager: requestFullscreen failed or device does not support the Fullscreen API". I'll let you know if I succeed ! Link to comment Share on other sites More sharing options...
Daniel Belohlavek Posted January 11, 2015 Author Share Posted January 11, 2015 Are you trying on desktop or Mobile? Which browser? Update: It seems like fullscreen mode fails in your template too (the same problem that I have), see image below:http://i.imgur.com/opFW8qv.png Link to comment Share on other sites More sharing options...
Daniel Belohlavek Posted January 12, 2015 Author Share Posted January 12, 2015 Finally I got it to work (I was missing a single line). I'll share the complete solution I used based on the answers on this thread. Boot.tsmodule Game { export class Boot extends Phaser.State { parentElement: HTMLElement = document.getElementById("game-canvas"); preload() { // preload something } create() { this.game.scale.fullScreenTarget = this.parentElement; this.game.scale.scaleMode = Phaser.ScaleManager.USER_SCALE; this.game.scale.fullScreenScaleMode = Phaser.ScaleManager.SHOW_ALL; // Important this.game.scale.pageAlignHorizontally = true; this.game.scale.pageAlignVertically = true; this.game.stage.disableVisibilityChange = true; this.game.input.maxPointers = 1; this.game.scale.setResizeCallback(function () { Utils.Mobile.resize(this.parentElement, this, true); // you would probably just use this.game.scale.setResizeCallback(this.resize, this); }, this); this.game.state.start('Preload', true, false); } }}Utils.Mobile.resize()static resize(element: HTMLElement, context: any, logging?: boolean) { var _this = context; // A value of 1 means no scaling 0.5 means half size, 2 double the size and so on. var scale = Math.min(window.innerWidth / _this.game.width, window.innerHeight / _this.game.height); // Resize parent div in order to vertically center the canvas correctly. element.style.minHeight = window.innerHeight.toString() + "px"; // Resize the canvas keeping the original aspect ratio. _this.game.scale.setUserScale(scale, scale, 0, 0); if (logging == true) { var w = Math.floor(_this.game.width * scale), h = Math.floor(_this.game.height * scale); console.info("The game has just been resized to: " + w + " x " + h); }}Then you can call startFullScreen() whenever you want. Personally I'm going yo make it so that the fullscreen is triggered every time the user taps into the game (to prevent the user from exiting fullscreen and continue playing). Thanks everybody for the help jdnichollsc 1 Link to comment Share on other sites More sharing options...
jdnichollsc Posted January 15, 2015 Share Posted January 15, 2015 Hi Belohlavek! This solution is to Landscape o portrait mode? Regards, Nicholls Link to comment Share on other sites More sharing options...
Recommended Posts