Closed Yayo-Arellano closed 1 year ago
I'd say the behaviour you are seeing is the correct one. The old camera system didn't really made any distinction between Viewport
and Viewfinder
, which has given a lot of the devs wrong idea about Viewport
.
CameraComponent.withFixedResolution
does not promise that the Viewport
will be of constant size. Instead, it just makes sure that only the visibleGameSize
world is rendered through the viewport. And to achieve this, the Vewfinder
has to zoom in on the game world. Hope that explains why manually changing the zoom does not seem to be working. By setting a visibleGameSize
on Viewfinder
, you are essentially giving up the control over zoom.
If you really want the Viewport
to be constant, you should use the FixedSizeViewport
.
The behavior of CameraComponent.withFixedResolution
is correct and works as expected, but neither FixedSizeViewport
nor CameraComponent.withFixedResolutionis
are a good replacement for FixedResolutionViewport
because if the screen is too small, there is a chance that the viewport is cut off, or I cannot use the zoom, etc.
The advantage of FixedResolutionViewport
is it allows us to work with virtual screen size while keeping the aspect ratio. What I mean is that we can always assume the viewport size is virtualWidth x virtualHeight
, and if the screen is too small it will add black bars to the top or bottom to keep the aspect ratio, and also I can apply zoom if needed.
Please look the following GIF. You can see that resizing the screen will keep the aspect ratio and will now cut off instead will add bars. From the GIF you ES: effectiveSize
& GS: gameSize
If I'm not wrong, that virtualWidth x virtualHeight
will be visibleGameSize
when using .withFixedResolution
.
Is it possible for you to share a side by side comparison of the new and old system? I feel it should be possible to achieve the same behaviour with new APIs as well. But if it is not, we definitely need to fix something in Flame then.
I can share the side-by-side comparison later. To summarize the differences.
In the new API virtualWidth x virtualHeight
will be visibleGameSize
when using .withFixedResolution
is correct. But only when adding components to the world. Like world. add(MyComponent()
But if I want to add UI elements to the viewport, for example, camera.viewport.add(FpsTextComponent(position: Vector2(0, 720)));
then the component will not stay in the fixed position because the viewport does not have virtual size, instead, it will change size (while keeping the aspect ratio) and the components may get out of the screen.
The behavior of the old FixedResolutionViewport
is exactly the same as the one from LibGDX FitViewport
But if I want to add UI elements to the viewport, for example,
camera.viewport.add(FpsTextComponent(position: Vector2(0, 720)));
then the component will not stay in the fixed position because the viewport does not have virtual size, instead, it will change size (while keeping the aspect ratio) and the components may get out of the screen.
I think you are confusing Viewfinder and Viewport 😅. If your game has a FixedAspectRatioViewport
and you resize the window, the size of viewport is expected to change. Remember, viewport is just the area of your application window where the game will get rendered. To get the behaviour that you want for the UI components, you need to add them to the Viewfinder
, because that is the component that is ensuring the fixed resolution (the virtualWidth x virtualHeight
).
I created two videos. Please take a look.
The first one is using the legacy camera with FixedAspectRatioViewport
. All the UI HUD elements are of type PositionType.viewport
. You can see the HUI items are fixed to the screen and do not change the size when I increase or decrease the zoom.
The second one is using CameraComponent.withFixedResolution
all the UI HUD elements (except the black background) are added to the viewfinder like camera.viewfinder.add(fps)
the game componens are added to the world like `world.add(gameComponent).
Some differences with the new camera:
camera.follow()
Zoom
does not work. The workaround was to do camera.viewfinder.visibleGameSize = virtualSize * scale
Google Drive Folder with videos
Basically, what I was able to achieve with the legacy FixedResolutionViewport
:
100
will affect the game, not the viewport. So the game size will become 1.28 x 7.20
the viewport still keep the original size.
- The HUD items are not fixed to the screen when using
camera.follow()
I wasn't aware of this. Its weird that the UI is not moving along with the camera in this case.
Zoom
does not work. The workaround was to docamera.viewfinder.visibleGameSize = virtualSize * scale
Yup, that is the only way to get zoom effect when using visibleGameSize
. In my case I try to apply a ScaleEffect to the viewfinder to make it zoom in/out.
- "zooming in/out" will also scale the UI HUD components.
True, it does scale with the new system. Not much useful for hud component.
Problem to solve
In the old camera API, we can use
FixedResolutionViewport
to set a virtual size.In the new camera API we can use
CameraComponent.withFixedResolution
that internally looks like:Using
CameraComponent.withFixedResolution
will not make the viewport to a fixed resolution. It partially works because thecamera.viewfinder.visibleWorldRect
will always be fixed to the givenwidth
andheight
butcamera.viewport.size
is not fixed and, also,zoom
is not working at all.When using
Forge2D
in the old API I can have a viewport withFixedResolutionViewport(Vector2(1280, 720))
. I can add all the UI components to this viewport usingPositionType.viewport
.For the Forge2D components, I will set a
zoom
of100
to scale the world to a resolution of12.8 * 7.2
to overcome Box2D speed and size limitations, and I can add all these components using the scaled values.Here is a git repository with an example of how I use the old
FixedResolutionViewPort
https://github.com/Yayo-Arellano/flutter_games_compilation/blob/main/flutter_learn_flame/lib/my_game.dart#L31