Code Monkey home page Code Monkey logo

forge2d's Introduction

flame

Forge2D - A Dart port of the Box2D physics engine

Test

The Box2D physics engine is a fairly famous open source physics engine and this is our Dart port of it.

You can use it independently in Dart or in your Flame project with the help of flame_forge2d.

Some documentation of how to use it together with flame can be found here.

Timeline

Box2D was first written in C++ and released by Erin Catto in 2007, but it is still maintained.

It was then ported to Java (jbox2d) by Daniel Murphy around 2015.

Then from that Java port it was ported to Dart by Dominic Hamon and Kevin Moore.

A few years after that Lukas Klingsbo refactored the code to better follow the Dart standard, since it still had a lot of reminiscence from C++. After this refactor, we renamed it to Forge2D, as the upstream wasn't maintained to take in our PRs.

There has also been countless other contributors which we are very thankful to!

Credits

  • The Flame engine team who is continuously working on maintaining and improving Forge2D.
  • Special thanks for Lukas Klingsbo, a Flame team member which took this project under his wing and greatly improved the project!
  • The Dart port of Box2D.

forge2d's People

Contributors

0llie avatar alestiago avatar alex-a4 avatar erickzanardo avatar feroult avatar filiph avatar gkjpettet avatar guyluz11 avatar hwan-seok avatar jamesdobson avatar japalekhin avatar johnmccutchan avatar kevmoo avatar kjagiello avatar luanpotter avatar mjordan56 avatar mraleph avatar msywensky avatar psiroki avatar renancaraujo avatar sethladd avatar spydon avatar srdjanmitrovic avatar tfoel avatar tommybuonomo avatar ufrshubham avatar yourpalal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

forge2d's Issues

feat: Include generics for `Joint` and `JointDef`

Problem to solve

Avoid casting and asserting when doing something as:

assert(joint.bodyA is Foo && joint.bodyB is Boo, 'Invalid joint.');
final foo = joint.bodyA as foo;
final boo = joint.bodyB as boo;

Proposal

Use of generics to determine the type of bodyA and bodyB. For example, Joint<T, S> and JointDef<T, S>.

More information

Similar to #36 but not the same.


I'm interested in working on a PR for this.

Unused method arguments in `Rot`. Can it be removed?

These two methods in common/rot.dart:

Vector2 getXAxis(Vector2 xAxis) => Vector2(cos, sin);

Vector2 getYAxis(Vector2 yAxis) => Vector2(-sin, cos);

Take a Vector2 but as far as I can see they aren't used. It looks like dynamics/fixture.dart calls this method and passes in a Vector2 but I think it is defunct.

I'm trying to port this library to another language and I just hope I'm not missing anything here.

update's dt is inconsistent between Game.pause and device lock

The update(dt) method gives The time dt in seconds since the last update cycle.
When the game is paused, it is expected that the update's dt time resumes were it was when game is resumed. So if the games pauses for 2min, the dt on resume will not be 2min or so.

This works perfectly fine when using the Game.pause field.
But if game is paused because device screen goes off, the dt time it inconsistent when screen goes on (it will be around 2min in my exemple).

PolygonShape Creates Invalid Convex Hull From Vertices

The code refactoring done in PR #7 to the gift wrapping algorithm for creating a convex hull is incorrect. The previous code properly implemented the gift wrapping algorithm and correctly generated a valid convex hull. The refactored code does not properly implement the gift wrapping algorithm. To demonstrate the error of the refactored code, consider this set of vertices to define a polygon:

var vertices = [
    Vector2(-10, 20),
    Vector2(-10, 0),
    Vector2(0, -30),
    Vector2(10, 0),
    Vector2(10, 10),
  ];

final shape = PolygonShape()..set(vertices);

The correct convex hull output from this set of vertices from the gift wrapping algorithm is (and was from the old code):

    Vector2(10, 0),
    Vector2(10, 10),
    Vector2(-10, 20),
    Vector2(-10, 0),
    Vector2(0, -30),

