Update 'Analog Clock'
parent
486d2f29e5
commit
0e4dea33d2
@ -486,3 +486,51 @@ It all looks like this:
|
||||
<a href="https://pgetinker.com/s/SnIkSOJ7Vk" title="Click to try it out!" target="_blank">[***Try it out!***]</a>
|
||||
|
||||
<a href="https://pgetinker.com/s/SnIkSOJ7Vk" title="Click to try it out!" target="_blank"><img src="https://pit.pgetinker.com/S2ySVCFsMKgw.png" width="256" height="240"></a>
|
||||
|
||||
## "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!
|
||||
|
||||
<a href="https://pgetinker.com/s/k2GF-BTk2tQ" title="Click to try it out!" target="_blank">[***Try it out!***]</a>
|
||||
|
||||
<a href="https://pgetinker.com/s/k2GF-BTk2tQ" title="Click to try it out!" target="_blank"><img src="https://pit.pgetinker.com/W4tqHfCm4TXo.png" width="256" height="240"></a>
|
Loading…
x
Reference in New Issue
Block a user