Improve default constructor for positioned components (#667)

This commit is contained in:
pedia
2021-02-24 00:27:17 +08:00
committed by GitHub
parent ec09ce0ce6
commit 9735cf5e08
11 changed files with 95 additions and 47 deletions

View File

@@ -22,6 +22,7 @@
- Add utility methods to the Anchor class to make it more "enum like" - Add utility methods to the Anchor class to make it more "enum like"
- Enable user-defined anchors - Enable user-defined anchors
- Added `toImage` method for the `Sprite` class - Added `toImage` method for the `Sprite` class
- Add more optional arguments for unified constructors of components
## 1.0.0-rc6 ## 1.0.0-rc6
- Use `Offset` type directly in `JoystickAction.update` calculations - Use `Offset` type directly in `JoystickAction.update` calculations

View File

@@ -20,9 +20,11 @@ class MyGame extends BaseGame {
jsonData, jsonData,
); );
final spriteSize = Vector2.all(200); final spriteSize = Vector2.all(200);
final animationComponent = final animationComponent = SpriteAnimationComponent(
SpriteAnimationComponent.fromSpriteAnimation(spriteSize, animation) position: size / 2 - Vector2.all(100),
..position = size / 2 - Vector2.all(100); size: spriteSize,
animation: animation,
);
add(animationComponent); add(animationComponent);
} }

View File

