diff --git a/doc/examples/widgets/assets/images/bomb_ptero.png b/doc/examples/widgets/assets/images/bomb_ptero.png new file mode 100644 index 000000000..fa4ddadc8 Binary files /dev/null and b/doc/examples/widgets/assets/images/bomb_ptero.png differ diff --git a/doc/examples/widgets/assets/images/shield.png b/doc/examples/widgets/assets/images/shield.png new file mode 100644 index 000000000..e80fb0a22 Binary files /dev/null and b/doc/examples/widgets/assets/images/shield.png differ diff --git a/doc/examples/widgets/lib/main.dart b/doc/examples/widgets/lib/main.dart index 2be556b02..e4e7d42a4 100644 --- a/doc/examples/widgets/lib/main.dart +++ b/doc/examples/widgets/lib/main.dart @@ -1,27 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flame/flame.dart'; +import 'package:flame/sprite.dart'; import 'package:flame/spritesheet.dart'; import 'package:dashbook/dashbook.dart'; import 'package:flame/widgets/nine_tile_box.dart'; import 'package:flame/widgets/sprite_button.dart'; +import 'package:flame/widgets/flame_sprite_widget.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - final nineTileBoxImage = await Flame.images.load('nine_tile_box.png'); - await Flame.images.load('buttons.png'); - - final _buttons = SpriteSheet( - imageName: 'buttons.png', - textureHeight: 20, - textureWidth: 60, - columns: 1, - rows: 2, - ); - final dashbook = Dashbook(); + final nineTileBoxImage = await Flame.images.load('nine_tile_box.png'); dashbook.storiesOf('NineTileBox').decorator(CenterDecorator()).add( 'default', (ctx) => Container( @@ -42,6 +34,15 @@ void main() async { ), )); + await Flame.images.load('buttons.png'); + + final _buttons = SpriteSheet( + imageName: 'buttons.png', + textureHeight: 20, + textureWidth: 60, + columns: 1, + rows: 2, + ); dashbook.storiesOf('SpriteButton').decorator(CenterDecorator()).add( 'default', (ctx) => Container( @@ -62,5 +63,18 @@ void main() async { ), ); + final shieldSprite = await Sprite.loadSprite('shield.png'); + dashbook.storiesOf('FlameSpriteWidget').decorator(CenterDecorator()).add( + 'default', + (ctx) => Container( + width: ctx.numberProperty('container width', 200), + height: ctx.numberProperty('container height', 200), + padding: const EdgeInsets.all(20), + child: FlameSpriteWidget( + sprite: shieldSprite, + ), + ), + ); + runApp(dashbook); } diff --git a/doc/examples/widgets/pubspec.yaml b/doc/examples/widgets/pubspec.yaml index 503e2fc86..16674b9be 100644 --- a/doc/examples/widgets/pubspec.yaml +++ b/doc/examples/widgets/pubspec.yaml @@ -19,3 +19,5 @@ flutter: assets: - assets/images/nine_tile_box.png - assets/images/buttons.png + - assets/images/shield.png + - assets/images/bomb_ptero.png diff --git a/doc/widgets.md b/doc/widgets.md index 6e9303db5..7fdac5063 100644 --- a/doc/widgets.md +++ b/doc/widgets.md @@ -47,3 +47,17 @@ SpriteButton( pressedSprite: _pressedSpriteButton, ) ``` + +## FlameSpriteWidget + +`FlameSpriteWidget` is a widget used to display [Sprites](https://github.com/flame-engine/flame/blob/master/lib/sprite.dart) inside a widget tree. + +How to use it: + +```dart +FlameSpriteWidget( + sprite: shieldSprite, + center: true, +), + +``` diff --git a/lib/util.dart b/lib/util.dart index dd2b50f04..86cb98e02 100644 --- a/lib/util.dart +++ b/lib/util.dart @@ -164,6 +164,8 @@ class Util { /// /// This will create a [CustomPaint] widget using a [CustomPainter] for rendering the [Sprite] /// Be aware that the Sprite must have been loaded, otherwise it can't be rendered + /// + /// @Deprecated('Use FlameSpriteWidget instead') widgets.CustomPaint spriteAsWidget(Size size, Sprite sprite) => widgets.CustomPaint(size: size, painter: _SpriteCustomPainter(sprite)); } diff --git a/lib/widgets/flame_sprite_widget.dart b/lib/widgets/flame_sprite_widget.dart new file mode 100644 index 000000000..15111a44f --- /dev/null +++ b/lib/widgets/flame_sprite_widget.dart @@ -0,0 +1,56 @@ +import 'package:flutter/widgets.dart'; +import 'package:meta/meta.dart'; +import '../sprite.dart'; + +import 'dart:math'; + +class FlameSpriteWidget extends StatelessWidget { + final Sprite sprite; + final bool center; + + FlameSpriteWidget({ + @required this.sprite, + this.center = false, + }) : assert(sprite.loaded(), 'Sprite must be loaded'); + + @override + Widget build(_) { + return Container( + child: CustomPaint(painter: _FlameSpritePainer(sprite, center)), + ); + } +} + +class _FlameSpritePainer extends CustomPainter { + final Sprite _sprite; + final bool _center; + + _FlameSpritePainer(this._sprite, this._center); + + @override + bool shouldRepaint(_FlameSpritePainer old) => old._sprite != _sprite; + + @override + void paint(Canvas canvas, Size size) { + final widthRate = size.width / _sprite.size.x; + final heightRate = size.height / _sprite.size.y; + + final rate = min(widthRate, heightRate); + + final rect = Rect.fromLTWH( + 0, + 0, + _sprite.size.x * rate, + _sprite.size.y * rate, + ); + + if (_center) { + canvas.translate( + size.width / 2 - rect.width / 2, + size.height / 2 - rect.height / 2, + ); + } + + _sprite.renderRect(canvas, rect); + } +}