├── LICENSE
├── example
├── README.md
├── assets
│ └── images
│ │ ├── city.png
│ │ ├── space.png
│ │ └── desert
│ │ ├── train.png
│ │ ├── clouds.png
│ │ ├── ground.png
│ │ ├── foreground.png
│ │ ├── mountains.png
│ │ ├── train.aseprite
│ │ └── mountains.aseprite
├── web
│ ├── icons
│ │ ├── Icon-192.png
│ │ └── Icon-512.png
│ ├── manifest.json
│ └── index.html
├── .metadata
├── pubspec.yaml
├── .gitignore
├── lib
│ ├── main_city.dart
│ ├── main_space.dart
│ ├── main_desert.dart
│ └── main.dart
└── pubspec.lock
├── scripts
└── format.sh
├── lib
├── flame_scrolling_sprite.dart
├── scrolling_sprite_component.dart
└── scrolling_sprite.dart
├── CHANGELOG.md
├── .metadata
├── .github
└── workflows
│ └── test.yml
├── pubspec.yaml
├── .gitignore
├── analysis_options.yaml
├── README.md
└── pubspec.lock
/LICENSE:
--------------------------------------------------------------------------------
1 | TODO: Add your license here.
2 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # example
2 |
3 | The project showcasing how to use this package.
4 |
--------------------------------------------------------------------------------
/example/assets/images/city.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/assets/images/city.png
--------------------------------------------------------------------------------
/example/assets/images/space.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/assets/images/space.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/scripts/format.sh:
--------------------------------------------------------------------------------
1 | if [[ $(flutter format -n .) ]]; then
2 | echo "files not formatted"
3 | exit 1
4 | else
5 | exit 0
6 | fi
--------------------------------------------------------------------------------
/example/assets/images/desert/train.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/assets/images/desert/train.png
--------------------------------------------------------------------------------
/example/assets/images/desert/clouds.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/assets/images/desert/clouds.png
--------------------------------------------------------------------------------
/example/assets/images/desert/ground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/assets/images/desert/ground.png
--------------------------------------------------------------------------------
/example/assets/images/desert/foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/assets/images/desert/foreground.png
--------------------------------------------------------------------------------
/example/assets/images/desert/mountains.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/assets/images/desert/mountains.png
--------------------------------------------------------------------------------
/example/assets/images/desert/train.aseprite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/assets/images/desert/train.aseprite
--------------------------------------------------------------------------------
/lib/flame_scrolling_sprite.dart:
--------------------------------------------------------------------------------
1 | library flame_scrolling_sprite;
2 |
3 | export './scrolling_sprite.dart';
4 | export './scrolling_sprite_component.dart';
5 |
--------------------------------------------------------------------------------
/example/assets/images/desert/mountains.aseprite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flame-engine/flame_scrolling_sprite/HEAD/example/assets/images/desert/mountains.aseprite
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.0.3]
2 |
3 | - Updating Flame version
4 |
5 | ## [0.0.2]
6 |
7 | - Updating Flame version
8 |
9 | ## [0.0.1]
10 |
11 | - Initial release
12 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: fabeb2a16f1d008ab8230f450c49141d35669798
8 | channel: beta
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: fabeb2a16f1d008ab8230f450c49141d35669798
8 | channel: beta
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on: push
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - uses: actions/checkout@v1
11 | - uses: actions/setup-java@v1
12 | with:
13 | java-version: '12.x'
14 | - uses: subosito/flutter-action@v1
15 | with:
16 | channel: 'stable'
17 | - run: flutter pub get
18 | - run: ./scripts/format.sh
19 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flame_scrolling_sprite
2 | description: Flame package adding a simple scrolling sprite to make it easy to repeat the same image over time.
3 | version: 0.0.3
4 | homepage: https://github.com/flame-engine/flame_scrolling_sprite
5 |
6 | environment:
7 | sdk: ">=2.1.0 <3.0.0"
8 |
9 | dependencies:
10 | flame: ">=0.24.0 <1.0.0"
11 | meta: ^1.1.8
12 | flutter:
13 | sdk: flutter
14 |
15 | dev_dependencies:
16 | flutter_test:
17 | sdk: flutter
18 |
19 | flutter:
20 |
--------------------------------------------------------------------------------
/lib/scrolling_sprite_component.dart:
--------------------------------------------------------------------------------
1 | import 'package:flame/components/component.dart';
2 | import 'dart:ui';
3 |
4 | import './scrolling_sprite.dart';
5 |
6 | class ScrollingSpriteComponent extends Component {
7 | ScrollingSprite scrollingSprite;
8 | double x;
9 | double y;
10 |
11 | ScrollingSpriteComponent({this.x, this.y, this.scrollingSprite});
12 |
13 | @override
14 | void update(double dt) {
15 | scrollingSprite.update(dt);
16 | }
17 |
18 | @override
19 | void render(Canvas canvas) {
20 | if (scrollingSprite.loaded()) {
21 | scrollingSprite.renderAt(x, y, canvas);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flame_scrolling_sprite_example
2 | description: a flame scrolling sprite example
3 |
4 | version: 1.0.0+1
5 |
6 | environment:
7 | sdk: ">=2.1.0 <3.0.0"
8 |
9 | dependencies:
10 | flame: 0.24.0
11 | flame_scrolling_sprite:
12 | path: ../
13 | flutter:
14 | sdk: flutter
15 |
16 | cupertino_icons: ^0.1.2
17 |
18 | flutter:
19 | assets:
20 | - assets/images/space.png
21 | - assets/images/city.png
22 |
23 | - assets/images/desert/clouds.png
24 | - assets/images/desert/mountains.png
25 | - assets/images/desert/ground.png
26 | - assets/images/desert/train.png
27 | - assets/images/desert/foreground.png
28 |
--------------------------------------------------------------------------------
/example/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "short_name": "example",
4 | "start_url": ".",
5 | "display": "minimal-ui",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "A new Flutter project.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | .dart_tool/
26 | .flutter-plugins
27 | .flutter-plugins-dependencies
28 | .packages
29 | .pub-cache/
30 | .pub/
31 | /build/
32 |
33 | # Web related
34 | lib/generated_plugin_registrant.dart
35 |
36 | # Exceptions to above rules.
37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
38 |
39 | android
40 | ios
41 |
--------------------------------------------------------------------------------
/example/lib/main_city.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flame/game.dart';
3 | import 'package:flame/flame.dart';
4 | import 'package:flame_scrolling_sprite/flame_scrolling_sprite.dart';
5 |
6 | void main() async {
7 | WidgetsFlutterBinding.ensureInitialized();
8 | await Flame.util.fullScreen();
9 | final size = await Flame.util.initialDimensions();
10 | runApp(MyGame(size).widget);
11 | }
12 |
13 | class MyGame extends Game {
14 | ScrollingSprite sprite;
15 | final Size size;
16 |
17 | MyGame(this.size) {
18 | sprite = ScrollingSprite(
19 | spritePath: 'city.png',
20 | width: size.width,
21 | horizontalSpeed: -100,
22 | spriteDestWidth: 300,
23 | spriteDestHeight: 150,
24 | );
25 | }
26 |
27 | @override
28 | void update(double dt) {
29 | sprite.update(dt);
30 | }
31 |
32 | @override
33 | void render(Canvas canvas) {
34 | if (sprite.loaded()) {
35 | sprite.renderAt(0, size.height - 150, canvas);
36 | }
37 | }
38 |
39 | @override
40 | Color backgroundColor() => const Color(0xFF3f3f74);
41 | }
42 |
--------------------------------------------------------------------------------
/example/lib/main_space.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flame/game.dart';
3 | import 'package:flame/flame.dart';
4 | import 'package:flame_scrolling_sprite/flame_scrolling_sprite.dart';
5 |
6 | void main() async {
7 | WidgetsFlutterBinding.ensureInitialized();
8 | await Flame.util.fullScreen();
9 | final size = await Flame.util.initialDimensions();
10 | runApp(MyGame(size).widget);
11 | }
12 |
13 | class MyGame extends Game {
14 | ScrollingSprite sprite;
15 | final Size size;
16 |
17 | MyGame(this.size) {
18 | sprite = ScrollingSprite(
19 | spritePath: 'space.png',
20 | width: size.width,
21 | height: size.height,
22 | verticalSpeed: 300,
23 | spriteDestWidth: 500,
24 | spriteDestHeight: 500,
25 | );
26 | }
27 |
28 | @override
29 | void update(double dt) {
30 | sprite.update(dt);
31 | }
32 |
33 | @override
34 | void render(Canvas canvas) {
35 | if (sprite.loaded()) {
36 | sprite.renderAt(0, 0, canvas);
37 | }
38 | }
39 |
40 | @override
41 | Color backgroundColor() => const Color(0xFF3f3f74);
42 | }
43 |
--------------------------------------------------------------------------------
/example/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | example
15 |
16 |
17 |
18 |
21 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | .dart_tool/
26 | .flutter-plugins
27 | .flutter-plugins-dependencies
28 | .packages
29 | .pub-cache/
30 | .pub/
31 | build/
32 |
33 | # Android related
34 | **/android/**/gradle-wrapper.jar
35 | **/android/.gradle
36 | **/android/captures/
37 | **/android/gradlew
38 | **/android/gradlew.bat
39 | **/android/local.properties
40 | **/android/**/GeneratedPluginRegistrant.java
41 |
42 | # iOS/XCode related
43 | **/ios/**/*.mode1v3
44 | **/ios/**/*.mode2v3
45 | **/ios/**/*.moved-aside
46 | **/ios/**/*.pbxuser
47 | **/ios/**/*.perspectivev3
48 | **/ios/**/*sync/
49 | **/ios/**/.sconsign.dblite
50 | **/ios/**/.tags*
51 | **/ios/**/.vagrant/
52 | **/ios/**/DerivedData/
53 | **/ios/**/Icon?
54 | **/ios/**/Pods/
55 | **/ios/**/.symlinks/
56 | **/ios/**/profile
57 | **/ios/**/xcuserdata
58 | **/ios/.generated/
59 | **/ios/Flutter/App.framework
60 | **/ios/Flutter/Flutter.framework
61 | **/ios/Flutter/Flutter.podspec
62 | **/ios/Flutter/Generated.xcconfig
63 | **/ios/Flutter/app.flx
64 | **/ios/Flutter/app.zip
65 | **/ios/Flutter/flutter_assets/
66 | **/ios/Flutter/flutter_export_environment.sh
67 | **/ios/ServiceDefinitions.json
68 | **/ios/Runner/GeneratedPluginRegistrant.*
69 |
70 | # Exceptions to above rules.
71 | !**/ios/**/default.mode1v3
72 | !**/ios/**/default.mode2v3
73 | !**/ios/**/default.pbxuser
74 | !**/ios/**/default.perspectivev3
75 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
76 |
--------------------------------------------------------------------------------
/example/lib/main_desert.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flame/game.dart';
3 | import 'package:flame/flame.dart';
4 | import 'package:flame/components/animation_component.dart';
5 | import 'package:flame_scrolling_sprite/flame_scrolling_sprite.dart';
6 |
7 | void main() async {
8 | WidgetsFlutterBinding.ensureInitialized();
9 | await Flame.util.fullScreen();
10 | final size = await Flame.util.initialDimensions();
11 | runApp(MyGame(size).widget);
12 | }
13 |
14 | class MyGame extends BaseGame {
15 | final Size size;
16 |
17 | MyGame(this.size) {
18 | add(ScrollingSpriteComponent(
19 | scrollingSprite: ScrollingSprite(
20 | spritePath: 'desert/clouds.png',
21 | width: size.width,
22 | spriteDestWidth: 640,
23 | spriteDestHeight: 160,
24 | horizontalSpeed: -50,
25 | ),
26 | y: 40,
27 | ));
28 |
29 | add(ScrollingSpriteComponent(
30 | scrollingSprite: ScrollingSprite(
31 | spritePath: 'desert/mountains.png',
32 | width: size.width,
33 | spriteDestWidth: 640,
34 | spriteDestHeight: 160,
35 | height: size.height,
36 | horizontalSpeed: -100,
37 | ),
38 | y: size.height - 180,
39 | ));
40 |
41 | add(ScrollingSpriteComponent(
42 | scrollingSprite: ScrollingSprite(
43 | spritePath: 'desert/ground.png',
44 | width: size.width,
45 | spriteDestWidth: 320,
46 | spriteDestHeight: 160,
47 | horizontalSpeed: -300,
48 | ),
49 | y: size.height - 160,
50 | ));
51 |
52 | add(AnimationComponent.sequenced(
53 | 192.0,
54 | 64.0,
55 | 'desert/train.png',
56 | 8,
57 | textureWidth: 96.0,
58 | textureHeight: 32.0,
59 | )
60 | ..y = size.height - 65
61 | ..x = size.width / 2 - 96);
62 |
63 | add(ScrollingSpriteComponent(
64 | scrollingSprite: ScrollingSprite(
65 | spritePath: 'desert/foreground.png',
66 | width: size.width,
67 | spriteDestWidth: 1280,
68 | spriteDestHeight: 160,
69 | height: size.height,
70 | horizontalSpeed: -1500,
71 | ),
72 | y: size.height - 160,
73 | ));
74 | }
75 |
76 | @override
77 | Color backgroundColor() => const Color(0xFF73acb6);
78 | }
79 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # Source of linter options:
2 | # http://dart-lang.github.io/linter/lints/options/options.html
3 |
4 | linter:
5 | rules:
6 | - always_declare_return_types
7 | - always_put_control_body_on_new_line
8 | - always_require_non_null_named_parameters
9 | - annotate_overrides
10 | - avoid_empty_else
11 | - avoid_field_initializers_in_const_classes
12 | - avoid_init_to_null
13 | - avoid_null_checks_in_equality_operators
14 | - avoid_relative_lib_imports
15 | - avoid_return_types_on_setters
16 | - avoid_slow_async_io
17 | - await_only_futures
18 | - camel_case_types
19 | - cancel_subscriptions
20 | - control_flow_in_finally
21 | - empty_catches
22 | - empty_constructor_bodies
23 | - empty_statements
24 | - hash_and_equals
25 | - implementation_imports
26 | - iterable_contains_unrelated_type
27 | - library_names
28 | - library_prefixes
29 | - list_remove_unrelated_type
30 | - no_adjacent_strings_in_list
31 | - no_duplicate_case_values
32 | - non_constant_identifier_names
33 | - package_api_docs
34 | - package_names
35 | - package_prefixed_library_names
36 | - prefer_adjacent_string_concatenation
37 | - prefer_asserts_in_initializer_lists
38 | - prefer_collection_literals
39 | - prefer_conditional_assignment
40 | - prefer_const_constructors
41 | - prefer_const_declarations
42 | - prefer_const_literals_to_create_immutables
43 | - prefer_contains
44 | - prefer_equal_for_default_values
45 | - prefer_final_fields
46 | - prefer_final_locals
47 | - prefer_foreach
48 | - prefer_initializing_formals
49 | - prefer_is_empty
50 | - prefer_is_not_empty
51 | - prefer_typing_uninitialized_variables
52 | - recursive_getters
53 | - slash_for_doc_comments
54 | - sort_unnamed_constructors_first
55 | - test_types_in_equals
56 | - throw_in_finally
57 | - type_init_formals
58 | - unnecessary_brace_in_string_interps
59 | - unnecessary_getters_setters
60 | - unnecessary_null_aware_assignments
61 | - unnecessary_null_in_if_null_operators
62 | - unnecessary_overrides
63 | - unnecessary_parenthesis
64 | - unnecessary_this
65 | - unrelated_type_equality_checks
66 | - use_rethrow_when_possible
67 | - unnecessary_new
68 |
69 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://pub.dartlang.org/packages/flame_scrolling_sprite)
2 | 
3 |
4 | # Flame Scrolling Sprite
5 |
6 | Flame Scrolling Sprite is a [Flame](https://github.com/flame-engine/flame) package to make it easy to render sprites that scrolls and repeat itself forever given a velocity.
7 |
8 | This can be used to create things like an scrolling background, or even create scenes, bellow you can see one example of this:
9 |
10 | 
11 |
12 | This package can be used by using the plain class `ScrollingSprite` or the `ScrollingSpriteComponent`, they do example the same thing, but the later can be used together with Flame component system.
13 |
14 | Bellow you can find all the parameters that the classes receives
15 |
16 | ```dart
17 | //// Resource path of the sprite
18 | @required String spritePath,
19 |
20 | //// X and Y coordinate do be used to map the sprite
21 | double spriteX = 0.0,
22 | double spriteY = 0.0,
23 |
24 | //// Width and height of the mapped sprite
25 | double spriteWidth,
26 | double spriteHeight,
27 |
28 | //// Destination width and height of the sprite, in case you want to scale its original size
29 | double spriteDestWidth,
30 | double spriteDestHeight,
31 |
32 | //// Width and height of the total area where the sprites will scroll
33 | double width,
34 | double height,
35 |
36 | //// Vertical and horizontal speed of the scrolling speed in pixels per second
37 | this.verticalSpeed = 0.0,
38 | this.horizontalSpeed = 0.0,
39 |
40 | //// Since the sprites are scrolling on an endless manner, the sprite can be draw outside of its
41 | //// area, by default, the package already clips the area to prevent it from showing, use this flag to change
42 | //// this behaviour
43 | this.clipToDimensions = true,
44 | ```
45 |
46 | When using the `ScrollingSpriteComponent` the same paramenters above apply to it, and additionally, you can inform the `x` and `y` where the area will place placed.
47 |
48 | For a live example of this running, please refer to the [example](/example) folder.
49 |
--------------------------------------------------------------------------------
/lib/scrolling_sprite.dart:
--------------------------------------------------------------------------------
1 | import 'package:flame/sprite.dart';
2 | import 'package:meta/meta.dart';
3 | import 'dart:ui';
4 |
5 | /// Describes a Sprite image that will animate on a axis resembling scroll moviment
6 | class ScrollingSprite {
7 | Sprite _sprite;
8 | double _width;
9 | double _height;
10 | double _spriteWidth;
11 | double _spriteHeight;
12 | final double verticalSpeed;
13 | final double horizontalSpeed;
14 |
15 | ///
16 | final bool clipToDimensions;
17 |
18 | List _chunks = [];
19 |
20 | /// Constructs a [ScrollingSprite] with the following params:
21 | ///
22 | /// [spritePath] - Resource path of the sprite
23 | /// [spriteX] and [spriteY] - X and Y coordinate do be used to map the sprite
24 | /// [spriteWidth] and [spriteHeight] - Width and height of the mapped sprite
25 | /// [spriteDestWidth] and [spriteDestHeight] - Destination width and height of the sprite, in case you want to scale its original size
26 | /// [width] and [height] - Width and height of the total area where the sprites will scroll
27 | /// [verticalSpeed] and [horizontalSpeed] - Vertical and horizontal speed of the scrolling speed in pixels per second
28 | /// [clipToDimensions] - Since the sprites are scrolling on an endless manner, the sprite can be draw outside of its
29 | /// area, by default, the package already clips the area to prevent it from showing, use this flag to change
30 | /// this behaviour
31 | ScrollingSprite({
32 | @required String spritePath,
33 | double spriteX = 0.0,
34 | double spriteY = 0.0,
35 | double spriteWidth,
36 | double spriteHeight,
37 | double spriteDestWidth,
38 | double spriteDestHeight,
39 | double width,
40 | double height,
41 | this.verticalSpeed = 0.0,
42 | this.horizontalSpeed = 0.0,
43 | this.clipToDimensions = true,
44 | }) {
45 | Sprite.loadSprite(
46 | spritePath,
47 | x: spriteX,
48 | y: spriteY,
49 | width: spriteWidth,
50 | height: spriteHeight,
51 | ).then((loadedSprite) {
52 | _sprite = loadedSprite;
53 |
54 | _spriteWidth = spriteDestWidth ?? _sprite.size.x;
55 | _spriteHeight = spriteDestHeight ?? _sprite.size.y;
56 |
57 | _width = width ?? _spriteWidth;
58 | _height = height ?? _spriteHeight;
59 |
60 | _calculate();
61 | });
62 | }
63 |
64 | set width(double w) {
65 | _width = w;
66 | _calculate();
67 | }
68 |
69 | double get width => _width;
70 |
71 | set height(double h) {
72 | _height = h;
73 | _calculate();
74 | }
75 |
76 | double get height => _height;
77 |
78 | void _calculate() {
79 | _chunks = [];
80 | final columns = (_width / _spriteWidth).ceil() + 1;
81 | final rows = (_height / _spriteHeight).ceil() + 1;
82 |
83 | for (var y = 0; y < rows; y++) {
84 | for (var x = 0; x < columns; x++) {
85 | _chunks.add(Rect.fromLTWH(
86 | x * _spriteWidth,
87 | y * _spriteHeight,
88 | _spriteWidth,
89 | _spriteHeight,
90 | ));
91 | }
92 | }
93 | }
94 |
95 | void update(double dt) {
96 | for (var i = 0; i < _chunks.length; i++) {
97 | Rect _c = _chunks[i];
98 |
99 | if (_c.top > _height && verticalSpeed > 0) {
100 | _c = _chunks[i] = _c.translate(0, -(height + _spriteHeight));
101 | } else if (_c.bottom < 0 && verticalSpeed < 0) {
102 | _c = _chunks[i] = _c.translate(0, height + _spriteHeight);
103 | }
104 |
105 | if (_c.left > _width && horizontalSpeed > 0) {
106 | _c = _chunks[i] = _c.translate(-(_width + _spriteWidth), 0);
107 | } else if (_c.right < 0 && horizontalSpeed < 0) {
108 | _c = _chunks[i] = _c.translate(_width + _spriteWidth, 0);
109 | }
110 |
111 | _c = _chunks[i] = _c.translate(horizontalSpeed * dt, verticalSpeed * dt);
112 | }
113 | }
114 |
115 | void renderAt(double x, double y, Canvas canvas) {
116 | if (!loaded()) {
117 | return;
118 | }
119 |
120 | if (clipToDimensions) {
121 | canvas.save();
122 | canvas.translate(x, y);
123 | canvas.clipRect(Rect.fromLTWH(0, 0, _width, _height));
124 | }
125 | _chunks.forEach((rect) {
126 | _sprite.renderRect(canvas, rect);
127 | });
128 | if (clipToDimensions) {
129 | canvas.restore();
130 | }
131 | }
132 |
133 | bool loaded() => _sprite != null && _sprite.loaded();
134 | }
135 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | void main() => runApp(MyApp());
4 |
5 | class MyApp extends StatelessWidget {
6 | // This widget is the root of your application.
7 | @override
8 | Widget build(BuildContext context) {
9 | return MaterialApp(
10 | title: 'Flutter Demo',
11 | theme: ThemeData(
12 | // This is the theme of your application.
13 | //
14 | // Try running your application with "flutter run". You'll see the
15 | // application has a blue toolbar. Then, without quitting the app, try
16 | // changing the primarySwatch below to Colors.green and then invoke
17 | // "hot reload" (press "r" in the console where you ran "flutter run",
18 | // or simply save your changes to "hot reload" in a Flutter IDE).
19 | // Notice that the counter didn't reset back to zero; the application
20 | // is not restarted.
21 | primarySwatch: Colors.blue,
22 | ),
23 | home: MyHomePage(title: 'Flutter Demo Home Page'),
24 | );
25 | }
26 | }
27 |
28 | class MyHomePage extends StatefulWidget {
29 | MyHomePage({Key key, this.title}) : super(key: key);
30 |
31 | // This widget is the home page of your application. It is stateful, meaning
32 | // that it has a State object (defined below) that contains fields that affect
33 | // how it looks.
34 |
35 | // This class is the configuration for the state. It holds the values (in this
36 | // case the title) provided by the parent (in this case the App widget) and
37 | // used by the build method of the State. Fields in a Widget subclass are
38 | // always marked "final".
39 |
40 | final String title;
41 |
42 | @override
43 | _MyHomePageState createState() => _MyHomePageState();
44 | }
45 |
46 | class _MyHomePageState extends State {
47 | int _counter = 0;
48 |
49 | void _incrementCounter() {
50 | setState(() {
51 | // This call to setState tells the Flutter framework that something has
52 | // changed in this State, which causes it to rerun the build method below
53 | // so that the display can reflect the updated values. If we changed
54 | // _counter without calling setState(), then the build method would not be
55 | // called again, and so nothing would appear to happen.
56 | _counter++;
57 | });
58 | }
59 |
60 | @override
61 | Widget build(BuildContext context) {
62 | // This method is rerun every time setState is called, for instance as done
63 | // by the _incrementCounter method above.
64 | //
65 | // The Flutter framework has been optimized to make rerunning build methods
66 | // fast, so that you can just rebuild anything that needs updating rather
67 | // than having to individually change instances of widgets.
68 | return Scaffold(
69 | appBar: AppBar(
70 | // Here we take the value from the MyHomePage object that was created by
71 | // the App.build method, and use it to set our appbar title.
72 | title: Text(widget.title),
73 | ),
74 | body: Center(
75 | // Center is a layout widget. It takes a single child and positions it
76 | // in the middle of the parent.
77 | child: Column(
78 | // Column is also a layout widget. It takes a list of children and
79 | // arranges them vertically. By default, it sizes itself to fit its
80 | // children horizontally, and tries to be as tall as its parent.
81 | //
82 | // Invoke "debug painting" (press "p" in the console, choose the
83 | // "Toggle Debug Paint" action from the Flutter Inspector in Android
84 | // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
85 | // to see the wireframe for each widget.
86 | //
87 | // Column has various properties to control how it sizes itself and
88 | // how it positions its children. Here we use mainAxisAlignment to
89 | // center the children vertically; the main axis here is the vertical
90 | // axis because Columns are vertical (the cross axis would be
91 | // horizontal).
92 | mainAxisAlignment: MainAxisAlignment.center,
93 | children: [
94 | Text(
95 | 'You have pushed the button this many times:',
96 | ),
97 | Text(
98 | '$_counter',
99 | style: Theme.of(context).textTheme.headline4,
100 | ),
101 | ],
102 | ),
103 | ),
104 | floatingActionButton: FloatingActionButton(
105 | onPressed: _incrementCounter,
106 | tooltip: 'Increment',
107 | child: Icon(Icons.add),
108 | ), // This trailing comma makes auto-formatting nicer for build methods.
109 | );
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/example/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | archive:
5 | dependency: transitive
6 | description:
7 | name: archive
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "2.0.13"
11 | args:
12 | dependency: transitive
13 | description:
14 | name: args
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "1.5.2"
18 | audioplayers:
19 | dependency: transitive
20 | description:
21 | name: audioplayers
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "0.15.1"
25 | box2d_flame:
26 | dependency: transitive
27 | description:
28 | name: box2d_flame
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "0.4.6"
32 | characters:
33 | dependency: transitive
34 | description:
35 | name: characters
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "1.0.0"
39 | charcode:
40 | dependency: transitive
41 | description:
42 | name: charcode
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "1.1.2"
46 | collection:
47 | dependency: transitive
48 | description:
49 | name: collection
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "1.14.13"
53 | convert:
54 | dependency: transitive
55 | description:
56 | name: convert
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "2.1.1"
60 | crypto:
61 | dependency: transitive
62 | description:
63 | name: crypto
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "2.1.3"
67 | cupertino_icons:
68 | dependency: "direct main"
69 | description:
70 | name: cupertino_icons
71 | url: "https://pub.dartlang.org"
72 | source: hosted
73 | version: "0.1.3"
74 | flame:
75 | dependency: "direct main"
76 | description:
77 | name: flame
78 | url: "https://pub.dartlang.org"
79 | source: hosted
80 | version: "0.24.0"
81 | flame_scrolling_sprite:
82 | dependency: "direct main"
83 | description:
84 | path: ".."
85 | relative: true
86 | source: path
87 | version: "0.0.3"
88 | flare_dart:
89 | dependency: transitive
90 | description:
91 | name: flare_dart
92 | url: "https://pub.dartlang.org"
93 | source: hosted
94 | version: "2.3.3"
95 | flare_flutter:
96 | dependency: transitive
97 | description:
98 | name: flare_flutter
99 | url: "https://pub.dartlang.org"
100 | source: hosted
101 | version: "2.0.1"
102 | flutter:
103 | dependency: "direct main"
104 | description: flutter
105 | source: sdk
106 | version: "0.0.0"
107 | flutter_web_plugins:
108 | dependency: transitive
109 | description: flutter
110 | source: sdk
111 | version: "0.0.0"
112 | meta:
113 | dependency: transitive
114 | description:
115 | name: meta
116 | url: "https://pub.dartlang.org"
117 | source: hosted
118 | version: "1.1.8"
119 | ordered_set:
120 | dependency: transitive
121 | description:
122 | name: ordered_set
123 | url: "https://pub.dartlang.org"
124 | source: hosted
125 | version: "2.0.0"
126 | path:
127 | dependency: transitive
128 | description:
129 | name: path
130 | url: "https://pub.dartlang.org"
131 | source: hosted
132 | version: "1.6.4"
133 | path_provider:
134 | dependency: transitive
135 | description:
136 | name: path_provider
137 | url: "https://pub.dartlang.org"
138 | source: hosted
139 | version: "1.6.0"
140 | petitparser:
141 | dependency: transitive
142 | description:
143 | name: petitparser
144 | url: "https://pub.dartlang.org"
145 | source: hosted
146 | version: "3.0.4"
147 | platform:
148 | dependency: transitive
149 | description:
150 | name: platform
151 | url: "https://pub.dartlang.org"
152 | source: hosted
153 | version: "2.2.1"
154 | sky_engine:
155 | dependency: transitive
156 | description: flutter
157 | source: sdk
158 | version: "0.0.99"
159 | synchronized:
160 | dependency: transitive
161 | description:
162 | name: synchronized
163 | url: "https://pub.dartlang.org"
164 | source: hosted
165 | version: "2.2.0"
166 | tiled:
167 | dependency: transitive
168 | description:
169 | name: tiled
170 | url: "https://pub.dartlang.org"
171 | source: hosted
172 | version: "0.6.0"
173 | typed_data:
174 | dependency: transitive
175 | description:
176 | name: typed_data
177 | url: "https://pub.dartlang.org"
178 | source: hosted
179 | version: "1.2.0"
180 | uuid:
181 | dependency: transitive
182 | description:
183 | name: uuid
184 | url: "https://pub.dartlang.org"
185 | source: hosted
186 | version: "2.0.4"
187 | vector_math:
188 | dependency: transitive
189 | description:
190 | name: vector_math
191 | url: "https://pub.dartlang.org"
192 | source: hosted
193 | version: "2.0.8"
194 | xml:
195 | dependency: transitive
196 | description:
197 | name: xml
198 | url: "https://pub.dartlang.org"
199 | source: hosted
200 | version: "4.2.0"
201 | sdks:
202 | dart: ">=2.9.0-14.0.dev <3.0.0"
203 | flutter: ">=1.10.0 <2.0.0"
204 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | archive:
5 | dependency: transitive
6 | description:
7 | name: archive
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "2.0.13"
11 | args:
12 | dependency: transitive
13 | description:
14 | name: args
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "1.5.2"
18 | async:
19 | dependency: transitive
20 | description:
21 | name: async
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "2.4.2"
25 | audioplayers:
26 | dependency: transitive
27 | description:
28 | name: audioplayers
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "0.15.1"
32 | boolean_selector:
33 | dependency: transitive
34 | description:
35 | name: boolean_selector
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "2.0.0"
39 | box2d_flame:
40 | dependency: transitive
41 | description:
42 | name: box2d_flame
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "0.4.6"
46 | characters:
47 | dependency: transitive
48 | description:
49 | name: characters
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "1.0.0"
53 | charcode:
54 | dependency: transitive
55 | description:
56 | name: charcode
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "1.1.3"
60 | clock:
61 | dependency: transitive
62 | description:
63 | name: clock
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "1.0.1"
67 | collection:
68 | dependency: transitive
69 | description:
70 | name: collection
71 | url: "https://pub.dartlang.org"
72 | source: hosted
73 | version: "1.14.13"
74 | convert:
75 | dependency: transitive
76 | description:
77 | name: convert
78 | url: "https://pub.dartlang.org"
79 | source: hosted
80 | version: "2.1.1"
81 | crypto:
82 | dependency: transitive
83 | description:
84 | name: crypto
85 | url: "https://pub.dartlang.org"
86 | source: hosted
87 | version: "2.1.3"
88 | fake_async:
89 | dependency: transitive
90 | description:
91 | name: fake_async
92 | url: "https://pub.dartlang.org"
93 | source: hosted
94 | version: "1.1.0"
95 | flame:
96 | dependency: "direct main"
97 | description:
98 | name: flame
99 | url: "https://pub.dartlang.org"
100 | source: hosted
101 | version: "0.24.0"
102 | flare_dart:
103 | dependency: transitive
104 | description:
105 | name: flare_dart
106 | url: "https://pub.dartlang.org"
107 | source: hosted
108 | version: "2.3.3"
109 | flare_flutter:
110 | dependency: transitive
111 | description:
112 | name: flare_flutter
113 | url: "https://pub.dartlang.org"
114 | source: hosted
115 | version: "2.0.1"
116 | flutter:
117 | dependency: "direct main"
118 | description: flutter
119 | source: sdk
120 | version: "0.0.0"
121 | flutter_test:
122 | dependency: "direct dev"
123 | description: flutter
124 | source: sdk
125 | version: "0.0.0"
126 | flutter_web_plugins:
127 | dependency: transitive
128 | description: flutter
129 | source: sdk
130 | version: "0.0.0"
131 | matcher:
132 | dependency: transitive
133 | description:
134 | name: matcher
135 | url: "https://pub.dartlang.org"
136 | source: hosted
137 | version: "0.12.8"
138 | meta:
139 | dependency: "direct main"
140 | description:
141 | name: meta
142 | url: "https://pub.dartlang.org"
143 | source: hosted
144 | version: "1.1.8"
145 | ordered_set:
146 | dependency: transitive
147 | description:
148 | name: ordered_set
149 | url: "https://pub.dartlang.org"
150 | source: hosted
151 | version: "2.0.0"
152 | path:
153 | dependency: transitive
154 | description:
155 | name: path
156 | url: "https://pub.dartlang.org"
157 | source: hosted
158 | version: "1.7.0"
159 | path_provider:
160 | dependency: transitive
161 | description:
162 | name: path_provider
163 | url: "https://pub.dartlang.org"
164 | source: hosted
165 | version: "1.6.0"
166 | petitparser:
167 | dependency: transitive
168 | description:
169 | name: petitparser
170 | url: "https://pub.dartlang.org"
171 | source: hosted
172 | version: "3.0.4"
173 | platform:
174 | dependency: transitive
175 | description:
176 | name: platform
177 | url: "https://pub.dartlang.org"
178 | source: hosted
179 | version: "2.2.1"
180 | sky_engine:
181 | dependency: transitive
182 | description: flutter
183 | source: sdk
184 | version: "0.0.99"
185 | source_span:
186 | dependency: transitive
187 | description:
188 | name: source_span
189 | url: "https://pub.dartlang.org"
190 | source: hosted
191 | version: "1.7.0"
192 | stack_trace:
193 | dependency: transitive
194 | description:
195 | name: stack_trace
196 | url: "https://pub.dartlang.org"
197 | source: hosted
198 | version: "1.9.5"
199 | stream_channel:
200 | dependency: transitive
201 | description:
202 | name: stream_channel
203 | url: "https://pub.dartlang.org"
204 | source: hosted
205 | version: "2.0.0"
206 | string_scanner:
207 | dependency: transitive
208 | description:
209 | name: string_scanner
210 | url: "https://pub.dartlang.org"
211 | source: hosted
212 | version: "1.0.5"
213 | synchronized:
214 | dependency: transitive
215 | description:
216 | name: synchronized
217 | url: "https://pub.dartlang.org"
218 | source: hosted
219 | version: "2.2.0"
220 | term_glyph:
221 | dependency: transitive
222 | description:
223 | name: term_glyph
224 | url: "https://pub.dartlang.org"
225 | source: hosted
226 | version: "1.1.0"
227 | test_api:
228 | dependency: transitive
229 | description:
230 | name: test_api
231 | url: "https://pub.dartlang.org"
232 | source: hosted
233 | version: "0.2.17"
234 | tiled:
235 | dependency: transitive
236 | description:
237 | name: tiled
238 | url: "https://pub.dartlang.org"
239 | source: hosted
240 | version: "0.6.0"
241 | typed_data:
242 | dependency: transitive
243 | description:
244 | name: typed_data
245 | url: "https://pub.dartlang.org"
246 | source: hosted
247 | version: "1.2.0"
248 | uuid:
249 | dependency: transitive
250 | description:
251 | name: uuid
252 | url: "https://pub.dartlang.org"
253 | source: hosted
254 | version: "2.0.4"
255 | vector_math:
256 | dependency: transitive
257 | description:
258 | name: vector_math
259 | url: "https://pub.dartlang.org"
260 | source: hosted
261 | version: "2.0.8"
262 | xml:
263 | dependency: transitive
264 | description:
265 | name: xml
266 | url: "https://pub.dartlang.org"
267 | source: hosted
268 | version: "4.2.0"
269 | sdks:
270 | dart: ">=2.9.0-14.0.dev <3.0.0"
271 | flutter: ">=1.10.0 <2.0.0"
272 |
--------------------------------------------------------------------------------