Add option to rotate SpriteWidget (#985)

This commit is contained in:
Luan Nico
2021-09-29 12:24:17 -04:00
committed by GitHub
parent 9f9d562261
commit 9cc19a76b4
4 changed files with 27 additions and 5 deletions

View File

@ -1,3 +1,5 @@
import 'dart:math';
import 'package:dashbook/dashbook.dart'; import 'package:dashbook/dashbook.dart';
import 'package:flame/widgets.dart'; import 'package:flame/widgets.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -12,6 +14,7 @@ Widget spriteWidgetBuilder(DashbookContext ctx) {
decoration: BoxDecoration(border: Border.all(color: Colors.amber)), decoration: BoxDecoration(border: Border.all(color: Colors.amber)),
child: SpriteWidget.asset( child: SpriteWidget.asset(
path: 'shield.png', path: 'shield.png',
angle: pi / 180 * ctx.numberProperty('angle (deg)', 0),
anchor: Anchor.valueOf( anchor: Anchor.valueOf(
ctx.listProperty('anchor', 'center', anchorOptions), ctx.listProperty('anchor', 'center', anchorOptions),
), ),

View File

@ -8,6 +8,7 @@
- Take in an optional `Camera` as a parameter to `FlameGame` - Take in an optional `Camera` as a parameter to `FlameGame`
- Make super.onLoad mandatory to avoid memory leaks - Make super.onLoad mandatory to avoid memory leaks
- `QueryableOrderedSet`'s `strictMode` is configurable so it is no longer necessary to call `register` before `query` - `QueryableOrderedSet`'s `strictMode` is configurable so it is no longer necessary to call `register` before `query`
- Add option to rotate `SpriteWidget`
## [1.0.0-releasecandidate.14] ## [1.0.0-releasecandidate.14]
- Reset effects after they are done so that they can be repeated - Reset effects after they are done so that they can be repeated

View File

@ -8,12 +8,16 @@ import '../sprite.dart';
class SpritePainter extends CustomPainter { class SpritePainter extends CustomPainter {
final Sprite _sprite; final Sprite _sprite;
final Anchor _anchor; final Anchor _anchor;
final double _angle;
SpritePainter(this._sprite, this._anchor); SpritePainter(this._sprite, this._anchor, {double angle = 0})
: _angle = angle;
@override @override
bool shouldRepaint(SpritePainter old) { bool shouldRepaint(SpritePainter old) {
return old._sprite != _sprite || old._anchor != _anchor; return old._sprite != _sprite ||
old._anchor != _anchor ||
old._angle != _angle;
} }
@override @override
@ -23,10 +27,14 @@ class SpritePainter extends CustomPainter {
final minRate = min(rate.x, rate.y); final minRate = min(rate.x, rate.y);
final paintSize = _sprite.srcSize * minRate; final paintSize = _sprite.srcSize * minRate;
final anchorPosition = _anchor.toVector2(); final anchorPosition = _anchor.toVector2();
final boxAnchorPosition = boxSize..multiply(anchorPosition); final boxAnchorPosition = boxSize.clone()..multiply(anchorPosition);
final spriteAnchorPosition = anchorPosition..multiply(paintSize); final spriteAnchorPosition = anchorPosition..multiply(paintSize);
canvas.translateVector(boxAnchorPosition..sub(spriteAnchorPosition)); canvas.translateVector(boxAnchorPosition..sub(spriteAnchorPosition));
_sprite.render(canvas, size: paintSize); canvas.renderRotated(
_angle,
spriteAnchorPosition,
(canvas) => _sprite.render(canvas, size: paintSize),
);
} }
} }

View File

@ -16,6 +16,9 @@ class SpriteWidget extends StatelessWidget {
/// The positioning [Anchor] /// The positioning [Anchor]
final Anchor anchor; final Anchor anchor;
/// The angle to rotate this [Sprite], in rad. (default = 0)
final double angle;
/// Holds the position of the sprite on the image /// Holds the position of the sprite on the image
final Vector2? srcPosition; final Vector2? srcPosition;
@ -33,6 +36,7 @@ class SpriteWidget extends StatelessWidget {
SpriteWidget({ SpriteWidget({
required Sprite sprite, required Sprite sprite,
this.anchor = Anchor.topLeft, this.anchor = Anchor.topLeft,
this.angle = 0,
this.srcPosition, this.srcPosition,
this.srcSize, this.srcSize,
this.errorBuilder, this.errorBuilder,
@ -43,6 +47,7 @@ class SpriteWidget extends StatelessWidget {
required String path, required String path,
Images? images, Images? images,
this.anchor = Anchor.topLeft, this.anchor = Anchor.topLeft,
this.angle = 0,
this.srcPosition, this.srcPosition,
this.srcSize, this.srcSize,
this.errorBuilder, this.errorBuilder,
@ -62,6 +67,7 @@ class SpriteWidget extends StatelessWidget {
return _SpriteWidget( return _SpriteWidget(
sprite: sprite, sprite: sprite,
anchor: anchor, anchor: anchor,
angle: angle,
); );
}, },
errorBuilder: errorBuilder, errorBuilder: errorBuilder,
@ -78,15 +84,19 @@ class _SpriteWidget extends StatelessWidget {
/// The positioning [Anchor] for the [sprite] /// The positioning [Anchor] for the [sprite]
final Anchor anchor; final Anchor anchor;
/// The angle to rotate this [sprite], in rad. (default = 0)
final double angle;
const _SpriteWidget({ const _SpriteWidget({
required this.sprite, required this.sprite,
this.anchor = Anchor.topLeft, this.anchor = Anchor.topLeft,
this.angle = 0,
}); });
@override @override
Widget build(_) { Widget build(_) {
return Container( return Container(
child: CustomPaint(painter: SpritePainter(sprite, anchor)), child: CustomPaint(painter: SpritePainter(sprite, anchor, angle: angle)),
); );
} }
} }