Skip to content

Commit 33d99b7

Browse files
authored
feat: Add imageRect for Tile (#64)
1 parent 1b516df commit 33d99b7

File tree

4 files changed

+107
-4
lines changed

4 files changed

+107
-4
lines changed

packages/tiled/lib/src/tileset/tile.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class Tile {
2727
List<int?> terrain;
2828

2929
TiledImage? image;
30+
Rect? imageRect;
3031
Layer? objectGroup;
3132
List<Frame> animation;
3233
CustomProperties properties;
@@ -37,6 +38,7 @@ class Tile {
3738
this.probability = 0,
3839
this.terrain = const [],
3940
this.image,
41+
this.imageRect,
4042
this.objectGroup,
4143
this.animation = const [],
4244
this.properties = CustomProperties.empty,
@@ -64,6 +66,12 @@ class Tile {
6466
.toList() ??
6567
[],
6668
image: parser.getSingleChildOrNullAs('image', TiledImage.parse),
69+
imageRect: Rect.fromLTWH(
70+
parser.getDoubleOrNull('x') ?? 0,
71+
parser.getDoubleOrNull('y') ?? 0,
72+
parser.getDoubleOrNull('width') ?? 0,
73+
parser.getDoubleOrNull('height') ?? 0,
74+
),
6775
objectGroup:
6876
parser.getSingleChildOrNullAs('objectgroup', Layer.parse),
6977
animation: parser.formatSpecificParsing(

packages/tiled/lib/src/tileset/tileset.dart

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,13 @@ class Tileset {
9393
this.backgroundColor,
9494
this.transparentColor,
9595
this.type = TilesetType.tileset,
96-
}) : tiles = _generateTiles(tiles, tileCount ?? 0) {
96+
}) : tiles = _generateTiles(
97+
tiles,
98+
tileCount ?? 0,
99+
columns,
100+
tileWidth,
101+
tileHeight,
102+
) {
97103
tileCount = this.tiles.length;
98104
}
99105

@@ -214,10 +220,36 @@ class Tileset {
214220
);
215221
}
216222

217-
static List<Tile> _generateTiles(List<Tile> explicitTiles, int tileCount) {
223+
static List<Tile> _generateTiles(
224+
List<Tile> explicitTiles,
225+
int tileCount,
226+
int? columns,
227+
int? tileWidth,
228+
int? tileHeight,
229+
) {
218230
final tiles = <Tile>[];
219-
for (var i = 0; i < tileCount; i += 1) {
220-
tiles.add(Tile(localId: i));
231+
232+
for (var i = 0; i < tileCount; ++i) {
233+
Rect? imageRect;
234+
235+
if (columns != null &&
236+
columns != 0 &&
237+
tileWidth != null &&
238+
tileHeight != null) {
239+
final x = (i % columns) * tileWidth;
240+
final y = i ~/ columns * tileHeight;
241+
242+
imageRect = Rect.fromLTWH(
243+
x.toDouble(),
244+
y.toDouble(),
245+
tileWidth.toDouble(),
246+
tileHeight.toDouble(),
247+
);
248+
}
249+
250+
tiles.add(
251+
Tile(localId: i, imageRect: imageRect),
252+
);
221253
}
222254

223255
for (final tile in explicitTiles) {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<tileset version="1.9" tiledversion="1.9.2" name="multi_image_tileset" tilewidth="32" tileheight="32" tilecount="2" columns="0">
3+
<grid orientation="orthogonal" width="1" height="1"/>
4+
<tile id="0" x="64" y="96" width="32" height="32">
5+
<image width="256" height="256" source="floortileset.png"/>
6+
</tile>
7+
<tile id="1" x="0" y="0" width="20" height="20">
8+
<image width="160" height="20" source="coins.png"/>
9+
</tile>
10+
</tileset>

packages/tiled/test/tile_test.dart

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import 'dart:io';
2+
import 'dart:ui';
3+
14
import 'package:test/test.dart';
25
import 'package:tiled/tiled.dart';
6+
import 'package:xml/xml.dart';
37

48
void main() {
59
group('Tile.emptyTile()', () {
@@ -25,4 +29,53 @@ void main() {
2529
final tile = Tile(localId: -1);
2630
expect(tile.properties, isA<CustomProperties>());
2731
});
32+
33+
group(
34+
'Tile.imageRect',
35+
() {
36+
late Tileset tileset1;
37+
late Tileset tileset2;
38+
39+
setUp(() {
40+
final f1 = File('./test/fixtures/multi_image_tileset.tsx')
41+
.readAsString()
42+
.then((xml) {
43+
final tilesetXml = XmlDocument.parse(xml).rootElement;
44+
tileset1 = Tileset.parse(XmlParser(tilesetXml));
45+
});
46+
47+
final f2 = File('./test/fixtures/tileid_over_tilecount.tsx')
48+
.readAsString()
49+
.then((xml) {
50+
final tilesetXml = XmlDocument.parse(xml).rootElement;
51+
tileset2 = Tileset.parse(XmlParser(tilesetXml));
52+
});
53+
54+
return Future.wait([f1, f2]);
55+
});
56+
57+
test('with image collections', () {
58+
final tile1 = tileset1.tiles.firstWhere((t) => t.localId == 0);
59+
final tile2 = tileset1.tiles.firstWhere((t) => t.localId == 1);
60+
61+
expect(tile1.imageRect, const Rect.fromLTWH(64, 96, 32, 32));
62+
expect(tile2.imageRect, const Rect.fromLTWH(0, 0, 20, 20));
63+
});
64+
65+
test(
66+
'with single image',
67+
() {
68+
final tile1 = tileset2.tiles.firstWhere((t) => t.localId == 58);
69+
final tile2 = tileset2.tiles.firstWhere((t) => t.localId == 106);
70+
final tile3 = tileset2.tiles.firstWhere((t) => t.localId == 129);
71+
final tile4 = tileset2.tiles.firstWhere((t) => t.localId == 11);
72+
73+
expect(tile1.imageRect, const Rect.fromLTWH(112, 48, 16, 16));
74+
expect(tile2.imageRect, const Rect.fromLTWH(64, 96, 16, 16));
75+
expect(tile3.imageRect, const Rect.fromLTWH(160, 112, 16, 16));
76+
expect(tile4.imageRect, const Rect.fromLTWH(176, 0, 16, 16));
77+
},
78+
);
79+
},
80+
);
2881
}

0 commit comments

Comments
 (0)