Skip to content
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

fix: Auto-resize SpriteComponent on sprite change #2430

Merged
merged 7 commits into from
Mar 26, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 46 additions & 5 deletions packages/flame/lib/src/components/sprite_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,46 @@ export '../sprite.dart';
class SpriteComponent extends PositionComponent
with HasPaint
implements SizeProvider {
/// When set to true, the component is auto-resized to match the
/// size of underlying sprite.
late bool _autoResize;

/// Returns current value of auto resize flag.
bool get autoResize => _autoResize;

/// Sets the given value of autoResize flag. Will update the [size]
/// to fit srcSize of [sprite] if set to true.
set autoResize(bool value) {
_autoResize = value;
if (value) {
size.setFrom(sprite?.srcSize ?? Vector2.zero());
ufrshubham marked this conversation as resolved.
Show resolved Hide resolved
}
}

/// The [sprite] to be rendered by this component.
Sprite? sprite;
Sprite? _sprite;

/// Returns the current sprite rendered by this component.
Sprite? get sprite => _sprite;

/// Sets the given sprite as the new [sprite] of this component.
/// Will update the size if [autoResize] is set to true.
set sprite(Sprite? value) {
_sprite = value;

if (_autoResize) {
if (value != null) {
size.setFrom(value.srcSize);
} else {
size.setZero();
ufrshubham marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

/// Creates a component with an empty sprite which can be set later
SpriteComponent({
this.sprite,
Sprite? sprite,
bool? autoResize,
Paint? paint,
super.position,
Vector2? size,
Expand All @@ -30,9 +64,14 @@ class SpriteComponent extends PositionComponent
super.anchor,
super.children,
super.priority,
}) : super(
size: size ?? sprite?.srcSize,
) {
}) : assert(
(size == null && (autoResize ?? true)) ||
(size != null && !(autoResize ?? false)),
ufrshubham marked this conversation as resolved.
Show resolved Hide resolved
'''If size is set, autoResize should be false or size should be null when autoResize is true.''',
),
_autoResize = autoResize ?? size == null,
_sprite = sprite,
super(size: size ?? sprite?.srcSize) {
if (paint != null) {
this.paint = paint;
}
Expand All @@ -42,6 +81,7 @@ class SpriteComponent extends PositionComponent
Image image, {
Vector2? srcPosition,
Vector2? srcSize,
bool? autoResize,
Paint? paint,
Vector2? position,
Vector2? size,
Expand All @@ -56,6 +96,7 @@ class SpriteComponent extends PositionComponent
srcPosition: srcPosition,
srcSize: srcSize,
),
autoResize: autoResize,
paint: paint,
position: position,
size: size ?? srcSize ?? image.size,
Expand Down
32 changes: 31 additions & 1 deletion packages/flame/test/components/sprite_component_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart';
import 'package:test/test.dart';
import 'package:flutter_test/flutter_test.dart';

Future<void> main() async {
final image = await generateImage();
Expand Down Expand Up @@ -37,4 +37,34 @@ Future<void> main() async {
expect(component6.size, Vector2(2, 2));
});
});

group('SpriteComponent.autoResize', () {
test('mutual exclusive with size while construction', () {
expect(
() => SpriteComponent(autoResize: true, size: Vector2.all(2)),
throwsAssertionError,
);

expect(() => SpriteComponent(autoResize: false), throwsAssertionError);
});

test('default value set correctly when not provided explicitly', () {
final component1 = SpriteComponent();
final component2 = SpriteComponent(size: Vector2.all(2));

expect(component1.autoResize, true);
expect(component2.autoResize, false);
});

test('resizes on sprite change', () {
final sprite1 = Sprite(image);
final sprite2 = Sprite(image, srcSize: Vector2.all(13));

final component = SpriteComponent()..sprite = sprite1;
expect(component.size, sprite1.srcSize);

component.sprite = sprite2;
expect(component.size, sprite2.srcSize);
});
});
}