mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-11-01 01:18:38 +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
	 Lukas Klingsbo
					Lukas Klingsbo