@@ -34,9 +34,9 @@ class MyGame extends BaseGame {
} }
SpriteAnimationComponent buildAnimationComponent(Image image) { SpriteAnimationComponent buildAnimationComponent(Image image) {
final ac = SpriteAnimationComponent.fromSpriteAnimation( final ac = SpriteAnimationComponent(
Vector2.all(100), size: Vector2.all(100),
buildAnimation(image), animation: buildAnimation(image),
); );
ac.x = size.x / 2 - ac.x / 2; ac.x = size.x / 2 - ac.x / 2;
return ac; return ac;

View File

@@ -19,10 +19,17 @@ class MyGame extends BaseGame {
Future<void> onLoad() async { Future<void> onLoad() async {
final r = Random(); final r = Random();
final image = await images.load('test.png'); final image = await images.load('test.png');
List.generate(500, (i) => SpriteComponent.fromImage(Vector2.all(32), image)) List.generate(
.forEach((sprite) { 500,
sprite.x = r.nextInt(size.x.toInt()).toDouble(); (i) => SpriteComponent(
sprite.y = r.nextInt(size.y.toInt()).toDouble(); position: Vector2(
r.nextInt(size.x.toInt()).toDouble(),
r.nextInt(size.x.toInt()).toDouble(),
),
size: Vector2.all(32),
sprite: Sprite(image),
),
).forEach((sprite) {
add(sprite); add(sprite);
}); });
} }

View File

@@ -27,31 +27,33 @@ class MyGame extends BaseGame {
spriteSheet.createAnimation(row: 1, stepTime: 0.1, to: 7); spriteSheet.createAnimation(row: 1, stepTime: 0.1, to: 7);
final spriteSize = Vector2(80.0, 90.0); final spriteSize = Vector2(80.0, 90.0);
final vampireComponent = SpriteAnimationComponent.fromSpriteAnimation( final vampireComponent = SpriteAnimationComponent(
spriteSize, position: Vector2(150, 100),
vampireAnimation, size: spriteSize,
) animation: vampireAnimation,
..x = 150 );
..y = 100;
final ghostComponent = final ghostComponent = SpriteAnimationComponent(
SpriteAnimationComponent.fromSpriteAnimation(spriteSize, ghostAnimation) position: Vector2(150, 220),
..x = 150 size: spriteSize,
..y = 220; animation: ghostAnimation,
);
add(vampireComponent); add(vampireComponent);
add(ghostComponent); add(ghostComponent);
// Some plain sprites // Some plain sprites
final vampireSpriteComponent = final vampireSpriteComponent = SpriteComponent(
SpriteComponent.fromSprite(spriteSize, spriteSheet.getSprite(0, 0)) position: Vector2(50, 100),
..x = 50 size: spriteSize,
..y = 100; sprite: spriteSheet.getSprite(0, 0),
);
final ghostSpriteComponent = final ghostSpriteComponent = SpriteComponent(
SpriteComponent.fromSprite(spriteSize, spriteSheet.getSprite(1, 0)) position: Vector2(50, 220),
..x = 50 size: spriteSize,
..y = 220; sprite: spriteSheet.getSprite(1, 0),
);
add(vampireSpriteComponent); add(vampireSpriteComponent);
add(ghostSpriteComponent); add(ghostSpriteComponent);

View File

@@ -15,7 +15,11 @@ class NineTileBoxComponent extends PositionComponent {
/// Takes the [NineTileBox] instance used to render this box. /// Takes the [NineTileBox] instance used to render this box.
/// ///
/// It uses the x, y, width and height coordinates from the [PositionComponent] to render. /// It uses the x, y, width and height coordinates from the [PositionComponent] to render.
NineTileBoxComponent(this.nineTileBox); NineTileBoxComponent(
this.nineTileBox, {
Vector2 position,
Vector2 size,
}) : super(position: position, size: size);
@mustCallSuper @mustCallSuper
@override @override

View File

@@ -23,7 +23,7 @@ import 'mixins/hitbox.dart';
/// within this component's (width, height). /// within this component's (width, height).
abstract class PositionComponent extends BaseComponent { abstract class PositionComponent extends BaseComponent {
/// The position of this component on the screen (relative to the anchor). /// The position of this component on the screen (relative to the anchor).
Vector2 position = Vector2.zero(); Vector2 position;
/// X position of this component on the screen (relative to the anchor). /// X position of this component on the screen (relative to the anchor).
double get x => position.x; double get x => position.x;
@@ -35,7 +35,7 @@ abstract class PositionComponent extends BaseComponent {
/// The size that this component is rendered with. /// The size that this component is rendered with.
/// This is not necessarily the source size of the asset. /// This is not necessarily the source size of the asset.
Vector2 size = Vector2.zero(); Vector2 size;
/// Width (size) that this component is rendered with. /// Width (size) that this component is rendered with.
double get width => size.x; double get width => size.x;
@@ -87,12 +87,12 @@ abstract class PositionComponent extends BaseComponent {
/// Angle (with respect to the x-axis) this component should be rendered with. /// Angle (with respect to the x-axis) this component should be rendered with.
/// It is rotated around its anchor. /// It is rotated around its anchor.
double angle = 0.0; double angle;
/// Anchor point for this component. This is where flame "grabs it". /// Anchor point for this component. This is where flame "grabs it".
/// The [position] is relative to this point inside the component. /// The [position] is relative to this point inside the component.
/// The [angle] is rotated around this point. /// The [angle] is rotated around this point.
Anchor anchor = Anchor.topLeft; Anchor anchor;
/// Whether this component should be flipped on the X axis before being rendered. /// Whether this component should be flipped on the X axis before being rendered.
bool renderFlipX = false; bool renderFlipX = false;
@@ -116,6 +116,16 @@ abstract class PositionComponent extends BaseComponent {
topLeftPosition = rect.topLeft.toVector2(); topLeftPosition = rect.topLeft.toVector2();
} }
PositionComponent({
Vector2 position,
Vector2 size,
this.angle = 0.0,
this.anchor = Anchor.topLeft,
this.renderFlipX = false,
this.renderFlipY = false,
}) : position = position ?? Vector2.zero(),
size = size ?? Vector2.zero();
@override @override
bool containsPoint(Vector2 point) { bool containsPoint(Vector2 point) {
final rectangle = Rectangle.fromRect(toAbsoluteRect(), angle: angle) final rectangle = Rectangle.fromRect(toAbsoluteRect(), angle: angle)

View File

@@ -14,18 +14,25 @@ class SpriteAnimationComponent extends PositionComponent {
bool removeOnFinish = false; bool removeOnFinish = false;
/// Creates a component with an empty animation which can be set later /// Creates a component with an empty animation which can be set later
SpriteAnimationComponent(); SpriteAnimationComponent({
Vector2 position,
Vector2 size,
this.animation,
this.overridePaint,
this.removeOnFinish = false,
}) : super(position: position, size: size);
/// Creates an [SpriteAnimationComponent] from an [animation] and a [size] /// Creates an [SpriteAnimationComponent] from an [animation] and a [size]
/// ///
/// Optionally [removeOnFinish] can be set to true to have this component be auto removed from the [BaseGame] when the animation is finished. /// Optionally [removeOnFinish] can be set to true to have this component be auto removed from the [BaseGame] when the animation is finished.
@Deprecated('Use SpriteAnimationComponent instead')
SpriteAnimationComponent.fromSpriteAnimation( SpriteAnimationComponent.fromSpriteAnimation(
Vector2 size, Vector2 size,
this.animation, { this.animation, {
Vector2 position,
this.removeOnFinish = false, this.removeOnFinish = false,
}) : assert(animation != null) { }) : assert(animation != null),
super.size.setFrom(size); super(size: size, position: position);
}
/// Creates a SpriteAnimationComponent from a [size], an [image] and [data]. Check [SpriteAnimationData] for more info on the available options. /// Creates a SpriteAnimationComponent from a [size], an [image] and [data]. Check [SpriteAnimationData] for more info on the available options.
/// ///

View File

@@ -24,14 +24,19 @@ class SpriteComponent extends PositionComponent {
Paint overridePaint; Paint overridePaint;
/// Creates a component with an empty sprite which can be set later /// Creates a component with an empty sprite which can be set later
SpriteComponent(); SpriteComponent({
Vector2 position,
Vector2 size,
this.sprite,
this.overridePaint,
}) : super(position: position, size: size);
SpriteComponent.fromImage(Vector2 size, Image image) factory SpriteComponent.fromImage(
: this.fromSprite(size, Sprite(image)); Vector2 size,
Image image, {
SpriteComponent.fromSprite(Vector2 size, this.sprite) { Vector2 position,
super.size.setFrom(size); }) =>
} SpriteComponent(size: size, sprite: Sprite(image), position: position);
@mustCallSuper @mustCallSuper
@override @override

View File

@@ -53,9 +53,12 @@ class TextBoxComponent extends PositionComponent {
String text, { String text, {
TextConfig config, TextConfig config,
TextBoxConfig boxConfig, TextBoxConfig boxConfig,
Vector2 position,
Vector2 size,
}) : _text = text, }) : _text = text,
_boxConfig = boxConfig ?? TextBoxConfig(), _boxConfig = boxConfig ?? TextBoxConfig(),
_config = config ?? TextConfig() { _config = config ?? TextConfig(),
super(position: position, size: size) {
_lines = []; _lines = [];
double lineHeight; double lineHeight;
text.split(' ').forEach((word) { text.split(' ').forEach((word) {

View File

@@ -3,6 +3,7 @@ import 'dart:ui';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import '../extensions/vector2.dart';
import '../text_config.dart'; import '../text_config.dart';
import 'position_component.dart'; import 'position_component.dart';
@@ -28,8 +29,14 @@ class TextComponent extends PositionComponent {
_updateBox(); _updateBox();
} }
TextComponent(this._text, {TextConfig config}) TextComponent(
: _config = config ?? TextConfig() { this._text, {
TextConfig config,
Vector2 position,
Vector2 size,
}) : assert(_text != null),
_config = config ?? TextConfig(),
super(position: position, size: size) {
_updateBox(); _updateBox();
} }