mirror of
https://github.com/flame-engine/flame.git
synced 2025-10-30 00:17:20 +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