From 9cc19a76b43816f652b31de1a1f8f947edbeb03c Mon Sep 17 00:00:00 2001 From: Luan Nico Date: Wed, 29 Sep 2021 12:24:17 -0400 Subject: [PATCH] Add option to rotate SpriteWidget (#985) --- examples/lib/stories/widgets/sprite_widget.dart | 3 +++ packages/flame/CHANGELOG.md | 1 + .../flame/lib/src/widgets/sprite_painter.dart | 16 ++++++++++++---- .../flame/lib/src/widgets/sprite_widget.dart | 12 +++++++++++- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/examples/lib/stories/widgets/sprite_widget.dart b/examples/lib/stories/widgets/sprite_widget.dart index c70f5155f..4c5b412d6 100644 --- a/examples/lib/stories/widgets/sprite_widget.dart +++ b/examples/lib/stories/widgets/sprite_widget.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:dashbook/dashbook.dart'; import 'package:flame/widgets.dart'; import 'package:flutter/material.dart'; @@ -12,6 +14,7 @@ Widget spriteWidgetBuilder(DashbookContext ctx) { decoration: BoxDecoration(border: Border.all(color: Colors.amber)), child: SpriteWidget.asset( path: 'shield.png', + angle: pi / 180 * ctx.numberProperty('angle (deg)', 0), anchor: Anchor.valueOf( ctx.listProperty('anchor', 'center', anchorOptions), ), diff --git a/packages/flame/CHANGELOG.md b/packages/flame/CHANGELOG.md index 20dd740dc..969df70ff 100644 --- a/packages/flame/CHANGELOG.md +++ b/packages/flame/CHANGELOG.md @@ -8,6 +8,7 @@ - Take in an optional `Camera` as a parameter to `FlameGame` - Make super.onLoad mandatory to avoid memory leaks - `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] - Reset effects after they are done so that they can be repeated diff --git a/packages/flame/lib/src/widgets/sprite_painter.dart b/packages/flame/lib/src/widgets/sprite_painter.dart index 5b94520fa..f4679bf02 100644 --- a/packages/flame/lib/src/widgets/sprite_painter.dart +++ b/packages/flame/lib/src/widgets/sprite_painter.dart @@ -8,12 +8,16 @@ import '../sprite.dart'; class SpritePainter extends CustomPainter { final Sprite _sprite; final Anchor _anchor; + final double _angle; - SpritePainter(this._sprite, this._anchor); + SpritePainter(this._sprite, this._anchor, {double angle = 0}) + : _angle = angle; @override bool shouldRepaint(SpritePainter old) { - return old._sprite != _sprite || old._anchor != _anchor; + return old._sprite != _sprite || + old._anchor != _anchor || + old._angle != _angle; } @override @@ -23,10 +27,14 @@ class SpritePainter extends CustomPainter { final minRate = min(rate.x, rate.y); final paintSize = _sprite.srcSize * minRate; final anchorPosition = _anchor.toVector2(); - final boxAnchorPosition = boxSize..multiply(anchorPosition); + final boxAnchorPosition = boxSize.clone()..multiply(anchorPosition); final spriteAnchorPosition = anchorPosition..multiply(paintSize); canvas.translateVector(boxAnchorPosition..sub(spriteAnchorPosition)); - _sprite.render(canvas, size: paintSize); + canvas.renderRotated( + _angle, + spriteAnchorPosition, + (canvas) => _sprite.render(canvas, size: paintSize), + ); } } diff --git a/packages/flame/lib/src/widgets/sprite_widget.dart b/packages/flame/lib/src/widgets/sprite_widget.dart index 0f9e484d7..fc7d0320e 100644 --- a/packages/flame/lib/src/widgets/sprite_widget.dart +++ b/packages/flame/lib/src/widgets/sprite_widget.dart @@ -16,6 +16,9 @@ class SpriteWidget extends StatelessWidget { /// The positioning [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 final Vector2? srcPosition; @@ -33,6 +36,7 @@ class SpriteWidget extends StatelessWidget { SpriteWidget({ required Sprite sprite, this.anchor = Anchor.topLeft, + this.angle = 0, this.srcPosition, this.srcSize, this.errorBuilder, @@ -43,6 +47,7 @@ class SpriteWidget extends StatelessWidget { required String path, Images? images, this.anchor = Anchor.topLeft, + this.angle = 0, this.srcPosition, this.srcSize, this.errorBuilder, @@ -62,6 +67,7 @@ class SpriteWidget extends StatelessWidget { return _SpriteWidget( sprite: sprite, anchor: anchor, + angle: angle, ); }, errorBuilder: errorBuilder, @@ -78,15 +84,19 @@ class _SpriteWidget extends StatelessWidget { /// The positioning [Anchor] for the [sprite] final Anchor anchor; + /// The angle to rotate this [sprite], in rad. (default = 0) + final double angle; + const _SpriteWidget({ required this.sprite, this.anchor = Anchor.topLeft, + this.angle = 0, }); @override Widget build(_) { return Container( - child: CustomPaint(painter: SpritePainter(sprite, anchor)), + child: CustomPaint(painter: SpritePainter(sprite, anchor, angle: angle)), ); } }