Skip to content

Commit 1d3043f

Browse files
authored
feat: Add convenience method for getting images in each layer (flame-engine#66)
This PR adds the convenience method to the TiledMap that gets all TiledImage in the specific layer. If the layer is Group, the method gets all images in the group recursively.
1 parent d71d0c8 commit 1d3043f

16 files changed

+182
-18
lines changed

packages/tiled/lib/src/tiled_map.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,33 @@ class TiledMap {
219219
return imageSet.toList();
220220
}
221221

222+
List<TiledImage> collectImagesInLayer(Layer layer) {
223+
if (layer is ImageLayer) {
224+
return [layer.image];
225+
} else if (layer is Group) {
226+
return layer.layers.expand(collectImagesInLayer).toList();
227+
} else if (layer is TileLayer) {
228+
const emptyTile = 0;
229+
final rows = layer.tileData ?? <List<Gid>>[];
230+
final gids = rows
231+
.expand((row) => row.map((gid) => gid.tile))
232+
.where((gid) => gid != emptyTile)
233+
.toSet();
234+
235+
return gids
236+
.map(tilesetByTileGId)
237+
.toSet() // The different gid can be in the same tileset
238+
.expand(
239+
(tileset) =>
240+
[tileset.image, ...tileset.tiles.map((tile) => tile.image)],
241+
)
242+
.whereNotNull()
243+
.toList();
244+
}
245+
246+
return [];
247+
}
248+
222249
/// Finds the first layer with the matching [name], or throw an
223250
/// [ArgumentError] if one cannot be found.
224251
/// Will search recursively through [Group] children.

packages/tiled/pubspec.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ dependencies:
1414
xml: ^6.1.0
1515

1616
dev_dependencies:
17-
dartdoc: ^4.1.0
18-
flame_lint: ^0.1.2
19-
test: any
17+
dartdoc: ^6.0.1
18+
flame_lint: ^0.2.0
19+
flutter_test:
20+
sdk: flutter

packages/tiled/test/complexmap_infinite_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'dart:io';
22

3-
import 'package:test/test.dart';
3+
import 'package:flutter_test/flutter_test.dart';
44
import 'package:tiled/tiled.dart';
55

66
void main() {

packages/tiled/test/image_layer_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'dart:io';
22

3-
import 'package:test/test.dart';
3+
import 'package:flutter_test/flutter_test.dart';
44
import 'package:tiled/tiled.dart';
55

66
void main() {

packages/tiled/test/isometric_staggered_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'dart:io';
22

3-
import 'package:test/test.dart';
3+
import 'package:flutter_test/flutter_test.dart';
44
import 'package:tiled/tiled.dart';
55

66
void main() {

packages/tiled/test/isometric_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'dart:io';
22

3-
import 'package:test/test.dart';
3+
import 'package:flutter_test/flutter_test.dart';
44
import 'package:tiled/tiled.dart';
55

66
void main() {

packages/tiled/test/layer_test.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import 'dart:async';
21
import 'dart:io';
32
import 'dart:ui';
43

5-
import 'package:test/test.dart';
4+
import 'package:flutter_test/flutter_test.dart';
65
import 'package:tiled/tiled.dart';
76

87
void main() {

packages/tiled/test/map_test.dart

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import 'package:test/test.dart';
1+
import 'package:flutter_test/flutter_test.dart';
22
import 'package:tiled/tiled.dart';
33

44
void main() {
@@ -151,6 +151,142 @@ void main() {
151151
});
152152
});
153153

154+
group('Map.collectImagesInLayer', () {
155+
late TiledMap map;
156+
setUp(() {
157+
map = TiledMap(
158+
width: 2,
159+
height: 2,
160+
tileWidth: 8,
161+
tileHeight: 8,
162+
layers: [
163+
TileLayer(
164+
name: 'tile layer 1',
165+
width: 2,
166+
height: 2,
167+
data: [1, 0, 2, 0],
168+
),
169+
Group(
170+
name: 'group layer 1',
171+
layers: [
172+
TileLayer(
173+
name: 'group - tile layer 1',
174+
width: 2,
175+
height: 2,
176+
data: [1, 2, 3, 0],
177+
),
178+
TileLayer(
179+
name: 'group - tile layer 2',
180+
width: 2,
181+
height: 2,
182+
data: [5, 0, 0, 0],
183+
),
184+
],
185+
),
186+
ImageLayer(
187+
name: 'image layer 1',
188+
image: const TiledImage(source: 'image_layer.png'),
189+
repeatX: false,
190+
repeatY: false,
191+
),
192+
ObjectGroup(name: 'object layer 1', objects: []),
193+
TileLayer(
194+
name: 'tile layer 3 (empty)',
195+
width: 2,
196+
height: 2,
197+
data: [0, 0, 0, 0],
198+
),
199+
],
200+
tilesets: [
201+
Tileset(
202+
name: 'TileSet_1',
203+
image: const TiledImage(source: 'tileset_1.png'),
204+
firstGid: 1,
205+
columns: 1,
206+
tileCount: 2,
207+
tiles: [
208+
Tile(localId: 0),
209+
Tile(localId: 1),
210+
],
211+
),
212+
Tileset(
213+
name: 'TileSet_2',
214+
image: const TiledImage(source: 'tileset_2.png'),
215+
firstGid: 3,
216+
columns: 1,
217+
tileCount: 2,
218+
tiles: [
219+
Tile(localId: 0),
220+
Tile(localId: 1),
221+
],
222+
),
223+
Tileset(
224+
name: 'TileSet_3',
225+
image: const TiledImage(source: 'tileset_3.png'),
226+
firstGid: 5,
227+
columns: 1,
228+
tileCount: 2,
229+
tiles: [
230+
Tile(localId: 0),
231+
Tile(localId: 1),
232+
],
233+
),
234+
],
235+
);
236+
});
237+
238+
test('gets images only in use on each TileLayer', () {
239+
final tileLayer1 = map.layerByName('tile layer 1');
240+
final tileLayer2 = map.layerByName('group - tile layer 1');
241+
242+
final images1 = map.collectImagesInLayer(tileLayer1);
243+
final images2 = map.collectImagesInLayer(tileLayer2);
244+
245+
expect(images1, hasLength(1));
246+
expect(images1[0].source, equals('tileset_1.png'));
247+
248+
expect(images2, hasLength(2));
249+
expect(images2[0].source, equals('tileset_1.png'));
250+
expect(images2[1].source, equals('tileset_2.png'));
251+
});
252+
253+
test('gets no image if TileLayer is empty', () {
254+
final tileLayer = map.layerByName('tile layer 3 (empty)');
255+
256+
final images = map.collectImagesInLayer(tileLayer);
257+
258+
expect(images, hasLength(0));
259+
});
260+
261+
test('gets all images recursively in the Group', () {
262+
final tileLayerInsideGroup = map.layerByName('group layer 1');
263+
264+
final images3 = map.collectImagesInLayer(tileLayerInsideGroup);
265+
266+
expect(images3, hasLength(3));
267+
expect(images3[0].source, equals('tileset_1.png'));
268+
expect(images3[1].source, equals('tileset_2.png'));
269+
expect(images3[2].source, equals('tileset_3.png'));
270+
});
271+
272+
test('gets a image in the ImageLayer', () {
273+
final imageLayer = map.layerByName('image layer 1');
274+
275+
final images = map.collectImagesInLayer(imageLayer);
276+
277+
expect(images, hasLength(1));
278+
expect(images[0].source, equals('image_layer.png'));
279+
});
280+
281+
test('gets no image in the ObjectLayer', () {
282+
final imageLayer = map.layerByName('object layer 1');
283+
284+
final images = map.collectImagesInLayer(imageLayer);
285+
286+
expect(images, hasLength(0));
287+
});
288+
});
289+
154290
group('Map.getTileSet', () {
155291
late TiledMap map;
156292
final tileset = Tileset(

packages/tiled/test/object_group_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'dart:io';
22
import 'dart:ui';
33

4-
import 'package:test/test.dart';
4+
import 'package:flutter_test/flutter_test.dart';
55
import 'package:tiled/tiled.dart';
66

77
void main() {

packages/tiled/test/overflow_bug_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import 'dart:io';
44

5-
import 'package:test/test.dart';
5+
import 'package:flutter_test/flutter_test.dart';
66
import 'package:tiled/tiled.dart';
77

88
void main() {

0 commit comments

Comments
 (0)