mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-02 03:15:43 +08:00
Rename isHud to respectCamera (#1159)
* Camera as an internal component * Correct respectCamera * Added changelog entry * Add super call that will later be removed * Rename callRender -> callOwnRender * Don't call render when root * Remove callOwnRender * Skip CameraWrapper in own renderTree * Too complex to have camera as component * Revert test * Update docs for respectCamera * Move down field * Fix changelog
This commit is contained in:
@ -24,8 +24,9 @@ component before the next update loop. It will then no longer be rendered or upd
|
||||
`game.remove(Component c)` and `component.removeFromParent()` also can be used to remove components
|
||||
from its parent.
|
||||
|
||||
The `isHUD` variable can be overridden or set to true (defaults to `false`) to make the `FlameGame`
|
||||
ignore the `camera` for this element, making it static in relation to the screen that is.
|
||||
The `respectCamera` variable can be overridden or set to `false` (defaults to `true`) to make the
|
||||
`FlameGame` ignore the `camera` for this component, making it static in relation to the viewport
|
||||
that is.
|
||||
Do note that this currently only works if the component is added directly to the root `FlameGame`.
|
||||
|
||||
The `onRemove` method can be overridden to run code before the component is removed from the game,
|
||||
|
||||
@ -111,7 +111,7 @@ you handle this through the `button` component.
|
||||
|
||||
As the name suggests this button is a hud by default, which means that it will be static on your
|
||||
screen even if the camera for the game moves around. You can also use this component as a non-hud by
|
||||
setting `hudButtonComponent.isHud = false;`.
|
||||
setting `hudButtonComponent.respectCamera = true;`.
|
||||
|
||||
If you want to act upon the button being pressed (which would be the common thing to do) you can either pass in
|
||||
a callback function as the `onPressed` argument, or you extend the component and override
|
||||
|
||||
@ -163,11 +163,11 @@ class JoystickAdvancedExample extends FlameGame
|
||||
speedText = TextComponent(
|
||||
text: 'Speed: 0',
|
||||
textRenderer: _regular,
|
||||
)..isHud = true;
|
||||
)..respectCamera = false;
|
||||
directionText = TextComponent(
|
||||
text: 'Direction: idle',
|
||||
textRenderer: _regular,
|
||||
)..isHud = true;
|
||||
)..respectCamera = false;
|
||||
|
||||
final speedWithMargin = HudMarginComponent(
|
||||
margin: const EdgeInsets.only(
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
- Export new effects system
|
||||
- Introduce `updateTree` to follow the `renderTree` convention
|
||||
- Fix `Parallax.load` with different loading times
|
||||
- `isHud` renamed to `respectCamera`
|
||||
|
||||
## [1.0.0-releasecandidate.18]
|
||||
- Forcing portrait and landscape mode is now supported on web
|
||||
|
||||
@ -18,11 +18,15 @@ import 'cache/value_cache.dart';
|
||||
/// called automatically once the component is added to the component tree in
|
||||
/// your game (with `game.add`).
|
||||
class Component with Loadable {
|
||||
/// Whether this component is a HUD (Heads-up display) object or not.
|
||||
/// Whether this component should respect the camera or not.
|
||||
///
|
||||
/// HUD objects ignore the FlameGame.camera when rendered (so their position
|
||||
/// coordinates are considered relative to the device screen).
|
||||
bool isHud = false;
|
||||
/// Components that have this property set to false will ignore the
|
||||
/// `FlameGame.camera` when rendered (so their position coordinates are
|
||||
/// considered relative only to the viewport instead).
|
||||
///
|
||||
/// Do note that this currently only works if the component is added directly
|
||||
/// to the root `FlameGame`.
|
||||
bool respectCamera = true;
|
||||
|
||||
/// Whether this component has been prepared and is ready to be added to the
|
||||
/// game loop.
|
||||
@ -153,7 +157,9 @@ class Component with Loadable {
|
||||
|
||||
@protected
|
||||
Vector2 eventPosition(PositionInfo info) {
|
||||
return isHud ? info.eventPosition.viewportOnly : info.eventPosition.game;
|
||||
return respectCamera
|
||||
? info.eventPosition.game
|
||||
: info.eventPosition.viewportOnly;
|
||||
}
|
||||
|
||||
/// Remove the component from its parent in the next tick.
|
||||
|
||||
@ -18,7 +18,7 @@ import '../../../game.dart';
|
||||
class HudMarginComponent<T extends FlameGame> extends PositionComponent
|
||||
with HasGameRef<T> {
|
||||
@override
|
||||
bool isHud = true;
|
||||
bool respectCamera = false;
|
||||
|
||||
/// Instead of setting a position of the [HudMarginComponent] a margin
|
||||
/// from the edges of the viewport can be used instead.
|
||||
|
||||
@ -38,7 +38,7 @@ import '../projector.dart';
|
||||
///
|
||||
/// Note: in the context of the FlameGame, the camera effectively translates
|
||||
/// the position where components are rendered with relation to the Viewport.
|
||||
/// Components marked as `isHud = true` are always rendered in screen
|
||||
/// Components marked as `respectCamera = false` are always rendered in screen
|
||||
/// coordinates, bypassing the camera altogether.
|
||||
class Camera extends Projector {
|
||||
Camera() : _viewport = DefaultViewport() {
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../../../components.dart';
|
||||
import 'camera.dart';
|
||||
|
||||
@ -7,6 +9,7 @@ import 'camera.dart';
|
||||
/// converted into a proper Component in a future release, but until then
|
||||
/// using it in any code other than the FlameGame class is unsafe and
|
||||
/// not recommended.
|
||||
@internal
|
||||
class CameraWrapper {
|
||||
// TODO(st-pasha): extend from Component
|
||||
CameraWrapper(this.camera, this.world);
|
||||
@ -19,16 +22,14 @@ class CameraWrapper {
|
||||
}
|
||||
|
||||
void render(Canvas canvas) {
|
||||
// TODO(st-pasha): it would be easier to keep the world and the
|
||||
// HUD as two separate component trees.
|
||||
camera.viewport.render(canvas, (_canvas) {
|
||||
var hasCamera = false; // so we don't apply unecessary transformations
|
||||
var hasCamera = false; // so we don't apply unnecessary transformations
|
||||
world.forEach((component) {
|
||||
if (!component.isHud && !hasCamera) {
|
||||
if (component.respectCamera && !hasCamera) {
|
||||
canvas.save();
|
||||
camera.apply(canvas);
|
||||
hasCamera = true;
|
||||
} else if (component.isHud && hasCamera) {
|
||||
} else if (!component.respectCamera && hasCamera) {
|
||||
canvas.restore();
|
||||
hasCamera = false;
|
||||
}
|
||||
|
||||
@ -21,13 +21,11 @@ class FlameGame extends Component with Game {
|
||||
_cameraWrapper = CameraWrapper(camera ?? Camera(), children);
|
||||
}
|
||||
|
||||
late final CameraWrapper _cameraWrapper;
|
||||
|
||||
/// The camera translates the coordinate space after the viewport is applied.
|
||||
Camera get camera => _cameraWrapper.camera;
|
||||
|
||||
// When the Game becomes a Component (#906), this could be added directly
|
||||
// into the component tree.
|
||||
late final CameraWrapper _cameraWrapper;
|
||||
|
||||
/// This is overwritten to consider the viewport transformation.
|
||||
///
|
||||
/// Which means that this is the logical size of the game screen area as
|
||||
@ -64,7 +62,17 @@ class FlameGame extends Component with Game {
|
||||
/// interfering with each others rendering.
|
||||
@override
|
||||
@mustCallSuper
|
||||
void render(Canvas canvas) => _cameraWrapper.render(canvas);
|
||||
void render(Canvas canvas) {
|
||||
if (parent == null) {
|
||||
renderTree(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void renderTree(Canvas canvas) {
|
||||
// Don't call super.renderTree, since the tree is rendered by the camera
|
||||
_cameraWrapper.render(canvas);
|
||||
}
|
||||
|
||||
/// This updates every component in the tree.
|
||||
///
|
||||
@ -75,10 +83,11 @@ class FlameGame extends Component with Game {
|
||||
@override
|
||||
@mustCallSuper
|
||||
void update(double dt) {
|
||||
super.update(dt);
|
||||
_cameraWrapper.update(dt);
|
||||
if (parent == null) {
|
||||
super.updateTree(dt, callOwnUpdate: false);
|
||||
}
|
||||
_cameraWrapper.update(dt);
|
||||
}
|
||||
|
||||
/// This passes the new size along to every component in the tree via their
|
||||
|
||||
@ -116,7 +116,7 @@ mixin Game on Loadable {
|
||||
onAttach();
|
||||
}
|
||||
|
||||
/// Called when the game has been attached. This can be overriden
|
||||
/// Called when the game has been attached. This can be overridden
|
||||
/// to add logic that requires the game to already be attached
|
||||
/// to the widget tree.
|
||||
void onAttach() {}
|
||||
@ -131,7 +131,7 @@ mixin Game on Loadable {
|
||||
}
|
||||
|
||||
/// Called after the game has left the widget tree.
|
||||
/// This can be overriden to add logic that requires the game
|
||||
/// This can be overridden to add logic that requires the game
|
||||
/// not be on the flutter widget tree anymore.
|
||||
void onDetach() {}
|
||||
|
||||
@ -157,12 +157,14 @@ mixin Game on Loadable {
|
||||
return _gameRenderBox!.localToGlobal(point.toOffset()).toVector2();
|
||||
}
|
||||
|
||||
/// This is the projector used by non-isHUD components.
|
||||
/// This can be overriden on your [Game] implementation.
|
||||
/// This is the projector used by all components that respect the camera
|
||||
/// (`respectCamera = true`).
|
||||
/// This can be overridden on your [Game] implementation.
|
||||
Projector projector = IdentityProjector();
|
||||
|
||||
/// This is the projector used by isHUD components.
|
||||
/// This can be overriden on your [Game] implementation.
|
||||
/// This is the projector used by components that don't respect the camera
|
||||
/// (`respectCamera = false`).
|
||||
/// This can be overridden on your [Game] implementation.
|
||||
Projector viewportProjector = IdentityProjector();
|
||||
|
||||
/// Utility method to load and cache the image for a sprite based on its
|
||||
|
||||
@ -11,9 +11,10 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
class _MyComponent extends Component {
|
||||
@override
|
||||
bool isHud;
|
||||
bool respectCamera;
|
||||
|
||||
_MyComponent(int priority, {this.isHud = false}) : super(priority: priority);
|
||||
_MyComponent(int priority, {this.respectCamera = true})
|
||||
: super(priority: priority);
|
||||
|
||||
@override
|
||||
void render(Canvas canvas) {
|
||||
@ -54,9 +55,9 @@ void main() {
|
||||
'only HUD components',
|
||||
(game) async {
|
||||
await game.ensureAddAll([
|
||||
_MyComponent(4, isHud: true),
|
||||
_MyComponent(1, isHud: true),
|
||||
_MyComponent(2, isHud: true),
|
||||
_MyComponent(4, respectCamera: false),
|
||||
_MyComponent(1, respectCamera: false),
|
||||
_MyComponent(2, respectCamera: false),
|
||||
]);
|
||||
final canvas = MockCanvas();
|
||||
game.camera.snapTo(Vector2(12.0, 18.0));
|
||||
@ -78,9 +79,9 @@ void main() {
|
||||
await game.ensureAddAll([
|
||||
_MyComponent(4),
|
||||
_MyComponent(1),
|
||||
_MyComponent(2, isHud: true),
|
||||
_MyComponent(5, isHud: true),
|
||||
_MyComponent(3, isHud: true),
|
||||
_MyComponent(2, respectCamera: false),
|
||||
_MyComponent(5, respectCamera: false),
|
||||
_MyComponent(3, respectCamera: false),
|
||||
_MyComponent(0),
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user