mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-10-31 17:06:50 +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 | ||||
|     with HasGameReference<SpriteBatchLoadExample> { | ||||
|   MySpriteBatchComponent() | ||||
|       : super( | ||||
|           blendMode: BlendMode.srcOver, | ||||
|         ); | ||||
|  | ||||
|   @override | ||||
|   Future<void> onLoad() async { | ||||
|     final spriteBatch = await game.loadSpriteBatch('boom.png'); | ||||
|  | ||||
| @ -277,9 +277,7 @@ class SpriteBatch { | ||||
|  | ||||
|     _sources[index] = newBatchItem.source; | ||||
|     _transforms[index] = newBatchItem.transform; | ||||
|     if (color != null) { | ||||
|       _colors[index] = color; | ||||
|     } | ||||
|     _colors[index] = color ?? _defaultColor; | ||||
|   } | ||||
|  | ||||
|   /// Add a new batch item using a RSTransform. | ||||
| @ -328,9 +326,7 @@ class SpriteBatch { | ||||
|           : batchItem.source, | ||||
|     ); | ||||
|     _transforms.add(batchItem.transform); | ||||
|     if (color != null) { | ||||
|       _colors.add(color); | ||||
|     } | ||||
|     _colors.add(color ?? _defaultColor); | ||||
|   } | ||||
|  | ||||
|   /// Add a new batch item. | ||||
| @ -413,13 +409,19 @@ class SpriteBatch { | ||||
|  | ||||
|     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) { | ||||
|       canvas.drawAtlas( | ||||
|         atlas, | ||||
|         _transforms, | ||||
|         _sources, | ||||
|         _colors.isEmpty ? null : _colors, | ||||
|         blendMode ?? defaultBlendMode, | ||||
|         hasNoColors ? null : _colors, | ||||
|         actualBlendMode, | ||||
|         cullRect, | ||||
|         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 'package:flame/components.dart'; | ||||
| import 'package:flame/sprite.dart'; | ||||
| import 'package:flame_test/flame_test.dart'; | ||||
| import 'package:flutter/material.dart' hide Image; | ||||
| import 'package:flutter_test/flutter_test.dart'; | ||||
| import 'package:mocktail/mocktail.dart'; | ||||
|  | ||||
| import '_resources/load_image.dart'; | ||||
|  | ||||
| class _MockImage extends Mock implements Image {} | ||||
|  | ||||
| void main() { | ||||
| @ -56,5 +60,68 @@ void main() { | ||||
|             .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, { | ||||
|   required String goldenFile, | ||||
|   Vector2? size, | ||||
|   Color? backgroundColor, | ||||
|   FlameGame? game, | ||||
|   bool skip = false, | ||||
| }) { | ||||
|   testWidgets( | ||||
|     testName, | ||||
|     (tester) async { | ||||
|       final gameInstance = game ?? FlameGame(); | ||||
|       final gameInstance = game ?? | ||||
|           (backgroundColor != null | ||||
|               ? GameWithBackgroundColor(backgroundColor) | ||||
|               : FlameGame()); | ||||
|       const myKey = ValueKey('game-instance'); | ||||
|  | ||||
|       await tester.runAsync(() async { | ||||
| @ -73,3 +77,12 @@ void testGolden( | ||||
| } | ||||
|  | ||||
| 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