I have made my game, which scaled accordingly to a % of the screen width with the Gdx.graphics.getWidth() method, and it works perfectly on all screens.
Now I am trying to learn viewports, but seems like there is a lot more trouble, like when does it take in world coordinated or when does it take actual screen pixels.
Do I have to constantly convert beetwen these two measurments? It seems like there is alot more trouble, than if I just scale it the old fasion way...
I can use the whole screen, and manually make the pictures non streched, if I used a FitViewport I would have like blackbars and the game would be totally different.
Any clear suggestions to why to use these ports, cause I cannot seem to understand them...
The thing is that you do not have to do anything especially making any conversion.
Viewport is a kind of tool that handling your app's rendering on many types of screens (I mean many other ratios) and you do not have to worry about it anymore.
Only thing you have to do is to "tell" viewport what is the size of your screen and to handle screen resizing by updateing the viewport. Then you are treating your app like it would be always for example 800 x 600px no matter how it looks actually.
The way your app will render depends on what viewport implementation you will use. For example:
FitViewport will fit your screen to device and add some black bars
FillViewport will fit your screen to device and cut off overflowing part
and so on...
The a look at official Viewport libGDX tutorial. Also you can take a look at this thread to get some information how to deal with viewports.
Related
I have few scenes in my project. I was able to center all of the other scenes. But i cannot center the main scene in my project. Its fine when it opened on a mobile device(probably because resolution matches i guess). but when i opened it in tablet(its an old tab "xiaomi tab 3") its always align to the right on the screen. I was able to center other scenes but i cant center the main scene to screen for some reason. project setting set as 2D and Expand. I also tried to use Control nod, canves layers, margine containers.. but nothing works. If someone can give any suggestions, Thank you in advance.
img1
https://i.stack.imgur.com/FJOHl.jpg
project
1920 x 1080
I have seen this problem, or similar, in windowed mode. I don't know if this is the exact case, but if it doesn't mess with your project, try full-screen mode.
If it's that, you can also take care of the window bar size (which is a problem because it can change from different devices), since godot will count its pixels too.
Notice that you're only having this problem in one axis.
Also, I think you could take a look into the Viewport Stretch Mode. It could mess your graphics depending of the intended result—but other projects won't even notice, so judge for yourself.
The viewport setting sets the root scene’s Viewport to the base resolution. The rendered output of the root Viewport is then scaled to the display resolution. [...]
The viewport setting is a better choice than the 2d setting when pixel-perfect precision is required, since primary rendering still occurs at the base resolution.
Support multiple devices
Scaling correctly for all devices could be an odyssey, so bon voyage.
I still have trouble understanding the possibilities of Scaling my UI in a responsive way in my Air Mobile App. On the web I'm familiar with it and the use of media-queries.
I dont want to scale my whole UI up and down or even stretch it (e.g: I use the camera in one DisplayObjectContainer, so this would be really bad for the performance to scale this.)
I currently go down the road defining all the container sizes by percent, but that is getting pretty ugly pretty fast as it leaves me with 68.95px values. I think this will get me in trouble one day as blocks appear not crisp anymore. If I round the values, I might have 1px gaps between Elements.
Currently I have this Setup. The idea is, to give every main Component a (maybe invisible) empty background-child. These can then deformed by width & height by any desire. The inner Elements of any Element (button, logo, etc) are not affected by the deformation of the bg and can then be arranged accordingly (as I now have position and size of this container - like in css).
But this does not feel like it is the right way.
Is there a magic lib/class I dont use currently and that allowes me to build in hard pixel for a defined setup and behaves appropriate when it comes to different stageWidths, DPI, etc?
What are your approaches for this problem?
I'm creating an iOs APP in adobe flash cs6 and everything works fine.
however the issue that I have now is the content of the app gets stretched in bigger iPhones like iPhone 5!
I am using the following code in my AS3 code on the first frame of the first layer:
import flash.display.Sprite;
import flash.display.Screen;
import flash.geom.Rectangle;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.system.Capabilities;
import flash.display.MovieClip;
import flash.display.*;
import flash.events.*;
import flash.geom.*;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.scaleMode = StageScaleMode.NO_BORDER;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.EXACT_FIT;
I am using the code above so the entire APP will fit every screen and it works fine but everything (the content of the APP) gets stretched!
is there anything i can do to keep the aspect ratio of the content while fitting the APP to every screen like my code above?
Thanks in advance
EDIT:
I've removed the stage.scaleMode = StageScaleMode.EXACT_FIT; and when i viewed the APP in the iphone, it doesn't get stretched BUT everything's slightly gone to the right which result in hiding the small part of the APP on the right side of the screen!
Despite Daniel is right, a more detailed answer is needed.
The truth is that this is a bit more sophisticated than you think. There is no way that Flash knows how to position your elements - sometimes you would like your button to stretch, but not that much. Or to keep it's aspect ratio, but then some of the content will fall out.
How it's usually done? The best practices in this field is to have a fixed stage viewport (initial stage size). Usually this is fixed at 320x480. Then, you let your app stretch this (if you run a bigger screen, your 320 pixels would be awfully scaled, and so pixelized).
Here comes the tricky part - depending on device resolution and dpi, you provide specific assets. Let's say you run your app on device that is twice your 'initial fixed viewport'. Then everything will seems zoomed twice (640x960 is twice 320x480). Everything is in pixels.
But here you provide graphics that are also twice as big - 640x960. This means that if you run them on the basic stage, they will be downsized - becoming 320x480. But if you run them on a bigger screen, the stage gets zoomed in (as talked before), and the graphics now become their actual size.
Imagine that each phone has the same display size (let's say 4 inches). But every one has different resolution - 320x840, 640x960, 720x1280, and so on. So if you want your app to look exactly the same, having a button that is 100% wide - then provide a graphic for it that is 100% of the resolution! So your graphic should come in different sized for each display - 320px, 640px, etc.
Of course you cannot match all the devices. So here comes 'aspect ration' - a number that indicates how much the screen is bigger. If your base is 320x480, and you run on 640x960, your aspect ratio would be 2. So you get your assets from folder 'assetsx2' (or whatever you call it, as long as you got some system to read it). If you run on different display and the ration gets for example 2.8, you would round it to 3. This way images would get a little scaled, but scaling 3 to 2.8 is better than scaling 3 to 1, right? The more you scale, the blurry it gets.
I'm sorry for the long answer, but I tried to explain it not very technical. There are great articles about that. These two resources helped me the most when I started:
http://sebastien-gabriel.com/designers-guide-to-dpi/home - info what's going on
http://screensiz.es/phone - info about different devices, their size, resolution, aspect ratio, and info about how your folder should be named (there are conventions).
Hope that helps! :)
p.s.
Forgot to add that this is all about graphics, having in mind that you build an UI maybe, so you use graphics. Despite that, the whole idea works no matter what kind of graphics you use - you just need to work with fixed size stage, position everything according to it, and then think of the scale factor. So for having a 100% wide button on 640px wide screen, instead of making it 620px wide with 10px margins on each side, you make it 310px with 5 px margin on each side.
no.
There's no way to magically deal with this. You have to tell it how to arrange the content.
I'm making an app (a game, to be exact) where each activity uses a SurfaceView for the UI. All of the drawing is done through onDraw. I am also designing this to use no Bitmap assets, so everything that is drawn is produced directly by the app. I'm trying to design the app in such a way that it can easily be viewed on any screen size.
So here's how I'm accomplishing this: I'm doing my testing on a Galaxy S4, which has a screen size of 1080x1920. In the constructor for each activity, the width and height of the current screen are calculated and stored as ints "w" and "h" (the app is already locked in portrait). Then, whenever anything needs to be drawn onto the screen, I multiply the desired dimension (as seen on my 1080x1920 screen) by either w or h, and then divide by 1080 or 1920. Since I'm not using any Bitmap assets, I never need to worry about pixelated images or anything this way.
This gets the job done, but seems like a bit of a roundabout way of doing it. I figured there would be a better framework for getting this done, and I'm worried that these big calculations are eating into my drawing time (running at 30FPS can get a little jerky).
Is this is the customary way of doing it, or is there a better way out there?
There's a very simple yet effective way to do it, you can declare all your sizes in a dimen file for each specific density/size, as you usually do for layouts e.g:
values/dimens.xml <--- With default sizes
values-sw600dp/dimens.xml <-- Tablets sizes
(etc...)
Now before you start drawing, load all the values in your program only once, maybe onCreate of your drawing activity, using the following command:
float someItemSize = Context.getResources().getDimension(R.dimen.some_itemSize)
etc...
That way, you let the operating system do the pixels conversion for you, you should do it only once and most important, this will give alot of flexibility to your code because you will be able to change sizes from xml files without even touching your actual code, hence, the customization should be easier as well as future changes...
Hope it helps!
Regards!
There are two considerations: screen size and screen aspect ratio. If you simply scale everything to match the display, you will appear stretched a bit if you put a 4:3 device next to a 16:9 device.
You generally have two options for dealing with the aspect ratio: you can letterbox / pillarbox the output (which is fine for movies, but looks kinda lame for an app), or you can recognize that your output isn't always proportionately the same, and adjust the layout to fit nicely on the screen.
As far as size matching goes, when using a SurfaceView you can actually use a single size and then let the hardware scaler handle the rest. For an example of this, see the "Hardware scaler exerciser" in Grafika. I put a demo video here, though it's a bit hard to evaluate after getting rinsed through screenrecord + youtube. What you're seeing is the same couple of shapes rendered onto a Surface whose size has been set to an arbitrary value, and then scaled up to match the display. This is most obvious on the final setting, where it's drawing on a 106x64 surface.
With this, you could size your assets for 720p and always draw them the same way, and let the scaler deal with the stretching. See also this blog post.
In my Flash AS3 app, I am using
stage.scaleMode = StageScaleMode.SHOW_ALL;
because graphically I want it to be workable out-of-the-box in all kinds of different mobile devices. It works a treat because it does a "best-fit" to the device's screen and simply "adds" black borders around it.
For example, in 4:3 screens it fills the whole screen nicely:
while in 16:9 screens I get black borders on the left and right:
Now here is the problem: when I am moving a display object "off-screen", I don't want it to be rendered inside those black borders.
The question is this: what is the fastest way to "clip" my app - considering I am targeting mobile devices? I have a feeling that a
stage.scrollRect
will blow things up performance-wise...
EDIT : I am using <renderMode>gpu</renderMode>
scrollRect is actually great and even makes your application perform better, unless you're using GPU composition (in which case it really degrades performance). So I'd suggest you trying it first.
But a good alternative solution (as crazy as it sounds) is to just have a huge rectangle with a hole on it on top of everything, as the last children of your stage. So suppose your stage is 640x480. You'd have a black rectangle on top of everything with dimensions of, say, 1640x1480, and with a hole of 640x480 pixels inside of it to let your content be visible. It's a cheap way to mimic a mask without forcing recomposition of the pixels inside that area.