2

I'm playing around with Forge2d on Flutter Flame and created a Ninja which throws Kanuies (a character shooting bullets basically). If I create Kanuies and the Ninja separately then add them separately to the game world, all will be fine. However, I want the Ninja class to be responsible for login for throwing the Kanui. So I was wondering what is the right way to add a bullet component to a character component in Forge2d.

In my current code, inside Ninja Class, if I call add(Kanui) there will be no graphics shown about Kanuie NOT even with debugMode=true . However, if use addToParrent(Kanui) it will be fine again.

Below is the link to my code. Please have a look and suggest corrections. I'll provide some snippets here as well.

https://github.com/bmd007/flame_playground/blob/154cc0a9a99cc4bd5732e8d0c94bfa38093b0298/lib/my_girl.dart#L134

Ninja Class:

class MyGirl extends BodyComponent {

  late SpriteAnimationComponent component;
  Queue<MyGirlKanui> kanuies = Queue<MyGirlKanui>();

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    idleAnimation = await gameRef.loadSpriteAnimation("red_girl/idle_spriteSheet.png", idleAnimationData);

    component = SpriteAnimationComponent()
      ..animation = idleAnimation
      ..size = Vector2.all(6)
      ..anchor = Anchor.center;
    add(component);

    kanuies.add(MyGirlKanui(initialPosition));
  }


  @override
  Body createBody() {
    final shape = PolygonShape()..setAsBoxXY(3, 3);
    final fixtureDefinition = FixtureDef(shape, density: 2, restitution: 0.1, friction: 2);
    final bodyDefinition = BodyDef(position: initialPosition, type: BodyType.dynamic)..fixedRotation = true;
    return world.createBody(bodyDefinition)..createFixture(fixtureDefinition);
  }

  throwKanui() async {
    if (kanuies.isNotEmpty) {
      var kanui = kanuies.removeFirst();
      // await parent?.add(kanui);
      await add(kanui);
      kanui.component.position = component.position;
      kanui.body.linearVelocity.x = 30;
    }
  }

I call the throw method when a UI button is pressed.

Mahdi Amini
  • 402
  • 1
  • 3
  • 17

1 Answers1

3

In Forge2D you shouldn't add any bodies as children to other components. You can add the HasGameRef<Forge2DGame> mixin to the component and then you can add the bullets directly to the game. Also don't forget to put the body of the bullet to isBullet = true if the "bullet" is moving very fast, otherwise you could end up with tunneling (where the body passes through the object that it is supposed to hit).

spydon
  • 9,372
  • 6
  • 33
  • 63
  • thanks for the response, would you explain why we shouldn't have subcomponents (components as children of other components). Because the API seems to support it and documentation also doesn't talk about it. – Mahdi Amini Dec 22 '22 at 22:21
  • also it seems that BodyComponent already has the `HasGameRef` mixin it self. – Mahdi Amini Dec 22 '22 at 22:27
  • 1
    It supports it because BodyComponent is also a component, we should probably put an assertion in BodyComponent so that people don't add it as a child to another BodyComponent. BodyComponents are only meant to be added and rendered on a top level, since Forge2D/Box2D doesn't have a concept of nested bodies, all bodies should live on a top level in the physics world. – spydon Dec 22 '22 at 23:49
  • amazing, thanks very much for your answer. probably mentioning this fact in a bolder manner in the documentation would help as well. – Mahdi Amini Dec 22 '22 at 23:58
  • 1
    We're open for PRs to the docs if you'd be interested in updating it. :) – spydon Dec 23 '22 at 09:30
  • https://github.com/flame-engine/flame/issues/2240 – Mahdi Amini Dec 25 '22 at 09:39
  • 1
    Finally I made it https://github.com/flame-engine/flame/pull/2242 :)) – Mahdi Amini Dec 25 '22 at 17:13
  • @spydon What about adding a Flame (`PositionedComponent`) child to a Forge2d(`BodyComponent`) parent? I want to be able to change the child's position and angle directly while it being anchored to the parent body. And this body should react to physcis events along with its child. example I am working on is a Tank Body and a Turret anchored to it. Both of them are controllable independently. Is this possible? Should I create a new SO question or issue in forge2d repo? Thanks – aytunch Jan 11 '23 at 18:48
  • 1
    @aytunch this is a question outside of the scope of OP's question, but the simple answer is yes. You can either write your own SO question, or join our Discord if you want a longer answer. :) – spydon Jan 11 '23 at 20:14