Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different behaviour function applyLinearVelocity in windows (120 fps) and android (60 fps) #3162

Closed
1 task done
drakkonne007 opened this issue May 17, 2024 · 11 comments
Closed
1 task done
Labels

Comments

@drakkonne007
Copy link

drakkonne007 commented May 17, 2024

What happened?

When I was testing my game on multiple platforms, I noticed that once the applyLinearImpulse(Vector2(3000, 0)) gives different results on the windows platform (120fps) and on my Android (60fps). In Windows, the distance the object traveled was noticeably greater than on the phone.
The code is written in such a way as to guarantee acceleration once and compare different platforms

What do you expect?

I expect the distance to be the same for all platforms

How can we reproduce this?

class OrthoPlayer extends SpriteAnimationComponent with KeyboardHandler
{
Body? groundBody;
bool isNeedImpulse = true;

@override
  Future<void> onLoad() async
  {
    position = Vector2(100,100);
    FixtureDef fix = FixtureDef(PolygonShape()..set([Vector2(-10,-10),Vector2(-10,10),Vector2(10,10),Vector2(10,-10)]), friction: 
    0.1, density: 0.1);
   groundBody = BodyDef(type: BodyType.dynamic, position: position, fixedRotation: true),
      gameRef.world.physicsWorld);

  @override
  bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed)
 {
       if(keysPressed.contains(LogicalKeyboardKey.keyE) && isNeedImpulse ){
           isNeedImpulse = false;
          groundBody?.applyLinearImpulse(Vector2(3000, 0));
       }
 }

  @override
  void update(double dt) 
     {
           super.update(dt);
           position = groundRigidBody?.position ?? position;
           //after the body stops, the distance is different
     }
}

What steps should take to fix this?

No response

Do have an example of where the bug occurs?

No response

Relevant log output

No response

Execute in a terminal and put output into the code block below

Output of: flutter doctor -v

PS C:\kyrgyz_epos_game> flutter doctor -v
[√] Flutter (Channel beta, 3.22.0-0.3.pre, on Microsoft Windows [Version 10.0.22631.3593], locale ru-RU)
• Flutter version 3.22.0-0.3.pre on channel beta at c:\flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 87b652410d (3 weeks ago), 2024-04-23 21:41:18 -0500
• Engine revision b4bfd45986
• Dart version 3.4.0 (build 3.4.0-282.3.beta)
• DevTools version 2.34.3

[√] Windows Version (Installed version of Windows is version 10 or higher)

[√] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at C:\Users\gagin\AppData\Local\Android\sdk
• Platform android-34, build-tools 34.0.0
• Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
• Java version OpenJDK Runtime Environment (build 17.0.9+0--11185874)
• All Android licenses accepted.

[√] Chrome - develop for the web
• Chrome at C:\Users\gagin\AppData\Local\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.7.5)
• Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
• Visual Studio Community 2022 version 17.7.34202.233
• Windows 10 SDK version 10.0.22621.0

[√] Android Studio (version 2023.2)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.9+0--11185874)

[√] VS Code (version 1.82.3)
• VS Code at C:\Users\gagin\AppData\Local\Programs\Microsoft VS Code
• Flutter extension can be installed from:
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[√] Connected device (3 available)
• Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.22631.3593]
• Chrome (web) • chrome • web-javascript • Google Chrome 124.0.6367.208
• Edge (web) • edge • web-javascript • Microsoft Edge 124.0.2478.97

[√] Network resources
• All expected network resources are available.

Affected platforms

Android, Windows

Other information

Version of my libraries:

flame-1.17.0
flame_forge2d-0.18.0
forge2d-0.13.0

Are you interested in working on a PR for this?

  • I want to work on this
@drakkonne007
Copy link
Author

image
image

First - on windows
Second - on Android.

In this example I once for all time call function applyLinearImpulse(Vector2(0, -5000));

But еhe player does not move up the same level

@spydon
Copy link
Member

spydon commented May 27, 2024

I'm guessing that you're hitting the max force per tick.
What is your zoom level, have you kept the default 10?

@drakkonne007
Copy link
Author

Yes, but on the contrary I multiply the rigid body position by 10, because I learned about Forge2d much later than I made the game.
I tried it with completely different values, and the speed is always completely different on the computer and on the phone. I have a sprint in the game, when I run without it, the speed on the computer and on the phone is also completely different. Although when I press sprint, the player on both devices starts running faster, i.e. this is not the maximum speed

@drakkonne007
Copy link
Author

video_2024-05-28_10-41-17.mp4

@spydon
Copy link
Member

spydon commented May 28, 2024

If you try a simpler example like https://examples.flame-engine.org/#/flame_forge2d_Tappable_Body, do you get the same behavior?

@drakkonne007
Copy link
Author

Absolutly yes. I just copied this example (https://github.com/flame-engine/flame/blob/main/packages/flame_forge2d/example/lib/main.dart) into clean new project and replace body.applyLinearImpulse(Vector2.random() * 5000);
on body.applyLinearImpulse(Vector2(3000,0));
And on the phone the speed of the ball is half as much. Maybe the DPI of the device matters?

@spydon
Copy link
Member

spydon commented May 28, 2024

DevKage had a look at it too and he found this from Box2D:
image

So I'm guessing the dt for forge2d should be set to a constant (or close to constant) and then that the rendering should interpolate between the results for this to be able to work more deterministically between different framerates.

@drakkonne007
Copy link
Author

So, I must override update() in my root game element about like this:

double currentDeltaTime = 0;
const double tickLimit = 1.0 / 30;

@override
void update(double dt)
{
    if(dt > tickLimit){ //to skip lags frame
       return;
    }
    currentDeltaTime  += dt;
    if(currentDeltaTime >= tickLimit){
       super.update(currentDeltaTime);
       currentDeltaTime = 0;
    }
}

@spydon
Copy link
Member

spydon commented May 28, 2024

That would probably work, but if I were you I would only set the physics engine to a fixed dt meanwhile the rest runs with a variable dt, so then you'd need to override update in the Forge2DWorld instead:
https://github.com/flame-engine/flame/blob/main/packages/flame_forge2d/lib/forge2d_world.dart#L22-L24

@drakkonne007
Copy link
Author

Yes, I tested several accelerations using a simple example and indeed - the speed is now the same on the phone and on the computer. Thank you!

@drakkonne007
Copy link
Author

drakkonne007 commented May 29, 2024

So, most staibility with this code:

static const double tickLimit = 1.0 / 45;
double currentDt = 0;

void update(double dt)
  {
    currentDt += dt;
    int cycles = currentDt ~/ tickLimit;
    for(int i = 0; i < cycles; i++){
      physicsWorld.stepDt(tickLimit);
    }
    currentDt -= cycles * tickLimit;
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants