-
-
Notifications
You must be signed in to change notification settings - Fork 899
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Backdrop (static backgrounds) component for CameraComponent (#2787
) This PR adds a backdrop component to the `CameraComponent` which renders behind the world. With this change the rendering order looks like this: ``` backdrop world viewport viewfinder ``` In the following example you can see a `ParallaxComponent` attached to the backdrop, a player and some other components attached to the world, and some texts attached to the viewfinder and viewport: ![image](https://github.com/flame-engine/flame/assets/744771/a0b2fe0e-bff3-4d1d-a2d1-ddd3199bbdab)
- Loading branch information
Showing
14 changed files
with
280 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
examples/lib/stories/camera_and_viewport/static_components_example.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import 'dart:ui'; | ||
|
||
import 'package:flame/components.dart'; | ||
import 'package:flame/effects.dart'; | ||
import 'package:flame/events.dart'; | ||
import 'package:flame/extensions.dart'; | ||
import 'package:flame/game.dart'; | ||
import 'package:flame/input.dart'; | ||
import 'package:flame/parallax.dart'; | ||
|
||
class StaticComponentsExample extends FlameGame | ||
with ScrollDetector, ScaleDetector { | ||
static const description = ''' | ||
This example shows a parallax which is attached to the viewport (behind the | ||
world), four Flame logos that are added to the world, and a player added to | ||
the world which is also followed by the camera when you click somewhere. | ||
The text components that are added are self-explanatory. | ||
'''; | ||
|
||
late final ParallaxComponent myParallax; | ||
|
||
StaticComponentsExample({ | ||
required Vector2 viewportResolution, | ||
}) : super( | ||
camera: CameraComponent.withFixedResolution( | ||
width: viewportResolution.x, | ||
height: viewportResolution.y, | ||
), | ||
world: _StaticComponentWorld(), | ||
); | ||
|
||
@override | ||
Future<void> onLoad() async { | ||
myParallax = MyParallaxComponent()..parallax?.baseVelocity.setZero(); | ||
camera.backdrop.addAll([ | ||
myParallax, | ||
TextComponent( | ||
text: 'Center backdrop Component', | ||
position: camera.viewport.size / 2 + Vector2(0, 30), | ||
anchor: Anchor.center, | ||
), | ||
]); | ||
camera.viewfinder.addAll([ | ||
TextComponent( | ||
text: 'Corner Viewfinder Component', | ||
position: camera.viewport.size - Vector2.all(10), | ||
anchor: Anchor.bottomRight, | ||
), | ||
]); | ||
camera.viewport.addAll( | ||
[ | ||
TextComponent( | ||
text: 'Corner Viewport Component', | ||
position: Vector2.all(10), | ||
), | ||
TextComponent( | ||
text: 'Center Viewport Component', | ||
position: camera.viewport.size / 2, | ||
anchor: Anchor.center, | ||
), | ||
], | ||
); | ||
} | ||
} | ||
|
||
class _StaticComponentWorld extends World | ||
with | ||
HasGameReference<StaticComponentsExample>, | ||
TapCallbacks, | ||
DoubleTapCallbacks { | ||
late SpriteComponent player; | ||
@override | ||
Future<void> onLoad() async { | ||
final playerSprite = await game.loadSprite('layers/player.png'); | ||
final flameSprite = await game.loadSprite('flame.png'); | ||
final visibleSize = game.camera.visibleWorldRect.toVector2(); | ||
add(player = SpriteComponent(sprite: playerSprite, anchor: Anchor.center)); | ||
addAll([ | ||
SpriteComponent( | ||
sprite: flameSprite, | ||
anchor: Anchor.center, | ||
position: -visibleSize / 8, | ||
size: Vector2(20, 30), | ||
), | ||
SpriteComponent( | ||
sprite: flameSprite, | ||
anchor: Anchor.center, | ||
position: visibleSize / 8, | ||
size: Vector2(20, 30), | ||
), | ||
SpriteComponent( | ||
sprite: flameSprite, | ||
anchor: Anchor.center, | ||
position: (visibleSize / 8)..multiply(Vector2(-1, 1)), | ||
size: Vector2(20, 30), | ||
), | ||
SpriteComponent( | ||
sprite: flameSprite, | ||
anchor: Anchor.center, | ||
position: (visibleSize / 8)..multiply(Vector2(1, -1)), | ||
size: Vector2(20, 30), | ||
), | ||
]); | ||
game.camera.follow(player, maxSpeed: 100); | ||
} | ||
|
||
@override | ||
void onTapDown(TapDownEvent event) { | ||
const moveDuration = 1.0; | ||
final deltaX = (event.localPosition - player.position).x; | ||
player.add( | ||
MoveToEffect( | ||
event.localPosition, | ||
EffectController( | ||
duration: moveDuration, | ||
), | ||
onComplete: () => game.myParallax.parallax?.baseVelocity.setZero(), | ||
), | ||
); | ||
final moveSpeedX = deltaX / moveDuration; | ||
game.myParallax.parallax?.baseVelocity.setValues(moveSpeedX, 0); | ||
} | ||
} | ||
|
||
class MyParallaxComponent extends ParallaxComponent { | ||
@override | ||
Future<void> onLoad() async { | ||
parallax = await game.loadParallax( | ||
[ | ||
ParallaxImageData('parallax/bg.png'), | ||
ParallaxImageData('parallax/mountain-far.png'), | ||
ParallaxImageData('parallax/mountains.png'), | ||
ParallaxImageData('parallax/trees.png'), | ||
ParallaxImageData('parallax/foreground-trees.png'), | ||
], | ||
baseVelocity: Vector2(0, 0), | ||
velocityMultiplierDelta: Vector2(1.8, 1.0), | ||
filterQuality: FilterQuality.none, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import 'dart:ui'; | ||
|
||
import 'package:flame/components.dart'; | ||
|
||
class CrossHair extends PositionComponent { | ||
CrossHair({super.size, super.position, this.color = const Color(0xFFFF0000)}) | ||
: super(anchor: Anchor.center); | ||
|
||
final Color color; | ||
Paint get _paint => Paint() | ||
..style = PaintingStyle.stroke | ||
..strokeWidth = 2.0 | ||
..color = color; | ||
|
||
@override | ||
void render(Canvas canvas) { | ||
canvas.drawLine(Offset(size.x / 2, 0), Offset(size.x / 2, size.y), _paint); | ||
canvas.drawLine(Offset(0, size.y / 2), Offset(size.x, size.y / 2), _paint); | ||
} | ||
} |
Oops, something went wrong.