Bug Description
The Sprite.rasterize() method creates a new sprite with a rasterized copy of just the sprite region, but it doesn't reset srcPosition to (0, 0). This causes the source rectangle to have coordinates that are completely outside the bounds of the new smaller image, leading to a drawImageRect assertion failure when the sprite is rendered.
Reproduction Steps
// 1. Create a sprite from an atlas at position (8, 7) with tileSize 16
final originalSprite = Sprite(
atlasImage, // e.g., 336x160 pixels
srcPosition: Vector2(128, 112), // 8 * 16, 7 * 16
srcSize: Vector2(16, 16),
);
// 2. Rasterize it - this creates a 16x16 image
final rasterized = await originalSprite.rasterize();
// 3. The rasterized sprite now has:
// - image: 16x16 (just the sprite region)
// - src: Rect(128, 112, 144, 128) <-- PROBLEM!
//
// The src rect is OUTSIDE the 16x16 image bounds!
// 4. Render it - this will crash:
// Failed assertion: line 7471 pos 12: '<optimized out>': is not true.
// (Canvas.drawImageRect with out-of-bounds src rect)
Root Cause
In packages/flame/lib/src/sprite.dart lines 93-96:
Future<Sprite> rasterize({String? cacheKey, Images? images}) async {
// ... creates rasterizedImage ...
return Sprite(
rasterizedImage,
srcSize: srcSize, // <-- Only srcSize is passed
// srcPosition is NOT passed, so it defaults to null
// and the original srcPosition is retained
);
}
The Sprite constructor at lines 23-30 only updates srcSize, but srcPosition defaults to null, which means the old position is used via the src Rect calculation.
Expected Behavior
After rasterize(), the sprite should have srcPosition reset to (0, 0) since the new image contains only the sprite region starting at the origin.
Fix
return Sprite(
rasterizedImage,
srcPosition: Vector2.zero(), // Reset to origin
srcSize: srcSize,
);
Environment
- Flame version: 1.35.1 (also affects earlier versions)
- Flutter version: 3.x
- Platform: All (macOS, iOS, Android, Web, Windows, Linux)
Impact
This bug affects:
SpriteWidget with rasterize: true parameter
- Any custom code that calls
Sprite.rasterize() and then renders the result
- Causes hard-to-debug
dart:ui assertion failures
Workaround
Until fixed, users can manually create the rasterized sprite:
final composition = ImageComposition()
..add(originalSprite.image, Vector2.zero(), source: originalSprite.src);
final rasterizedImage = await composition.compose();
final fixedSprite = Sprite(
rasterizedImage,
srcPosition: Vector2.zero(), // Explicitly set to origin
srcSize: originalSprite.srcSize,
);
Bug Description
The
Sprite.rasterize()method creates a new sprite with a rasterized copy of just the sprite region, but it doesn't resetsrcPositionto(0, 0). This causes the source rectangle to have coordinates that are completely outside the bounds of the new smaller image, leading to adrawImageRectassertion failure when the sprite is rendered.Reproduction Steps
Root Cause
In
packages/flame/lib/src/sprite.dartlines 93-96:The
Spriteconstructor at lines 23-30 only updatessrcSize, butsrcPositiondefaults to null, which means the old position is used via thesrcRect calculation.Expected Behavior
After
rasterize(), the sprite should havesrcPositionreset to(0, 0)since the new image contains only the sprite region starting at the origin.Fix
Environment
Impact
This bug affects:
SpriteWidgetwithrasterize: trueparameterSprite.rasterize()and then renders the resultdart:uiassertion failuresWorkaround
Until fixed, users can manually create the rasterized sprite: