mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-02 03:15:43 +08:00
docs: Move flame_forge2d examples to main examples (#1588)
This commit is contained in:
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
@ -2,6 +2,7 @@ import 'package:dashbook/dashbook.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'stories/animations/animations.dart';
|
import 'stories/animations/animations.dart';
|
||||||
|
import 'stories/bridge_libraries/forge2d/flame_forge2d.dart';
|
||||||
import 'stories/camera_and_viewport/camera_and_viewport.dart';
|
import 'stories/camera_and_viewport/camera_and_viewport.dart';
|
||||||
import 'stories/collision_detection/collision_detection.dart';
|
import 'stories/collision_detection/collision_detection.dart';
|
||||||
import 'stories/components/components.dart';
|
import 'stories/components/components.dart';
|
||||||
@ -37,5 +38,8 @@ void main() async {
|
|||||||
addUtilsStories(dashbook);
|
addUtilsStories(dashbook);
|
||||||
addWidgetsStories(dashbook);
|
addWidgetsStories(dashbook);
|
||||||
|
|
||||||
|
// Bridge package examples
|
||||||
|
addForge2DStories(dashbook);
|
||||||
|
|
||||||
runApp(dashbook);
|
runApp(dashbook);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,51 @@ import 'package:flame/components.dart';
|
|||||||
import 'package:flame/input.dart';
|
import 'package:flame/input.dart';
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
|
class AnimatedBodyExample extends Forge2DGame with TapDetector {
|
||||||
|
static const String description = '''
|
||||||
|
In this example we show how to add an animated chopper, which is created
|
||||||
|
with a SpriteAnimationComponent, on top of a BodyComponent.
|
||||||
|
|
||||||
|
Tap the screen to add more choppers.
|
||||||
|
''';
|
||||||
|
|
||||||
|
AnimatedBodyExample() : super(gravity: Vector2.zero());
|
||||||
|
|
||||||
|
late Image chopper;
|
||||||
|
late SpriteAnimation animation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
chopper = await images.load('animations/chopper.png');
|
||||||
|
|
||||||
|
animation = SpriteAnimation.fromFrameData(
|
||||||
|
chopper,
|
||||||
|
SpriteAnimationData.sequenced(
|
||||||
|
amount: 4,
|
||||||
|
textureSize: Vector2.all(48),
|
||||||
|
stepTime: 0.15,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final boundaries = createBoundaries(this);
|
||||||
|
boundaries.forEach(add);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onTapDown(TapDownInfo details) {
|
||||||
|
super.onTapDown(details);
|
||||||
|
final position = details.eventPosition.game;
|
||||||
|
final spriteSize = Vector2.all(10);
|
||||||
|
final animationComponent = SpriteAnimationComponent(
|
||||||
|
animation: animation,
|
||||||
|
size: spriteSize,
|
||||||
|
anchor: Anchor.center,
|
||||||
|
);
|
||||||
|
add(ChopperBody(position, animationComponent));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ChopperBody extends BodyComponent {
|
class ChopperBody extends BodyComponent {
|
||||||
final Vector2 position;
|
final Vector2 position;
|
||||||
@ -39,40 +83,3 @@ class ChopperBody extends BodyComponent {
|
|||||||
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PositionBodySample extends Forge2DGame with TapDetector {
|
|
||||||
late Image chopper;
|
|
||||||
late SpriteAnimation animation;
|
|
||||||
|
|
||||||
PositionBodySample() : super(gravity: Vector2.zero());
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> onLoad() async {
|
|
||||||
chopper = await images.load('chopper.png');
|
|
||||||
|
|
||||||
animation = SpriteAnimation.fromFrameData(
|
|
||||||
chopper,
|
|
||||||
SpriteAnimationData.sequenced(
|
|
||||||
amount: 4,
|
|
||||||
textureSize: Vector2.all(48),
|
|
||||||
stepTime: 0.15,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
final boundaries = createBoundaries(this);
|
|
||||||
boundaries.forEach(add);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onTapDown(TapDownInfo details) {
|
|
||||||
super.onTapDown(details);
|
|
||||||
final position = details.eventPosition.game;
|
|
||||||
final spriteSize = Vector2.all(10);
|
|
||||||
final animationComponent = SpriteAnimationComponent(
|
|
||||||
animation: animation,
|
|
||||||
size: spriteSize,
|
|
||||||
anchor: Anchor.center,
|
|
||||||
);
|
|
||||||
add(ChopperBody(position, animationComponent));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,7 +3,40 @@ import 'dart:math' as math;
|
|||||||
import 'package:flame/input.dart';
|
import 'package:flame/input.dart';
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
|
class BlobExample extends Forge2DGame with TapDetector {
|
||||||
|
static const String description = '''
|
||||||
|
In this example we show the power of joints by showing interactions between
|
||||||
|
bodies tied together.
|
||||||
|
|
||||||
|
Tap the screen to add boxes that will bounce on the "blob" in the center.
|
||||||
|
''';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
final worldCenter = screenToWorld(size * camera.zoom / 2);
|
||||||
|
final blobCenter = worldCenter + Vector2(0, -30);
|
||||||
|
final blobRadius = Vector2.all(6.0);
|
||||||
|
addAll(createBoundaries(this));
|
||||||
|
add(Ground(worldCenter));
|
||||||
|
final jointDef = ConstantVolumeJointDef()
|
||||||
|
..frequencyHz = 20.0
|
||||||
|
..dampingRatio = 1.0
|
||||||
|
..collideConnected = false;
|
||||||
|
|
||||||
|
await addAll([
|
||||||
|
for (var i = 0; i < 20; i++) BlobPart(i, jointDef, blobRadius, blobCenter)
|
||||||
|
]);
|
||||||
|
world.createJoint(ConstantVolumeJoint(world, jointDef));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onTapDown(TapDownInfo details) {
|
||||||
|
super.onTapDown(details);
|
||||||
|
add(FallingBox(details.eventPosition.game));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Ground extends BodyComponent {
|
class Ground extends BodyComponent {
|
||||||
final Vector2 worldCenter;
|
final Vector2 worldCenter;
|
||||||
@ -14,15 +47,16 @@ class Ground extends BodyComponent {
|
|||||||
Body createBody() {
|
Body createBody() {
|
||||||
final shape = PolygonShape();
|
final shape = PolygonShape();
|
||||||
shape.setAsBoxXY(20.0, 0.4);
|
shape.setAsBoxXY(20.0, 0.4);
|
||||||
|
final fixtureDef = FixtureDef(shape, friction: 0.2);
|
||||||
|
|
||||||
final bodyDef = BodyDef(position: worldCenter.clone());
|
final bodyDef = BodyDef(position: worldCenter.clone());
|
||||||
final ground = world.createBody(bodyDef);
|
final ground = world.createBody(bodyDef);
|
||||||
ground.createFixtureFromShape(shape);
|
ground.createFixture(fixtureDef);
|
||||||
|
|
||||||
shape.setAsBox(0.4, 20.0, Vector2(-10.0, 0.0), 0.0);
|
shape.setAsBox(0.4, 20.0, Vector2(-10.0, 0.0), 0.0);
|
||||||
ground.createFixtureFromShape(shape);
|
ground.createFixture(fixtureDef);
|
||||||
shape.setAsBox(0.4, 20.0, Vector2(10.0, 0.0), 0.0);
|
shape.setAsBox(0.4, 20.0, Vector2(10.0, 0.0), 0.0);
|
||||||
ground.createFixtureFromShape(shape);
|
ground.createFixture(fixtureDef);
|
||||||
return ground;
|
return ground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,7 +93,7 @@ class BlobPart extends BodyComponent {
|
|||||||
final fixtureDef = FixtureDef(
|
final fixtureDef = FixtureDef(
|
||||||
shape,
|
shape,
|
||||||
density: 1.0,
|
density: 1.0,
|
||||||
filter: Filter()..groupIndex = -2,
|
friction: 0.2,
|
||||||
);
|
);
|
||||||
body.createFixture(fixtureDef);
|
body.createFixture(fixtureDef);
|
||||||
jointDef.addBody(body);
|
jointDef.addBody(body);
|
||||||
@ -84,29 +118,3 @@ class FallingBox extends BodyComponent {
|
|||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlobSample extends Forge2DGame with TapDetector {
|
|
||||||
@override
|
|
||||||
Future<void> onLoad() async {
|
|
||||||
final worldCenter = screenToWorld(size * camera.zoom / 2);
|
|
||||||
final blobCenter = worldCenter + Vector2(0, -30);
|
|
||||||
final blobRadius = Vector2.all(6.0);
|
|
||||||
addAll(createBoundaries(this));
|
|
||||||
add(Ground(worldCenter));
|
|
||||||
final jointDef = ConstantVolumeJointDef()
|
|
||||||
..frequencyHz = 20.0
|
|
||||||
..dampingRatio = 1.0
|
|
||||||
..collideConnected = false;
|
|
||||||
|
|
||||||
await addAll([
|
|
||||||
for (var i = 0; i < 20; i++) BlobPart(i, jointDef, blobRadius, blobCenter)
|
|
||||||
]);
|
|
||||||
world.createJoint(ConstantVolumeJoint(world, jointDef));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onTapDown(TapDownInfo details) {
|
|
||||||
super.onTapDown(details);
|
|
||||||
add(FallingBox(details.eventPosition.game));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import 'package:flame/input.dart';
|
||||||
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
|
||||||
|
import 'domino_example.dart';
|
||||||
|
import 'sprite_body_example.dart';
|
||||||
|
|
||||||
|
class CameraExample extends DominoExample {
|
||||||
|
static const String description = '''
|
||||||
|
This example showcases the possibility to follow BodyComponents with the
|
||||||
|
camera. When the screen is tapped a pizza is added, which the camera will
|
||||||
|
follow. Other than that it is the same as the domino example.
|
||||||
|
''';
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onTapDown(TapDownInfo details) {
|
||||||
|
final position = details.eventPosition.game;
|
||||||
|
final pizza = Pizza(position);
|
||||||
|
add(pizza);
|
||||||
|
pizza.mounted.whenComplete(() => camera.followBodyComponent(pizza));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,18 +5,18 @@ import 'package:flame/input.dart';
|
|||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'balls.dart';
|
import 'utils/balls.dart';
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
const TextStyle _textStyle = TextStyle(color: Colors.white, fontSize: 2);
|
const TextStyle _textStyle = TextStyle(color: Colors.white, fontSize: 2);
|
||||||
|
|
||||||
class CompositionSample extends Forge2DGame with HasTappables {
|
class CompositionExample extends Forge2DGame with HasTappables {
|
||||||
static const info = '''
|
static const description = '''
|
||||||
This example shows how to compose a `BodyComponent` together with a normal Flame
|
This example shows how to compose a `BodyComponent` together with a normal
|
||||||
component. Click the ball to see the number increment.
|
Flame component. Click the ball to see the number increment.
|
||||||
''';
|
''';
|
||||||
|
|
||||||
CompositionSample() : super(zoom: 20, gravity: Vector2(0, 10.0));
|
CompositionExample() : super(zoom: 20, gravity: Vector2(0, 10.0));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
@ -3,17 +3,18 @@ import 'dart:math' as math;
|
|||||||
import 'package:flame/input.dart';
|
import 'package:flame/input.dart';
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
|
||||||
import 'balls.dart';
|
import 'utils/balls.dart';
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
class ContactCallbacksSample extends Forge2DGame with TapDetector {
|
class ContactCallbacksExample extends Forge2DGame with TapDetector {
|
||||||
static const info = '''
|
static const description = '''
|
||||||
This example shows how `BodyComponent`s can react to collisions with other
|
This example shows how `BodyComponent`s can react to collisions with other
|
||||||
bodies.
|
bodies.
|
||||||
Tap the screen to add balls, the white balls will give an impulse to the balls
|
Tap the screen to add balls, the white balls will give an impulse to the
|
||||||
that it collides with.
|
balls that it collides with.
|
||||||
''';
|
''';
|
||||||
ContactCallbacksSample() : super(gravity: Vector2(0, 10.0));
|
|
||||||
|
ContactCallbacksExample() : super(gravity: Vector2(0, 10.0));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
@ -3,8 +3,49 @@ import 'dart:ui';
|
|||||||
import 'package:flame/input.dart';
|
import 'package:flame/input.dart';
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
|
||||||
import 'boundaries.dart';
|
import 'sprite_body_example.dart';
|
||||||
import 'sprite_body_sample.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
|
class DominoExample extends Forge2DGame with TapDetector {
|
||||||
|
static const description = '''
|
||||||
|
In this example we can see some domino tiles lined up.
|
||||||
|
If you tap on the screen a pizza is added which can tip the tiles over and
|
||||||
|
cause a chain reaction.
|
||||||
|
''';
|
||||||
|
|
||||||
|
DominoExample() : super(gravity: Vector2(0, 10.0));
|
||||||
|
|
||||||
|
late Image pizzaImage;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
final boundaries = createBoundaries(this);
|
||||||
|
boundaries.forEach(add);
|
||||||
|
final center = screenToWorld(camera.viewport.effectiveSize / 2);
|
||||||
|
|
||||||
|
const numberOfRows = 7;
|
||||||
|
for (var i = 0; i < numberOfRows - 2; i++) {
|
||||||
|
final position = center + Vector2(0.0, 5.0 * i);
|
||||||
|
add(Platform(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
const numberPerRow = 25;
|
||||||
|
for (var i = 0; i < numberOfRows; ++i) {
|
||||||
|
for (var j = 0; j < numberPerRow; j++) {
|
||||||
|
final position = center +
|
||||||
|
Vector2(-14.75 + j * (29.5 / (numberPerRow - 1)), -12.7 + 5 * i);
|
||||||
|
add(DominoBrick(position));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onTapDown(TapDownInfo details) {
|
||||||
|
super.onTapDown(details);
|
||||||
|
final position = details.eventPosition.game;
|
||||||
|
add(Pizza(position)..renderBody = true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Platform extends BodyComponent {
|
class Platform extends BodyComponent {
|
||||||
final Vector2 position;
|
final Vector2 position;
|
||||||
@ -41,38 +82,3 @@ class DominoBrick extends BodyComponent {
|
|||||||
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DominoSample extends Forge2DGame with TapDetector {
|
|
||||||
late Image pizzaImage;
|
|
||||||
|
|
||||||
DominoSample() : super(gravity: Vector2(0, 10.0));
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> onLoad() async {
|
|
||||||
final boundaries = createBoundaries(this);
|
|
||||||
boundaries.forEach(add);
|
|
||||||
final center = screenToWorld(camera.viewport.effectiveSize / 2);
|
|
||||||
|
|
||||||
const numberOfRows = 7;
|
|
||||||
for (var i = 0; i < numberOfRows - 2; i++) {
|
|
||||||
final position = center + Vector2(0.0, 5.0 * i);
|
|
||||||
add(Platform(position));
|
|
||||||
}
|
|
||||||
|
|
||||||
const numberPerRow = 25;
|
|
||||||
for (var i = 0; i < numberOfRows; ++i) {
|
|
||||||
for (var j = 0; j < numberPerRow; j++) {
|
|
||||||
final position = center +
|
|
||||||
Vector2(-14.75 + j * (29.5 / (numberPerRow - 1)), -12.7 + 5 * i);
|
|
||||||
add(DominoBrick(position));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onTapDown(TapDownInfo details) {
|
|
||||||
super.onTapDown(details);
|
|
||||||
final position = details.eventPosition.game;
|
|
||||||
add(Pizza(position)..renderBody = true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,11 +4,17 @@ import 'package:flame/input.dart';
|
|||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
import 'package:flutter/material.dart' hide Draggable;
|
import 'package:flutter/material.dart' hide Draggable;
|
||||||
|
|
||||||
import 'balls.dart';
|
import 'utils/balls.dart';
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
class DraggableSample extends Forge2DGame with HasDraggables {
|
class DraggableExample extends Forge2DGame with HasDraggables {
|
||||||
DraggableSample() : super(gravity: Vector2.all(0.0));
|
static const description = '''
|
||||||
|
In this example we use Flame's normal `Draggable` mixin to give impulses to
|
||||||
|
a ball when we are dragging it around. If you are interested in dragging
|
||||||
|
bodies around, also have a look at the MouseJointExample.
|
||||||
|
''';
|
||||||
|
|
||||||
|
DraggableExample() : super(gravity: Vector2.all(0.0));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
108
examples/lib/stories/bridge_libraries/forge2d/flame_forge2d.dart
Normal file
108
examples/lib/stories/bridge_libraries/forge2d/flame_forge2d.dart
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import 'package:dashbook/dashbook.dart';
|
||||||
|
import 'package:flame/game.dart';
|
||||||
|
|
||||||
|
import '../../../commons/commons.dart';
|
||||||
|
import 'animated_body_example.dart';
|
||||||
|
import 'blob_example.dart';
|
||||||
|
import 'camera_example.dart';
|
||||||
|
import 'composition_example.dart';
|
||||||
|
import 'contact_callbacks_example.dart';
|
||||||
|
import 'domino_example.dart';
|
||||||
|
import 'draggable_example.dart';
|
||||||
|
import 'joint_example.dart';
|
||||||
|
import 'mouse_joint_example.dart';
|
||||||
|
import 'raycast_example.dart';
|
||||||
|
import 'revolute_joint_example.dart';
|
||||||
|
import 'sprite_body_example.dart';
|
||||||
|
import 'tappable_example.dart';
|
||||||
|
import 'widget_example.dart';
|
||||||
|
|
||||||
|
String link(String example) => baseLink('bride_libraries/$example');
|
||||||
|
|
||||||
|
void addForge2DStories(Dashbook dashbook) {
|
||||||
|
dashbook.storiesOf('flame_forge2d')
|
||||||
|
..add(
|
||||||
|
'Blob example',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: BlobExample()),
|
||||||
|
codeLink: link('blob_example.dart'),
|
||||||
|
info: BlobExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Composition example',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: CompositionExample()),
|
||||||
|
codeLink: link('composition_example.dart'),
|
||||||
|
info: CompositionExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Domino example',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: DominoExample()),
|
||||||
|
codeLink: link('domino_example.dart'),
|
||||||
|
info: DominoExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Contact Callbacks',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: ContactCallbacksExample()),
|
||||||
|
codeLink: link('contact_callbacks_example.dart'),
|
||||||
|
info: ContactCallbacksExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'RevoluteJoint',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: RevoluteJointExample()),
|
||||||
|
codeLink: link('revolute_joint_example.dart'),
|
||||||
|
info: RevoluteJointExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Sprite Bodies',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: SpriteBodyExample()),
|
||||||
|
codeLink: link('sprite_body_example.dart'),
|
||||||
|
info: SpriteBodyExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Animated Bodies',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: AnimatedBodyExample()),
|
||||||
|
codeLink: link('animated_body_example.dart'),
|
||||||
|
info: AnimatedBodyExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Tappable Body',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: TappableExample()),
|
||||||
|
codeLink: link('tappable_example.dart'),
|
||||||
|
info: TappableExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Draggable Body',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: DraggableExample()),
|
||||||
|
codeLink: link('draggable_example.dart'),
|
||||||
|
info: DraggableExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Basic joint',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: JointExample()),
|
||||||
|
codeLink: link('joint_example.dart'),
|
||||||
|
info: JointExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Mouse Joint',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: MouseJointExample()),
|
||||||
|
codeLink: link('mouse_joint_example.dart'),
|
||||||
|
info: MouseJointExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Camera',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: CameraExample()),
|
||||||
|
codeLink: link('camera_example.dart'),
|
||||||
|
info: CameraExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Raycasting',
|
||||||
|
(DashbookContext ctx) => GameWidget(game: RaycastExample()),
|
||||||
|
codeLink: link('raycast_example.dart'),
|
||||||
|
info: RaycastExample.description,
|
||||||
|
)
|
||||||
|
..add(
|
||||||
|
'Widgets',
|
||||||
|
(DashbookContext ctx) => const BodyWidgetExample(),
|
||||||
|
codeLink: link('widget_example.dart'),
|
||||||
|
info: WidgetExample.description,
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// ignore_for_file: directives_ordering
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:shared_preferences_web/shared_preferences_web.dart';
|
||||||
|
import 'package:url_launcher_web/url_launcher_web.dart';
|
||||||
|
|
||||||
|
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
||||||
|
|
||||||
|
// ignore: public_member_api_docs
|
||||||
|
void registerPlugins(Registrar registrar) {
|
||||||
|
SharedPreferencesPlugin.registerWith(registrar);
|
||||||
|
UrlLauncherPlugin.registerWith(registrar);
|
||||||
|
registrar.registerMessageHandler();
|
||||||
|
}
|
||||||
@ -3,8 +3,32 @@ import 'dart:math';
|
|||||||
import 'package:flame/input.dart';
|
import 'package:flame/input.dart';
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
|
||||||
import 'balls.dart';
|
import 'utils/balls.dart';
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
|
class JointExample extends Forge2DGame with TapDetector {
|
||||||
|
static const description = '''
|
||||||
|
In this example we use a joint to keep a body with several fixtures stuck
|
||||||
|
to another body.
|
||||||
|
|
||||||
|
Tap the screen to add more of these combined bodies.
|
||||||
|
''';
|
||||||
|
|
||||||
|
JointExample() : super(gravity: Vector2(0, 10.0));
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
addAll(createBoundaries(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onTapDown(TapDownInfo details) {
|
||||||
|
super.onTapDown(details);
|
||||||
|
final ball = Ball(details.eventPosition.game);
|
||||||
|
add(ball);
|
||||||
|
add(CircleShuffler(ball));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CircleShuffler extends BodyComponent {
|
class CircleShuffler extends BodyComponent {
|
||||||
final Ball ball;
|
final Ball ball;
|
||||||
@ -39,27 +63,10 @@ class CircleShuffler extends BodyComponent {
|
|||||||
body.createFixture(fixtureDef);
|
body.createFixture(fixtureDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
final revoluteJointDef = RevoluteJointDef()
|
final jointDef = RevoluteJointDef()
|
||||||
..initialize(body, ball.body, body.position);
|
..initialize(body, ball.body, body.position);
|
||||||
|
world.createJoint(RevoluteJoint(jointDef));
|
||||||
|
|
||||||
world.createJoint(RevoluteJoint(revoluteJointDef));
|
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class JointSample extends Forge2DGame with TapDetector {
|
|
||||||
JointSample() : super(gravity: Vector2(0, 10.0));
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> onLoad() async {
|
|
||||||
addAll(createBoundaries(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onTapDown(TapDownInfo details) {
|
|
||||||
super.onTapDown(details);
|
|
||||||
final ball = Ball(details.eventPosition.game);
|
|
||||||
add(ball);
|
|
||||||
add(CircleShuffler(ball));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +1,22 @@
|
|||||||
import 'package:flame/input.dart';
|
import 'package:flame/input.dart';
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
|
||||||
import 'balls.dart';
|
import 'revolute_joint_example.dart';
|
||||||
import 'boundaries.dart';
|
import 'utils/balls.dart';
|
||||||
import 'circle_stress_sample.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
|
class MouseJointExample extends Forge2DGame with MultiTouchDragDetector {
|
||||||
|
static const description = '''
|
||||||
|
In this example we use a `MouseJoint` to make the ball follow the mouse
|
||||||
|
when you drag it around.
|
||||||
|
''';
|
||||||
|
|
||||||
|
MouseJointExample() : super(gravity: Vector2(0, 10.0));
|
||||||
|
|
||||||
class MouseJointSample extends Forge2DGame with MultiTouchDragDetector {
|
|
||||||
late Ball ball;
|
late Ball ball;
|
||||||
late Body groundBody;
|
late Body groundBody;
|
||||||
MouseJoint? mouseJoint;
|
MouseJoint? mouseJoint;
|
||||||
|
|
||||||
MouseJointSample() : super(gravity: Vector2(0, 10.0));
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
final boundaries = createBoundaries(this);
|
final boundaries = createBoundaries(this);
|
||||||
@ -4,80 +4,16 @@ import 'package:flame/input.dart';
|
|||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
import 'package:flutter/material.dart' show Colors, Paint, Canvas;
|
import 'package:flutter/material.dart' show Colors, Paint, Canvas;
|
||||||
|
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
const raycastSampleDescription = '''
|
class RaycastExample extends Forge2DGame
|
||||||
This example shows how raycasts can be used to find nearest and farthest fixtures.
|
|
||||||
Red ray finds the nearest fixture and blue ray finds the farthest fixture.
|
|
||||||
''';
|
|
||||||
|
|
||||||
class Box extends BodyComponent {
|
|
||||||
final Vector2 position;
|
|
||||||
|
|
||||||
Box(this.position);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Body createBody() {
|
|
||||||
final shape = PolygonShape()..setAsBoxXY(2.0, 4.0);
|
|
||||||
final fixtureDef = FixtureDef(shape, userData: this);
|
|
||||||
final bodyDef = BodyDef(position: position);
|
|
||||||
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NearestBoxRayCastCallback extends RayCastCallback {
|
|
||||||
Box? box;
|
|
||||||
Vector2? nearestPoint;
|
|
||||||
Vector2? normalAtInter;
|
|
||||||
|
|
||||||
@override
|
|
||||||
double reportFixture(
|
|
||||||
Fixture fixture,
|
|
||||||
Vector2 point,
|
|
||||||
Vector2 normal,
|
|
||||||
double fraction,
|
|
||||||
) {
|
|
||||||
nearestPoint = point.clone();
|
|
||||||
normalAtInter = normal.clone();
|
|
||||||
box = fixture.userData as Box?;
|
|
||||||
|
|
||||||
// Returning fraction implies that we care only about
|
|
||||||
// fixtures that are closer to ray start point than
|
|
||||||
// the current fixture
|
|
||||||
return fraction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FarthestBoxRayCastCallback extends RayCastCallback {
|
|
||||||
Box? box;
|
|
||||||
Vector2? farthestPoint;
|
|
||||||
Vector2? normalAtInter;
|
|
||||||
double previousFraction = 0.0;
|
|
||||||
|
|
||||||
@override
|
|
||||||
double reportFixture(
|
|
||||||
Fixture fixture,
|
|
||||||
Vector2 point,
|
|
||||||
Vector2 normal,
|
|
||||||
double fraction,
|
|
||||||
) {
|
|
||||||
// Value of fraction is directly proportional to
|
|
||||||
// the distance of fixture from ray start point.
|
|
||||||
// So we are interested in the current fixture only if
|
|
||||||
// it has a higher fraction value than previousFraction.
|
|
||||||
if (previousFraction < fraction) {
|
|
||||||
farthestPoint = point.clone();
|
|
||||||
normalAtInter = normal.clone();
|
|
||||||
box = fixture.userData as Box?;
|
|
||||||
previousFraction = fraction;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RaycastSample extends Forge2DGame
|
|
||||||
with TapDetector, MouseMovementDetector {
|
with TapDetector, MouseMovementDetector {
|
||||||
|
static const String description = '''
|
||||||
|
This example shows how raycasts can be used to find nearest and farthest
|
||||||
|
fixtures.
|
||||||
|
Red ray finds the nearest fixture and blue ray finds the farthest fixture.
|
||||||
|
''';
|
||||||
|
|
||||||
final random = Random();
|
final random = Random();
|
||||||
|
|
||||||
final redPoints = List<Vector2>.empty(growable: true);
|
final redPoints = List<Vector2>.empty(growable: true);
|
||||||
@ -86,7 +22,7 @@ class RaycastSample extends Forge2DGame
|
|||||||
Box? nearestBox;
|
Box? nearestBox;
|
||||||
Box? farthestBox;
|
Box? farthestBox;
|
||||||
|
|
||||||
RaycastSample() : super(gravity: Vector2.zero());
|
RaycastExample() : super(gravity: Vector2.zero());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
@ -192,3 +128,68 @@ class RaycastSample extends Forge2DGame
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Box extends BodyComponent {
|
||||||
|
final Vector2 position;
|
||||||
|
|
||||||
|
Box(this.position);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Body createBody() {
|
||||||
|
final shape = PolygonShape()..setAsBoxXY(2.0, 4.0);
|
||||||
|
final fixtureDef = FixtureDef(shape, userData: this);
|
||||||
|
final bodyDef = BodyDef(position: position);
|
||||||
|
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NearestBoxRayCastCallback extends RayCastCallback {
|
||||||
|
Box? box;
|
||||||
|
Vector2? nearestPoint;
|
||||||
|
Vector2? normalAtInter;
|
||||||
|
|
||||||
|
@override
|
||||||
|
double reportFixture(
|
||||||
|
Fixture fixture,
|
||||||
|
Vector2 point,
|
||||||
|
Vector2 normal,
|
||||||
|
double fraction,
|
||||||
|
) {
|
||||||
|
nearestPoint = point.clone();
|
||||||
|
normalAtInter = normal.clone();
|
||||||
|
box = fixture.userData as Box?;
|
||||||
|
|
||||||
|
// Returning fraction implies that we care only about
|
||||||
|
// fixtures that are closer to ray start point than
|
||||||
|
// the current fixture
|
||||||
|
return fraction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FarthestBoxRayCastCallback extends RayCastCallback {
|
||||||
|
Box? box;
|
||||||
|
Vector2? farthestPoint;
|
||||||
|
Vector2? normalAtInter;
|
||||||
|
double previousFraction = 0.0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
double reportFixture(
|
||||||
|
Fixture fixture,
|
||||||
|
Vector2 point,
|
||||||
|
Vector2 normal,
|
||||||
|
double fraction,
|
||||||
|
) {
|
||||||
|
// Value of fraction is directly proportional to
|
||||||
|
// the distance of fixture from ray start point.
|
||||||
|
// So we are interested in the current fixture only if
|
||||||
|
// it has a higher fraction value than previousFraction.
|
||||||
|
if (previousFraction < fraction) {
|
||||||
|
farthestPoint = point.clone();
|
||||||
|
normalAtInter = normal.clone();
|
||||||
|
box = fixture.userData as Box?;
|
||||||
|
previousFraction = fraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,19 +3,51 @@ import 'dart:math';
|
|||||||
import 'package:flame/input.dart';
|
import 'package:flame/input.dart';
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
|
||||||
import 'balls.dart';
|
import 'utils/balls.dart';
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
|
class RevoluteJointExample extends Forge2DGame with TapDetector {
|
||||||
|
static const String description = '''
|
||||||
|
This example showcases a revolute joint, which is the spinning balls in the
|
||||||
|
center.
|
||||||
|
|
||||||
|
If you tap the screen some colourful balls are added and will
|
||||||
|
interact with the bodies tied to the revolute joint once they have fallen
|
||||||
|
down the funnel.
|
||||||
|
''';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
final boundaries = createBoundaries(this);
|
||||||
|
boundaries.forEach(add);
|
||||||
|
final center = screenToWorld(camera.viewport.effectiveSize / 2);
|
||||||
|
add(CircleShuffler(center));
|
||||||
|
add(CornerRamp(center, isMirrored: true));
|
||||||
|
add(CornerRamp(center));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onTapDown(TapDownInfo details) {
|
||||||
|
super.onTapDown(details);
|
||||||
|
final tapPosition = details.eventPosition.game;
|
||||||
|
final random = Random();
|
||||||
|
List.generate(15, (i) {
|
||||||
|
final randomVector = (Vector2.random() - Vector2.all(-0.5)).normalized();
|
||||||
|
add(Ball(tapPosition + randomVector, radius: random.nextDouble()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CircleShuffler extends BodyComponent {
|
class CircleShuffler extends BodyComponent {
|
||||||
final Vector2 _center;
|
|
||||||
|
|
||||||
CircleShuffler(this._center);
|
CircleShuffler(this._center);
|
||||||
|
|
||||||
|
final Vector2 _center;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Body createBody() {
|
Body createBody() {
|
||||||
final bodyDef = BodyDef(
|
final bodyDef = BodyDef(
|
||||||
type: BodyType.dynamic,
|
type: BodyType.dynamic,
|
||||||
position: _center + Vector2(0.0, -25.0),
|
position: _center + Vector2(0.0, 25.0),
|
||||||
);
|
);
|
||||||
const numPieces = 5;
|
const numPieces = 5;
|
||||||
const radius = 6.0;
|
const radius = 6.0;
|
||||||
@ -53,11 +85,11 @@ class CircleShuffler extends BodyComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CornerRamp extends BodyComponent {
|
class CornerRamp extends BodyComponent {
|
||||||
|
CornerRamp(this._center, {this.isMirrored = false});
|
||||||
|
|
||||||
final bool isMirrored;
|
final bool isMirrored;
|
||||||
final Vector2 _center;
|
final Vector2 _center;
|
||||||
|
|
||||||
CornerRamp(this._center, {this.isMirrored = false});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Body createBody() {
|
Body createBody() {
|
||||||
final shape = ChainShape();
|
final shape = ChainShape();
|
||||||
@ -78,26 +110,3 @@ class CornerRamp extends BodyComponent {
|
|||||||
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CircleStressSample extends Forge2DGame with TapDetector {
|
|
||||||
@override
|
|
||||||
Future<void> onLoad() async {
|
|
||||||
final boundaries = createBoundaries(this);
|
|
||||||
boundaries.forEach(add);
|
|
||||||
final center = screenToWorld(camera.viewport.effectiveSize / 2);
|
|
||||||
add(CircleShuffler(center));
|
|
||||||
add(CornerRamp(center, isMirrored: true));
|
|
||||||
add(CornerRamp(center));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onTapDown(TapDownInfo details) {
|
|
||||||
super.onTapDown(details);
|
|
||||||
final tapPosition = details.eventPosition.game;
|
|
||||||
final random = Random();
|
|
||||||
List.generate(15, (i) {
|
|
||||||
final randomVector = (Vector2.random() - Vector2.all(-0.5)).normalized();
|
|
||||||
add(Ball(tapPosition + randomVector, radius: random.nextDouble()));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,10 +4,15 @@ import 'package:flame/components.dart';
|
|||||||
import 'package:flame/input.dart';
|
import 'package:flame/input.dart';
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
class SpriteBodySample extends Forge2DGame with TapDetector {
|
class SpriteBodyExample extends Forge2DGame with TapDetector {
|
||||||
SpriteBodySample() : super(gravity: Vector2(0, 10.0));
|
static const String description = '''
|
||||||
|
In this example we show how to add a sprite on top of a `BodyComponent`.
|
||||||
|
Tap the screen to add more pizzas.
|
||||||
|
''';
|
||||||
|
|
||||||
|
SpriteBodyExample() : super(gravity: Vector2(0, 10.0));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
@ -3,11 +3,17 @@ import 'package:flame/game.dart';
|
|||||||
import 'package:flame/palette.dart';
|
import 'package:flame/palette.dart';
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
|
||||||
import 'balls.dart';
|
import 'utils/balls.dart';
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
class TappableSample extends Forge2DGame with HasTappables {
|
class TappableExample extends Forge2DGame with HasTappables {
|
||||||
TappableSample() : super(zoom: 20, gravity: Vector2(0, 10.0));
|
static const String description = '''
|
||||||
|
In this example we show how to use Flame's tappable mixin to react to taps
|
||||||
|
on `BodyComponent`s.
|
||||||
|
Tap the ball to give it a random impulse, or the text to add an effect to
|
||||||
|
it.
|
||||||
|
''';
|
||||||
|
TappableExample() : super(zoom: 20, gravity: Vector2(0, 10.0));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
@ -3,20 +3,21 @@ import 'package:flame/input.dart';
|
|||||||
import 'package:flame_forge2d/flame_forge2d.dart' hide Transform;
|
import 'package:flame_forge2d/flame_forge2d.dart' hide Transform;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'boundaries.dart';
|
import 'utils/boundaries.dart';
|
||||||
|
|
||||||
const widgetSampleDescription = '''
|
class WidgetExample extends Forge2DGame with TapDetector {
|
||||||
This examples shows how to render a widget on top of a Forge2D body.
|
static const String description = '''
|
||||||
''';
|
This examples shows how to render a widget on top of a Forge2D body outside
|
||||||
|
of Flame.
|
||||||
|
''';
|
||||||
|
|
||||||
class WidgetSample extends Forge2DGame with TapDetector {
|
|
||||||
List<Function()> updateStates = [];
|
List<Function()> updateStates = [];
|
||||||
Map<int, Body> bodyIdMap = {};
|
Map<int, Body> bodyIdMap = {};
|
||||||
List<int> addLaterIds = [];
|
List<int> addLaterIds = [];
|
||||||
|
|
||||||
Vector2 screenPosition(Body body) => worldToScreen(body.worldCenter);
|
Vector2 screenPosition(Body body) => worldToScreen(body.worldCenter);
|
||||||
|
|
||||||
WidgetSample() : super(zoom: 20, gravity: Vector2(0, 10.0));
|
WidgetExample() : super(zoom: 20, gravity: Vector2(0, 10.0));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
@ -38,7 +39,8 @@ class WidgetSample extends Forge2DGame with TapDetector {
|
|||||||
final fixtureDef = FixtureDef(
|
final fixtureDef = FixtureDef(
|
||||||
shape,
|
shape,
|
||||||
density: 1.0,
|
density: 1.0,
|
||||||
restitution: 0.95,
|
restitution: 0.8,
|
||||||
|
friction: 0.2,
|
||||||
);
|
);
|
||||||
body.createFixture(fixtureDef);
|
body.createFixture(fixtureDef);
|
||||||
return body;
|
return body;
|
||||||
@ -59,13 +61,13 @@ class WidgetSample extends Forge2DGame with TapDetector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BodyWidgetSample extends StatelessWidget {
|
class BodyWidgetExample extends StatelessWidget {
|
||||||
const BodyWidgetSample({Key? key}) : super(key: key);
|
const BodyWidgetExample({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GameWidget<WidgetSample>(
|
return GameWidget<WidgetExample>(
|
||||||
game: WidgetSample(),
|
game: WidgetExample(),
|
||||||
overlayBuilderMap: {
|
overlayBuilderMap: {
|
||||||
'button1': (ctx, game) {
|
'button1': (ctx, game) {
|
||||||
return BodyButtonWidget(game, game.createBodyId());
|
return BodyButtonWidget(game, game.createBodyId());
|
||||||
@ -80,7 +82,7 @@ class BodyWidgetSample extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class BodyButtonWidget extends StatefulWidget {
|
class BodyButtonWidget extends StatefulWidget {
|
||||||
final WidgetSample _game;
|
final WidgetExample _game;
|
||||||
final int _bodyId;
|
final int _bodyId;
|
||||||
|
|
||||||
const BodyButtonWidget(
|
const BodyButtonWidget(
|
||||||
@ -96,7 +98,7 @@ class BodyButtonWidget extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _BodyButtonState extends State<BodyButtonWidget> {
|
class _BodyButtonState extends State<BodyButtonWidget> {
|
||||||
final WidgetSample _game;
|
final WidgetExample _game;
|
||||||
final int _bodyId;
|
final int _bodyId;
|
||||||
Body? _body;
|
Body? _body;
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ class MultipleShapesExample extends FlameGame
|
|||||||
add(screenHitbox);
|
add(screenHitbox);
|
||||||
add(snowman);
|
add(snowman);
|
||||||
var totalAdded = 1;
|
var totalAdded = 1;
|
||||||
while (totalAdded < 100) {
|
while (totalAdded < 1000) {
|
||||||
lastToAdd = nextRandomCollidable(lastToAdd, screenHitbox);
|
lastToAdd = nextRandomCollidable(lastToAdd, screenHitbox);
|
||||||
final lastBottomRight = lastToAdd.toAbsoluteRect().bottomRight;
|
final lastBottomRight = lastToAdd.toAbsoluteRect().bottomRight;
|
||||||
if (lastBottomRight.dx < size.x && lastBottomRight.dy < size.y) {
|
if (lastBottomRight.dx < size.x && lastBottomRight.dy < size.y) {
|
||||||
|
|||||||
@ -12,6 +12,7 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flame: ^1.1.1
|
flame: ^1.1.1
|
||||||
flame_svg: ^1.2.0
|
flame_svg: ^1.2.0
|
||||||
|
flame_forge2d: ^0.11.0
|
||||||
dashbook: 0.1.6
|
dashbook: 0.1.6
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB |
@ -1,15 +0,0 @@
|
|||||||
import 'package:flame/input.dart';
|
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
|
||||||
|
|
||||||
import 'domino_sample.dart';
|
|
||||||
import 'sprite_body_sample.dart';
|
|
||||||
|
|
||||||
class CameraSample extends DominoSample {
|
|
||||||
@override
|
|
||||||
void onTapDown(TapDownInfo details) {
|
|
||||||
final position = details.eventPosition.game;
|
|
||||||
final pizza = Pizza(position);
|
|
||||||
add(pizza);
|
|
||||||
pizza.mounted.whenComplete(() => camera.followBodyComponent(pizza));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,112 +1,7 @@
|
|||||||
import 'package:dashbook/dashbook.dart';
|
|
||||||
import 'package:flame/game.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'animated_body_sample.dart';
|
|
||||||
import 'blob_sample.dart';
|
|
||||||
import 'camera_sample.dart';
|
|
||||||
import 'circle_stress_sample.dart';
|
|
||||||
import 'composition_sample.dart';
|
|
||||||
import 'contact_callbacks_sample.dart';
|
|
||||||
import 'domino_sample.dart';
|
|
||||||
import 'draggable_sample.dart';
|
|
||||||
import 'joint_sample.dart';
|
|
||||||
import 'mouse_joint_sample.dart';
|
|
||||||
import 'raycast_sample.dart';
|
|
||||||
import 'sprite_body_sample.dart';
|
|
||||||
import 'tappable_sample.dart';
|
|
||||||
import 'widget_sample.dart';
|
|
||||||
|
|
||||||
String link(String example) =>
|
|
||||||
'https://github.com/flame-engine/flame_forge2d/tree/main/example/lib/$example';
|
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
// There will be a new example in here after Google I/O, stay tuned!
|
||||||
final dashbook = Dashbook(theme: ThemeData.dark());
|
// If you want to see the previous examples, go to the flame_forge2d section
|
||||||
|
// of https://examples.flame-engine.org
|
||||||
dashbook.storiesOf('Flame with Forge2D').decorator(TopDecorator())
|
// The sourcecode lives here:
|
||||||
..add(
|
// https://github.com/flame-engine/flame/tree/main/examples/lib/stories/bridge_libraries/forge2d
|
||||||
'Blob sample',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: BlobSample()),
|
|
||||||
codeLink: link('blob_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Composition sample',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: CompositionSample()),
|
|
||||||
codeLink: link('composition_sample.dart'),
|
|
||||||
info: CompositionSample.info,
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Domino sample',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: DominoSample()),
|
|
||||||
codeLink: link('domino_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Contact Callbacks',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: ContactCallbacksSample()),
|
|
||||||
codeLink: link('contact_callbacks_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Circle stress sample',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: CircleStressSample()),
|
|
||||||
codeLink: link('circle_stress_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Sprite Bodies',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: SpriteBodySample()),
|
|
||||||
codeLink: link('sprite_body_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'PositionBodyComponent',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: PositionBodySample()),
|
|
||||||
codeLink: link('animated_body_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Tappable Body',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: TappableSample()),
|
|
||||||
codeLink: link('tappable_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Draggable Body',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: DraggableSample()),
|
|
||||||
codeLink: link('draggable_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Basic joint',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: JointSample()),
|
|
||||||
codeLink: link('joint_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Mouse Joint',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: MouseJointSample()),
|
|
||||||
codeLink: link('mouse_joint_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Camera',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: CameraSample()),
|
|
||||||
codeLink: link('camera_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Widget sample',
|
|
||||||
(DashbookContext ctx) => const BodyWidgetSample(),
|
|
||||||
info: widgetSampleDescription,
|
|
||||||
codeLink: link('widget_sample.dart'),
|
|
||||||
)
|
|
||||||
..add(
|
|
||||||
'Raycast sample',
|
|
||||||
(DashbookContext ctx) => GameWidget(game: RaycastSample()),
|
|
||||||
codeLink: link('raycast_sample.dart'),
|
|
||||||
info: raycastSampleDescription,
|
|
||||||
);
|
|
||||||
runApp(dashbook);
|
|
||||||
}
|
|
||||||
|
|
||||||
class TopDecorator extends Decorator {
|
|
||||||
@override
|
|
||||||
Widget decorate(Widget child) {
|
|
||||||
return Align(
|
|
||||||
child: child,
|
|
||||||
alignment: Alignment.topCenter,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,3 @@ dev_dependencies:
|
|||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
assets:
|
|
||||||
- assets/images/pizza.png
|
|
||||||
- assets/images/chopper.png
|
|
||||||
|
|||||||
Reference in New Issue
Block a user