Skip to content

Commit f1e6d0e

Browse files
authored
Merge branch 'main' into feat-add-rewind-textboxcomponent
2 parents 41a2a60 + 16f10c8 commit f1e6d0e

File tree

22 files changed

+315
-74
lines changed

22 files changed

+315
-74
lines changed

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,27 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## 2025-12-17
7+
8+
### Changes
9+
10+
---
11+
12+
Packages with breaking changes:
13+
14+
- There are no breaking changes in this release.
15+
16+
Packages with other changes:
17+
18+
- [`flame_riverpod` - `v5.5.0`](#flame_riverpod---v550)
19+
20+
---
21+
22+
#### `flame_riverpod` - `v5.5.0`
23+
24+
- **FEAT**: Riverpod 3.0 in flame_riverpod ([#3789](https://github.com/flame-engine/flame/issues/3789)). ([57f7f9d8](https://github.com/flame-engine/flame/commit/57f7f9d8b30632717fdf894321758a26d4985907))
25+
26+
627
## 2025-11-23
728

829
### Changes

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ network.
9999
framework.
100100
- [flame_rive][flame_rive] for [Rive][rive]: Create interactive animations.
101101
- [flame_svg][flame_svg] for [flutter_svg][flutter_svg]: Draw SVG files in Flutter.
102+
- [flame_texturepacker][flame_texturepacker]: Load and use sprite sheets generated with [TexturePacker][texturepacker]
102103
- [flame_tiled][flame_tiled] for [Tiled][tiled]: 2D tile map level editor.
103104

104105

@@ -194,5 +195,7 @@ via an issue, GitHub discussion, or reach out to the team either using the
194195
[rive]: https://rive.app/
195196
[flame_svg]: https://github.com/flame-engine/flame/tree/main/packages/flame_svg
196197
[flutter_svg]: https://github.com/dnfield/flutter_svg
198+
[flame_texturepacker]: https://github.com/flame-engine/flame/tree/main/packages/flame_texturepacker
199+
[texturepacker]: https://www.codeandweb.com/texturepacker
197200
[flame_tiled]: https://github.com/flame-engine/flame/tree/main/packages/flame_tiled
198201
[tiled]: https://www.mapeditor.org/

doc/bridge_packages/bridge_packages.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ Add the "Powered by Flame" splash screen.
8181
Draw SVG files in Flutter (bridge package for [flutter_svg]).
8282
:::
8383

84+
:::{package} flame_texturepacker
85+
86+
Load sprite sheets created by TexturePacker tool (bridge package for
87+
[TexturePacker]).
88+
:::
89+
8490
:::{package} flame_tiled
8591

8692
2D tilemap level editor (bridge package for [Tiled]).
@@ -94,6 +100,7 @@ Draw SVG files in Flutter (bridge package for [flutter_svg]).
94100
[Rive]: https://rive.app/
95101
[Riverpod]: https://github.com/rrousselGit/riverpod
96102
[Spine]: https://pub.dev/packages/spine_flutter
103+
[TexturePacker]: https://www.codeandweb.com/texturepacker
97104
[Tiled]: https://www.mapeditor.org/
98105
[flutter_svg]: https://github.com/dnfield/flutter_svg
99106

@@ -115,5 +122,6 @@ flame_riverpod <flame_riverpod/flame_riverpod.md>
115122
flame_splash_screen <flame_splash_screen/flame_splash_screen.md>
116123
flame_spine <flame_spine/flame_spine.md>
117124
flame_svg <flame_svg/flame_svg.md>
125+
flame_texturepacker <flame_texturepacker/flame_texturepacker.md>
118126
flame_tiled <flame_tiled/flame_tiled.md>
119127
```
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# flame_texturepacker
2+
3+
**flame_texturepacker**
4+
is a bridge package that allows you to load sprite sheets generated by [CodeAndWeb's TexturePacker]
5+
into your Flame game.
6+
7+
A sprite sheet (or texture atlas) is a larger image that packs many smaller sprites together.
8+
This reduces the number of separate textures a game must load, which lowers overhead
9+
and can improve loading speed and rendering performance.
10+
11+
12+
## Installation
13+
14+
Add *flame_texturepacker* to your project:
15+
16+
```shell
17+
flutter pub add flame_texturepacker
18+
```
19+
20+
Then import it in your Dart code:
21+
22+
```dart
23+
import 'package:flame_texturepacker/flame_texturepacker.dart';
24+
```
25+
26+
27+
## Usage
28+
29+
30+
### Loading from Assets
31+
32+
First, add your ``.atlas`` data file and sprite sheet images to your assets directory and reference
33+
them in your `pubspec.yaml`:
34+
35+
```yaml
36+
flutter:
37+
assets:
38+
- assets/images/atlas_map.atlas
39+
- assets/images/sprite_sheet1.png
40+
- assets/images/sprite_sheet2.png
41+
- assets/images/sprite_sheet3.png
42+
```
43+
44+
Then load the atlas in your game:
45+
46+
```dart
47+
class MyGame extends FlameGame {
48+
@override
49+
Future<void> onLoad() async {
50+
// Load the texture atlas
51+
final atlas = await atlasFromAssets('atlas_map.atlas');
52+
53+
// Use the atlas to get sprites
54+
final sprite = atlas.findSpriteByName('robot_jump')!;
55+
add(SpriteComponent(sprite: sprite));
56+
}
57+
}
58+
```
59+
60+
61+
## TexturePackerAtlas
62+
63+
The `TexturePackerAtlas` class is the main interface for working with texture atlases. It provides
64+
several methods to query and retrieve sprites.
65+
66+
67+
### Finding Sprites
68+
69+
**Find a single sprite by name:**
70+
71+
```dart
72+
final jumpSprite = atlas.findSpriteByName('robot_jump')!;
73+
final fallSprite = atlas.findSpriteByName('robot_fall')!;
74+
```
75+
76+
**Find a sprite by name and index:**
77+
78+
```dart
79+
final sprite = atlas.findSpriteByNameIndex('robot_walk', 0);
80+
```
81+
82+
**Find all sprites with the same name:**
83+
84+
This is particularly useful for creating animations from indexed sprites:
85+
86+
```dart
87+
// Get all sprites with the name 'robot_walk'
88+
// (e.g., robot_walk_0, robot_walk_1, etc.)
89+
final walkingSprites = atlas.findSpritesByName('robot_walk');
90+
91+
// Create an animation from the sprite list
92+
final walkingAnimation = SpriteAnimation.spriteList(
93+
walkingSprites,
94+
stepTime: 0.1,
95+
loop: true,
96+
);
97+
98+
add(SpriteAnimationComponent(animation: walkingAnimation));
99+
```
100+
101+
102+
## Advanced Options
103+
104+
105+
### Whitelist Filtering
106+
107+
To optimize memory usage, you can specify a whitelist of sprite names to load. Only sprites whose
108+
names contain any of the whitelist strings will be loaded:
109+
110+
```dart
111+
final atlas = await TexturePackerAtlas.load(
112+
'atlas_map.atlas',
113+
whiteList: [ 'robot_walk' ]
114+
);
115+
```
116+
117+
This is particularly useful for large atlases where you only need a subset of sprites.
118+
119+
120+
### Original Size vs Packed Size
121+
122+
TexturePacker can trim transparent pixels from sprites to save space. By default,
123+
`flame_texturepacker` uses the original (untrimmed) size. You can change this behavior:
124+
125+
```dart
126+
final atlas = await TexturePackerAtlas.load(
127+
'atlas_map.atlas',
128+
useOriginalSize: false, // Use the trimmed/packed size instead
129+
);
130+
```
131+
132+
133+
### Custom Asset Prefix
134+
135+
If your ``.atlas`` data file is not stored in the default `images` directory:
136+
137+
```dart
138+
final atlas = await atlasFromAssets(
139+
'atlas_map.atlas',
140+
assetsPrefix: 'custom_path',
141+
);
142+
```
143+
144+
145+
## Full Example
146+
147+
A complete working example can be found in the [flame_texturepacker example] or
148+
in this [tutorial from CodeAndWeb].
149+
150+
151+
[flame_texturepacker example]: https://github.com/flame-engine/flame/tree/main/packages/flame_texturepacker/example
152+
[tutorial from CodeAndWeb]: https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-and-animations-with-flame-engine
153+
[CodeAndWeb's TexturePacker]: https://www.codeandweb.com/texturepacker

examples/lib/stories/experimental/experimental.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ void addExperimentalStories(Dashbook dashbook) {
5454
'Wrap with ExpandedComponent',
5555
false,
5656
),
57+
paddingInflateChild: context.boolProperty(
58+
'Padding Component inflates child',
59+
false,
60+
),
5761
),
5862
);
5963
},

examples/lib/stories/experimental/layout_component_example_1.dart

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class LayoutComponentExample1 extends FlameGame with DragCallbacks {
1616
required this.demoSize,
1717
required this.padding,
1818
required this.expandedMode,
19+
required this.paddingInflateChild,
1920
});
2021

2122
static const String description = '''
@@ -31,6 +32,7 @@ the various ways you can change this layout.
3132
final LayoutComponentExampleSize demoSize;
3233
final EdgeInsets padding;
3334
final bool expandedMode;
35+
final bool paddingInflateChild;
3436

3537
@override
3638
FutureOr<void> onLoad() {
@@ -54,6 +56,7 @@ the various ways you can change this layout.
5456
position: Vector2.zero(),
5557
padding: padding,
5658
expandedMode: expandedMode,
59+
paddingInflateChild: paddingInflateChild,
5760
size: demoSize.toVector2(),
5861
),
5962
],
@@ -83,6 +86,7 @@ class LayoutDemo1 extends LinearLayoutComponent {
8386
required super.position,
8487
required EdgeInsets padding,
8588
required bool expandedMode,
89+
required this.paddingInflateChild,
8690
super.size,
8791
super.key,
8892
}) : _padding = padding,
@@ -96,7 +100,13 @@ class LayoutDemo1 extends LinearLayoutComponent {
96100
set expandedMode(bool value) {
97101
_expandedMode = value;
98102
removeAll(children.toList());
99-
addAll(createComponentList(expandedMode: expandedMode, padding: padding));
103+
addAll(
104+
createComponentList(
105+
expandedMode: expandedMode,
106+
padding: padding,
107+
inflateChild: paddingInflateChild,
108+
),
109+
);
100110
}
101111

102112
EdgeInsets _padding = EdgeInsets.zero;
@@ -108,10 +118,18 @@ class LayoutDemo1 extends LinearLayoutComponent {
108118
paddingComponent?.padding = padding;
109119
}
110120

121+
final bool paddingInflateChild;
122+
111123
@override
112124
FutureOr<void> onLoad() {
113125
super.onLoad();
114-
addAll(createComponentList(expandedMode: expandedMode, padding: padding));
126+
addAll(
127+
createComponentList(
128+
expandedMode: expandedMode,
129+
padding: padding,
130+
inflateChild: paddingInflateChild,
131+
),
132+
);
115133
}
116134

117135
PaddingComponent? get paddingComponent {
@@ -124,6 +142,7 @@ class LayoutDemo1 extends LinearLayoutComponent {
124142
static List<Component> createComponentList({
125143
required bool expandedMode,
126144
required EdgeInsets padding,
145+
required bool inflateChild,
127146
}) {
128147
return [
129148
TextComponent(text: 'Some short text'),
@@ -143,6 +162,7 @@ class LayoutDemo1 extends LinearLayoutComponent {
143162
ExpandedComponent(
144163
child: PaddingComponent(
145164
padding: padding,
165+
inflateChild: inflateChild,
146166
child: RectangleComponent(
147167
size: Vector2(96, 96),
148168
paint: Paint()..color = Colors.blue,
@@ -152,6 +172,7 @@ class LayoutDemo1 extends LinearLayoutComponent {
152172
else
153173
PaddingComponent(
154174
padding: padding,
175+
inflateChild: inflateChild,
155176
child: RectangleComponent(
156177
size: Vector2(96, 96),
157178
paint: Paint()..color = Colors.blue,

packages/flame/lib/src/experimental/expanded_component.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,10 @@ class ExpandedComponent extends SingleLayoutComponent
3838
super.position,
3939
super.anchor,
4040
super.priority,
41-
this.inflateChild = true,
41+
super.inflateChild = true,
4242
super.child,
4343
}) : super(size: null);
4444

45-
/// Whether or not this [ExpandedComponent] will set [child]'s size to its own
46-
final bool inflateChild;
47-
4845
@override
4946
void setLayoutAxisLength(LayoutAxis axis, double? value) {
5047
super.setLayoutAxisLength(axis, value);

packages/flame/lib/src/experimental/layout_component.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ abstract class LayoutComponent extends PositionComponent {
3434
/// vector components, and subsequently selective setting of the
3535
/// size components.
3636
void setLayoutSize(double? layoutSizeX, double? layoutSizeY) {
37-
_layoutSizeX = layoutSizeX;
38-
_layoutSizeY = layoutSizeY;
39-
resetSize();
37+
setLayoutAxisLength(LayoutAxis.x, layoutSizeX);
38+
setLayoutAxisLength(LayoutAxis.y, layoutSizeY);
4039
}
4140

4241
/// A helper function to set the appropriate layout dimension based on

packages/flame/lib/src/experimental/padding_component.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import 'package:flutter/rendering.dart';
1616
/// You may set [padding] as well as the [child] after the fact, and it will
1717
/// cause the layout to refresh.
1818
///
19+
/// If [inflateChild] is true, [resetSize] sets the child's size to fill up
20+
/// available space via [syncChildSize]. If the child is a [LayoutComponent]
21+
/// descendant, then [resetSize] uses the [LayoutComponent.setLayoutSize].
22+
///
1923
/// Example usage:
2024
/// ```dart
2125
/// PaddingComponent(
@@ -31,6 +35,7 @@ class PaddingComponent extends SingleLayoutComponent {
3135
super.position,
3236
super.priority,
3337
super.size,
38+
super.inflateChild = false,
3439
PositionComponent? child,
3540
}) : _padding = padding ?? EdgeInsets.zero,
3641
super(child: null) {
@@ -48,8 +53,6 @@ class PaddingComponent extends SingleLayoutComponent {
4853

4954
@override
5055
void layoutChildren() {
51-
// Only resets to null if it's already null. This way, we avoid overwriting
52-
// an explicit width/height.
5356
resetSize();
5457
final child = this.child;
5558
if (child == null) {
@@ -59,6 +62,11 @@ class PaddingComponent extends SingleLayoutComponent {
5962
child.topLeftPosition.setFrom(padding.topLeft.toVector2());
6063
}
6164

65+
@override
66+
Vector2 get availableSize {
67+
return padding.deflateSize(size.toSize()).toVector2();
68+
}
69+
6270
@override
6371
Vector2 get intrinsicSize {
6472
final childWidth = child?.size.x ?? 0;

0 commit comments

Comments
 (0)