@@ -262,9 +262,31 @@ Future<TextureAtlasData> _parse(
262262 }
263263 }
264264
265+ var currentPackage = package;
266+ var finalPath = fullPath;
267+
268+ // Check for package path in the full path (which may already include assetsPrefix)
269+ const packageKeyword = 'packages/' ;
270+ final packageIndex = finalPath.indexOf (packageKeyword);
271+ if (packageIndex != - 1 ) {
272+ final subPath = finalPath.substring (packageIndex + packageKeyword.length);
273+ final parts = subPath.split ('/' );
274+ if (parts.length > 1 ) {
275+ currentPackage ?? = parts[0 ];
276+ // Clean the path by removing everything up to and including the package name
277+ finalPath = parts.sublist (1 ).join ('/' );
278+ }
279+ }
280+
281+ // AssetsCache also prepends its own prefix (usually 'assets/')
282+ final assetsCachePrefix = (assets ?? Flame .assets).prefix;
283+ if (finalPath.startsWith (assetsCachePrefix)) {
284+ finalPath = finalPath.replaceFirst (assetsCachePrefix, '' );
285+ }
286+
265287 fileContent = await (assets ?? Flame .assets).readFile (
266- fullPath ,
267- package: package ,
288+ finalPath ,
289+ package: currentPackage ,
268290 );
269291 }
270292
@@ -293,6 +315,30 @@ Future<TextureAtlasData> _parse(
293315
294316 // Check if this line looks like a texture file (has file extension)
295317 if (_isTextureFile (line)) {
318+ // Peek at the next line to see if it's a region or a new page.
319+ // Regions are followed by properties like 'bounds:', 'rotate:', 'xy:', 'offsets:'.
320+ // Pages are followed by 'size:', 'format:', 'filter:', 'repeat:'.
321+ if (lineQueue.length > 1 ) {
322+ final nextLine = lineQueue.elementAt (1 ).trim ();
323+ final isRegionProperty =
324+ nextLine.startsWith ('bounds:' ) ||
325+ nextLine.startsWith ('rotate:' ) ||
326+ nextLine.startsWith ('xy:' ) ||
327+ nextLine.startsWith ('offsets:' ) ||
328+ nextLine.startsWith ('orig:' ) ||
329+ nextLine.startsWith ('offset:' ) ||
330+ nextLine.startsWith ('index:' );
331+
332+ if (isRegionProperty) {
333+ // This is a region name that happens to have a file extension.
334+ final region = _parseRegion (lineQueue, page);
335+ if (region.index != - 1 ) {
336+ hasIndexes = true ;
337+ }
338+ regions.add (region);
339+ continue ;
340+ }
341+ }
296342 break ; // This is a new page, break out of region parsing
297343 }
298344
@@ -388,7 +434,29 @@ Future<Page> _parsePage(
388434 }
389435 }
390436
391- page.texture = await images.load (fullTexturePath, package: package);
437+ var currentPackage = package;
438+ var finalTexturePath = fullTexturePath;
439+
440+ const packageKeyword = 'packages/' ;
441+ final packageIndex = finalTexturePath.indexOf (packageKeyword);
442+ if (packageIndex != - 1 ) {
443+ final subPath = finalTexturePath.substring (
444+ packageIndex + packageKeyword.length,
445+ );
446+ final parts = subPath.split ('/' );
447+ if (parts.length > 1 ) {
448+ currentPackage ?? = parts[0 ];
449+ finalTexturePath = parts.sublist (1 ).join ('/' );
450+ }
451+ }
452+
453+ // Images cache also prepends its own prefix (usually 'assets/images/')
454+ final imagesPrefix = images.prefix;
455+ if (finalTexturePath.startsWith (imagesPrefix)) {
456+ finalTexturePath = finalTexturePath.replaceFirst (imagesPrefix, '' );
457+ }
458+
459+ page.texture = await images.load (finalTexturePath, package: currentPackage);
392460 }
393461
394462 _parsePageProperties (lineQueue, page);
@@ -436,7 +504,29 @@ void _parsePageProperties(ListQueue<String> lineQueue, Page page) {
436504///
437505/// Returns the parsed [Region] .
438506Region _parseRegion (ListQueue <String > lineQueue, Page page) {
439- final name = lineQueue.removeFirst ().trim ();
507+ var name = lineQueue.removeFirst ().trim ();
508+ var extractedIndex = - 1 ;
509+
510+ // Attempt to extract index and clean name if it follows patterns like
511+ // 'name_01.png' or 'name_01'
512+ final extensionMatch = RegExp (
513+ r'\.(png|jpg|jpeg|bmp|tga|webp)$' ,
514+ caseSensitive: false ,
515+ ).firstMatch (name);
516+ if (extensionMatch != null ) {
517+ name = name.substring (0 , extensionMatch.start);
518+ }
519+
520+ final indexMatch = RegExp (r'_(\d+)$' ).firstMatch (name);
521+ if (indexMatch != null ) {
522+ try {
523+ extractedIndex = int .parse (indexMatch.group (1 )! );
524+ name = name.substring (0 , indexMatch.start);
525+ } catch (_) {
526+ // Ignore parsing errors for very large numbers
527+ }
528+ }
529+
440530 final values = < String , List <String >> {};
441531
442532 while (lineQueue.isNotEmpty) {
@@ -504,7 +594,7 @@ Region _parseRegion(ListQueue<String> lineQueue, Page page) {
504594 originalHeight: finalOriginalHeight,
505595 degrees: _parseDegrees (rotate? .first),
506596 rotate: _parseDegrees (rotate? .first) == 90 ,
507- index: index != null ? int .parse (index[0 ]) : - 1 ,
597+ index: index != null ? int .parse (index[0 ]) : extractedIndex ,
508598 );
509599}
510600
0 commit comments