But the output from the new refactored code is an invalid polygon that crosses over itself:

    Vector2(10, 0),
    Vector2(-10, 0),
    Vector2(0, -30),
    Vector2(10, 10),
    Vector2(-10, 20),

The incorrect refactored code is in forge2d-0.7.2 > lib > src > collision > shapes > polygon_shape.dart beginning at line 90:

    final hull = <Vector2>[rightMostPoint];
    for (final point1 in points) {
      var currentPoint = hull.last;
      for (final point2 in points) {
        if (currentPoint == hull.last) {
          currentPoint = point2;
          continue;
        }

        final r = currentPoint.clone()..sub(point1);
        final v = point2.clone()..sub(point1);
        final c = r.cross(v);
        if (c < 0.0) {
          currentPoint = point2;
        }

        // Collinearity check
        if (c == 0.0 && v.length2 > r.length2) {
          currentPoint = point2;
        }
      }

      if (!hull.contains(currentPoint)) {
        hull.add(currentPoint);
      }
    }

Not only is this code incorrect, but it also changes the complexity of the gift wrapping algorithm from O(nh) where n is the number of vertices and h is the number of vertices on the hull, to O(nn).

I'd like to offer this fix for consideration as a correct implementation of the gift wrapping algorithm:

    final hull = <Vector2>[rightMostPoint];
    var pointOnHull = rightMostPoint;
    do {
      // Set first point in the set as the initial candidate for the
      // next point on the convex hull.
      var endPoint = points[0];

      // Test the candidate point against all points in the set to find
      // the next convex hull point.
      for (final point in points) {
        // If the candidate point is current last point on the convex
        // hull update the candidate point to the current point and continue
        // checking against the remaining points.
        if (endPoint == pointOnHull) {
          endPoint = point;
          continue;
        }

        // Use the cross product of the vectors from the current convex hull
        // point to the candidate point and the current test point to see if
        // the test point is changes the winding to CW. Update the candidate
        // point when the winding changes.
        final r = endPoint.clone()..sub(pointOnHull);
        final v = point.clone()..sub(pointOnHull);
        final c = r.cross(v);
        if (c < 0.0) {
          endPoint = point;
        }

        // Collinearity check
        if (c == 0.0 && v.length2 > r.length2) {
          endPoint = point;
        }
      }

      // Set the end point candidate as the new current convex hull point.
      pointOnHull = endPoint;
      if (!hull.contains(pointOnHull)) {
        hull.add(pointOnHull);
      }
    } while (pointOnHull != hull.first);

Exception: Concurrent modification during iteration when body containing joints is destroyed

I'm using Flame & Forge2d draw some components based on the state of my application. There's also the option to filter such state to display only a certain type of data, which in turn means the Forge2DGame rebuilds to reflect the new data source.

In my simulation, I have the components drawn into a tree-like structure, where children are tied to their parent through a Joint. Whenever my game gets rebuilt (and, in the process, destroyed) I get the following exception:
The following ConcurrentModificationError was thrown building _BodyBuilder: Concurrent modification during iteration: Instance(length:2) of '_GrowableList'.

It seems that the culprit is forge2d/lib/src/dynamics/world.dart:144:

  // Delete the attached joints.
  for (final joint in body.joints) {
    destroyListener?.onDestroyJoint(joint);
    destroyJoint(joint);
  }

Maybe something in the line of this would work to fix it?

Here's a minimal reproducible example:

import 'dart:math' as math;

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flame_forge2d/body_component.dart';
import 'package:flame_forge2d/forge2d_game.dart';
import 'package:flutter/material.dart';
import 'package:forge2d/forge2d.dart';

void main() {
  runApp(const MaterialApp(home: SampleScreen()));
}

class SampleScreen extends StatefulWidget {
  const SampleScreen({Key? key}) : super(key: key);

  @override
  State<SampleScreen> createState() => _SampleScreenState();
}

