mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-10-30 16:36:57 +08:00 
			
		
		
		
	fix: Fix SpriteBatch to comply with new drawAtlas requirement (#3338)
Fix SpriteBatch to comply with new drawAtlas requirement Fixes: #3331
This commit is contained in:
		| @ -20,6 +20,11 @@ class SpriteBatchLoadExample extends FlameGame { | |||||||
|  |  | ||||||
| class MySpriteBatchComponent extends SpriteBatchComponent | class MySpriteBatchComponent extends SpriteBatchComponent | ||||||
|     with HasGameReference<SpriteBatchLoadExample> { |     with HasGameReference<SpriteBatchLoadExample> { | ||||||
|  |   MySpriteBatchComponent() | ||||||
|  |       : super( | ||||||
|  |           blendMode: BlendMode.srcOver, | ||||||
|  |         ); | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Future<void> onLoad() async { |   Future<void> onLoad() async { | ||||||
|     final spriteBatch = await game.loadSpriteBatch('boom.png'); |     final spriteBatch = await game.loadSpriteBatch('boom.png'); | ||||||
|  | |||||||
| @ -277,9 +277,7 @@ class SpriteBatch { | |||||||
|  |  | ||||||
|     _sources[index] = newBatchItem.source; |     _sources[index] = newBatchItem.source; | ||||||
|     _transforms[index] = newBatchItem.transform; |     _transforms[index] = newBatchItem.transform; | ||||||
|     if (color != null) { |     _colors[index] = color ?? _defaultColor; | ||||||
|       _colors[index] = color; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /// Add a new batch item using a RSTransform. |   /// Add a new batch item using a RSTransform. | ||||||
| @ -328,9 +326,7 @@ class SpriteBatch { | |||||||
|           : batchItem.source, |           : batchItem.source, | ||||||
|     ); |     ); | ||||||
|     _transforms.add(batchItem.transform); |     _transforms.add(batchItem.transform); | ||||||
|     if (color != null) { |     _colors.add(color ?? _defaultColor); | ||||||
|       _colors.add(color); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /// Add a new batch item. |   /// Add a new batch item. | ||||||
| @ -413,13 +409,19 @@ class SpriteBatch { | |||||||
|  |  | ||||||
|     final renderPaint = paint ?? _emptyPaint; |     final renderPaint = paint ?? _emptyPaint; | ||||||
|  |  | ||||||
|  |     final hasNoColors = _colors.every((c) => c == _defaultColor); | ||||||
|  |     final actualBlendMode = blendMode ?? defaultBlendMode; | ||||||
|  |     if (!hasNoColors && actualBlendMode == null) { | ||||||
|  |       throw 'When setting any colors, a blend mode must be provided.'; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (useAtlas && !_flippedAtlasStatus.isGenerating) { |     if (useAtlas && !_flippedAtlasStatus.isGenerating) { | ||||||
|       canvas.drawAtlas( |       canvas.drawAtlas( | ||||||
|         atlas, |         atlas, | ||||||
|         _transforms, |         _transforms, | ||||||
|         _sources, |         _sources, | ||||||
|         _colors.isEmpty ? null : _colors, |         hasNoColors ? null : _colors, | ||||||
|         blendMode ?? defaultBlendMode, |         actualBlendMode, | ||||||
|         cullRect, |         cullRect, | ||||||
|         renderPaint, |         renderPaint, | ||||||
|       ); |       ); | ||||||
| @ -441,4 +443,6 @@ class SpriteBatch { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static const _defaultColor = Color(0x00000000); | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								packages/flame/test/_goldens/sprite_batch_test_1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								packages/flame/test/_goldens/sprite_batch_test_1.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 173 B | 
							
								
								
									
										
											BIN
										
									
								
								packages/flame/test/_goldens/sprite_batch_test_2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								packages/flame/test/_goldens/sprite_batch_test_2.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 147 B | 
| @ -1,10 +1,14 @@ | |||||||
| import 'dart:ui'; | import 'dart:ui'; | ||||||
|  |  | ||||||
|  | import 'package:flame/components.dart'; | ||||||
| import 'package:flame/sprite.dart'; | import 'package:flame/sprite.dart'; | ||||||
|  | import 'package:flame_test/flame_test.dart'; | ||||||
| import 'package:flutter/material.dart' hide Image; | import 'package:flutter/material.dart' hide Image; | ||||||
| import 'package:flutter_test/flutter_test.dart'; | import 'package:flutter_test/flutter_test.dart'; | ||||||
| import 'package:mocktail/mocktail.dart'; | import 'package:mocktail/mocktail.dart'; | ||||||
|  |  | ||||||
|  | import '_resources/load_image.dart'; | ||||||
|  |  | ||||||
| class _MockImage extends Mock implements Image {} | class _MockImage extends Mock implements Image {} | ||||||
|  |  | ||||||
| void main() { | void main() { | ||||||
| @ -56,5 +60,68 @@ void main() { | |||||||
|             .having((t) => t.ty, 'ty', 1), |             .having((t) => t.ty, 'ty', 1), | ||||||
|       ); |       ); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     const margin = 2.0; | ||||||
|  |     const tileSize = 6.0; | ||||||
|  |  | ||||||
|  |     testGolden( | ||||||
|  |       'can render a batch with blend mode', | ||||||
|  |       (game) async { | ||||||
|  |         final spriteSheet = await loadImage('alphabet.png'); | ||||||
|  |         final spriteBatch = SpriteBatch(spriteSheet); | ||||||
|  |  | ||||||
|  |         const source = Rect.fromLTWH(3 * tileSize, 0, tileSize, tileSize); | ||||||
|  |  | ||||||
|  |         spriteBatch.add( | ||||||
|  |           source: source, | ||||||
|  |           color: Colors.redAccent, | ||||||
|  |           offset: Vector2.all(margin), | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         spriteBatch.add( | ||||||
|  |           source: source, | ||||||
|  |           offset: Vector2(2 * margin + tileSize, margin), | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         game.add( | ||||||
|  |           SpriteBatchComponent( | ||||||
|  |             spriteBatch: spriteBatch, | ||||||
|  |             blendMode: BlendMode.srcOver, | ||||||
|  |           ), | ||||||
|  |         ); | ||||||
|  |       }, | ||||||
|  |       size: Vector2(3 * margin + 2 * tileSize, 2 * margin + tileSize), | ||||||
|  |       backgroundColor: const Color(0xFFFFFFFF), | ||||||
|  |       goldenFile: '_goldens/sprite_batch_test_1.png', | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     testGolden( | ||||||
|  |       'can render a batch without blend mode', | ||||||
|  |       (game) async { | ||||||
|  |         final spriteSheet = await loadImage('alphabet.png'); | ||||||
|  |         final spriteBatch = SpriteBatch(spriteSheet); | ||||||
|  |  | ||||||
|  |         const source = Rect.fromLTWH(3 * tileSize, 0, tileSize, tileSize); | ||||||
|  |  | ||||||
|  |         spriteBatch.add( | ||||||
|  |           source: source, | ||||||
|  |           offset: Vector2.all(margin), | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         spriteBatch.add( | ||||||
|  |           source: source, | ||||||
|  |           offset: Vector2(2 * margin + tileSize, margin), | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         game.add( | ||||||
|  |           SpriteBatchComponent( | ||||||
|  |             spriteBatch: spriteBatch, | ||||||
|  |           ), | ||||||
|  |         ); | ||||||
|  |       }, | ||||||
|  |       size: Vector2(3 * margin + 2 * tileSize, 2 * margin + tileSize), | ||||||
|  |       backgroundColor: const Color(0xFFFFFFFF), | ||||||
|  |       goldenFile: '_goldens/sprite_batch_test_2.png', | ||||||
|  |     ); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
|  | |||||||
| @ -34,13 +34,17 @@ void testGolden( | |||||||
|   PrepareGameFunction testBody, { |   PrepareGameFunction testBody, { | ||||||
|   required String goldenFile, |   required String goldenFile, | ||||||
|   Vector2? size, |   Vector2? size, | ||||||
|  |   Color? backgroundColor, | ||||||
|   FlameGame? game, |   FlameGame? game, | ||||||
|   bool skip = false, |   bool skip = false, | ||||||
| }) { | }) { | ||||||
|   testWidgets( |   testWidgets( | ||||||
|     testName, |     testName, | ||||||
|     (tester) async { |     (tester) async { | ||||||
|       final gameInstance = game ?? FlameGame(); |       final gameInstance = game ?? | ||||||
|  |           (backgroundColor != null | ||||||
|  |               ? GameWithBackgroundColor(backgroundColor) | ||||||
|  |               : FlameGame()); | ||||||
|       const myKey = ValueKey('game-instance'); |       const myKey = ValueKey('game-instance'); | ||||||
|  |  | ||||||
|       await tester.runAsync(() async { |       await tester.runAsync(() async { | ||||||
| @ -73,3 +77,12 @@ void testGolden( | |||||||
| } | } | ||||||
|  |  | ||||||
| typedef PrepareGameFunction = Future<void> Function(FlameGame game); | typedef PrepareGameFunction = Future<void> Function(FlameGame game); | ||||||
|  |  | ||||||
|  | class GameWithBackgroundColor extends FlameGame { | ||||||
|  |   final Color _backgroundColor; | ||||||
|  |  | ||||||
|  |   GameWithBackgroundColor(this._backgroundColor); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Color backgroundColor() => _backgroundColor; | ||||||
|  | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Luan Nico
					Luan Nico