Improving Parallax APIs regarding handling its size and the use outside FCS (#651)

* Improving Parallax APIs regarding handling its size and the use outside FCS

* Formatting

* Fixing flutter format vs flutter analyze crazy conflicts

* Some suggestions

* Removing unecessary line

* Luan suggestions

* Luan suggestion

* Lukas suggestions

* updating comment
This commit is contained in:
Erick
2021-02-04 12:26:37 -03:00
committed by GitHub
parent 4db3c0e401
commit d98a1ede44
8 changed files with 111 additions and 18 deletions

View File

@ -5,6 +5,7 @@
- Moving render functions from `util.dart` to `extensions/canvas.dart`
- Adapting ParallaxComponent contructors to match the pattern followed on other components
- Adapting SpriteBatchComponent constructors to match the pattern used on other components
- Improving Parallax APIs regarding handling its size and the use outside FCS
- Enabling direct import of Sprite and SpriteAnimation
- Renamed `Composition` to `ImageComposition` to prevent confusion with the composition component
- Added `rotation` and `anchor` arguments to `ImageComposition.add`

View File

@ -264,6 +264,7 @@ final layers = images.map((image) => ParallaxLayer(await image, velocityMulitpli
final parallaxComponent = ParallaxComponent.fromParallax(
Parallax(
await Future.wait(layers),
size, // size is a property on the Game class
baseVelocity: Vector2(50, 0),
),
);

View File

@ -24,11 +24,10 @@ class MyGame extends BaseGame {
@override
Future<void> onLoad() async {
final parallax = await ParallaxComponent.load(
final parallax = await loadParallaxComponent(
_imageNames,
baseVelocity: Vector2(20, 0),
velocityMultiplierDelta: Vector2(1.8, 1.0),
images: images,
);
add(parallax);
}

View File

@ -34,6 +34,7 @@ class MyGame extends BaseGame {
final parallax = ParallaxComponent.fromParallax(
Parallax(
await Future.wait(layers),
size,
baseVelocity: Vector2(20, 0),
),
);

View File

@ -32,6 +32,7 @@ class MyParallaxComponent extends ParallaxComponent with HasGameRef<MyGame> {
'trees.png',
'foreground-trees.png',
],
size,
baseVelocity: Vector2(20, 0),
velocityMultiplierDelta: Vector2(1.8, 1.0),
);

View File

@ -0,0 +1,51 @@
import 'package:flame/components.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/parallax.dart';
import 'package:flame/extensions.dart';
import 'package:flutter/material.dart';
/// This examples serves to test the Parallax feature outside of the
/// Flame Component System (FCS), use the other files in this folder
/// for examples on how to use parallax with FCS
/// FCS is only used when you extend BaseGame, not Game,
/// like we do in this example.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Flame.device.fullScreen();
runApp(
GameWidget(
game: MyGame(),
),
);
}
class MyGame extends Game {
Parallax parallax;
@override
Future<void> onLoad() async {
parallax = await loadParallax(
[
'bg.png',
'mountain-far.png',
'mountains.png',
'trees.png',
'foreground-trees.png',
],
size,
baseVelocity: Vector2(20, 0),
velocityMultiplierDelta: Vector2(1.8, 1.0),
);
}
@override
void update(double dt) {
parallax.update(dt);
}
@override
void render(Canvas canvas) {
parallax.render(canvas);
}
}

View File

@ -13,14 +13,17 @@ import 'position_component.dart';
extension ParallaxComponentExtension on Game {
Future<ParallaxComponent> loadParallaxComponent(
List<String> paths, {
Vector2 size,
Vector2 baseVelocity,
Vector2 velocityMultiplierDelta,
ImageRepeat repeat = ImageRepeat.repeatX,
Alignment alignment = Alignment.bottomLeft,
LayerFill fill = LayerFill.height,
}) {
return ParallaxComponent.load(
}) async {
final componentSize = size ?? this.size;
final component = await ParallaxComponent.load(
paths,
size: componentSize,
baseVelocity: baseVelocity,
velocityMultiplierDelta: velocityMultiplierDelta,
repeat: repeat,
@ -28,6 +31,8 @@ extension ParallaxComponentExtension on Game {
fill: fill,
images: images,
);
return component..size.setFrom(componentSize);
}
}
@ -66,13 +71,7 @@ class ParallaxComponent extends PositionComponent {
@override
void render(Canvas canvas) {
super.render(canvas);
canvas.save();
parallax?.layers?.forEach((layer) {
canvas.save();
layer.render(canvas);
canvas.restore();
});
canvas.restore();
parallax?.render(canvas);
}
/// Note that this method only should be used if all of your layers should
@ -80,7 +79,7 @@ class ParallaxComponent extends PositionComponent {
/// and filled), otherwise load the [ParallaxLayer]s individually and use the
/// normal constructor.
///
/// [load] takes a list of paths to all the images that you want to use in the
/// [load] takes a list of paths to all the images and a size that you want to use in the
/// parallax.
/// Optionally arguments for the [baseVelocity] and [layerDelta] can be passed
/// in, [baseVelocity] defines what the base velocity of the layers should be
@ -94,6 +93,7 @@ class ParallaxComponent extends PositionComponent {
/// If no image cache is set, the global flame cache is used.
static Future<ParallaxComponent> load(
List<String> paths, {
Vector2 size,
Vector2 baseVelocity,
Vector2 velocityMultiplierDelta,
ImageRepeat repeat = ImageRepeat.repeatX,
@ -101,9 +101,10 @@ class ParallaxComponent extends PositionComponent {
LayerFill fill = LayerFill.height,
Images images,
}) async {
return ParallaxComponent.fromParallax(
final component = ParallaxComponent.fromParallax(
await Parallax.load(
paths,
size,
baseVelocity: baseVelocity,
velocityMultiplierDelta: velocityMultiplierDelta,
repeat: repeat,
@ -112,5 +113,11 @@ class ParallaxComponent extends PositionComponent {
images: images,
),
);
if (size != null) {
component.size.setFrom(size);
}
return component;
}
}

View File

@ -6,12 +6,14 @@ import 'package:flutter/painting.dart';
import 'assets/images.dart';
import 'extensions/rect.dart';
import 'extensions/vector2.dart';
import 'extensions/canvas.dart';
import 'flame.dart';
import 'game/game.dart';
extension ParallaxExtension on Game {
Future<Parallax> loadParallax(
List<String> paths, {
List<String> paths,
Vector2 size, {
Vector2 baseVelocity,
Vector2 velocityMultiplierDelta,
ImageRepeat repeat = ImageRepeat.repeatX,
@ -20,6 +22,7 @@ extension ParallaxExtension on Game {
}) {
return Parallax.load(
paths,
size,
baseVelocity: baseVelocity,
velocityMultiplierDelta: velocityMultiplierDelta,
repeat: repeat,
@ -235,12 +238,19 @@ enum LayerFill { height, width, none }
/// layer moves with different velocities to give an effect of depth.
class Parallax {
Vector2 baseVelocity;
Vector2 _size = Vector2.zero();
Rect _clipRect;
final List<ParallaxLayer> layers;
Parallax(
this.layers, {
this.layers,
Vector2 size, {
Vector2 baseVelocity,
}) : baseVelocity = baseVelocity ?? Vector2.zero();
}) : assert(layers != null),
assert(size != null) {
this.baseVelocity = baseVelocity ?? Vector2.zero();
resize(size);
}
/// The base offset of the parallax, can be used in an outer update loop
/// if you want to transition the parallax to a certain position.
@ -248,7 +258,13 @@ class Parallax {
/// If the `ParallaxComponent` isn't used your own wrapper needs to call this
/// on creation.
void resize(Vector2 size) => layers.forEach((layer) => layer.resize(size));
void resize(Vector2 newSize) {
if (newSize != _size) {
_size = newSize;
_clipRect = newSize.toRect();
layers.forEach((layer) => layer.resize(newSize));
}
}
void update(double t) {
layers.forEach((layer) {
@ -276,7 +292,8 @@ class Parallax {
/// used can also be passed in.
/// If no image cache is set, the global flame cache is used.
static Future<Parallax> load(
List<String> paths, {
List<String> paths,
Vector2 size, {
Vector2 baseVelocity,
Vector2 velocityMultiplierDelta,
ImageRepeat repeat = ImageRepeat.repeatX,
@ -309,7 +326,22 @@ class Parallax {
);
return Parallax(
layers,
size,
baseVelocity: baseVelocity,
);
}
void render(Canvas canvas, {Vector2 position}) {
canvas.save();
if (position != null) {
canvas.translateVector(position);
}
canvas.clipRect(_clipRect);
layers.forEach((layer) {
canvas.save();
layer.render(canvas);
canvas.restore();
});
canvas.restore();
}
}