matti peter
matti peter

Reputation: 201

How to make BodyDef smooth movement

I tried to use the method setTransform like this:

@override
  void update(double dt) {
    super.update(dt);
    increaseTimer.update(dt);
    if (side == 3) {
      body.setTransform(Vector2(0, gameRef.increasedHeight), 0);
    }
  }

But the item looks like it is flashing from point A to point B, and the Items above this body are falling. I just want this body and the items above to move smoothly in a direction , how to achieve this? Thanks, I found some methods like using MouseJoint, but I guess it is too complicated for my topic?

=========UPDATE==========

Hi spydon, thanks for reply, I checked your answer, sry I didnt describe my question clearly.

The item I want to keep moving upward is like a wall/ground so it is a static body, therefore applyLinearImpulse/applyForce does not work right (since these both works only for dynamic body?).

Therefore I found setTransform, which works for static body,

increasedHeight++; //<= in update method

body.setTransform(Vector2(0, increasedHeight), 0);

works fine which make my ground move upward in 1 unit, but if the distance is larger than 1 unit, like increasedHeight = increasedHeight + 10;, the ground will be beamed to top and balls on this ground will be falling, which I don't want to, I tried to make balls and ground move together upward, is it possible?

Thanks for your time!

=========2.UPDATE==========

Hi Spydon, thanks again for your help! Plz check the example I created, since this Ground didn't move upward as I expected and just stuck in the position ...

class Ground extends SpriteBodyComponent {
  Vector2 groundPosition;
  bool removed = false;

  final velocity = Vector2(0, 1000);

  Ground({Sprite sprite, Vector2 size, this.groundPosition}) : super(sprite, size);


  @override
  Body createBody() {
    final shape = CircleShape()..radius = size.x / 4;
    var position = groundPosition.clone();
    var worldPosition = viewport.getScreenToWorld(position);

    final fixtureDef = FixtureDef()
      ..shape = shape
      ..restitution = 0.1
      ..density = 0.1
      ..friction = 0.1;

    final bodyDef = BodyDef()
      ..userData = this
      ..angularDamping = 0.1
      ..position = worldPosition
      ..type = BodyType.STATIC;

    return world.createBody(bodyDef)..createFixture(fixtureDef);
  }

  @override
  void update(double dt) {
    super.update(dt);
    body.setTransform(velocity * dt, 0);
    print('body position == ${body.position.y}'); //<= body position == 16.667
  }

}

Upvotes: 1

Views: 400

Answers (1)

spydon
spydon

Reputation: 11562

You should almost never use setTransform on dynamic bodies, since this disturbs the physics calculations. If you are not certain that you need the physics simulation you most likely want to go with pure Flame and use one of the MoveEffects instead.

If you do need Forge2D, you should either use body.applyLinearImpulse or body.applyForce, depending on how you want to affect your bodies movement.

You can read more about it here and you can check out the flame_forge2d examples here, you can get to the code for each example by pressing < > in the upper right corner.

Reply to updated question:

You should change these things in your update method which gives you a delta time dt, this delta time you use together with the velocity that you want to the body to change with, for example:

final velocity = Vector2(0, 100); // Will move with 100px/s

@override
void update(double dt) {
  if(!velocity.isZero) {
    // Here you have to multiply with dt, to make the transform become px/s
    body.setTransform(velocity * dt, 0);
  }
}

Upvotes: 1

Related Questions