flame icon indicating copy to clipboard operation
flame copied to clipboard

(flame) allow theming `paint`

Open alestiago opened this issue 3 years ago • 5 comments

What could be improved

As a flame developer I would like to set all my component paints to paint.filterQuality = FilterQuality.medium. However, flame currently doesn't expose an API to achieve so.

Currently the paint is hard coded and can't be changed https://github.com/flame-engine/flame/blob/275ca17d7e780deb9c72c8b439309a1f1413b7a1/packages/flame/lib/src/components/mixins/has_paint.dart#L15

As a developer I would like to specify what the default paint should be.

Why should this be improved

  • Improve developer experience
  • Specify how my HasPaint components should paint in a single place

Any risks?

No, as long as the theming defaults are kept to the current defaults.

More information

alestiago avatar Aug 22 '22 06:08 alestiago

(cc: @erickzanardo , @wolfenrain)

alestiago avatar Aug 22 '22 06:08 alestiago

How do you propose to solve this? If the user sets a manual paint, how will you know if the user wants to use the global setting or the setting from the paint that it has currently set? You can do:

propagateToChildren<HasPaint>((c) => c.paint.filterQuality = FilterQuality.medium);

But you won't know if you overwrite a user set value.

spydon avatar Aug 22 '22 11:08 spydon

I'm open to proposals.

If we had an InheritedComponent concept we can have a DefaultPaintStyleComponent and when painting the closest DefaultPaintStyleComponent would be fetched (in O(1)) and used. This would only be done if the user has not specified a paint via the constructor.

(Note: this mimics https://api.flutter.dev/flutter/widgets/DefaultTextStyle-class.html)

This way you can scope different painting styles to the desired subtree.

However, since we do not have the concept of an InheritedComponent. There could be a variable in the game that is defaultPaintStyle and the above logic would apply.

alestiago avatar Aug 22 '22 12:08 alestiago

If you have a component with HasPaint, then you'd want to change that paint. After all, you probably don't want everything in the game painted with one color (yesterday's jam excepting). Thus, somewhere in your component you have

class MyComponent extends Component with HasPaint {
  @override
  Future<void>? onLoad() async {
    paint = Paint()..color = const Color(0xFF00FF00);
    ...
  }
}

Now, are you saying that the setter of HasPaint should modify that paint to set it to the medium quality based on some global setting?

st-pasha avatar Aug 22 '22 16:08 st-pasha

Now, are you saying that the setter of HasPaint should modify that paint to set it to the medium quality based on some global setting?

Yes. I want this to work similar to how flutter approaches theming. So I would like to have an API that allows setting the quality to medium in all components of my game unless overrided by the component itself.

It would be nicer if the API allowed me to apply a paint quality to a component subtree only and another paint quality to another component subtree. This would, for example, allow me to increase the quality for the component subtree that has foreground or important sprites and reduce the quality for the component subtree that has background or not so important sprites.

After all, you probably don't want everything in the game painted with one color (yesterday's jam excepting).

I think it would be nice if the engined allowed to do so, since that way one could implement nice flashing colour or tinting animations in the entire game. Aaaand we already know it is useful for 1bit games.

alestiago avatar Aug 22 '22 16:08 alestiago