diff --git a/Analog-Clock.md b/Analog-Clock.md index dc2fd68..26bcac1 100644 --- a/Analog-Clock.md +++ b/Analog-Clock.md @@ -486,3 +486,51 @@ It all looks like this: [***Try it out!***] + +## "Ticking" Jump Back Motion +When the second hand jumps forward, it has a slight jump back as it locks into place. It's very subtle but also a feature in analog clocks that I like. Let's try to recreate that subtle detail. + +Start by adding a new variable to track the amount of time it takes before the second hand "jumps back". We'll make it 0.02 seconds for now (very subtle). We also need a variable tracking what the amount of seconds that have passed was the previous frame. If it ever differs, we set the `secondHandBounceTimer` to `0.02` and it starts decreasing by `GetElapsedTime()` (the amount of time in seconds that have passed for this rendering frame). + +One way we would be able to trigger the "tick back" motion is by modifying the `DrawHand()` lambda inside `DrawClockHands()` to have a float parameter passed in with an "additional rotation" amount. + +First update the `DrawHand()` lambda with the new parameter and angle offset: +```cpp + const auto DrawHand=[&](const float handLength,const float secondsPerRevolution,const olc::Pixel col,const float angleOffset=0.f){ + using namespace std::numbers; + const float angle{float(2*pi*fmod(totalTime,secondsPerRevolution)/secondsPerRevolution+angleOffset)}; + olc::vf2d handVec{handLength,float(angle-pi/2)}; + DrawLine(GetScreenSize()/2,GetScreenSize()/2+handVec.cart(),col); + }; +``` +Add two new variables into the game class: +```cpp +public: + bool OnUserCreate() override + { + return true; + } + + float secondHandBounceTimer{0.f}; + size_t lastSecond{}; +``` +Update the last second value and the bounce timer if it changes. +```cpp + if(lastSecond!=localTime->tm_sec){ + secondHandBounceTimer=0.02f; + lastSecond=localTime->tm_sec; + } +``` +In `OnUserUpdate()` we have to tick down the bounce timer. We use `std::max` as it's equivalent to `if(secondHandBounceTimer>0)secondHandBounceTimer-=fElapsedTime; secondHandBounceTimer=std::max(secondHandBounceTimer,0.f);` +```cpp + secondHandBounceTimer=std::max(secondHandBounceTimer-fElapsedTime,0.f); +``` +Finally, apply the bounce timer to the `DrawHand()` call for the second hand. +```cpp + DrawHand(85,60,olc::RED,secondHandBounceTimer); +``` +Screenshots don't do it justice, but look at the results for yourself and it is a pretty convincing behavior! + +[***Try it out!***] + + \ No newline at end of file