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">[***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>
|
<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