-
-
Notifications
You must be signed in to change notification settings - Fork 937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add a method to adapt the camera bounds to the world #2769
Conversation
@spydon I see, but calculating the |
Maybe:
|
Okay, I've made the changes you've suggested : if (considerViewport && bounds != null) {
final halfViewportSize = viewport.size / 2;
bounds = Rectangle.fromCenter(
center: bounds.center,
size: Vector2(bounds.support(Vector2(1, 0)), bounds.support(Vector2(0, 1))) - halfViewportSize,
);
} One drawback is that the |
Much better! Except that it doesn't compile. 😅 |
Yep, it still wip. More commits to follow 🙂 |
This method allows to support various other viewport shapes.
Alright, so I've added the following method : Shape? _calculateViewportAwareBounds(Shape originalBounds) {
final worldSize = Vector2(
originalBounds.support(Vector2(1, 0)).x,
originalBounds.support(Vector2(0, 1)).y,
);
final halfViewportSize = viewport.size / 2;
if (originalBounds is Rectangle) {
return Rectangle.fromCenter(
center: originalBounds.center,
size: worldSize - halfViewportSize,
);
} else if (originalBounds is RoundedRectangle) {
final halfSize = (worldSize - halfViewportSize) / 2;
return RoundedRectangle.fromPoints(
originalBounds.center - halfSize,
originalBounds.center + halfSize,
originalBounds.radius,
);
} else if (originalBounds is Circle) {
return Circle(
originalBounds.center,
worldSize.x - max(halfViewportSize.x, halfViewportSize.y),
);
}
return null;
} Which is being used in if (considerViewport && bounds != null) {
bounds = _calculateViewportAwareBounds(bounds) ?? bounds;
} Tell me what you think about it 🙂 |
Looks good! I think we need to take the zoom into consideration too though, because this doesn't work when the zoom level is changed right? |
Let's do that ! |
@spydon Just checked the source code and it seems that |
The |
Alright. Maybe the best approach is to add a new behavior to the viewfinder so that it can update the bounds based on the visible rectangle. That's what I did in the latest commit. I haven't implemented the "update" part, but can you tell me what you think about it please ? |
… visible world rectangle has changed.
The idea is good, but the |
Yes, I was thinking about that. The thing is, from what I know, these transforms don't have any method that allow to register a listener. I'll see what's the best approach. |
The |
Yes, what I mean is I didn't know that the |
…to be listened by `ViewportAwareBoundsBehavior`.
Okay, the problem with listening for owner.position = delta..add(owner.position); triggers an update at every tick. |
|
Oh yes, sure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting to look good!
Just some tests missing, the easiest would be to do golden tests for this I think, you can get some inspiration from here for example:
https://github.com/flame-engine/flame/blob/main/packages/flame/test/camera/viewports/fixed_aspect_ratio_viewport_test.dart
packages/flame/lib/src/camera/behaviors/viewport_aware_bounds_behavior.dart
Outdated
Show resolved
Hide resolved
packages/flame/lib/src/camera/behaviors/viewport_aware_bounds_behavior.dart
Outdated
Show resolved
Hide resolved
Any updates on this @Skyost? :) |
Hey @spydon, Sorry, I've never written any golden test in my life and have been unactive for the past two weeks. I'll try to make some progress today 🙂 |
I've added a test that checks whether the viewport has been correctly updated. It's not a golden test, but I think it does the trick. Do you think it needs more tests ? If so, what parts of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm, the test doesn't really ensure things are rendered correctly, but since the other camera behaviour doesn't have a goldens test either I think we can let this pass for now.
packages/flame/test/camera/behaviors/viewport_aware_bounds_behavior_test.dart
Outdated
Show resolved
Hide resolved
# Description The behavior for `CameraComponent.setBounds` was not behaving correctly. The viewport-aware behavior was not triggering until a window resize event. All supported bound variants were not respecting the fixed resolution viewport, or in some cases, behaving unpredictably. The issue was with the fact the viewport-aware behavior component depends on the bounded position component to be in its parent, but was returning `null` during `onMount`. The viewport math was using the logical size instead of the virtual size. I made some math changes to be accurate. This PR adds new a getter `CameraComponent.considerViewport`. `ViewportAwareBoundsBehavior` is now added as a side effect of mounting `BoundedPositionBehavior` by waiting for the `mounted` future. This guarantees that Flames life cycle is respected and the components behave as expected. Tests pass on my own local project. Videos are linked on the discord thread [here](https://discord.com/channels/509714518008528896/1275814019235709003/1275888732481785925). Melos dry run completed successfully. ## Checklist - [x] I have followed the [Contributor Guide] when preparing my PR. - [x] I have updated/added tests for ALL new/updated/fixed functionality. - [x] I have updated/added relevant documentation in `docs` and added dartdoc comments with `///`. - [ ] I have updated/added relevant examples in `examples` or `docs`. ## Breaking Change? - [ ] Yes, this PR is a breaking change. - [x] No, this PR is not a breaking change. ### Migration instructions No work to be done. ## Related Issues #2769 ## QUESTIONS FOR THE DEVS So I'm not satisfied with the fixes for `Circle` bounds. The bounds uses the maxima of the viewport, and yes, creates a circle that stays within the size of the bounds circle, but I'd expect that `Circle` bounds should keep my viewport _inside_ the circle as it is documented to stay _inside_ the desired bounds shape. Therefore, I think `Circle` case should have 4 incident points to fit the viewport. That is to say, the viewport is not the maxima of the newly calculated `Circle`, but will be fully contained by this new `Circle`. This way, you'll never see outside of the bounds as it, seems to me anyway, implies. However I do not know if this is intuitive for others and expected behavior. Thoughts?
# Description The behavior for `CameraComponent.setBounds` was not behaving correctly. The viewport-aware behavior was not triggering until a window resize event. All supported bound variants were not respecting the fixed resolution viewport, or in some cases, behaving unpredictably. The issue was with the fact the viewport-aware behavior component depends on the bounded position component to be in its parent, but was returning `null` during `onMount`. The viewport math was using the logical size instead of the virtual size. I made some math changes to be accurate. This PR adds new a getter `CameraComponent.considerViewport`. `ViewportAwareBoundsBehavior` is now added as a side effect of mounting `BoundedPositionBehavior` by waiting for the `mounted` future. This guarantees that Flames life cycle is respected and the components behave as expected. Tests pass on my own local project. Videos are linked on the discord thread [here](https://discord.com/channels/509714518008528896/1275814019235709003/1275888732481785925). Melos dry run completed successfully. ## Checklist - [x] I have followed the [Contributor Guide] when preparing my PR. - [x] I have updated/added tests for ALL new/updated/fixed functionality. - [x] I have updated/added relevant documentation in `docs` and added dartdoc comments with `///`. - [ ] I have updated/added relevant examples in `examples` or `docs`. ## Breaking Change? - [ ] Yes, this PR is a breaking change. - [x] No, this PR is not a breaking change. ### Migration instructions No work to be done. ## Related Issues #2769 ## QUESTIONS FOR THE DEVS So I'm not satisfied with the fixes for `Circle` bounds. The bounds uses the maxima of the viewport, and yes, creates a circle that stays within the size of the bounds circle, but I'd expect that `Circle` bounds should keep my viewport _inside_ the circle as it is documented to stay _inside_ the desired bounds shape. Therefore, I think `Circle` case should have 4 incident points to fit the viewport. That is to say, the viewport is not the maxima of the newly calculated `Circle`, but will be fully contained by this new `Circle`. This way, you'll never see outside of the bounds as it, seems to me anyway, implies. However I do not know if this is intuitive for others and expected behavior. Thoughts?
Description
This PR adds a method to the
CameraComponent
class that allows it to set its bounds according to the current world. In fact, this was the behavior of the old camera object.Checklist
docs
and added dartdoc comments with///
.examples
ordocs
.Breaking Change?
Related Issues
Closes #2601.