class _SampleScreenState extends State<SampleScreen> {
  int childrenCount = 3;

  void incr() => setState(() => childrenCount += 1);

  void decr() => setState(() => childrenCount -= 1);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        alignment: AlignmentDirectional.topEnd,
        children: [
          GameWidget(game: SampleGame(childrenCount)),
          Positioned(
            bottom: 20,
            right: 20,
            child: Row(
              children: [
                IconButton(onPressed: incr, icon: const Icon(Icons.add)),
                IconButton(onPressed: decr, icon: const Icon(Icons.remove)),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class SampleGame extends Forge2DGame with HasTappables {
  SampleGame(this.count) : super(gravity: Vector2(0, 0));
  final int count;

  @override
  Color backgroundColor() => Colors.transparent;

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    final worldCenter = screenToWorld(size * camera.zoom / 2);
    add(SampleComponent(worldCenter, radius: 8, numberOfChildren: count));
  }
}

class SampleComponent extends BodyComponent with Tappable {
  SampleComponent(
    this._position, {
    required this.radius,
    this.numberOfChildren = 0,
    this.parentComponent,
  }) {
    paint = Paint()..color = Colors.teal;
  }

  final double radius;
  final Vector2 _position;
  final int numberOfChildren;
  final SampleComponent? parentComponent;

  @override
  Future<void> onLoad() async {
    await super.onLoad();

    for (var i = 0; i < numberOfChildren; i++) {
      final angle = i * (2 * math.pi / numberOfChildren);

      var polar = Vector2(math.cos(angle), math.sin(angle));
      final scaled = polar.clone()..scaleTo((radius + radius / 3));

      var component = SampleComponent(_position - scaled,
          radius: radius / 3, parentComponent: this);

      gameRef.add(component);
    }
  }

  @override
  Body createBody() {
    final bodyDef = BodyDef()
      ..userData = this
      ..angularDamping = 0.8
      ..position = _position
      ..type = BodyType.dynamic;

    final shape = CircleShape();
    shape.radius = radius;

    final fixtureDef = FixtureDef(shape)
      ..restitution = 0.8
      ..density = 1.0
      ..friction = 0.4;

    final body = world.createBody(bodyDef)..createFixture(fixtureDef);

    if (parentComponent != null) {
      final jointDef = DistanceJointDef();
      jointDef.initialize(
        body,
        parentComponent!.body,
        body.position,
        parentComponent!.body.position,
      );
      world.createJoint(jointDef);
    }

    return body;
  }
}

Full Stacktrace

======== Exception caught by widgets library =======================================================
The following ConcurrentModificationError was thrown building _BodyBuilder:
Concurrent modification during iteration: Instance(length:2) of '_GrowableList'.

When the exception was thrown, this was the stack: 
#0      ListIterator.moveNext (dart:_internal/iterable.dart:336:7)
#1      World.destroyBody (package:forge2d/src/dynamics/world.dart:144:30)
#2      BodyComponent.onRemove (package:flame_forge2d/body_component.dart:146:11)
#3      Component.onRemove.<anonymous closure> (package:flame/src/components/component.dart:208:13)
#4      IterableMixin.forEach (dart:collection/iterable.dart:45:35)
#5      Component.onRemove (package:flame/src/components/component.dart:207:14)
#6      _GameWidgetState.didUpdateWidget (package:flame/src/game/game_widget/game_widget.dart:201:22)
#7      StatefulElement.update (package:flutter/src/widgets/framework.dart:4943:57)
#8      Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#9      RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:5787:32)
#10     MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6445:17)
#11     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#12     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#13     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#14     StatelessElement.update (package:flutter/src/widgets/framework.dart:4834:5)
#15     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#16     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#17     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#18     ProxyElement.update (package:flutter/src/widgets/framework.dart:5108:5)
#19     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#20     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#21     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#22     ProxyElement.update (package:flutter/src/widgets/framework.dart:5108:5)
#23     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#24     RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:5787:32)
#25     MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6445:17)
#26     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#27     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#28     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11)
#29     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#30     StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5)
#31     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#32     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#33     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#34     ProxyElement.update (package:flutter/src/widgets/framework.dart:5108:5)
#35     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#36     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#37     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11)
#38     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#39     StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5)
#40     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#41     SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6291:14)
#42     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#43     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#44     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#45     StatelessElement.update (package:flutter/src/widgets/framework.dart:4834:5)
#46     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#47     SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6291:14)
#48     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#49     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#50     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11)
#51     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#52     StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5)
#53     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#54     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#55     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11)
#56     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#57     StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5)
#58     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#59     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#60     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#61     ProxyElement.update (package:flutter/src/widgets/framework.dart:5108:5)
#62     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#63     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#64     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#65     StatelessElement.update (package:flutter/src/widgets/framework.dart:4834:5)
#66     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#67     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#68     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11)
#69     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#70     StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5)
#71     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#72     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#73     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#74     ProxyElement.update (package:flutter/src/widgets/framework.dart:5108:5)
#75     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#76     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#77     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11)
#78     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#79     StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5)
#80     Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15)
#81     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16)
#82     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11)
#83     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#84     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2659:19)
#85     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21)
#86     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5)
#87     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1144:15)
#88     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1081:9)
#89     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:995:5)
#93     _invoke (dart:ui/hooks.dart:151:10)
#94     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308:5)
#95     _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
====================================================================================================

Thanks for the great package! Let me know if any further info is needed.

Include generic for `world.createJoint`

Problem to solve

Avoid casting when doing something as:

PrismaticJoint prismaticJoint = world.createJoint(prismaticJointDef) as PrismaticJoint

Proposal

Use of generics to avoid casting:

PrismaticJoint prismaticJoint = world.createJoint<PrismaticJoint>(prismaticJointDef)

More information

Possible solutions

  1. Updating function signature to T createJoint<T extends Joint>(JointDef def) and return to return joint as T; (Simplest Solution)
  2. Refactoring joint.dart to perhaps benefit from OOP and simplify static method static Joint create(World world, JointDef def)
  3. Open to further suggestions

I'm interested in working on a PR for this.

How can I create a BodyComponent that keeps moving horizontally?

PositionComponent was driven by redefining position as follows.

@OverRide
void update(double dt) {
super.update(dt);
position += Vector2( 1, 0)
}

However, since BodyComponent's position is only get, it cannot be redefined and cannot be moved horizontally.
If there is a way to handle this, could you please let me know?

feat: deprecate `JointType` in favour of dart type system

Problem to solve

Use of JointType enum is redundant or in many cases loses type inference.

Proposal

Remove JointType enum in favour of dart type system to simplify the library.

More information

I predict this would be a breaking change.


I'm interested in working on a PR for this.

Question: Where is the "testbed"

When I looked at the mousejoint in the code it says I have to look at the testbed if I want to learn how to use it.
But where is the testbed?

[Feature Request] Box2d Lights

Hi! First of all thank you very much for all the work implied in this project. It looks promising! ๐Ÿ˜„ ๐Ÿ’™

A while ago I made a game with libGDX and Box2d, using Box2dLights to create nice lightnings visuals. So I was wondering if you have in mind (maybe in the future) to incorporate Box2d Lights into forge2d? I think it can be a really good addition to the package and flame itself.

camera.followBodyComponent allow to follow center not position

I have a BodyComponent with fixtures that give it a visually off-center center of gravity.
When I use camera.followBodyComponent to track it, the view centers on the body's position (the visual center), not its body center.

This means when the body rotates, the world view wobbles around since the body rotates about its center point, not its position point.

I could not find a way to work around this using anchors (since BodyComponent does not have an anchor property) nor any other way of offsetting the tracking point. This is despite the description for followBodyComponent saying "The component is "grabbed" by its anchor (default top left)"?

So to track rotating objects more smoothly, can I suggest camera.followBodyComponent provides a flag to switch between using visual (position) or center of mass (center) values?

bug: Particles are never destroyed

As far as I can see, particles in a particle system are never destroyed.

In the original LiquidFun library, particles expired after a certain time period:

https://google.github.io/liquidfun/Programmers-Guide/html/md__chapter11__particles.html

Looking through the particle system in Forge2D however, I can't see anyway that a particle is ever removed automatically from the particle system. The only time a particle is removed from the system's internal list is if it is a "zombie" by having it's flags property set to have the zombie flag. However, I can't see any code that ever does this.

Am I missing something here?

queryAABB does not work

According to box2d documentations this code shoud work but nothing gets logged.

class Game extends Forge2DGame{

  Game(): super(zoom: 1, gravity: Vector2(0, 0));

  @override
  Future<void>? onLoad() async{
    super.onLoad();
    add(Planet(Vector2(100, 50)));
    add(Planet(Vector2(700, 300)));
    add(Player());
    world.queryAABB(MyCallBack(), AABB.withVec2(Vector2(-2000, -2000), Vector2(2000, 2000)));
  }
}

class MyCallBack extends QueryCallback{

  @override
  bool reportFixture(Fixture fixture) {
    print("Called");
    return true;
  }
}

class Player extends BodyComponent{
  @override
  Body createBody() {
    var bodyDef = BodyDef(type: BodyType.dynamic, position: Vector2(320, 220), linearVelocity: Vector2(-10, -10));
    var body = world.createBody(bodyDef);
    var shape = CircleShape();
    shape.radius = 15;
    body.createFixtureFromShape(shape);
    renderBody = true;
    return body;
  }
}

class Planet extends BodyComponent{
  final Vector2 position;
  Planet(this.position);

  @override
  Body createBody() {
    var bodyDef = BodyDef(type: BodyType.static, position: position);
    var body = world.createBody(bodyDef);
    body.createFixtureFromShape(CircleShape()..radius = 50);
    return body;
  }
}

There is clearly overlap between game objects and queried aabb but reportFixture never gets called. Have I missed something?

bug: chain shape collisions throw error

hi there,
for my application I need to recreate a chain shape each frame based on some computer vision contour tracking. Works fine with polygons but wanted to use chain shapes as need concave hulls. However, when doing this I frequently get the this error despite the only fixtures colliding being the chain shape and some circles:

Not compatible contact type, line 121 in 'package:forge2d/src/dynamics/contacts/contact.dart

Note that the circles may be anywhere at the time the chain shape is drawn although I understand chain shape supports collision from both sides (I can remove circle objects manually if inside chain shape). Any advice? My fallback would be to triangulate the poly and create multiple polys/tris but this is a lot more expensive.

Accessing Mutable Settings

Now that velocityIterations and positionIterations have been moved to settings.dart, how are users of Forge2d suppose to access these mutable settings? It seems like there should be getters and setters for these mutable settings. This is also true for the mutable setting velocityThreshold. All of the other values in settings.dart are immutable. If getters and setters are not desirable, then I believe setting.dart should be exported in forge2d.dart so users of the library can access the variables.

sensor-sensor collision

should I be able to detect sensors colliding with other sensors?
I can successfully detect contacts between a physics body and a sensor.

I am using body.setPosition to move one of my sensors so not sure if that is a problem with the way I am moving it or if somehow sensors do not interact with each other.

My use case is this:

I have sensors to detect when the player enters them to perform some action for things like teleporters or objects the player can pickup.

But there are something I want the player to be able to specifically "use" so when the player is i the use state I want to turn on a sensor that detects if it is within other sensors to be able to use the physics system to find what might be usable.

Static and Kinetic Friction

Hi all,

Thanks for developing such an amazing framework for Flutter. Using Froge2d, I am trying to develop a 2D board game (named Carrom) exactly like this one: https://play.google.com/store/apps/details?id=com.miniclip.carrom

Everything went fine until I hit the roadblock on implementing the Friction between the board and the pucks (bodies). If you look at the game in the link I provided, you will see the pucks are kind of steady when not applying enough force from a collision. On the other hand, they implemented the proper physics for Static and Kinetic friction when a body slides over a plane (explained here https://www.youtube.com/watch?v=RIBeeW1DSZg).

I tried to replicate that using restitution and the friction properties of the fixture but looks like the restitution is not exactly for this and the friction property is really for the collisions of two bodies, having nothing to do with the friction between the bodies and the unlying plane.

I tried using the FrictionJoint but that is also not implement the correct friction algorithm as per physics.

I am more interested in implementing static friction for my game. Tried looking into the Collision code but the code is very cryptic for me.

Wondering, if anybody had the same issue, or if you have any suggestions.

Feel free to check out the game I am developing here https://gg-carrom.web.app/

Thanks!

feat: update API to allow optional parameters

Description

From flame, one can instantiate a component as follows:

 textComponent = TextComponent(
    text: counter.toString(),
    textRenderer: _textPaint,
  );

See implementation here.

For consistency, perhaps it would be nice to update forge2d API to also support this pattern. For example, with shapes. We could:

final shape = CircleShape(radius: radius);

instead of

final shape = CircleShape()
  ..radius = radius;

Additional Context
Personally, both can be seen as equivalent. I think both APIs should be supported (cascading and optional parameters). Besides consistency with flame, one could also argue that using the positional parameter avoids setting/changing the value first unnecessary, since we already know its computed value and will change instantly after.

In addition, we also benefit from the analyser when we are setting default values.

This issue is open to discussion. If we decide to proceed I'm willing to contribute with this update.

settings are difficult to change

There are some tunable limits in src/settings.dart. I couldn't find a way for the caller to pass in new values for these. So I created a fork with my values. I realize these limits aren't meant to be changed often but I have found it useful. The presenting case was to increase maxTranslation in order to verify the cause of my body's velocity limit was this parameter and not something wrong in my logic. It would be very useful to be able to tune these settings without forking a new version.

Bug in `particle/particle_system.dart`

I think that the commented line (particle/particle_system.dart line 233) below needs deleting:

for (var y = (aabb.lowerBound.y / stride).floor() * stride;
          y < upperBoundY;
          y += stride) {
        for (var x = (aabb.lowerBound.x / stride).floor() * stride;
            x < upperBoundX;
            x += stride) {
          final p = _tempVec..setValues(x, y);
          if (shape.testPoint(identity, p)) {
            p.setFrom(Transform.mulVec2(transform, p));
            final particle = seedParticle.clone();
            p.sub(groupDef.position); // <---- This needs removing
            particle.position.setFrom(p);
            p.scaleOrthogonalInto(
              groupDef.angularVelocity,
              particle.velocity,
            );
            particle.velocity.add(groupDef.linearVelocity);
            createParticle(particle);
          }
        }
      }

By subtracting the group definition's position from the particle's position it causes all particles in the group being created to be centred around world position (0, 0). If you remove the commented line then any offset you apply to the group's position (via GroupDef.position is honoured.

This bug is also present in JBox2D.

Error: 'Viewport' is imported from both 'package:flame/src/game/viewport.dart' and 'package:flame_forge2d/viewport.dart'.

Hi, I just started using forge2d and I can't manage to get it running. This literally happens on an empty project. My code is just:

// main.dart
void main() {
  runApp(GameWidget(game: MyGame()));
}
// game.dart
class MyGame extends Forge2DGame {} // This works if I use flame's BaseGame instead.

My dependencies look like this:

// pubspec.yaml

dependencies:
  # other stuff
  flame: ^1.0.0-rc7  # tried removing this
  forge2d: ^0.6.5  # tried removing this
  flame_forge2d: ^0.6.4-rc4

I'm kinda new to dart/flutter, so I actually have no idea what's the todo here.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.