Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions packages/flame_tiled/lib/src/renderable_layers/image_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class FlameImageLayer extends RenderableLayer<ImageLayer> {
final Image _image;
late final ImageRepeat _repeat;
final MutableRect _paintArea = MutableRect.fromLTRB(0, 0, 0, 0);
final Vector2 _canvasSize = Vector2.zero();
final Vector2 _maxTranslation = Vector2.zero();
late final Vector2 _mapSize;

FlameImageLayer({
required super.layer,
Expand All @@ -25,13 +25,15 @@ class FlameImageLayer extends RenderableLayer<ImageLayer> {
required Image image,
super.filterQuality,
}) : _image = image {
_mapSize = Vector2(
map.width * destTileSize.x,
map.height * destTileSize.y,
);
_initImageRepeat();
}

@override
void handleResize(Vector2 canvasSize) {
_canvasSize.setFrom(canvasSize);
}
void handleResize(Vector2 canvasSize) {}

@override
void render(Canvas canvas, CameraComponent? camera) {
Expand Down Expand Up @@ -79,20 +81,22 @@ class FlameImageLayer extends RenderableLayer<ImageLayer> {
// it still matches up with its initial layer offsets.

if (_repeat == ImageRepeat.repeatX || _repeat == ImageRepeat.repeat) {
final xImages = (_maxTranslation.x / _image.size.x).ceil();
// Calculate images needed for max translation and map size
final xImages = ((_maxTranslation.x + _mapSize.x) / _image.size.x).ceil();
_paintArea.left = -_image.size.x * xImages;
_paintArea.right = _canvasSize.x + _image.size.x * xImages;
_paintArea.right = _image.size.x * xImages;
} else {
_paintArea.left = 0;
_paintArea.right = _canvasSize.x;
_paintArea.right = _mapSize.x;
}
if (_repeat == ImageRepeat.repeatY || _repeat == ImageRepeat.repeat) {
final yImages = (_maxTranslation.y / _image.size.y).ceil();
// Calculate images needed for max translation and map size
final yImages = ((_maxTranslation.y + _mapSize.y) / _image.size.y).ceil();
_paintArea.top = -_image.size.y * yImages;
_paintArea.bottom = _canvasSize.y + _image.size.y * yImages;
_paintArea.bottom = _image.size.y * yImages;
} else {
_paintArea.top = 0;
_paintArea.bottom = _canvasSize.y;
_paintArea.bottom = _mapSize.y;
}
}

Expand Down
17 changes: 17 additions & 0 deletions packages/flame_tiled/test/assets/image_layer_full_screen.tmx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.11.2" orientation="orthogonal" renderorder="right-down"
width="15" height="15" tilewidth="16" tileheight="16" infinite="0" nextlayerid="5"
nextobjectid="1">
<imagelayer id="1" name="BackgroundImage">
<image source="Tileset_Hexagonal_PointyTop_60x52_60x80.png" width="240" height="240" />
</imagelayer>
<imagelayer id="2" name="GreenSprite" offsetx="112" offsety="112">
<image source="green_sprite.png" width="16" height="16" />
</imagelayer>
<imagelayer id="3" name="RedSprite" offsetx="224" offsety="0">
<image source="red_sprite.png" width="16" height="16" />
</imagelayer>
<imagelayer id="4" name="Gear" offsetx="16" offsety="144">
<image source="images/gear.png" width="128" height="74" />
</imagelayer>
</map>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions packages/flame_tiled/test/image_layer_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import 'package:flame/cache.dart';
import 'package:flame/game.dart';
import 'package:flame_tiled/flame_tiled.dart';
import 'package:flutter_test/flutter_test.dart';

import 'test_asset_bundle.dart';
import 'test_image_utils.dart';

void main() {
TestWidgetsFlutterBinding.ensureInitialized();

setUp(TiledAtlas.atlasMap.clear);

group('ImageLayer rendering', () {
test(
'image layer covers entire map',
() async {
final bundle = TestAssetBundle(
imageNames: [
'Tileset_Hexagonal_PointyTop_60x52_60x80.png',
'images/gear.png',
'green_sprite.png',
'red_sprite.png',
],
stringNames: ['image_layer_full_screen.tmx'],
);

final component = await TiledComponent.load(
'image_layer_full_screen.tmx',
Vector2.all(16),
bundle: bundle,
images: Images(bundle: bundle),
);

// The map is 15x15 tiles at 16x16, so the total size is 240x240
expect(component.size, Vector2(240, 240));

// Initialize game context
final game = FlameGame();
game.onGameResize(component.size);
game.world.add(component);
await component.onLoad();
await game.ready();

final pngData = await renderMapToPng(component);

expect(
pngData,
matchesGoldenFile('goldens/image_layer_covers_map.png'),
);
},
);
});
}