How create fully responsive html5 game using Phaser library? - html

I'm using Phaser 2.5.0 (tried 2.4.8 also) and I'm trying to create fully responsive game using phaser library.
Everything is ok when I refresh page, here is image:
but when I change rotation to portrait dialog message is not ok, image:
When I refresh page using portrait mode I get ok dialog:
So problem is when I resize browser window.
Here is code for init phaser game:
var game = new Phaser.Game(window.innerWidth, window.innerHeight, Phaser.AUTO);
Tried also:
var game = new Phaser.Game("100%", "100%", Phaser.AUTO);
Here is create function located in main.js:
create: function(){
console.log('create');
this.game.antialias = true;
this.game.stage.smoothed = true;
this.input.maxPointers = 1;
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.minHeight = 0;
this.game.time.advancedTiming = true;
},
So to tell again problem is when I resize browser window but when I do refresh then it's not working ok. Game must support resize.
Here is one simple example which is giving almost same result, on refresh is ok but when doing resize is not ok: https://jsfiddle.net/CroDac/tv010u0t/
Thank you

There was/is an old, but apparently not fixed, bug in iOS that caused (causes?) this. There are several workarounds on the net, on of them is here:
https://github.com/scottjehl/iOS-Orientationchange-Fix
From the description:
This fix works by listening to the device's accelerometer to predict
when an orientation change is about to occur. When it deems an
orientation change imminent, the script disables user zooming,
allowing the orientation change to occur properly, with zooming
disabled. The script restores zoom again once the device is either
oriented close to upright, or after its orientation has changed. This
way, user zooming is never disabled while the page is in use.
Maybe this can help you....

Related

Is there anyway to make resolution settings using AS3 in Animate CC?

I have a project that needs to be made in Animate CC using ActionScript3.
The situation is that I have to make resolution options, meaning that if I select a button it will change the resolution of my project to said resolution like 800x600 etc. Like video games you know.
i've tried using
res1.addEventListener(MouseEvent.CLICK, setRes1);
function setRes1(event:MouseEvent):void
{
stage.fullScreenSourceRect = new Rectangle(0, 0, 800, 600);
stage.displayState = StageDisplayState.FULL_SCREEN;
}
But it doesn't seem to work, is there even a way to do this?
Not using the Flash Player, but If you target AIR yes you can do it accessing the properties of NativeWindow. Stage.fullScreenSourceRect is read-only. But you can modify application size accessing NativeApplication.nativeApplication.nativeWindow.width = ...; This will not modify your pc screen resolution, but only resize the application window. You can change resolution in AIR though using the ScreenMode class. Detailed working is described here: https://helpx.adobe.com/flash-player/release-note/fp_31_air_31_release_notes.html#ScreenModeConfigurationforAIRDesktop

Libgdx, Setting the full screen resolution during runtime causes application to render at the wrong size

I am only using the desktop Application, no mobile.
I am experimenting with letting the user set the screen resolution during run time. I give him the Display Modes available and he applies one. This part actually works. The problem occurs when i save this mode and try to set this display mode the next time they launch the game.
I am using preferences to store the mode the user selected. I am unable to access preferences before the Create method in my Game class, or in the DesktopLauncher Object, where you normally set up the config file and pass it into the application. So my DesktopLauncher looks like this.
val config = Lwjgl3ApplicationConfiguration()
config.setFullscreenMode(Lwjgl3ApplicationConfiguration.getDisplayMode())
Lwjgl3Application(MainGame(), config)
I use the current screen resolution on the creation of the application. Then in my Create method in my MainGame class i get the mode they set from preferences and i set it like so...
override fun create() {
var modes = Gdx.graphics.displayModes.toList()
val mode = Gdx.graphics.displayMode
val preference: Preferences = Gdx.app.getPreferences("screenPreference")
val screenWidth = preference.getInteger("width", mode.width)
val screenHeight = preference.getInteger("height", mode.height)
val refreshRate = preference.getInteger("refreshRate", mode.refreshRate)
modes = modes.filter { it.width == screenWidth }
modes = modes.filter { it.height == screenHeight }
modes = modes.filter { it.refreshRate == refreshRate }
if (modes.isNotEmpty()) {
Gdx.graphics.setFullscreenMode(modes[0])
}
....
}
To summarize i get the list of modes, i pull from preferences what was set last, and i filter the list according to what was in preferences. This should leave one item left in the list and i apply it. If for some reason the list is empty, then i don't set it, or there is no preference set i just apply the current mode again.
This is where the weird stuff happens. I have checked all the numbers when creating my screens and cameras, and they are all correct. I do receive the correct resolution, but the application doesn't render correctly. Below are a couple examples of what happens.
In the first image you see the bounds of the application to the screen. My application only renders in the bottom corner, and the rest is black. What happened to achieve this effect is i started the application with a smaller resolution than my native resolution, so 1280x1024, then in my create method i set the application full screen mode to 1920x1080 before building the rest of my application. I have checked my cameras and my viewports, and they all have the resolution 1920x1080, but the image is not filling the entire screen.
And a second.
This one is what happens when i reverse the settings. So i start at native resolution 1920x1080, and in my create method i set it to 1280x1024, again before creating the rest of my application. This gives me black bars on both sides of the image like id expect, but the application is HUGE, and only a portion of it fits in the window, the rest goes out of bounds, as depicted by the dotted lines.
It will remain like this the entire time, unless i change the resolution while the application is running, it will then correct itself for the rest of the applications life.
I am confounded by this effect i am getting, and am looking for an answer as to why, or how to fix it.
I found the issue that was causing the image to render incorrectly. I was setting the display mode in the create() function in my main game class. This function is not run on the rendering thread, and you do not want to use Gdx.graphics on anything other than the rendering thread, as described in the libgdx wiki https://github.com/libgdx/libgdx/wiki/Threading
There is a function where you can pass in a lambda to be run on the rendering thread.
Gdx.app.postRunnable {
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode(modes[0]))
}
After passing that into postRunnable the game renders correctly on launch.

