mirror of
https://github.com/flame-engine/flame.git
synced 2025-10-30 00:17:20 +08:00
feat(flame): Add helper methods to create frame data on SpriteSheet (#2754)
Add two methods to SpriteSheet to create frame data for SpriteAnimation
This commit is contained in:
committed by
GitHub
parent
7313cd5352
commit
477221998a
@ -331,21 +331,37 @@ a very simple example of how to use it:
|
|||||||
```dart
|
```dart
|
||||||
import 'package:flame/sprite.dart';
|
import 'package:flame/sprite.dart';
|
||||||
|
|
||||||
final spritesheet = SpriteSheet(
|
final spriteSheet = SpriteSheet(
|
||||||
image: imageInstance,
|
image: imageInstance,
|
||||||
srcSize: Vector2.all(16.0),
|
srcSize: Vector2.all(16.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
final animation = spritesheet.createAnimation(0, stepTime: 0.1);
|
final animation = spriteSheet.createAnimation(0, stepTime: 0.1);
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you can use the animation directly or use it in an animation component.
|
Now you can use the animation directly or use it in an animation component.
|
||||||
|
|
||||||
You can also get a single frame of the sprite sheet using the `getSprite` method:
|
You can also create a custom animation by retrieving individual `SpriteAnimationFrameData` using
|
||||||
|
either `SpriteSheet.createFrameData` or `SpriteSheet.createFrameDataFromId`:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
spritesheet.getSprite(0, 0) // row, column;
|
final animation = SpriteAnimation.fromFrameData(
|
||||||
|
imageInstance,
|
||||||
|
SpriteAnimationData([
|
||||||
|
spriteSheet.createFrameDataFromId(1, stepTime: 0.1), // by id
|
||||||
|
spriteSheet.createFrameData(2, 3, stepTime: 0.3), // row, column
|
||||||
|
spriteSheet.createFrameDataFromId(4, stepTime: 0.1), // by id
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
If you don't need any kind of animation and instead only want an instance of a `Sprite` on the
|
||||||
|
`SpriteSheet` you can use the `getSprite` or `getSpriteById` methods:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
spriteSheet.getSpriteById(2); // by id
|
||||||
|
spriteSheet.getSprite(0, 0); // row, column
|
||||||
```
|
```
|
||||||
|
|
||||||
You can see a full example of the `SpriteSheet` class
|
You can see a full example of the `SpriteSheet` class
|
||||||
[here](https://github.com/flame-engine/flame/blob/main/examples/lib/stories/sprites/spritesheet_example.dart).
|
[here](https://github.com/flame-engine/flame/blob/main/examples/lib/stories/sprites/sprite_sheet_example.dart).
|
||||||
|
|||||||
@ -308,7 +308,7 @@ it's fully played during the `Particle` lifespan. It's possible to override this
|
|||||||
`alignAnimationTime` argument.
|
`alignAnimationTime` argument.
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
final spritesheet = SpriteSheet(
|
final spriteSheet = SpriteSheet(
|
||||||
image: yourSpriteSheetImage,
|
image: yourSpriteSheetImage,
|
||||||
srcSize: Vector2.all(16.0),
|
srcSize: Vector2.all(16.0),
|
||||||
);
|
);
|
||||||
@ -316,7 +316,7 @@ final spritesheet = SpriteSheet(
|
|||||||
game.add(
|
game.add(
|
||||||
ParticleSystemComponent(
|
ParticleSystemComponent(
|
||||||
particle: SpriteAnimationParticle(
|
particle: SpriteAnimationParticle(
|
||||||
animation: spritesheet.createAnimation(0, stepTime: 0.1),
|
animation: spriteSheet.createAnimation(0, stepTime: 0.1),
|
||||||
);
|
);
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -261,7 +261,7 @@ generate a `TextElement`.
|
|||||||
Flame provides two concrete implementations:
|
Flame provides two concrete implementations:
|
||||||
|
|
||||||
- `TextPaint`: most used, uses Flutter `TextPainter` to render regular text
|
- `TextPaint`: most used, uses Flutter `TextPainter` to render regular text
|
||||||
- `SpriteFontRenderer`: uses a `SpriteFont` (a spritesheet-based font) to render bitmap text
|
- `SpriteFontRenderer`: uses a `SpriteFont` (a sprite sheet-based font) to render bitmap text
|
||||||
- `DebugTextRenderer`: only intended to be used for Golden Tests
|
- `DebugTextRenderer`: only intended to be used for Golden Tests
|
||||||
|
|
||||||
But you can also provide your own if you want to extend to other customized forms of text rendering.
|
But you can also provide your own if you want to extend to other customized forms of text rendering.
|
||||||
@ -340,7 +340,7 @@ Palette](palette.md) guide.
|
|||||||
#### SpriteFontRenderer
|
#### SpriteFontRenderer
|
||||||
|
|
||||||
The other renderer option provided out of the box is `SpriteFontRenderer`, which allows you to
|
The other renderer option provided out of the box is `SpriteFontRenderer`, which allows you to
|
||||||
provide a `SpriteFont` based off of a spritesheet. TODO
|
provide a `SpriteFont` based off of a sprite sheet. TODO
|
||||||
|
|
||||||
|
|
||||||
#### DebugTextRenderer
|
#### DebugTextRenderer
|
||||||
|
|||||||
@ -75,14 +75,14 @@ klondike/
|
|||||||
└─pubspec.yaml
|
└─pubspec.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
By the way, this kind of file is called the **spritesheet**: it's just a
|
By the way, this kind of file is called the **sprite sheet**: it's just a
|
||||||
collection of multiple independent images in a single file. We are using a
|
collection of multiple independent images in a single file. We are using a
|
||||||
spritesheet here for the simple reason that loading a single large image is
|
sprite sheet here for the simple reason that loading a single large image is
|
||||||
faster than many small images. In addition, rendering sprites that were
|
faster than many small images. In addition, rendering sprites that were
|
||||||
extracted from a single source image can be faster too, since Flutter will
|
extracted from a single source image can be faster too, since Flutter will
|
||||||
optimize multiple such drawing commands into a single `drawAtlas` command.
|
optimize multiple such drawing commands into a single `drawAtlas` command.
|
||||||
|
|
||||||
Here are the contents of my spritesheet:
|
Here are the contents of my sprite sheet:
|
||||||
|
|
||||||
- Numerals 2, 3, 4, ..., K, A. In theory, we could have rendered these in the
|
- Numerals 2, 3, 4, ..., K, A. In theory, we could have rendered these in the
|
||||||
game as text strings, but then we would need to also include a font as an
|
game as text strings, but then we would need to also include a font as an
|
||||||
|
|||||||
@ -39,9 +39,9 @@ have been more difficult to access that image from other classes.
|
|||||||
|
|
||||||
Also note that I am `await`ing the image to finish loading before initializing
|
Also note that I am `await`ing the image to finish loading before initializing
|
||||||
anything else in the game. This is for convenience: it means that by the time
|
anything else in the game. This is for convenience: it means that by the time
|
||||||
all other components are initialized, they can assume the spritesheet is already
|
all other components are initialized, they can assume the sprite sheet is already
|
||||||
loaded. We can even add a helper function to extract a sprite from the common
|
loaded. We can even add a helper function to extract a sprite from the common
|
||||||
spritesheet:
|
sprite sheet:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
Sprite klondikeSprite(double x, double y, double width, double height) {
|
Sprite klondikeSprite(double x, double y, double width, double height) {
|
||||||
@ -193,7 +193,7 @@ not planning to change these values during the game:
|
|||||||
Next, we will create a `Stock` component, the `Waste`, four `Foundation`s and
|
Next, we will create a `Stock` component, the `Waste`, four `Foundation`s and
|
||||||
seven `Pile`s, setting their sizes and positions in the world. The positions
|
seven `Pile`s, setting their sizes and positions in the world. The positions
|
||||||
are calculated using simple arithmetics. This should all happen inside the
|
are calculated using simple arithmetics. This should all happen inside the
|
||||||
`onLoad` method, after loading the spritesheet:
|
`onLoad` method, after loading the sprite sheet:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
final stock = Stock()
|
final stock = Stock()
|
||||||
|
|||||||
@ -71,9 +71,9 @@ after the image is loaded into the cache.
|
|||||||
```
|
```
|
||||||
|
|
||||||
The last four numbers in the constructor are the coordinates of the sprite
|
The last four numbers in the constructor are the coordinates of the sprite
|
||||||
image within the spritesheet `klondike-sprites.png`. If you're wondering how I
|
image within the sprite sheet `klondike-sprites.png`. If you're wondering how I
|
||||||
obtained these numbers, the answer is that I used a free online service
|
obtained these numbers, the answer is that I used a free online service
|
||||||
[spritecow.com] -- it's a handy tool for locating sprites within a spritesheet.
|
[spritecow.com] -- it's a handy tool for locating sprites within a sprite sheet.
|
||||||
|
|
||||||
Lastly, I have simple getters to determine the "color" of a suit. This will be
|
Lastly, I have simple getters to determine the "color" of a suit. This will be
|
||||||
needed later when we need to enforce the rule that cards can only be placed
|
needed later when we need to enforce the rule that cards can only be placed
|
||||||
|
|||||||
@ -52,10 +52,10 @@ provide free pixel art that can be used in games, but please check and comply wi
|
|||||||
always provide valid creator attribution. For this game though, I am going to take a chance and
|
always provide valid creator attribution. For this game though, I am going to take a chance and
|
||||||
make my artwork using an online pixel art tool. If you decide to use this tool, multiple online
|
make my artwork using an online pixel art tool. If you decide to use this tool, multiple online
|
||||||
tutorials will assist you with the basic operations as well as exporting the assets. Now normally,
|
tutorials will assist you with the basic operations as well as exporting the assets. Now normally,
|
||||||
most games will utilize spritesheets. These combine many images into one larger image that can be
|
most games will utilize sprite sheets. These combine many images into one larger image that can be
|
||||||
sectioned and used as individual images. For this tutorial though, I specifically will save the
|
sectioned and used as individual images. For this tutorial though, I specifically will save the
|
||||||
images individually as I want to demonstrate the Flame engine's caching abilities. Ember and the
|
images individually as I want to demonstrate the Flame engine's caching abilities. Ember and the
|
||||||
water enemy are spritesheets though as they contain multiple images to create animations.
|
water enemy are sprite sheets though as they contain multiple images to create animations.
|
||||||
|
|
||||||
Right-click the images below, choose "Save as...", and store them in the `assets/images` folder of the
|
Right-click the images below, choose "Save as...", and store them in the `assets/images` folder of the
|
||||||
project. At this point our project's structure looks like this:
|
project. At this point our project's structure looks like this:
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@ -501,12 +501,12 @@ class ParticlesExample extends FlameGame {
|
|||||||
const rows = 8;
|
const rows = 8;
|
||||||
const frames = columns * rows;
|
const frames = columns * rows;
|
||||||
final spriteImage = images.fromCache('boom.png');
|
final spriteImage = images.fromCache('boom.png');
|
||||||
final spritesheet = SpriteSheet.fromColumnsAndRows(
|
final spriteSheet = SpriteSheet.fromColumnsAndRows(
|
||||||
image: spriteImage,
|
image: spriteImage,
|
||||||
columns: columns,
|
columns: columns,
|
||||||
rows: rows,
|
rows: rows,
|
||||||
);
|
);
|
||||||
final sprites = List<Sprite>.generate(frames, spritesheet.getSpriteById);
|
final sprites = List<Sprite>.generate(frames, spriteSheet.getSpriteById);
|
||||||
return SpriteAnimation.spriteList(sprites, stepTime: 0.1);
|
return SpriteAnimation.spriteList(sprites, stepTime: 0.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import 'package:flame/components.dart';
|
|||||||
import 'package:flame/game.dart';
|
import 'package:flame/game.dart';
|
||||||
import 'package:flame/sprite.dart';
|
import 'package:flame/sprite.dart';
|
||||||
|
|
||||||
class SpritesheetExample extends FlameGame {
|
class SpriteSheetExample extends FlameGame {
|
||||||
static const String description = '''
|
static const String description = '''
|
||||||
In this example we show how to load images and how to create animations from
|
In this example we show how to load images and how to create animations from
|
||||||
sprite sheets.
|
sprite sheets.
|
||||||
@ -11,7 +11,7 @@ class SpritesheetExample extends FlameGame {
|
|||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
final spriteSheet = SpriteSheet(
|
final spriteSheet = SpriteSheet(
|
||||||
image: await images.load('spritesheet.png'),
|
image: await images.load('sprite_sheet.png'),
|
||||||
srcSize: Vector2(16.0, 18.0),
|
srcSize: Vector2(16.0, 18.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -28,6 +28,19 @@ class SpritesheetExample extends FlameGame {
|
|||||||
stepTimes: [0.1, 0.1, 0.3, 0.3, 0.5, 0.3, 0.1],
|
stepTimes: [0.1, 0.1, 0.3, 0.3, 0.5, 0.3, 0.1],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final customVampireAnimation = SpriteAnimation.fromFrameData(
|
||||||
|
spriteSheet.image,
|
||||||
|
SpriteAnimationData([
|
||||||
|
spriteSheet.createFrameData(0, 0, stepTime: 0.1),
|
||||||
|
spriteSheet.createFrameData(0, 1, stepTime: 0.1),
|
||||||
|
spriteSheet.createFrameData(0, 2, stepTime: 0.3),
|
||||||
|
spriteSheet.createFrameDataFromId(4, stepTime: 0.3),
|
||||||
|
spriteSheet.createFrameDataFromId(5, stepTime: 0.5),
|
||||||
|
spriteSheet.createFrameDataFromId(6, stepTime: 0.3),
|
||||||
|
spriteSheet.createFrameDataFromId(7, stepTime: 0.1),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
final spriteSize = Vector2(80.0, 90.0);
|
final spriteSize = Vector2(80.0, 90.0);
|
||||||
|
|
||||||
final vampireComponent = SpriteAnimationComponent(
|
final vampireComponent = SpriteAnimationComponent(
|
||||||
@ -44,13 +57,20 @@ class SpritesheetExample extends FlameGame {
|
|||||||
|
|
||||||
final ghostAnimationVariableStepTimesComponent = SpriteAnimationComponent(
|
final ghostAnimationVariableStepTimesComponent = SpriteAnimationComponent(
|
||||||
animation: ghostAnimationVariableStepTimes,
|
animation: ghostAnimationVariableStepTimes,
|
||||||
position: Vector2(150, 340),
|
position: Vector2(250, 220),
|
||||||
|
size: spriteSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
final customVampireComponent = SpriteAnimationComponent(
|
||||||
|
animation: customVampireAnimation,
|
||||||
|
position: Vector2(250, 100),
|
||||||
size: spriteSize,
|
size: spriteSize,
|
||||||
);
|
);
|
||||||
|
|
||||||
add(vampireComponent);
|
add(vampireComponent);
|
||||||
add(ghostComponent);
|
add(ghostComponent);
|
||||||
add(ghostAnimationVariableStepTimesComponent);
|
add(ghostAnimationVariableStepTimesComponent);
|
||||||
|
add(customVampireComponent);
|
||||||
|
|
||||||
// Some plain sprites
|
// Some plain sprites
|
||||||
final vampireSpriteComponent = SpriteComponent(
|
final vampireSpriteComponent = SpriteComponent(
|
||||||
@ -65,14 +85,7 @@ class SpritesheetExample extends FlameGame {
|
|||||||
position: Vector2(50, 220),
|
position: Vector2(50, 220),
|
||||||
);
|
);
|
||||||
|
|
||||||
final ghostVariableSpriteComponent = SpriteComponent(
|
|
||||||
sprite: spriteSheet.getSprite(1, 0),
|
|
||||||
size: spriteSize,
|
|
||||||
position: Vector2(50, 340),
|
|
||||||
);
|
|
||||||
|
|
||||||
add(vampireSpriteComponent);
|
add(vampireSpriteComponent);
|
||||||
add(ghostSpriteComponent);
|
add(ghostSpriteComponent);
|
||||||
add(ghostVariableSpriteComponent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,7 +5,7 @@ import 'package:examples/stories/sprites/basic_sprite_example.dart';
|
|||||||
import 'package:examples/stories/sprites/sprite_batch_example.dart';
|
import 'package:examples/stories/sprites/sprite_batch_example.dart';
|
||||||
import 'package:examples/stories/sprites/sprite_batch_load_example.dart';
|
import 'package:examples/stories/sprites/sprite_batch_load_example.dart';
|
||||||
import 'package:examples/stories/sprites/sprite_group_example.dart';
|
import 'package:examples/stories/sprites/sprite_group_example.dart';
|
||||||
import 'package:examples/stories/sprites/spritesheet_example.dart';
|
import 'package:examples/stories/sprites/sprite_sheet_example.dart';
|
||||||
import 'package:flame/game.dart';
|
import 'package:flame/game.dart';
|
||||||
|
|
||||||
void addSpritesStories(Dashbook dashbook) {
|
void addSpritesStories(Dashbook dashbook) {
|
||||||
@ -23,10 +23,10 @@ void addSpritesStories(Dashbook dashbook) {
|
|||||||
info: Base64SpriteExample.description,
|
info: Base64SpriteExample.description,
|
||||||
)
|
)
|
||||||
..add(
|
..add(
|
||||||
'Spritesheet',
|
'SpriteSheet',
|
||||||
(_) => GameWidget(game: SpritesheetExample()),
|
(_) => GameWidget(game: SpriteSheetExample()),
|
||||||
codeLink: baseLink('sprites/spritesheet_example.dart'),
|
codeLink: baseLink('sprites/sprite_sheet_example.dart'),
|
||||||
info: SpritesheetExample.description,
|
info: SpriteSheetExample.description,
|
||||||
)
|
)
|
||||||
..add(
|
..add(
|
||||||
'SpriteBatch',
|
'SpriteBatch',
|
||||||
|
|||||||
@ -7,4 +7,4 @@ export 'src/sprite.dart';
|
|||||||
export 'src/sprite_animation.dart';
|
export 'src/sprite_animation.dart';
|
||||||
export 'src/sprite_animation_ticker.dart';
|
export 'src/sprite_animation_ticker.dart';
|
||||||
export 'src/sprite_batch.dart' hide FlippedAtlasStatus;
|
export 'src/sprite_batch.dart' hide FlippedAtlasStatus;
|
||||||
export 'src/spritesheet.dart';
|
export 'src/sprite_sheet.dart';
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flame/components.dart';
|
import 'package:flame/components.dart';
|
||||||
import 'package:flame/src/spritesheet.dart';
|
import 'package:flame/src/sprite_sheet.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
/// This is just a pair of <int, int>.
|
/// This is just a pair of <int, int>.
|
||||||
|
|||||||
@ -68,6 +68,34 @@ class SpriteSheet {
|
|||||||
return _spriteCache[spriteId] ??= _computeSprite(spriteId);
|
return _spriteCache[spriteId] ??= _computeSprite(spriteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a [SpriteAnimationFrameData] for the sprite in the position
|
||||||
|
/// (row, column) on the sprite sheet grid.
|
||||||
|
SpriteAnimationFrameData createFrameData(
|
||||||
|
int row,
|
||||||
|
int column, {
|
||||||
|
required double stepTime,
|
||||||
|
}) {
|
||||||
|
return createFrameDataFromId(row * columns + column, stepTime: stepTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a [SpriteAnimationFrameData] for the sprite with id [spriteId]
|
||||||
|
/// from the grid.
|
||||||
|
///
|
||||||
|
/// The ids are defined as starting at 0 on the top left and going
|
||||||
|
/// sequentially on each row.
|
||||||
|
SpriteAnimationFrameData createFrameDataFromId(
|
||||||
|
int spriteId, {
|
||||||
|
required double stepTime,
|
||||||
|
}) {
|
||||||
|
final i = spriteId % columns;
|
||||||
|
final j = spriteId ~/ columns;
|
||||||
|
return SpriteAnimationFrameData(
|
||||||
|
srcPosition: Vector2Extension.fromInts(i, j)..multiply(srcSize),
|
||||||
|
srcSize: srcSize,
|
||||||
|
stepTime: stepTime,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Sprite _computeSprite(int spriteId) {
|
Sprite _computeSprite(int spriteId) {
|
||||||
final i = spriteId % columns;
|
final i = spriteId % columns;
|
||||||
final j = spriteId ~/ columns;
|
final j = spriteId ~/ columns;
|
||||||
@ -5,7 +5,7 @@ import 'package:flame/input.dart';
|
|||||||
import 'package:flame/src/anchor.dart';
|
import 'package:flame/src/anchor.dart';
|
||||||
import 'package:flame/src/components/sprite_group_component.dart';
|
import 'package:flame/src/components/sprite_group_component.dart';
|
||||||
import 'package:flame/src/events/flame_game_mixins/multi_tap_dispatcher.dart';
|
import 'package:flame/src/events/flame_game_mixins/multi_tap_dispatcher.dart';
|
||||||
import 'package:flame/src/spritesheet.dart';
|
import 'package:flame/src/sprite_sheet.dart';
|
||||||
import 'package:flame_test/flame_test.dart';
|
import 'package:flame_test/flame_test.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|||||||
@ -54,5 +54,69 @@ void main() {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test('return sprite based on row and column', () {
|
||||||
|
final spriteSheet = SpriteSheet(
|
||||||
|
image: image,
|
||||||
|
srcSize: Vector2(50, 50),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
spriteSheet.getSprite(1, 1),
|
||||||
|
isA<Sprite>().having(
|
||||||
|
(sprite) => sprite.srcPosition,
|
||||||
|
'srcPosition',
|
||||||
|
equals(Vector2(50, 50)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('return sprite based on id', () {
|
||||||
|
final spriteSheet = SpriteSheet(
|
||||||
|
image: image,
|
||||||
|
srcSize: Vector2(50, 50),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
spriteSheet.getSpriteById(3),
|
||||||
|
isA<Sprite>().having(
|
||||||
|
(sprite) => sprite.srcPosition,
|
||||||
|
'srcPosition',
|
||||||
|
equals(Vector2(50, 50)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('create sprite animation frame data based on row and column', () {
|
||||||
|
final spriteSheet = SpriteSheet(
|
||||||
|
image: image,
|
||||||
|
srcSize: Vector2(50, 50),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
spriteSheet.createFrameData(1, 1, stepTime: 0.1),
|
||||||
|
isA<SpriteAnimationFrameData>().having(
|
||||||
|
(frame) => frame.srcPosition,
|
||||||
|
'srcPosition',
|
||||||
|
equals(Vector2(50, 50)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('create sprite animation frame data based on id', () {
|
||||||
|
final spriteSheet = SpriteSheet(
|
||||||
|
image: image,
|
||||||
|
srcSize: Vector2(50, 50),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
spriteSheet.createFrameDataFromId(3, stepTime: 0.1),
|
||||||
|
isA<SpriteAnimationFrameData>().having(
|
||||||
|
(frame) => frame.srcPosition,
|
||||||
|
'srcPosition',
|
||||||
|
equals(Vector2(50, 50)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user