diff --git a/bricks/example/__brick__/lib/main.dart b/bricks/example/__brick__/lib/main.dart index f2320cb..303dc6d 100644 --- a/bricks/example/__brick__/lib/main.dart +++ b/bricks/example/__brick__/lib/main.dart @@ -9,42 +9,41 @@ import 'package:flutter/material.dart'; final _rng = Random(); void main() { - runApp(GameWidget(game: MyGame())); + runApp(const GameWidget.controlled(gameFactory: MyGame.new)); } -class MyGame extends FlameGame with TapCallbacks { +class MyGame extends FlameGame { + MyGame() : super(world: MyWorld()); +} + +class MyWorld extends World { late final MyComponent myComponent; @override Future onLoad() async { - await world.add(myComponent = MyComponent()); + await add(myComponent = MyComponent()); return super.onLoad(); } - - @override - void onTapUp(TapUpEvent event) { - myComponent.speed.x = -1 + 2 * _rng.nextDouble(); - myComponent.speed.y = -1 + 2 * _rng.nextDouble(); - } } -class MyComponent extends PositionComponent with HasGameRef { - static final _paint = BasicPalette.white.paint(); +class MyComponent extends RectangleComponent with TapCallbacks { final Vector2 speed = Vector2.zero(); MyComponent() - : super( + : super.square( + size: 64, anchor: Anchor.center, - size: Vector2.all(32), + paint: BasicPalette.magenta.paint(), ); @override - void render(Canvas c) { - c.drawRect(size.toRect(), _paint); + void update(double dt) { + position += speed * 128.0 * dt; } @override - void update(double dt) { - position += speed * 32.0 * dt; + void onTapDown(TapDownEvent event) { + speed.x = -1 + 2 * _rng.nextDouble(); + speed.y = -1 + 2 * _rng.nextDouble(); } } diff --git a/bricks/example/__brick__/test/my_component_test.dart b/bricks/example/__brick__/test/my_component_test.dart new file mode 100644 index 0000000..532aae5 --- /dev/null +++ b/bricks/example/__brick__/test/my_component_test.dart @@ -0,0 +1,30 @@ +import 'package:flame/events.dart'; +import 'package:flame/game.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:{{name}}/main.dart'; + +void main() { + testWithGame( + 'game will load and MyComponent responds to taps', + MyGame.new, + (game) async { + await game.ready(); + + expect(game.world.children.length, 1); + expect(game.world.myComponent.speed, Vector2.zero()); + + final dispatcher = game.firstChild()!; + dispatcher.onTapDown( + createTapDownEvents( + game: game, + localPosition: (game.size / 2).toOffset(), + globalPosition: (game.size / 2).toOffset(), + ), + ); + + expect(game.world.myComponent.speed, isNot(equals(Vector2.zero()))); + }, + ); +} diff --git a/bricks/example/__brick__/test/widget_test.dart b/bricks/example/__brick__/test/widget_test.dart deleted file mode 100644 index ca6426a..0000000 --- a/bricks/example/__brick__/test/widget_test.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flame/game.dart'; -import 'package:flame_test/flame_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:{{name}}/main.dart'; - -final myGame = FlameTester(MyGame.new); - -void main() { - myGame.testGameWidget( - 'game will load its child', - verify: (game, tester) async { - game.update(0.0); - - expect(game.children.length, 1); - expect(game.myComponent.speed, Vector2.zero()); - - await tester.tapAt(const Offset(10, 10)); - expect(game.myComponent.speed, isNot(equals(Vector2.zero()))); - }, - ); -} diff --git a/lib/templates/bricks/example_bundle.dart b/lib/templates/bricks/example_bundle.dart index 873e746..7ab5f10 100644 --- a/lib/templates/bricks/example_bundle.dart +++ b/lib/templates/bricks/example_bundle.dart @@ -3,4 +3,4 @@ import 'package:mason/mason.dart'; -final exampleBundle = MasonBundle.fromJson({"files":[{"path":"analysis_options.yaml","data":"aW5jbHVkZTogcGFja2FnZTpmbGFtZV9saW50L2FuYWx5c2lzX29wdGlvbnMueWFtbA==","type":"text"},{"path":"lib/main.dart","data":"aW1wb3J0ICdkYXJ0Om1hdGgnOwoKaW1wb3J0ICdwYWNrYWdlOmZsYW1lL2NvbXBvbmVudHMuZGFydCc7CmltcG9ydCAncGFja2FnZTpmbGFtZS9ldmVudHMuZGFydCc7CmltcG9ydCAncGFja2FnZTpmbGFtZS9nYW1lLmRhcnQnOwppbXBvcnQgJ3BhY2thZ2U6ZmxhbWUvcGFsZXR0ZS5kYXJ0JzsKaW1wb3J0ICdwYWNrYWdlOmZsdXR0ZXIvbWF0ZXJpYWwuZGFydCc7CgpmaW5hbCBfcm5nID0gUmFuZG9tKCk7Cgp2b2lkIG1haW4oKSB7CiAgcnVuQXBwKEdhbWVXaWRnZXQoZ2FtZTogTXlHYW1lKCkpKTsKfQoKY2xhc3MgTXlHYW1lIGV4dGVuZHMgRmxhbWVHYW1lIHdpdGggVGFwQ2FsbGJhY2tzIHsKICBsYXRlIGZpbmFsIE15Q29tcG9uZW50IG15Q29tcG9uZW50OwoKICBAb3ZlcnJpZGUKICBGdXR1cmU8dm9pZD4gb25Mb2FkKCkgYXN5bmMgewogICAgYXdhaXQgd29ybGQuYWRkKG15Q29tcG9uZW50ID0gTXlDb21wb25lbnQoKSk7CiAgICByZXR1cm4gc3VwZXIub25Mb2FkKCk7CiAgfQoKICBAb3ZlcnJpZGUKICB2b2lkIG9uVGFwVXAoVGFwVXBFdmVudCBldmVudCkgewogICAgbXlDb21wb25lbnQuc3BlZWQueCA9IC0xICsgMiAqIF9ybmcubmV4dERvdWJsZSgpOwogICAgbXlDb21wb25lbnQuc3BlZWQueSA9IC0xICsgMiAqIF9ybmcubmV4dERvdWJsZSgpOwogIH0KfQoKY2xhc3MgTXlDb21wb25lbnQgZXh0ZW5kcyBQb3NpdGlvbkNvbXBvbmVudCB3aXRoIEhhc0dhbWVSZWY8TXlHYW1lPiB7CiAgc3RhdGljIGZpbmFsIF9wYWludCA9IEJhc2ljUGFsZXR0ZS53aGl0ZS5wYWludCgpOwogIGZpbmFsIFZlY3RvcjIgc3BlZWQgPSBWZWN0b3IyLnplcm8oKTsKCiAgTXlDb21wb25lbnQoKQogICAgICA6IHN1cGVyKAogICAgICAgICAgYW5jaG9yOiBBbmNob3IuY2VudGVyLAogICAgICAgICAgc2l6ZTogVmVjdG9yMi5hbGwoMzIpLAogICAgICAgICk7CgogIEBvdmVycmlkZQogIHZvaWQgcmVuZGVyKENhbnZhcyBjKSB7CiAgICBjLmRyYXdSZWN0KHNpemUudG9SZWN0KCksIF9wYWludCk7CiAgfQoKICBAb3ZlcnJpZGUKICB2b2lkIHVwZGF0ZShkb3VibGUgZHQpIHsKICAgIHBvc2l0aW9uICs9IHNwZWVkICogMzIuMCAqIGR0OwogIH0KfQo=","type":"text"},{"path":"pubspec.yaml","data":"bmFtZToge3tuYW1lfX0KZGVzY3JpcHRpb246IHt7ZGVzY3JpcHRpb259fQp2ZXJzaW9uOiB7e3ZlcnNpb259fQoKcHVibGlzaF90bzogJ25vbmUnCgplbnZpcm9ubWVudDoKICBzZGs6ICI+PTMuMC4wIDw0LjAuMCIKCmRlcGVuZGVuY2llczp7eyNleHRyYS1kZXBlbmRlbmNpZXN9fQogIHt7bmFtZX19OiB7e3ZlcnNpb259fXt7L2V4dHJhLWRlcGVuZGVuY2llc319CiAgZmx1dHRlcjoKICAgIHNkazogZmx1dHRlcgoKZGV2X2RlcGVuZGVuY2llczp7eyNleHRyYS1kZXYtZGVwZW5kZW5jaWVzfX0KICB7e25hbWV9fToge3t2ZXJzaW9ufX17ey9leHRyYS1kZXYtZGVwZW5kZW5jaWVzfX0KICBmbHV0dGVyX3Rlc3Q6CiAgICBzZGs6IGZsdXR0ZXIKICBpbnRlZ3JhdGlvbl90ZXN0OgogICAgc2RrOiBmbHV0dGVyCgpmbHV0dGVyOgogIHVzZXMtbWF0ZXJpYWwtZGVzaWduOiBmYWxzZQ==","type":"text"},{"path":"test/widget_test.dart","data":"aW1wb3J0ICdwYWNrYWdlOmZsYW1lL2dhbWUuZGFydCc7CmltcG9ydCAncGFja2FnZTpmbGFtZV90ZXN0L2ZsYW1lX3Rlc3QuZGFydCc7CmltcG9ydCAncGFja2FnZTpmbHV0dGVyX3Rlc3QvZmx1dHRlcl90ZXN0LmRhcnQnOwoKaW1wb3J0ICdwYWNrYWdlOnt7bmFtZX19L21haW4uZGFydCc7CgpmaW5hbCBteUdhbWUgPSBGbGFtZVRlc3RlcihNeUdhbWUubmV3KTsKCnZvaWQgbWFpbigpIHsKICBteUdhbWUudGVzdEdhbWVXaWRnZXQoCiAgICAnZ2FtZSB3aWxsIGxvYWQgaXRzIGNoaWxkJywKICAgIHZlcmlmeTogKGdhbWUsIHRlc3RlcikgYXN5bmMgewogICAgICBnYW1lLnVwZGF0ZSgwLjApOwoKICAgICAgZXhwZWN0KGdhbWUuY2hpbGRyZW4ubGVuZ3RoLCAxKTsKICAgICAgZXhwZWN0KGdhbWUubXlDb21wb25lbnQuc3BlZWQsIFZlY3RvcjIuemVybygpKTsKCiAgICAgIGF3YWl0IHRlc3Rlci50YXBBdChjb25zdCBPZmZzZXQoMTAsIDEwKSk7CiAgICAgIGV4cGVjdChnYW1lLm15Q29tcG9uZW50LnNwZWVkLCBpc05vdChlcXVhbHMoVmVjdG9yMi56ZXJvKCkpKSk7CiAgICB9LAogICk7Cn0K","type":"text"}],"hooks":[],"name":"example","description":"An actual complete, working game example. Extra code that you won't need but will teach you how to wire the most important pieces.","version":"0.1.0","environment":{"mason":"any"},"vars":{"name":{"type":"string"},"description":{"type":"string"},"version":{"type":"string"},"flame-version":{"type":"string"},"flame-lint-version":{"type":"string"},"extra-dependencies":{"type":"array"},"extra-dev-dependencies":{"type":"array"}}}); \ No newline at end of file +final exampleBundle = MasonBundle.fromJson({"files":[{"path":"analysis_options.yaml","data":"aW5jbHVkZTogcGFja2FnZTpmbGFtZV9saW50L2FuYWx5c2lzX29wdGlvbnMueWFtbA==","type":"text"},{"path":"lib/main.dart","data":"aW1wb3J0ICdkYXJ0Om1hdGgnOwoKaW1wb3J0ICdwYWNrYWdlOmZsYW1lL2NvbXBvbmVudHMuZGFydCc7CmltcG9ydCAncGFja2FnZTpmbGFtZS9ldmVudHMuZGFydCc7CmltcG9ydCAncGFja2FnZTpmbGFtZS9nYW1lLmRhcnQnOwppbXBvcnQgJ3BhY2thZ2U6ZmxhbWUvcGFsZXR0ZS5kYXJ0JzsKaW1wb3J0ICdwYWNrYWdlOmZsdXR0ZXIvbWF0ZXJpYWwuZGFydCc7CgpmaW5hbCBfcm5nID0gUmFuZG9tKCk7Cgp2b2lkIG1haW4oKSB7CiAgcnVuQXBwKGNvbnN0IEdhbWVXaWRnZXQuY29udHJvbGxlZChnYW1lRmFjdG9yeTogTXlHYW1lLm5ldykpOwp9CgpjbGFzcyBNeUdhbWUgZXh0ZW5kcyBGbGFtZUdhbWU8TXlXb3JsZD4gewogIE15R2FtZSgpIDogc3VwZXIod29ybGQ6IE15V29ybGQoKSk7Cn0KCmNsYXNzIE15V29ybGQgZXh0ZW5kcyBXb3JsZCB7CiAgbGF0ZSBmaW5hbCBNeUNvbXBvbmVudCBteUNvbXBvbmVudDsKCiAgQG92ZXJyaWRlCiAgRnV0dXJlPHZvaWQ+IG9uTG9hZCgpIGFzeW5jIHsKICAgIGF3YWl0IGFkZChteUNvbXBvbmVudCA9IE15Q29tcG9uZW50KCkpOwogICAgcmV0dXJuIHN1cGVyLm9uTG9hZCgpOwogIH0KfQoKY2xhc3MgTXlDb21wb25lbnQgZXh0ZW5kcyBSZWN0YW5nbGVDb21wb25lbnQgd2l0aCBUYXBDYWxsYmFja3MgewogIGZpbmFsIFZlY3RvcjIgc3BlZWQgPSBWZWN0b3IyLnplcm8oKTsKCiAgTXlDb21wb25lbnQoKQogICAgICA6IHN1cGVyLnNxdWFyZSgKICAgICAgICAgIHNpemU6IDY0LAogICAgICAgICAgYW5jaG9yOiBBbmNob3IuY2VudGVyLAogICAgICAgICAgcGFpbnQ6IEJhc2ljUGFsZXR0ZS5tYWdlbnRhLnBhaW50KCksCiAgICAgICAgKTsKCiAgQG92ZXJyaWRlCiAgdm9pZCB1cGRhdGUoZG91YmxlIGR0KSB7CiAgICBwb3NpdGlvbiArPSBzcGVlZCAqIDEyOC4wICogZHQ7CiAgfQoKICBAb3ZlcnJpZGUKICB2b2lkIG9uVGFwRG93bihUYXBEb3duRXZlbnQgZXZlbnQpIHsKICAgIHNwZWVkLnggPSAtMSArIDIgKiBfcm5nLm5leHREb3VibGUoKTsKICAgIHNwZWVkLnkgPSAtMSArIDIgKiBfcm5nLm5leHREb3VibGUoKTsKICB9Cn0K","type":"text"},{"path":"pubspec.yaml","data":"bmFtZToge3tuYW1lfX0KZGVzY3JpcHRpb246IHt7ZGVzY3JpcHRpb259fQp2ZXJzaW9uOiB7e3ZlcnNpb259fQoKcHVibGlzaF90bzogJ25vbmUnCgplbnZpcm9ubWVudDoKICBzZGs6ICI+PTMuMC4wIDw0LjAuMCIKCmRlcGVuZGVuY2llczp7eyNleHRyYS1kZXBlbmRlbmNpZXN9fQogIHt7bmFtZX19OiB7e3ZlcnNpb259fXt7L2V4dHJhLWRlcGVuZGVuY2llc319CiAgZmx1dHRlcjoKICAgIHNkazogZmx1dHRlcgoKZGV2X2RlcGVuZGVuY2llczp7eyNleHRyYS1kZXYtZGVwZW5kZW5jaWVzfX0KICB7e25hbWV9fToge3t2ZXJzaW9ufX17ey9leHRyYS1kZXYtZGVwZW5kZW5jaWVzfX0KICBmbHV0dGVyX3Rlc3Q6CiAgICBzZGs6IGZsdXR0ZXIKICBpbnRlZ3JhdGlvbl90ZXN0OgogICAgc2RrOiBmbHV0dGVyCgpmbHV0dGVyOgogIHVzZXMtbWF0ZXJpYWwtZGVzaWduOiBmYWxzZQ==","type":"text"},{"path":"test/my_component_test.dart","data":"aW1wb3J0ICdwYWNrYWdlOmZsYW1lL2V2ZW50cy5kYXJ0JzsKaW1wb3J0ICdwYWNrYWdlOmZsYW1lL2dhbWUuZGFydCc7CmltcG9ydCAncGFja2FnZTpmbGFtZV90ZXN0L2ZsYW1lX3Rlc3QuZGFydCc7CmltcG9ydCAncGFja2FnZTpmbHV0dGVyX3Rlc3QvZmx1dHRlcl90ZXN0LmRhcnQnOwoKaW1wb3J0ICdwYWNrYWdlOnt7bmFtZX19L21haW4uZGFydCc7Cgp2b2lkIG1haW4oKSB7CiAgdGVzdFdpdGhHYW1lPE15R2FtZT4oCiAgICAnZ2FtZSB3aWxsIGxvYWQgYW5kIE15Q29tcG9uZW50IHJlc3BvbmRzIHRvIHRhcHMnLAogICAgTXlHYW1lLm5ldywKICAgIChnYW1lKSBhc3luYyB7CiAgICAgIGF3YWl0IGdhbWUucmVhZHkoKTsKCiAgICAgIGV4cGVjdChnYW1lLndvcmxkLmNoaWxkcmVuLmxlbmd0aCwgMSk7CiAgICAgIGV4cGVjdChnYW1lLndvcmxkLm15Q29tcG9uZW50LnNwZWVkLCBWZWN0b3IyLnplcm8oKSk7CgogICAgICBmaW5hbCBkaXNwYXRjaGVyID0gZ2FtZS5maXJzdENoaWxkPE11bHRpVGFwRGlzcGF0Y2hlcj4oKSE7CiAgICAgIGRpc3BhdGNoZXIub25UYXBEb3duKAogICAgICAgIGNyZWF0ZVRhcERvd25FdmVudHMoCiAgICAgICAgICBnYW1lOiBnYW1lLAogICAgICAgICAgbG9jYWxQb3NpdGlvbjogKGdhbWUuc2l6ZSAvIDIpLnRvT2Zmc2V0KCksCiAgICAgICAgICBnbG9iYWxQb3NpdGlvbjogKGdhbWUuc2l6ZSAvIDIpLnRvT2Zmc2V0KCksCiAgICAgICAgKSwKICAgICAgKTsKCiAgICAgIGV4cGVjdChnYW1lLndvcmxkLm15Q29tcG9uZW50LnNwZWVkLCBpc05vdChlcXVhbHMoVmVjdG9yMi56ZXJvKCkpKSk7CiAgICB9LAogICk7Cn0K","type":"text"}],"hooks":[],"name":"example","description":"An actual complete, working game example. Extra code that you won't need but will teach you how to wire the most important pieces.","version":"0.1.0","environment":{"mason":"any"},"vars":{"name":{"type":"string"},"description":{"type":"string"},"version":{"type":"string"},"flame-version":{"type":"string"},"flame-lint-version":{"type":"string"},"extra-dependencies":{"type":"array"},"extra-dev-dependencies":{"type":"array"}}}); \ No newline at end of file