sprite.dart 3.4 KB
Newer Older
1 2
part of sprites;

3
/// A Sprite is a [Node] that renders a bitmap image to the screen.
4
class Sprite extends NodeWithSize with SpritePaint {
5

6
  /// The texture that the sprite will render to screen.
7
  ///
8
  /// If the texture is null, the sprite will be rendered as a red square
9 10
  /// marking the bounds of the sprite.
  ///
11 12
  ///     mySprite.texture = myTexture;
  Texture texture;
13 14 15 16

  /// If true, constrains the proportions of the image by scaling it down, if its proportions doesn't match the [size].
  ///
  ///     mySprite.constrainProportions = true;
17
  bool constrainProportions = false;
18

19 20 21
  Paint _cachedPaint = new Paint()
    ..setFilterQuality(FilterQuality.low)
    ..isAntiAlias = false;
22

23 24 25
  /// Creates a new sprite from the provided [texture].
  ///
  ///     var mySprite = new Sprite(myTexture)
26
  Sprite([this.texture]) : super(Size.zero) {
27 28 29 30 31 32 33 34
    if (texture != null) {
      size = texture.size;
      pivot = texture.pivot;
    } else {
      pivot = new Point(0.5, 0.5);
    }
  }

35 36
  /// Creates a new sprite from the provided [image].
  ///
37
  /// var mySprite = new Sprite.fromImage(myImage);
38
  Sprite.fromImage(Image image) : super(Size.zero) {
39 40 41 42 43
    assert(image != null);

    texture = new Texture(image);
    size = texture.size;

44
    pivot = new Point(0.5, 0.5);
45
  }
46

47
  void paint(PaintingCanvas canvas) {
48 49
    // Account for pivot point
    applyTransformForPivot(canvas);
50

51 52 53 54 55
    if (texture != null) {
      double w = texture.size.width;
      double h = texture.size.height;

      if (w <= 0 || h <= 0) return;
56

57 58
      double scaleX = size.width / w;
      double scaleY = size.height / h;
59

60 61 62
      if (constrainProportions) {
        // Constrain proportions, using the smallest scale and by centering the image
        if (scaleX < scaleY) {
63
          canvas.translate(0.0, (size.height - scaleX * h) / 2.0);
64
          scaleY = scaleX;
65 66
        } else {
          canvas.translate((size.width - scaleY * w) / 2.0, 0.0);
67 68 69
          scaleX = scaleY;
        }
      }
70

71
      canvas.scale(scaleX, scaleY);
72 73

      // Setup paint object for opacity and transfer mode
74
      _updatePaint(_cachedPaint);
75

76
      // Do actual drawing of the sprite
77
      texture.drawTexture(canvas, Point.origin, _cachedPaint);
78
    } else {
79
      // Paint a red square for missing texture
80
      canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width, size.height),
81
      new Paint()..color = new Color.fromARGB(255, 255, 0, 0));
82 83
    }
  }
84
}
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115

abstract class SpritePaint {
  double _opacity = 1.0;

  /// The opacity of the sprite in the range 0.0 to 1.0.
  ///
  ///     mySprite.opacity = 0.5;
  double get opacity => _opacity;

  void set opacity(double opacity) {
    assert(opacity != null);
    assert(opacity >= 0.0 && opacity <= 1.0);
    _opacity = opacity;
  }

  /// The color to draw on top of the sprite, null if no color overlay is used.
  ///
  ///     // Color the sprite red
  ///     mySprite.colorOverlay = new Color(0x77ff0000);
  Color colorOverlay;

  /// The transfer mode used when drawing the sprite to screen.
  ///
  ///     // Add the colors of the sprite with the colors of the background
  ///     mySprite.transferMode = TransferMode.plusMode;
  TransferMode transferMode;

  void _updatePaint(Paint paint) {
    paint.color = new Color.fromARGB((255.0*_opacity).toInt(), 255, 255, 255);

    if (colorOverlay != null) {
V
Viktor Lidholt 已提交
116
      paint.setColorFilter(new ColorFilter.mode(colorOverlay, TransferMode.srcATop));
117 118 119
    }

    if (transferMode != null) {
V
Viktor Lidholt 已提交
120
      paint.setTransferMode(transferMode);
121 122 123
    }
  }
}