StageWebView Flash's White when Displayed

StageWebView Flash's White when Displayed
So I've been working on a project using Adobe Animate to create a universal Air application that can be ported to multiple platforms i.e. Mac, Windows, and iOS.
It uses StageWebView to display videos embedded on HTML pages that have their own custom html5 video player and everything works well except for one simple but annoying thing.
Whenever I display a Stage Web View you'll see a flash of white before the page displays.
Now I originally thought this was an issue with checking for a URL load completion or a poorly formatted HTML document but that doesn't seem to be the case.
What I did notice after several attempts of trying to remove the issue is that it did go away if I used the embedded Air WebKit opposed to using the native WebKit from the desktop device.
(Code Below) Causes white flash on load:
var webView:StageWebView = new StageWebView(true);
(Code Below) This gets rid of the issue but my HTML tags like video and progress are not supported by the embedded WebKit and no longer function properly.
var webView:StageWebView = new StageWebView();
Information from about the setting from Adobe:
useNative:Boolean (default = false) — When useNative is false, a version of WebKit embedded within AIR is used as the source of the
StageWebView created. When useNative is true, then AIR will use the
the system's default web engine. Mobile platforms only support using
the system web engine, so useNative is ignored on mobile platforms.
The frustrating thing is that I've set a listener to check for load completion and that doesn't get rid of the issue. So as a workaround I've hidden the displayed StageWebView off the screen and then moved it's location to where I want it to be after a delay which is not great.
Other attempts to display it small as a pixel resize it in place cause the issue still.
/* Check for Stage Web View Errors */
webView.addEventListener(ErrorEvent.ERROR, onError);
function onError(e:ErrorEvent):void {
trace("Stage Web View error: " + e);
}
/* Function to not show Stage Web View until loaded. */
function onCompleteHandler(e:Event):void {
webView.assignFocus();
// Delay the Stage Web View to fix white flash issue.
setTimeout(callWebView,500);
webView.removeEventListener(Event.COMPLETE,onCompleteHandler);
}
/* Multi-Function Stage Web View Loader, Just add file path string to call */
function webviewFilePath(path:String):void {
webView.stage = this.stage;
// Prep filepath
filePath = new File(new File(path).nativePath).url;
// Load file path
webView.loadURL(filePath);
// Add listener for Complete URL Load then Show
webView.addEventListener(Event.COMPLETE,onCompleteHandler);
}
/* Function to call Stage Web View independantly so it can be delayed with a timer */
function callWebView() {
webView.viewPort = new Rectangle(posX(viewX), posY(viewY), viewWidth, viewHeight);
}
Any hints or tips on how I can alleviate or fix the issue would be great.
Of course if Adobe just actually updated the embedded Air WebKit that would probably fix the whole issue in the first place but I doubt that's happening anytime soon.
Partial Fix
So the issue still exists when I initially load up the Stage Web View but I've managed to minimize its appearance during app use.
One major part of the issue was how I reset the StageWebView in preparation for a new page I wanted to load or when I wanted to close the view.
I went a little overboard on resetting StageWebView because audio in StageWebView has been known to continue playing even when it's hidden.
/* Function to Reset Stage Web View */
function resetWebView():void {
webView.loadString("<!DOCTYPE HTML><html><body></body></html>");
//webView.viewPort = new Rectangle(0, 0, 0, 0);
webView.stage = null;
//webView.viewPort = null;
}
I realized I could just simply hide the StageWebView and load up a blank page while it was hidden from view to stop any audio playing. That was easy enough to accomplish with a simple string loaded into it.
Although from time to time I'll still see that white flash it's occurrence is minimal.
private var webView : StageWebView;
webView = new StageWebView( true );
webView.stage = this.stage;
webView.viewPort = new Rectangle( 0, 0, 1024, 768 );

AS3 Camera input gets distorted when exported to AIR

