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

Smooth badguy and other object motion when frame prediction is on #3044

Merged
merged 1 commit into from
Sep 16, 2024

Conversation

mstoeckl
Copy link
Contributor

This commit extrapolates the drawn position for badguys and some other moving objects, making their motion look smoother when both the frame rate is high and frame prediction is on. This is already being done for Tux, but that is not enough to always produce the illusion of smooth motion. Without this commit one can at high frame rates see choppy motion on carried objects when Tux is running, and on quickly moving badguys, like a sliding MrIceBlock.

@tobbi
Copy link
Member

tobbi commented Aug 13, 2024

I'm gonna test this in a few.

@tobbi
Copy link
Member

tobbi commented Aug 16, 2024

"A few" turned out to take a little longer. However, seems like it looks good. 👍

Copy link
Member

@Zwatotem Zwatotem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't test, but code looks good.

Copy link
Member

@bruhmoent bruhmoent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested.

src/badguy/badguy.cpp Outdated Show resolved Hide resolved
This commit extrapolates the drawn position for badguys and some other
moving objects, making their motion look smoother when both the frame
rate is high and frame prediction is on. This is already being done for
Tux, but that is not enough to always produce the illusion of smooth
motion. Without this commit one can at high frame rates see choppy
motion on carried objects when Tux is running, and on quickly moving
badguys, like MrIceBlock.
Copy link
Member

@MatusGuy MatusGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work with the tarantula? When I was writing the code for that I had to pull off some stinky tricks and as a result I don't think it uses velocity properly?

Also, you say "when frame prediction is on" but you don't check for this setting anywhere in this PR.

@mstoeckl
Copy link
Contributor Author

mstoeckl commented Aug 21, 2024

Does this work with the tarantula?

It looks fine to me, when I test it at 165Hz. (It's possible the velocity values are a bit off, but if so they aren't wrong enough to be noticeable for me.) (Note: looking at the code, the tarantula position is extrapolated via BadGuy's implementation of ::draw, but its string is not; however, there appears to always be enough overlap between the two that the lower string end is never visible.)

Also, you say "when frame prediction is on" but you don't check for this setting anywhere in this PR.

The distances that drawing positions are extrapolated are proportional to context.get_time_offset(), which varies depending on the real time/last logic step time difference when frame prediction is on. When frame prediction is off, context.get_time_offset() is always zero and objects are drawn as normal. A specific check is not necessary.

@bruhmoent
Copy link
Member

@mstoeckl What do you think about implementing this, but for scripted objects? (Not related to this pr).

@mstoeckl
Copy link
Contributor Author

mstoeckl commented Sep 5, 2024

What do you think about implementing this, but for scripted objects? (Not related to this pr).

Doing position extrapolation for ScriptedObjects is very low priority for me, as AFAIK they are rare and only seen moving in certain cutscenes. Also, they use MovingSprite's ::draw implementation, and could in theory be handled in a more general fashion.

The next most important things to update (which I may or may not get to myself) are probably:

  • Things that use Path (like Camera, moving platforms, moving coins, etc.): getting position predictions (or even just a velocity estimate) for the next few milliseconds would require some adjustments to the Path class. (Currently the Camera class interpolates one frame behind, which is not ideal and only looks OK for Camera because there are no other objects to compare it with. Having a moving platform be one frame behind Tux's position could lead to some unfortunate narrow misses -- so it's better to do this right.)

  • MovingSprite and the many classes directly using its ::draw() implementation; MovingSprite does not (at draw time) have any velocity estimate (it had through its base class MovingObject some collision information with associated velocity, but AFAIK the way collisions are handled this gets reset before ::draw() gets called, and thus cannot be used.). I think some adjustment to MovingObject would need to be made to get a 'next-frame' velocity estimate, after which one could adjust MovingSprite to use it.

@MatusGuy MatusGuy merged commit 608c8df into SuperTux:master Sep 16, 2024
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants