Skip to content

Commit

Permalink
feat: Add margin and spacing properties to SpriteSheet (#2925)
Browse files Browse the repository at this point in the history
This PR adds `margin` and `spacing` properties to the `SpriteSheet`
APIs. This will allow loading images that have margin and spacing in the
tiles.

---------

Co-authored-by: Lukas Klingsbo <me@lukas.fyi>
  • Loading branch information
ufrshubham and spydon committed Dec 17, 2023
1 parent dbdb137 commit 67f7c12
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
41 changes: 27 additions & 14 deletions packages/flame/lib/src/sprite_sheet.dart
Expand Up @@ -27,31 +27,42 @@ class SpriteSheet {
/// size. If it's an animation sheet, this would be the frame size.
final Vector2 srcSize;

/// The empty space around the edges of the image.
final double margin;

/// This empty space in between adjacent tiles within the image.
final double spacing;

/// The number of rows in the image based on the image height and the tile
/// size.
final int rows;

/// The number of columns in the image based on the image width and the tile
/// size.
final int columns;

final Map<int, Sprite> _spriteCache = {};

/// Creates a sprite sheet given the image and the tile size.
SpriteSheet({
required this.image,
required this.srcSize,
});
this.margin = 0,
this.spacing = 0,
}) : columns = (image.width - 2 * margin + spacing) ~/ (srcSize.x + spacing),
rows = (image.height - 2 * margin + spacing) ~/ (srcSize.y + spacing);

SpriteSheet.fromColumnsAndRows({
required this.image,
required int columns,
required int rows,
required this.columns,
required this.rows,
this.spacing = 0,
this.margin = 0,
}) : srcSize = Vector2(
image.width / columns,
image.height / rows,
(image.width - 2 * margin - (columns - 1) * spacing) / columns,
(image.height - 2 * margin - (rows - 1) * spacing) / rows,
);

/// Compute the number of columns the image has
/// by using the image width and tile size.
int get columns => image.width ~/ srcSize.x;

/// Compute the number of rows the image has
/// by using the image height and tile size.
int get rows => image.height ~/ srcSize.y;

/// Gets the sprite in the position (row, column) on the sprite sheet grid.
///
/// This is lazily computed and cached for your convenience.
Expand Down Expand Up @@ -101,7 +112,9 @@ class SpriteSheet {
final j = spriteId ~/ columns;
return Sprite(
image,
srcPosition: Vector2Extension.fromInts(i, j)..multiply(srcSize),
srcPosition: Vector2Extension.fromInts(i, j)
..multiply(srcSize)
..translate(margin + i * spacing, margin + j * spacing),
srcSize: srcSize,
);
}
Expand Down
25 changes: 25 additions & 0 deletions packages/flame/test/spritesheet_test.dart
Expand Up @@ -23,6 +23,31 @@ void main() {
expect(spriteSheet.columns, 100);
});

test('calculates columns and rows with margin and spacing', () {
final spriteSheet = SpriteSheet(
image: image,
srcSize: Vector2(1, 2),
margin: 3,
spacing: 2,
);

expect(spriteSheet.rows, 24);
expect(spriteSheet.columns, 32);
});

test('calculates srcSize with margin and spacing', () {
final spriteSheet = SpriteSheet.fromColumnsAndRows(
image: image,
columns: 32,
rows: 24,
margin: 3,
spacing: 2,
);

expect(spriteSheet.srcSize.x, 1);
expect(spriteSheet.srcSize.y, 2);
});

test('assign the correct time in sprite', () {
final spriteSheet = SpriteSheet(
image: image,
Expand Down

0 comments on commit 67f7c12

Please sign in to comment.