I've built an AIR application with flash/as3 that has a webcam display on the stage. While building the app, and in all my tests everything looks and works just dandy, but when I publish for AIR the image gets stretched. The bounds of the image seem to stay the same, but the actual cam output is what's distorted. Has anyone come into this problem before?
I should add, this is a desktop app, which is permanently installed on one machine, so device compatibility should not be an issue.
this is the camera setup:
var cam:Camera = Camera.getCamera();
cam.setMode(280,380,20);
var video:Video = new Video(380,380);
this is where i first call the camera...
video.attachCamera(cam);
video.x = 355;
video.scaleX = -1;
video.y = -100;
addChildAt(video, 0);
the reason for the odd sizing, is that it sits behind a frame, that changes positions throughout the interactive.
Not necessarily the answer you are looking for, but you should keep this in mind:
You are asking the camera to capture at the resolution of 280 x 380, which is not a standard 4:3 aspect ratio.
When you call cam.setMode(280,380,20); the docs say that Flash will try to set the cameras resolution to your specifications, and if the camera does not support that resolution it will try to find one that matches. So you may or may not be getting this actual resolution.
setMode() has a fourth parameter, which can disable this functionality. Read the docs on that so you understand the implications :)
Then you display the video in a Video object that is 380x380. So I would expect the image to be stretched in the horizontal direction (b/c the original source is only 280).
It's not clear why this behaves differently: are you saying that running the debug version of the app works, but when you export the release build and run that it looks funky?
Finally, what is scaleX = -1 doing? I recall this as some sort of nifty trick I used in the past... but it's purpose here is escaping me :)
Yep, source code would be cool. Btw, i suggest you, as soon as you get the video streaming running, to set by hand the video.width and video.height property.
This will force the cam to display at the correct size.

AS3 - iOS force landscape mode only?

I've built a game for iOS that is designed for landscape mode and it works just fine except that if you turn the device to portrait mode it stops there to with the interface only filling about the middle half of the screen. How can I force the app to only allow the two landscape modes and not stop at the portrait position.
I've tried all the publishing settings. Aspect Ratio is set for Landscape and Auto Orientation is checked on, if I uncheck AUto Orientation that the app does not rotate to the other landscape mode and I hear that's an automatic rejection from Apple.
This app is ready to go except for this little flaw. Thanks for any help you can offer.
Rich
I found the answer to this over on the Adobe forums a few days ago.
Set Aspect Ratio to Auto.
Set Auto Orientation to allowed.
Then use this code on your main clip:
var startOrientation:String = stage.orientation;
if (startOrientation == StageOrientation.DEFAULT || startOrientation == StageOrientation.UPSIDE_DOWN)
{
stage.setOrientation(StageOrientation.ROTATED_RIGHT);
}
else
{
stage.setOrientation(startOrientation);
}
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChangeListener);
function orientationChangeListener(e:StageOrientationEvent)
{
if (e.afterOrientation == StageOrientation.DEFAULT || e.afterOrientation == StageOrientation.UPSIDE_DOWN)
{
e.preventDefault();
}
}
Worked fine for me..
Another, albeit similar, way to do this is to set the aspectRatio to landscape in the application descriptor and autoOrients to false. Then enable autoOrients once the application has loaded and listen for the orientationChanging event. In Flash Builder 4.6, this may be done as follows:
Descriptor:
<aspectRatio>landscape</aspectRatio>
<autoOrients>false</autoOrients>
Application code:
private function applicationCompleteHandler():void {
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, stageOrientationChangingHandler);
stage.autoOrients = true;
}
private function stageOrientationChangingHandler(event:StageOrientationEvent):void {
if (event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN) {
event.preventDefault();
}
}
It looks like you also have to make sure that the application has explicit dimensions; otherwise, views may still be resized even through the stage does not reorient.
Please see:
http://bugs.adobe.com/jira/browse/SDK-32082
The answer above did not work for me, because on iOS the preventDefault no longer works.
For anyone who just still isn't having good luck... Here's what I did.
I wanted:
Ipad & All Android Tablet devices to be able to Portrait or Landscape and auto-rotate in any direction
Iphones, Ipods, & All Small Screen Devices to be forced Landscape (or maybe in your case you want forced portrait).
I Did:
IN my -app.xml:
<aspectRatio>any</aspectRatio>
<autoOrients>true</autoOrients>
In Actionscript:
var screenDPI:Number = Capabilities.screenDPI;
var resolutionX:Number = Capabilities.screenResolutionX;
var resolutionY:Number = Capabilities.screenResolutionY;
var numDiagonalDistance:Number = Math.round(Math.sqrt((resolutionX*resolutionX)+(resolutionY*resolutionY)));
var numDiagonalInches:Number = numDiagonalDistance/screenDPI;
if(numDiagonalInches<6){
MainData.SMALL_DEVICE=true;
}else{
MainData.SMALL_DEVICE=false;
}
if(MainData.SMALL_DEVICE){
this.stage.setAspectRatio(StageAspectRatio.LANDSCAPE);
}
Though I guess you could easily put StageAspectRatio.PORTRAIT or even use the reverse logic to logic ipads only or something. Good Luck!
EDITED: I'm actually editing this because even this method still has problems. You'll get landscape but its not always the landscape oriented to how you're holding the device...
EDITED AGAIN (2-27-2014): Turns out if I included -swf-version 23 (now with AIR 4.0) this problem is finally solved.